From e9b5c85041e0ccecf46e241a01f51f3daec8e215 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 1 Jul 2011 22:22:42 +0000 Subject: [PATCH] Break Sema::GetTypeForDeclarator in 2 functions, one for DeclSpec processing and another for the rest. No functionality change. llvm-svn: 134272 --- clang/lib/Sema/SemaType.cpp | 323 +++++++++++++++++++----------------- 1 file changed, 175 insertions(+), 148 deletions(-) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 2254821cb108..41d3916a5007 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -591,10 +591,11 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state, /// \param D the declarator containing the declaration specifier. /// \returns The type described by the declaration specifiers. This function /// never returns null. -static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) { +static QualType ConvertDeclSpecToType(TypeProcessingState &state) { // FIXME: Should move the logic from DeclSpec::Finish to here for validity // checking. + Sema &S = state.getSema(); Declarator &declarator = state.getDeclarator(); const DeclSpec &DS = declarator.getDeclSpec(); SourceLocation DeclLoc = declarator.getIdentifierLoc(); @@ -1712,40 +1713,22 @@ static void DiagnoseIgnoredQualifiers(unsigned Quals, << QualStr << NumQuals << ConstFixIt << VolatileFixIt << RestrictFixIt; } -/// GetTypeForDeclarator - Convert the type for the specified -/// declarator to Type instances. -/// -/// If OwnedDecl is non-NULL, and this declarator's decl-specifier-seq -/// owns the declaration of a type (e.g., the definition of a struct -/// type), then *OwnedDecl will receive the owned declaration. -/// -/// The result of this call will never be null, but the associated -/// type may be a null type if there's an unrecoverable error. -TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { - // Determine the type of the declarator. Not all forms of declarator - // have a type. +static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, + TypeSourceInfo *&ReturnTypeInfo) { + Sema &SemaRef = state.getSema(); + Declarator &D = state.getDeclarator(); QualType T; - TypeSourceInfo *ReturnTypeInfo = 0; + ReturnTypeInfo = 0; + + // The TagDecl owned by the DeclSpec. TagDecl *OwnedTagDecl = 0; - TypeProcessingState state(*this, D); - - // In C++0x, deallocation functions (normal and array operator delete) - // are implicitly noexcept. - bool ImplicitlyNoexcept = false; - switch (D.getName().getKind()) { case UnqualifiedId::IK_OperatorFunctionId: - if (getLangOptions().CPlusPlus0x) { - OverloadedOperatorKind OO = D.getName().OperatorFunctionId.Operator; - if (OO == OO_Delete || OO == OO_Array_Delete) - ImplicitlyNoexcept = true; - } - // Intentional fall-through. case UnqualifiedId::IK_Identifier: case UnqualifiedId::IK_LiteralOperatorId: case UnqualifiedId::IK_TemplateId: - T = ConvertDeclSpecToType(*this, state); + T = ConvertDeclSpecToType(state); if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) { OwnedTagDecl = cast(D.getDeclSpec().getRepAsDecl()); @@ -1759,29 +1742,26 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { case UnqualifiedId::IK_DestructorName: // Constructors and destructors don't have return types. Use // "void" instead. - T = Context.VoidTy; + T = SemaRef.Context.VoidTy; break; case UnqualifiedId::IK_ConversionFunctionId: // The result type of a conversion function is the type that it // converts to. - T = GetTypeFromParser(D.getName().ConversionFunctionId, - &ReturnTypeInfo); + T = SemaRef.GetTypeFromParser(D.getName().ConversionFunctionId, + &ReturnTypeInfo); break; } if (D.getAttributes()) distributeTypeAttrsFromDeclarator(state, T); - if (D.isPrototypeContext() && getLangOptions().ObjCAutoRefCount) - inferARCWriteback(state, T); - // C++0x [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context. // In C++0x, a function declarator using 'auto' must have a trailing return // type (this is checked later) and we can skip this. In other languages // using auto, we need to check regardless. if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto && - (!getLangOptions().CPlusPlus0x || !D.isFunctionDeclarator())) { + (!SemaRef.getLangOptions().CPlusPlus0x || !D.isFunctionDeclarator())) { int Error = -1; switch (D.getContext()) { @@ -1795,7 +1775,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { case Declarator::MemberContext: if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static) break; - switch (cast(CurContext)->getTagKind()) { + switch (cast(SemaRef.CurContext)->getTagKind()) { case TTK_Enum: assert(0 && "unhandled tag kind"); break; case TTK_Struct: Error = 1; /* Struct member */ break; case TTK_Union: Error = 2; /* Union member */ break; @@ -1841,7 +1821,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // contains a trailing return type. That is only legal at the outermost // level. Check all declarator chunks (outermost first) anyway, to give // better diagnostics. - if (getLangOptions().CPlusPlus0x && Error != -1) { + if (SemaRef.getLangOptions().CPlusPlus0x && Error != -1) { for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { unsigned chunkIndex = e - i - 1; state.setCurrentChunkIndex(chunkIndex); @@ -1857,15 +1837,86 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { } if (Error != -1) { - Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_auto_not_allowed) + SemaRef.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), + diag::err_auto_not_allowed) << Error; - T = Context.IntTy; + T = SemaRef.Context.IntTy; D.setInvalidType(true); } } - - if (T.isNull()) - return Context.getNullTypeSourceInfo(); + + if (SemaRef.getLangOptions().CPlusPlus && + OwnedTagDecl && OwnedTagDecl->isDefinition()) { + // Check the contexts where C++ forbids the declaration of a new class + // or enumeration in a type-specifier-seq. + switch (D.getContext()) { + case Declarator::FileContext: + case Declarator::MemberContext: + case Declarator::BlockContext: + case Declarator::ForContext: + case Declarator::BlockLiteralContext: + // C++0x [dcl.type]p3: + // A type-specifier-seq shall not define a class or enumeration unless + // it appears in the type-id of an alias-declaration (7.1.3) that is not + // the declaration of a template-declaration. + case Declarator::AliasDeclContext: + break; + case Declarator::AliasTemplateContext: + SemaRef.Diag(OwnedTagDecl->getLocation(), + diag::err_type_defined_in_alias_template) + << SemaRef.Context.getTypeDeclType(OwnedTagDecl); + break; + case Declarator::TypeNameContext: + case Declarator::TemplateParamContext: + case Declarator::CXXNewContext: + case Declarator::CXXCatchContext: + case Declarator::ObjCCatchContext: + case Declarator::TemplateTypeArgContext: + SemaRef.Diag(OwnedTagDecl->getLocation(), + diag::err_type_defined_in_type_specifier) + << SemaRef.Context.getTypeDeclType(OwnedTagDecl); + break; + case Declarator::PrototypeContext: + case Declarator::ObjCPrototypeContext: + case Declarator::KNRTypeListContext: + // C++ [dcl.fct]p6: + // Types shall not be defined in return or parameter types. + SemaRef.Diag(OwnedTagDecl->getLocation(), + diag::err_type_defined_in_param_type) + << SemaRef.Context.getTypeDeclType(OwnedTagDecl); + break; + case Declarator::ConditionContext: + // C++ 6.4p2: + // The type-specifier-seq shall not contain typedef and shall not declare + // a new class or enumeration. + SemaRef.Diag(OwnedTagDecl->getLocation(), + diag::err_type_defined_in_condition); + break; + } + } + + return T; +} + +static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, + QualType declSpecType, + TypeSourceInfo *TInfo) { + + QualType T = declSpecType; + Declarator &D = state.getDeclarator(); + Sema &S = state.getSema(); + ASTContext &Context = S.Context; + const LangOptions &LangOpts = S.getLangOptions(); + + bool ImplicitlyNoexcept = false; + if (D.getName().getKind() == UnqualifiedId::IK_OperatorFunctionId && + LangOpts.CPlusPlus0x) { + OverloadedOperatorKind OO = D.getName().OperatorFunctionId.Operator; + /// In C++0x, deallocation functions (normal and array operator delete) + /// are implicitly noexcept. + if (OO == OO_Delete || OO == OO_Array_Delete) + ImplicitlyNoexcept = true; + } // The name we're declaring, if any. DeclarationName Name; @@ -1888,56 +1939,56 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { switch (DeclType.Kind) { default: assert(0 && "Unknown decltype!"); case DeclaratorChunk::Paren: - T = BuildParenType(T); + T = S.BuildParenType(T); break; case DeclaratorChunk::BlockPointer: // If blocks are disabled, emit an error. if (!LangOpts.Blocks) - Diag(DeclType.Loc, diag::err_blocks_disable); + S.Diag(DeclType.Loc, diag::err_blocks_disable); - T = BuildBlockPointerType(T, D.getIdentifierLoc(), Name); + T = S.BuildBlockPointerType(T, D.getIdentifierLoc(), Name); if (DeclType.Cls.TypeQuals) - T = BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals); + T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Cls.TypeQuals); break; case DeclaratorChunk::Pointer: // Verify that we're not building a pointer to pointer to function with // exception specification. - if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { - Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) { + S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); D.setInvalidType(true); // Build the type anyway. } - if (getLangOptions().ObjC1 && T->getAs()) { + if (LangOpts.ObjC1 && T->getAs()) { T = Context.getObjCObjectPointerType(T); if (DeclType.Ptr.TypeQuals) - T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); + T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); break; } - T = BuildPointerType(T, DeclType.Loc, Name); + T = S.BuildPointerType(T, DeclType.Loc, Name); if (DeclType.Ptr.TypeQuals) - T = BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); + T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); break; case DeclaratorChunk::Reference: { // Verify that we're not building a reference to pointer to function with // exception specification. - if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { - Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) { + S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); D.setInvalidType(true); // Build the type anyway. } - T = BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name); + T = S.BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name); Qualifiers Quals; if (DeclType.Ref.HasRestrict) - T = BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict); + T = S.BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict); break; } case DeclaratorChunk::Array: { // Verify that we're not building an array of pointers to function with // exception specification. - if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { - Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + if (LangOpts.CPlusPlus && S.CheckDistantExceptionSpec(T)) { + S.Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); D.setInvalidType(true); // Build the type anyway. } @@ -1954,13 +2005,13 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // FIXME: This check isn't quite right: it allows star in prototypes // for function definitions, and disallows some edge cases detailed // in http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00133.html - Diag(DeclType.Loc, diag::err_array_star_outside_prototype); + S.Diag(DeclType.Loc, diag::err_array_star_outside_prototype); ASM = ArrayType::Normal; D.setInvalidType(true); } - T = BuildArrayType(T, ASM, ArraySize, - Qualifiers::fromCVRMask(ATI.TypeQuals), - SourceRange(DeclType.Loc, DeclType.EndLoc), Name); + T = S.BuildArrayType(T, ASM, ArraySize, + Qualifiers::fromCVRMask(ATI.TypeQuals), + SourceRange(DeclType.Loc, DeclType.EndLoc), Name); break; } case DeclaratorChunk::Function: { @@ -1976,27 +2027,27 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // and not, for instance, a pointer to a function. if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto && !FTI.TrailingReturnType && chunkIndex == 0) { - Diag(D.getDeclSpec().getTypeSpecTypeLoc(), + S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_auto_missing_trailing_return); T = Context.IntTy; D.setInvalidType(true); } else if (FTI.TrailingReturnType) { // T must be exactly 'auto' at this point. See CWG issue 681. if (isa(T)) { - Diag(D.getDeclSpec().getTypeSpecTypeLoc(), + S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_trailing_return_in_parens) << T << D.getDeclSpec().getSourceRange(); D.setInvalidType(true); } else if (T.hasQualifiers() || !isa(T)) { - Diag(D.getDeclSpec().getTypeSpecTypeLoc(), + S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_trailing_return_without_auto) << T << D.getDeclSpec().getSourceRange(); D.setInvalidType(true); } - T = GetTypeFromParser( + T = S.GetTypeFromParser( ParsedType::getFromOpaquePtr(FTI.TrailingReturnType), - &ReturnTypeInfo); + &TInfo); } } @@ -2010,7 +2061,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { if (chunkIndex == 0 && D.getContext() == Declarator::BlockLiteralContext) diagID = diag::err_block_returning_array_function; - Diag(DeclType.Loc, diagID) << T->isFunctionType() << T; + S.Diag(DeclType.Loc, diagID) << T->isFunctionType() << T; T = Context.IntTy; D.setInvalidType(true); } @@ -2019,7 +2070,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // class type in C++. if (isa(T) && T.getLocalCVRQualifiers() && (D.getName().getKind() != UnqualifiedId::IK_ConversionFunctionId) && - (!getLangOptions().CPlusPlus || !T->isDependentType())) { + (!LangOpts.CPlusPlus || !T->isDependentType())) { assert(chunkIndex + 1 < e && "No DeclaratorChunk for the return type?"); DeclaratorChunk ReturnTypeChunk = D.getTypeObject(chunkIndex + 1); assert(ReturnTypeChunk.Kind == DeclaratorChunk::Pointer); @@ -2030,43 +2081,43 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { SourceLocation::getFromRawEncoding(PTI.ConstQualLoc), SourceLocation::getFromRawEncoding(PTI.VolatileQualLoc), SourceLocation::getFromRawEncoding(PTI.RestrictQualLoc), - *this); + S); } else if (T.getCVRQualifiers() && D.getDeclSpec().getTypeQualifiers() && - (!getLangOptions().CPlusPlus || + (!LangOpts.CPlusPlus || (!T->isDependentType() && !T->isRecordType()))) { DiagnoseIgnoredQualifiers(D.getDeclSpec().getTypeQualifiers(), D.getDeclSpec().getConstSpecLoc(), D.getDeclSpec().getVolatileSpecLoc(), D.getDeclSpec().getRestrictSpecLoc(), - *this); + S); } - if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) { + if (LangOpts.CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) { // C++ [dcl.fct]p6: // Types shall not be defined in return or parameter types. TagDecl *Tag = cast(D.getDeclSpec().getRepAsDecl()); if (Tag->isDefinition()) - Diag(Tag->getLocation(), diag::err_type_defined_in_result_type) + S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type) << Context.getTypeDeclType(Tag); } // Exception specs are not allowed in typedefs. Complain, but add it // anyway. if (IsTypedefName && FTI.getExceptionSpecType()) - Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef) + S.Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef) << (D.getContext() == Declarator::AliasDeclContext || D.getContext() == Declarator::AliasTemplateContext); - if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) { + if (!FTI.NumArgs && !FTI.isVariadic && !LangOpts.CPlusPlus) { // Simple void foo(), where the incoming T is the result type. T = Context.getFunctionNoProtoType(T); } else { // We allow a zero-parameter variadic function in C if the // function is marked with the "overloadable" attribute. Scan // for this attribute now. - if (!FTI.NumArgs && FTI.isVariadic && !getLangOptions().CPlusPlus) { + if (!FTI.NumArgs && FTI.isVariadic && !LangOpts.CPlusPlus) { bool Overloadable = false; for (const AttributeList *Attrs = D.getAttributes(); Attrs; Attrs = Attrs->getNext()) { @@ -2077,13 +2128,13 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { } if (!Overloadable) - Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg); + S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg); } if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) { // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function // definition. - Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration); + S.Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration); D.setInvalidType(true); break; } @@ -2110,7 +2161,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { assert(!ArgTy.isNull() && "Couldn't parse type?"); // Adjust the parameter type. - assert((ArgTy == adjustParameterType(ArgTy)) && "Unadjusted type?"); + assert((ArgTy == S.adjustParameterType(ArgTy)) && "Unadjusted type?"); // Look for 'void'. void is allowed only as a single argument to a // function with no other parameters (C99 6.7.5.3p10). We record @@ -2120,19 +2171,19 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // is an incomplete type (C99 6.2.5p19) and function decls cannot // have arguments of incomplete type. if (FTI.NumArgs != 1 || FTI.isVariadic) { - Diag(DeclType.Loc, diag::err_void_only_param); + S.Diag(DeclType.Loc, diag::err_void_only_param); ArgTy = Context.IntTy; Param->setType(ArgTy); } else if (FTI.ArgInfo[i].Ident) { // Reject, but continue to parse 'int(void abc)'. - Diag(FTI.ArgInfo[i].IdentLoc, + S.Diag(FTI.ArgInfo[i].IdentLoc, diag::err_param_with_void_type); ArgTy = Context.IntTy; Param->setType(ArgTy); } else { // Reject, but continue to parse 'float(const void)'. if (ArgTy.hasQualifiers()) - Diag(DeclType.Loc, diag::err_void_param_qualified); + S.Diag(DeclType.Loc, diag::err_void_param_qualified); // Do not add 'void' to the ArgTys list. break; @@ -2149,7 +2200,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { } } - if (getLangOptions().ObjCAutoRefCount) { + if (LangOpts.ObjCAutoRefCount) { bool Consumed = Param->hasAttr(); ConsumedArguments.push_back(Consumed); HasAnyConsumedArguments |= Consumed; @@ -2167,10 +2218,10 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { Exceptions.reserve(FTI.NumExceptions); for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) { // FIXME: Preserve type source info. - QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty); + QualType ET = S.GetTypeFromParser(FTI.Exceptions[ei].Ty); // Check that the type is valid for an exception spec, and // drop it if not. - if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range)) + if (!S.CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range)) Exceptions.push_back(ET); } EPI.NumExceptions = Exceptions.size(); @@ -2187,7 +2238,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { if (!NoexceptExpr->isValueDependent() && !NoexceptExpr->isIntegerConstantExpr(Dummy, Context, &ErrLoc, /*evaluated*/false)) - Diag(ErrLoc, diag::err_noexcept_needs_constant_expression) + S.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression) << NoexceptExpr->getSourceRange(); else EPI.NoexceptExpr = NoexceptExpr; @@ -2210,8 +2261,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { if (SS.isInvalid()) { // Avoid emitting extra errors if we already errored on the scope. D.setInvalidType(true); - } else if (isDependentScopeSpecifier(SS) || - dyn_cast_or_null(computeDeclContext(SS))) { + } else if (S.isDependentScopeSpecifier(SS) || + dyn_cast_or_null(S.computeDeclContext(SS))) { NestedNameSpecifier *NNS = static_cast(SS.getScopeRep()); NestedNameSpecifier *NNSPrefix = NNS->getPrefix(); @@ -2240,7 +2291,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { break; } } else { - Diag(DeclType.Mem.Scope().getBeginLoc(), + S.Diag(DeclType.Mem.Scope().getBeginLoc(), diag::err_illegal_decl_mempointer_in_nonclass) << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name") << DeclType.Mem.Scope().getRange(); @@ -2248,12 +2299,12 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { } if (!ClsType.isNull()) - T = BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier()); + T = S.BuildMemberPointerType(T, ClsType, DeclType.Loc, D.getIdentifier()); if (T.isNull()) { T = Context.IntTy; D.setInvalidType(true); } else if (DeclType.Mem.TypeQuals) { - T = BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals); + T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Mem.TypeQuals); } break; } @@ -2268,7 +2319,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { processTypeAttrs(state, T, false, attrs); } - if (getLangOptions().CPlusPlus && T->isFunctionType()) { + if (LangOpts.CPlusPlus && T->isFunctionType()) { const FunctionProtoType *FnTy = T->getAs(); assert(FnTy && "Why oh why is there not a FunctionProtoType here?"); @@ -2285,7 +2336,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { FreeFunction = (D.getContext() != Declarator::MemberContext || D.getDeclSpec().isFriendSpecified()); } else { - DeclContext *DC = computeDeclContext(D.getCXXScopeSpec()); + DeclContext *DC = S.computeDeclContext(D.getCXXScopeSpec()); FreeFunction = (DC && !DC->isRecord()); } @@ -2323,16 +2374,16 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { break; } - Diag(D.getIdentifierLoc(), + S.Diag(D.getIdentifierLoc(), diag::ext_qualified_function_type_template_arg) << Quals; } else { if (FnTy->getTypeQuals() != 0) { if (D.isFunctionDeclarator()) - Diag(D.getIdentifierLoc(), + S.Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type); else - Diag(D.getIdentifierLoc(), + S.Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_typedef_function_type_use) << FreeFunction; } @@ -2349,11 +2400,11 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { } } - Diag(Loc, diag::err_invalid_ref_qualifier_function_type) + S.Diag(Loc, diag::err_invalid_ref_qualifier_function_type) << (FnTy->getRefQualifier() == RQ_LValue) << FixItHint::CreateRemoval(Loc); } else { - Diag(D.getIdentifierLoc(), + S.Diag(D.getIdentifierLoc(), diag::err_invalid_ref_qualifier_typedef_function_type_use) << FreeFunction << (FnTy->getRefQualifier() == RQ_LValue); @@ -2406,7 +2457,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // We represent function parameter packs as function parameters whose // type is a pack expansion. if (!T->containsUnexpandedParameterPack()) { - Diag(D.getEllipsisLoc(), + S.Diag(D.getEllipsisLoc(), diag::err_function_parameter_pack_without_parameter_packs) << T << D.getSourceRange(); D.setEllipsisLoc(SourceLocation()); @@ -2426,8 +2477,8 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // it expands those parameter packs. if (T->containsUnexpandedParameterPack()) T = Context.getPackExpansionType(T, llvm::Optional()); - else if (!getLangOptions().CPlusPlus0x) - Diag(D.getEllipsisLoc(), diag::ext_variadic_templates); + else if (!LangOpts.CPlusPlus0x) + S.Diag(D.getEllipsisLoc(), diag::ext_variadic_templates); break; case Declarator::FileContext: @@ -2447,7 +2498,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { case Declarator::TemplateTypeArgContext: // FIXME: We may want to allow parameter packs in block-literal contexts // in the future. - Diag(D.getEllipsisLoc(), diag::err_ellipsis_in_declarator_not_parameter); + S.Diag(D.getEllipsisLoc(), diag::err_ellipsis_in_declarator_not_parameter); D.setEllipsisLoc(SourceLocation()); break; } @@ -2458,53 +2509,29 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { else if (D.isInvalidType()) return Context.getTrivialTypeSourceInfo(T); - if (getLangOptions().CPlusPlus && - OwnedTagDecl && OwnedTagDecl->isDefinition()) { - // Check the contexts where C++ forbids the declaration of a new class - // or enumeration in a type-specifier-seq. - switch (D.getContext()) { - case Declarator::FileContext: - case Declarator::MemberContext: - case Declarator::BlockContext: - case Declarator::ForContext: - case Declarator::BlockLiteralContext: - // C++0x [dcl.type]p3: - // A type-specifier-seq shall not define a class or enumeration unless - // it appears in the type-id of an alias-declaration (7.1.3) that is not - // the declaration of a template-declaration. - case Declarator::AliasDeclContext: - break; - case Declarator::AliasTemplateContext: - Diag(OwnedTagDecl->getLocation(),diag::err_type_defined_in_alias_template) - << Context.getTypeDeclType(OwnedTagDecl); - break; - case Declarator::TypeNameContext: - case Declarator::TemplateParamContext: - case Declarator::CXXNewContext: - case Declarator::CXXCatchContext: - case Declarator::ObjCCatchContext: - case Declarator::TemplateTypeArgContext: - Diag(OwnedTagDecl->getLocation(),diag::err_type_defined_in_type_specifier) - << Context.getTypeDeclType(OwnedTagDecl); - break; - case Declarator::PrototypeContext: - case Declarator::ObjCPrototypeContext: - case Declarator::KNRTypeListContext: - // C++ [dcl.fct]p6: - // Types shall not be defined in return or parameter types. - Diag(OwnedTagDecl->getLocation(), diag::err_type_defined_in_param_type) - << Context.getTypeDeclType(OwnedTagDecl); - break; - case Declarator::ConditionContext: - // C++ 6.4p2: - // The type-specifier-seq shall not contain typedef and shall not declare - // a new class or enumeration. - Diag(OwnedTagDecl->getLocation(), diag::err_type_defined_in_condition); - break; - } - } + return S.GetTypeSourceInfoForDeclarator(D, T, TInfo); +} + +/// GetTypeForDeclarator - Convert the type for the specified +/// declarator to Type instances. +/// +/// The result of this call will never be null, but the associated +/// type may be a null type if there's an unrecoverable error. +TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { + // Determine the type of the declarator. Not all forms of declarator + // have a type. + + TypeProcessingState state(*this, D); + + TypeSourceInfo *ReturnTypeInfo = 0; + QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo); + if (T.isNull()) + return Context.getNullTypeSourceInfo(); + + if (D.isPrototypeContext() && getLangOptions().ObjCAutoRefCount) + inferARCWriteback(state, T); - return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo); + return GetFullTypeForDeclarator(state, T, ReturnTypeInfo); } /// Map an AttributedType::Kind to an AttributeList::Kind.