]> granicus.if.org Git - clang/commitdiff
Remove the call to GetTypeForDeclarator in Sema::ActOnCXXConditionDeclaration.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 28 Jun 2011 03:01:12 +0000 (03:01 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 28 Jun 2011 03:01:12 +0000 (03:01 +0000)
No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133984 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/condition.cpp

index 07eb9fe572aa4a696bfb79e7caa5406bdaa93a68..c0d34da922149caf6d011320d4231cfa661368e2 100644 (file)
@@ -8913,25 +8913,13 @@ DeclResult Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
   // new class or enumeration.
   assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
          "Parser allowed 'typedef' as storage class of condition decl.");
-  
-  TagDecl *OwnedTag = 0;
-  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S, &OwnedTag);
-  QualType Ty = TInfo->getType();
-  
-  if (Ty->isFunctionType()) { // The declarator shall not specify a function...
-                              // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
-                              // would be created and CXXConditionDeclExpr wants a VarDecl.
-    Diag(D.getIdentifierLoc(), diag::err_invalid_use_of_function_type)
+
+  Decl *Dcl = ActOnDeclarator(S, D);
+  if (isa<FunctionDecl>(Dcl)) { // The declarator shall not specify a function.
+    Diag(Dcl->getLocation(), diag::err_invalid_use_of_function_type)
       << D.getSourceRange();
     return DeclResult();
-  } else if (OwnedTag && OwnedTag->isDefinition()) {
-    // The type-specifier-seq shall not declare a new class or enumeration.
-    Diag(OwnedTag->getLocation(), diag::err_type_defined_in_condition);
   }
-  
-  Decl *Dcl = ActOnDeclarator(S, D);
-  if (!Dcl)
-    return DeclResult();
 
   return Dcl;
 }
index ea1086c867183cda7651295abe0bce53f66f75ef..489e50dc1c549725c3eeca1331eca60ba22fd591 100644 (file)
@@ -1728,6 +1728,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
   // have a type.
   QualType T;
   TypeSourceInfo *ReturnTypeInfo = 0;
+  TagDecl *OwnedTagDeclInternal = 0;
 
   TypeProcessingState state(*this, D);
 
@@ -1752,7 +1753,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
       TagDecl* Owned = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
       // Owned declaration is embedded in declarator.
       Owned->setEmbeddedInDeclarator(true);
-      if (OwnedDecl) *OwnedDecl = Owned;
+      OwnedTagDeclInternal = Owned;
     }
     break;
 
@@ -2456,6 +2457,39 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
     return Context.getNullTypeSourceInfo();
   else if (D.isInvalidType())
     return Context.getTrivialTypeSourceInfo(T);
+
+  if (OwnedTagDeclInternal && OwnedDecl)
+    *OwnedDecl = OwnedTagDeclInternal;
+
+  if (getLangOptions().CPlusPlus &&
+      OwnedTagDeclInternal && OwnedTagDeclInternal->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::PrototypeContext:
+    case Declarator::ObjCPrototypeContext:
+    case Declarator::KNRTypeListContext:
+    case Declarator::TypeNameContext:
+    case Declarator::MemberContext:
+    case Declarator::BlockContext:
+    case Declarator::ForContext:
+    case Declarator::TemplateParamContext:
+    case Declarator::CXXCatchContext:
+    case Declarator::BlockLiteralContext:
+    case Declarator::TemplateTypeArgContext:
+    case Declarator::AliasDeclContext:
+    case Declarator::AliasTemplateContext:
+      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(OwnedTagDeclInternal->getLocation(), diag::err_type_defined_in_condition);
+      break;
+    }
+  }
+  
   return GetTypeSourceInfoForDeclarator(D, T, ReturnTypeInfo);
 }
 
index cb7391a5f1f74f43aa6f9470ed256cdaafac66a9..3441bae67076b9d317ecfd6c0bd28a074bd74cad 100644 (file)
@@ -16,6 +16,7 @@ void test() {
   for (;s;) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
   switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}}
 
+  while (struct NewS *x=0) ;
   while (struct S {} *x=0) ; // expected-error {{types may not be defined in conditions}}
   while (struct {} *x=0) ; // expected-error {{types may not be defined in conditions}}
   switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \