[cfe-commits] r134272 - /cfe/trunk/lib/Sema/SemaType.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Jul 1 15:22:42 PDT 2011


Author: akirtzidis
Date: Fri Jul  1 17:22:42 2011
New Revision: 134272

URL: http://llvm.org/viewvc/llvm-project?rev=134272&view=rev
Log:
Break Sema::GetTypeForDeclarator in 2 functions, one for DeclSpec processing and another for the rest.
No functionality change.

Modified:
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=134272&r1=134271&r2=134272&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Jul  1 17:22:42 2011
@@ -591,10 +591,11 @@
 /// \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 @@
     << 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;
-  TagDecl *OwnedTagDecl = 0;
+  ReturnTypeInfo = 0;
 
-  TypeProcessingState state(*this, D);
-
-  // In C++0x, deallocation functions (normal and array operator delete)
-  // are implicitly noexcept.
-  bool ImplicitlyNoexcept = false;
+  // The TagDecl owned by the DeclSpec.
+  TagDecl *OwnedTagDecl = 0;
 
   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<TagDecl>(D.getDeclSpec().getRepAsDecl());
@@ -1759,29 +1742,26 @@
   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 @@
     case Declarator::MemberContext:
       if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)
         break;
-      switch (cast<TagDecl>(CurContext)->getTagKind()) {
+      switch (cast<TagDecl>(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 @@
     // 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 @@
     }
 
     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 @@
     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<ObjCObjectType>()) {
+      if (LangOpts.ObjC1 && T->getAs<ObjCObjectType>()) {
         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 @@
         // 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 @@
         // 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<ParenType>(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<AutoType>(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 @@
         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 @@
       // class type in C++.
       if (isa<PointerType>(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 @@
             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<TagDecl>(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 @@
           }
 
           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 @@
           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 @@
             // 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 @@
             }
           }
 
-          if (getLangOptions().ObjCAutoRefCount) {
+          if (LangOpts.ObjCAutoRefCount) {
             bool Consumed = Param->hasAttr<NSConsumedAttr>();
             ConsumedArguments.push_back(Consumed);
             HasAnyConsumedArguments |= Consumed;
@@ -2167,10 +2218,10 @@
           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 @@
             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 @@
       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<CXXRecordDecl>(computeDeclContext(SS))) {
+      } else if (S.isDependentScopeSpecifier(SS) ||
+                 dyn_cast_or_null<CXXRecordDecl>(S.computeDeclContext(SS))) {
         NestedNameSpecifier *NNS
           = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
         NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
@@ -2240,7 +2291,7 @@
           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 @@
       }
 
       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 @@
       processTypeAttrs(state, T, false, attrs);
   }
 
-  if (getLangOptions().CPlusPlus && T->isFunctionType()) {
+  if (LangOpts.CPlusPlus && T->isFunctionType()) {
     const FunctionProtoType *FnTy = T->getAs<FunctionProtoType>();
     assert(FnTy && "Why oh why is there not a FunctionProtoType here?");
 
@@ -2285,7 +2336,7 @@
       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 @@
           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 @@
               }
             }
 
-            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 @@
       // 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 @@
       // it expands those parameter packs.
       if (T->containsUnexpandedParameterPack())
         T = Context.getPackExpansionType(T, llvm::Optional<unsigned>());
-      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 @@
     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 @@
   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.





More information about the cfe-commits mailing list