[cfe-commits] r41521 - in /cfe/trunk: Parse/ParseDecl.cpp Sema/SemaDecl.cpp Sema/SemaExpr.cpp Sema/SemaType.cpp include/clang/AST/Decl.h include/clang/Parse/DeclSpec.h

Steve Naroff snaroff at apple.com
Mon Aug 27 20:03:09 PDT 2007


Author: snaroff
Date: Mon Aug 27 22:03:08 2007
New Revision: 41521

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

Implement more thoughful error recovery when dealing with bogus declarator types.

For example, the following code was resulting in spurious warnings. This was the result of
Sema::GetTypeForDeclarator() synthesizing a type to hand back to the caller (in this case,
"int []", instead of "struct s[]", which is invalid).

struct s; 
struct s* t (struct s z[]) {   // expected-error {{array has incomplete element type}}
  return z;
}

Strategy: Flag the error in Declarator/DeclaratorChunk. This info is later stored in 
the ParmVarDecl. If the decl is referenced, Sema::ParseIdentifierExpr() will check if 
the type is invalid. If so, it quietly returns "true", without instantiating a DeclRefExpr.

This seems to work nicely. If Chris is happy with the approach, I will generalize this to
all VarDecls.

Modified:
    cfe/trunk/Parse/ParseDecl.cpp
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/Sema/SemaType.cpp
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/Parse/DeclSpec.h

Modified: cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseDecl.cpp?rev=41521&r1=41520&r2=41521&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/Parse/ParseDecl.cpp Mon Aug 27 22:03:08 2007
@@ -1332,9 +1332,8 @@
         ParmII = 0;
       }
         
-      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
-                                                    ParmDecl.getIdentifierLoc(),
-                                                     ParamTy.Val));
+      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, 
+        ParmDecl.getIdentifierLoc(), ParamTy.Val, ParmDecl.getInvalidType()));
       
       // If the next token is a comma, consume it and keep reading arguments.
       if (Tok.getKind() != tok::comma) break;

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Mon Aug 27 22:03:08 2007
@@ -463,7 +463,8 @@
   }
   return NewGroup;
 }
-  
+
+// Called from Sema::ParseStartOfFunctionDef().
 ParmVarDecl *
 Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
                            Scope *FnScope) {
@@ -505,7 +506,7 @@
     parmDeclType = Context.getPointerType(parmDeclType);
   
   ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II, parmDeclType, 
-                                     VarDecl::None, 0);
+                                     VarDecl::None, 0, PI.InvalidType);
 
   // If this has an identifier, add it to the scope stack.
   if (II) {

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

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Mon Aug 27 22:03:08 2007
@@ -74,8 +74,14 @@
       return Diag(Loc, diag::err_undeclared_var_use, II.getName());
     }
   }
-  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
+    ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD);
+    
+    // FIXME: generalize this for all decls.
+    if (PVD && PVD->getInvalidType())
+      return true;
     return new DeclRefExpr(VD, VD->getType(), Loc);
+  }
   if (isa<TypedefDecl>(D))
     return Diag(Loc, diag::err_unexpected_typedef, II.getName());
 

Modified: cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaType.cpp?rev=41521&r1=41520&r2=41521&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/trunk/Sema/SemaType.cpp Mon Aug 27 22:03:08 2007
@@ -123,7 +123,7 @@
 /// instances.
 QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
   QualType T = ConvertDeclSpecToType(D.getDeclSpec(), Context);
-
+  
   // Apply const/volatile/restrict qualifiers to T.
   T = T.getQualifiedType(D.getDeclSpec().getTypeQualifiers());
   
@@ -138,6 +138,7 @@
         // C++ 8.3.2p4: There shall be no ... pointers to references ...
         Diag(D.getIdentifierLoc(), diag::err_illegal_decl_pointer_to_reference,
              D.getIdentifier()->getName());
+        D.setInvalidType(true);
         T = Context.IntTy;
       }
 
@@ -150,6 +151,7 @@
         Diag(D.getIdentifierLoc(),
              diag::err_illegal_decl_reference_to_reference,
              D.getIdentifier()->getName());
+        D.setInvalidType(true);
         T = RT->getReferenceeType();
       }
 
@@ -170,19 +172,27 @@
       if (T->isIncompleteType()) { 
         Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_incomplete_type,
              T.getAsString());
+        T = Context.IntTy;
+        D.setInvalidType(true);
       } else if (T->isFunctionType()) {
         Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_functions,
              D.getIdentifier()->getName());
+        T = Context.getPointerType(T);
+        D.setInvalidType(true);
       } else if (const ReferenceType *RT = T->getAsReferenceType()) {
         // C++ 8.3.2p4: There shall be no ... arrays of references ...
         Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references,
              D.getIdentifier()->getName());
+        T = RT->getReferenceeType();
+        D.setInvalidType(true);
       } else if (const RecordType *EltTy = T->getAsRecordType()) {
         // If the element type is a struct or union that contains a variadic
         // array, reject it: C99 6.7.2.1p2.
         if (EltTy->getDecl()->hasFlexibleArrayMember()) {
           Diag(DeclType.Loc, diag::err_flexible_array_in_array,
                T.getAsString());
+          T = Context.IntTy;
+          D.setInvalidType(true);
         }
       }
       T = Context.getArrayType(T, ASM, ATI.TypeQuals, 
@@ -264,6 +274,7 @@
   return T.getAsOpaquePtr();
 }
 
+// Called from Parser::ParseParenDeclarator().
 Sema::TypeResult Sema::ParseParamDeclaratorType(Scope *S, Declarator &D) {
   // Note: parameters have identifiers, but we don't care about them here, we
   // just want the type converted.

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

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Aug 27 22:03:08 2007
@@ -221,11 +221,14 @@
 
 /// 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)
-    : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
+              Decl *PrevDecl, bool flag)
+    : VarDecl(ParmVariable, L, Id, T, S, PrevDecl), InvalidType(flag) {}
 
+  bool getInvalidType() const { return InvalidType; }
+  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
   static bool classof(const ParmVarDecl *D) { return true; }

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=41521&r1=41520&r2=41521&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Mon Aug 27 22:03:08 2007
@@ -315,10 +315,12 @@
     IdentifierInfo *Ident;
     SourceLocation IdentLoc;
     Action::TypeTy *TypeInfo;
+    bool InvalidType;
     // FIXME: this also needs an attribute list.
     ParamInfo() {}
-    ParamInfo(IdentifierInfo *ident, SourceLocation iloc, Action::TypeTy *typ)
-      : Ident(ident), IdentLoc(iloc), TypeInfo(typ) {
+    ParamInfo(IdentifierInfo *ident, SourceLocation iloc, Action::TypeTy *typ,
+              bool flag = false)
+      : Ident(ident), IdentLoc(iloc), TypeInfo(typ), InvalidType(flag) {
     }
   };
   
@@ -447,11 +449,14 @@
   /// DeclTypeInfo.back() will be the least closely bound.
   llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
 
+  // InvalidType - Set by Sema::GetTypeForDeclarator().
+  bool InvalidType;
+
   // attributes.
-  AttributeList *AttrList;  
+  AttributeList *AttrList;
 public:
   Declarator(const DeclSpec &ds, TheContext C)
-    : DS(ds), Identifier(0), Context(C), AttrList(0) {
+    : DS(ds), Identifier(0), Context(C), InvalidType(false), AttrList(0) {
   }
   
   ~Declarator() {
@@ -552,6 +557,9 @@
     AttrList = alist;
   }
   AttributeList *getAttributes() const { return AttrList; }
+  
+  void setInvalidType(bool flag) { InvalidType = flag; }
+  bool getInvalidType() { return InvalidType; }
 };
 
   





More information about the cfe-commits mailing list