[cfe-commits] r41552 - in /cfe/trunk: Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/AST/Decl.h test/Sema/array-constraint.c

Steve Naroff snaroff at apple.com
Tue Aug 28 11:45:29 PDT 2007


Author: snaroff
Date: Tue Aug 28 13:45:29 2007
New Revision: 41552

URL: http://llvm.org/viewvc/llvm-project?rev=41552&view=rev
Log:

Move the "invalid decl" idiom up to Decl (where we have some bits to steal:-)

Converted ParmVarDecl, FileVarDecl, BlockVarDecl, and Sema::ParseIdentifierExpr() to use the idiom.

Updated array-constraint.c to make sure we no longer get "undeclared identifier" errors:-)

Modified:
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/test/Sema/array-constraint.c

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=41552&r1=41551&r2=41552&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Tue Aug 28 13:45:29 2007
@@ -356,7 +356,9 @@
     New = NewFD;
   } else {
     QualType R = GetTypeForDeclarator(D, S);
-    if (R.isNull()) return 0;
+    
+    assert(!R.isNull() && "GetTypeForDeclarator() returned null type");
+    bool InvalidDecl = false;
 
     VarDecl *NewVD;
     VarDecl::StorageClass SC;
@@ -381,7 +383,7 @@
         if (R->isIncompleteType()) {
           Diag(D.getIdentifierLoc(), diag::err_typecheck_decl_incomplete_type,
                R.getAsString());
-          return 0;
+          InvalidDecl = true;
         }
       }
       // C99 6.9p2: The storage-class specifiers auto and register shall not
@@ -389,13 +391,13 @@
       if (SC == VarDecl::Auto || SC == VarDecl::Register) {
         Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope,
              R.getAsString());
-        return 0;
+        InvalidDecl = true;
       }
       // C99 6.7.5.2p2: If an identifier is declared to be an object with 
       // static storage duration, it shall not have a variable length array.
       if (const ArrayType *ary = R->getAsArrayType()) {
         if (VerifyConstantArrayType(ary, D.getIdentifierLoc()))
-          return 0;
+          InvalidDecl = true;
       }
       NewVD = new FileVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
     } else { 
@@ -405,7 +407,7 @@
         if (R->isIncompleteType()) {
           Diag(D.getIdentifierLoc(), diag::err_typecheck_decl_incomplete_type,
                R.getAsString());
-          return 0;
+          InvalidDecl = true;
         }
       }
       if (SC == VarDecl::Static) {
@@ -413,11 +415,14 @@
         // static storage duration, it shall not have a variable length array.
         if (const ArrayType *ary = R->getAsArrayType()) {
           if (VerifyConstantArrayType(ary, D.getIdentifierLoc()))
-            return 0;
+            InvalidDecl = true;
         }
       }
       NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
-    }    
+    }
+    if (InvalidDecl)
+      NewVD->setInvalidDecl();
+      
     // Handle attributes prior to checking for duplicates in MergeVarDecl
     HandleDeclAttributes(NewVD, D.getDeclSpec().getAttributes(),
                          D.getAttributes());
@@ -507,8 +512,10 @@
     parmDeclType = Context.getPointerType(parmDeclType);
   
   ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II, parmDeclType, 
-                                     VarDecl::None, 0, PI.InvalidType);
-
+                                     VarDecl::None, 0);
+  if (PI.InvalidType)
+    New->setInvalidDecl();
+    
   // If this has an identifier, add it to the scope stack.
   if (II) {
     New->setNext(II->getFETokenInfo<Decl>());

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=41552&r1=41551&r2=41552&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Tue Aug 28 13:45:29 2007
@@ -75,10 +75,8 @@
     }
   }
   if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
-    ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD);
-    
-    // FIXME: generalize this for all decls.
-    if (PVD && PVD->getInvalidType())
+    // Only create DeclRefExpr's for valid Decl's.
+    if (VD->getInvalidDecl())
       return true;
     return new DeclRefExpr(VD, VD->getType(), Loc);
   }

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=41552&r1=41551&r2=41552&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Aug 28 13:45:29 2007
@@ -49,8 +49,11 @@
   };
 private:
   /// DeclKind - This indicates which class this is.
-  Kind DeclKind;
+  Kind DeclKind   :  8;
   
+  /// InvalidDecl - This indicates a semantic error occurred.
+  int InvalidDecl :  1;
+
   /// Loc - The location that this decl.
   SourceLocation Loc;
   
@@ -70,7 +73,8 @@
   
 protected:
   Decl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *NextDecl)
-    : DeclKind(DK), Loc(L), Identifier(Id), Next(0), NextDeclarator(NextDecl) {
+    : DeclKind(DK), InvalidDecl(0), Loc(L), Identifier(Id), Next(0), 
+      NextDeclarator(NextDecl) {
     if (Decl::CollectingStats()) addDeclKind(DK);
   }
   virtual ~Decl();
@@ -84,6 +88,11 @@
   Kind getKind() const { return DeclKind; }
   Decl *getNext() const { return Next; }
   void setNext(Decl *N) { Next = N; }
+
+  /// setInvalidDecl - Indicates the Decl had a semantic error. This
+  /// allows for graceful error recovery.
+  void setInvalidDecl() { InvalidDecl = 1; }
+  int getInvalidDecl() const { return InvalidDecl; }
   
   /// getNextDeclarator - If this decl was part of a multi-declarator
   /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
@@ -221,13 +230,10 @@
 
 /// ParmVarDecl - Represent a parameter to a function.
 class ParmVarDecl : public VarDecl {
-  bool InvalidType;
 public:
   ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
-              Decl *PrevDecl, bool flag)
-    : VarDecl(ParmVariable, L, Id, T, S, PrevDecl), InvalidType(flag) {}
-
-  bool getInvalidType() const { return InvalidType; }
+              Decl *PrevDecl)
+    : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
   
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }

Modified: cfe/trunk/test/Sema/array-constraint.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/array-constraint.c?rev=41552&r1=41551&r2=41552&view=diff

==============================================================================
--- cfe/trunk/test/Sema/array-constraint.c (original)
+++ cfe/trunk/test/Sema/array-constraint.c Tue Aug 28 13:45:29 2007
@@ -5,6 +5,12 @@
   return z;
 }
 
+void ff() { 
+  struct s v, *p; // expected-error {{variable has incomplete type 'struct s'}}
+
+  p = &v;
+}
+
 void *k (void l[2]) {          // expected-error {{array has incomplete element type}}
   return l; 
 }





More information about the cfe-commits mailing list