From 74216648a51e3aee7e59c27e1f1e5c132c024830 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Fri, 14 Sep 2007 22:20:54 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41964 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/SemaDecl.cpp | 50 ++++++++++++++++----------------- clang.xcodeproj/project.pbxproj | 1 - include/clang/AST/Decl.h | 2 +- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 6e2f431a56..260a450dd4 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1096,8 +1096,10 @@ Sema::DeclTy *Sema::ParseField(Scope *S, DeclTy *TagDecl, // it also used for ivar semantics check. void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl, DeclTy **Fields, unsigned NumFields) { - RecordDecl *Record = - dyn_cast_or_null(static_cast(RecDecl)); + Decl *EnclosingDecl = static_cast(RecDecl); + assert(EnclosingDecl && "missing record or interface decl"); + RecordDecl *Record = dyn_cast(EnclosingDecl); + if (Record && Record->isDefinition()) { // Diagnose code like: // struct S { struct S {} X; }; @@ -1106,60 +1108,60 @@ void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl, 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 RecFields; llvm::SmallSet FieldIDs; + for (unsigned i = 0; i != NumFields; ++i) { - FieldDecl *FD; - if (Record) - FD = cast_or_null(static_cast(Fields[i])); - else - FD = cast_or_null(static_cast(Fields[i])); - if (!FD) continue; // Already issued a diagnostic. + FieldDecl *FD = cast_or_null(static_cast(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 @@ void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl, 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 @@ void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl, } } } - // Keep track of the number of named members. if (IdentifierInfo *II = FD->getIdentifier()) { // Detect duplicate member names. @@ -1203,17 +1204,14 @@ void Sema::ParseRecordBody(SourceLocation RecLoc, DeclTy *RecDecl, } } 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()); diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index a7d7e5fae4..06a6d796fb 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -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 = ""; diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 46ffb6c7a2..e7fbdabcd8 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -342,7 +342,7 @@ public: // 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; } }; -- 2.40.0