[cfe-commits] r41964 - in /cfe/trunk: Sema/SemaDecl.cpp clang.xcodeproj/project.pbxproj include/clang/AST/Decl.h

Steve Naroff snaroff at apple.com
Fri Sep 14 15:20:55 PDT 2007


Author: snaroff
Date: Fri Sep 14 17:20:54 2007
New Revision: 41964

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

Several improvement to Sema::ParseRecordBody()...

- Adding a safer prologue. The previous prologue would accept a null and therefore assume we had an interface (which was incorrect).
- Fixed FieldDecl's classof method. This allowed me to simplify some unnecessary casting.
- When diagnosing errors, make sure the FieldDecl/EnclosingDecl are marked as invalid. In addition, don't delete the field...rather, add all fields to the enclosing decl. Memory management can/should be done elsewhere. This code was never "upgraded" to the recently added invalid decl strategy.


Modified:
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/include/clang/AST/Decl.h

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Fri Sep 14 17:20:54 2007
@@ -1096,8 +1096,10 @@
 // it also used for ivar semantics check.
 void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl,
                            DeclTy **Fields, unsigned NumFields) {
-  RecordDecl *Record = 
-		dyn_cast_or_null<RecordDecl>(static_cast<Decl*>(RecDecl));
+  Decl *EnclosingDecl = static_cast<Decl*>(RecDecl);
+  assert(EnclosingDecl && "missing record or interface decl");
+  RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
+  
   if (Record && Record->isDefinition()) {
     // Diagnose code like:
     //     struct S { struct S {} X; };
@@ -1106,60 +1108,60 @@
     Diag(Record->getLocation(), diag::err_nested_redefinition,
          Record->getKindName());
     Diag(RecLoc, diag::err_previous_definition);
+    Record->setInvalidDecl();
     return;
   }
-
   // Verify that all the fields are okay.
   unsigned NumNamedMembers = 0;
   llvm::SmallVector<FieldDecl*, 32> RecFields;
   llvm::SmallSet<const IdentifierInfo*, 32> FieldIDs;
+  
   for (unsigned i = 0; i != NumFields; ++i) {
     
-    FieldDecl *FD;
-    if (Record)
-      FD = cast_or_null<FieldDecl>(static_cast<Decl*>(Fields[i]));
-    else
-      FD = cast_or_null<ObjcIvarDecl>(static_cast<Decl*>(Fields[i]));
-    if (!FD) continue;  // Already issued a diagnostic.
+    FieldDecl *FD = cast_or_null<FieldDecl>(static_cast<Decl*>(Fields[i]));
+    assert(FD && "missing field decl");
+    
+    // Remember all fields.
+    RecFields.push_back(FD);
     
     // Get the type for the field.
     Type *FDTy = FD->getType().getTypePtr();
     
     // C99 6.7.2.1p2 - A field may not be a function type.
     if (FDTy->isFunctionType()) {
-      Diag(FD->getLocation(), diag::err_field_declared_as_function,
+      Diag(FD->getLocation(), diag::err_field_declared_as_function, 
            FD->getName());
-      delete FD;
+      FD->setInvalidDecl();
+      EnclosingDecl->setInvalidDecl();
       continue;
     }
-
     // C99 6.7.2.1p2 - A field may not be an incomplete type except...
     if (FDTy->isIncompleteType()) {
       if (!Record) {  // Incomplete ivar type is always an error.
 	Diag(FD->getLocation(), diag::err_field_incomplete, FD->getName());
-	delete FD;
+        FD->setInvalidDecl();
+        EnclosingDecl->setInvalidDecl();
 	continue;
       }
       if (i != NumFields-1 ||                   // ... that the last member ...
           Record->getKind() != Decl::Struct ||  // ... of a structure ...
           !FDTy->isArrayType()) {         //... may have incomplete array type.
         Diag(FD->getLocation(), diag::err_field_incomplete, FD->getName());
-        delete FD;
+        FD->setInvalidDecl();
+        EnclosingDecl->setInvalidDecl();
         continue;
       }
       if (NumNamedMembers < 1) {  //... must have more than named member ...
         Diag(FD->getLocation(), diag::err_flexible_array_empty_struct,
              FD->getName());
-        delete FD;
+        FD->setInvalidDecl();
+        EnclosingDecl->setInvalidDecl();
         continue;
       }
-      
       // Okay, we have a legal flexible array member at the end of the struct.
       if (Record)
         Record->setHasFlexibleArrayMember(true);
     }
-    
-    
     /// C99 6.7.2.1p2 - a struct ending in a flexible array member cannot be the
     /// field of another structure or the element of an array.
     if (const RecordType *FDTTy = FDTy->getAsRecordType()) {
@@ -1174,10 +1176,10 @@
           if (i != NumFields-1) {
             Diag(FD->getLocation(), diag::err_variable_sized_type_in_struct,
                  FD->getName());
-            delete FD;
+            FD->setInvalidDecl();
+            EnclosingDecl->setInvalidDecl();
             continue;
           }
-
           // We support flexible arrays at the end of structs in other structs
           // as an extension.
           Diag(FD->getLocation(), diag::ext_flexible_array_in_struct,
@@ -1187,7 +1189,6 @@
         }
       }
     }
-    
     // Keep track of the number of named members.
     if (IdentifierInfo *II = FD->getIdentifier()) {
       // Detect duplicate member names.
@@ -1203,17 +1204,14 @@
           }
         }
         Diag(PrevLoc, diag::err_previous_definition);
-        delete FD;
+        FD->setInvalidDecl();
+        EnclosingDecl->setInvalidDecl();
         continue;
       }
       ++NumNamedMembers;
     }
-    
-    // Remember good fields.
-    RecFields.push_back(FD);
   }
  
-  
   // Okay, we successfully defined 'Record'.
   if (Record)
     Record->defineBody(&RecFields[0], RecFields.size());

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=41964&r1=41963&r2=41964&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Fri Sep 14 17:20:54 2007
@@ -675,7 +675,6 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
-			compatibilityVersion = "Xcode 2.4";
 			hasScannedForEncodings = 1;
 			mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
 			projectDirPath = "";

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

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Sep 14 17:20:54 2007
@@ -342,7 +342,7 @@
   
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
-    return D->getKind() == Field;
+    return D->getKind() == Field || D->getKind() == ObjcIvar;
   }
   static bool classof(const FieldDecl *D) { return true; }
 };





More information about the cfe-commits mailing list