From: Daniel Dunbar Date: Tue, 21 Apr 2009 21:41:56 +0000 (+0000) Subject: Make sure to mark the interface as completed when we see an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24c8991f4dd0ab86678b5ab11f05586687b55be9;p=clang Make sure to mark the interface as completed when we see an @implementation that closes a @class delcaration. - I don't know how to make a test case for this, but this strengthens the invariants that hold internally. The functionality change here is the edit to SemaDeclObjC.cpp. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69728 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index cfff4b5440..c4597e2235 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -644,6 +644,9 @@ void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, /// ivars and all those inherited. /// const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D) { + // FIXME: The only client relying on this working in the presence of + // forward declarations is IRgen, which should not need it. Fix + // and simplify this code. RecordDecl *&RD = ASTRecordForInterface[D]; if (RD) { // If we have a record decl already and it is either a definition or if 'D' diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 9cc22912ca..5df5ff3a7a 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -381,6 +381,7 @@ ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { const FieldDecl * ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, const ObjCIvarDecl *IVar) const { + assert(!isForwardDecl() && "Invalid interface decl!"); const RecordDecl *RecordForDecl = Context.addRecordToClass(this); assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class"); DeclContext::lookup_const_result Lookup = diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index ed71b09942..de29427c0e 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -2564,11 +2564,7 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { /// interface declaration. const llvm::StructLayout *CGObjCCommonMac::GetInterfaceDeclStructLayout( const ObjCInterfaceDecl *OID) const { - // FIXME: When does this happen? It seems pretty bad to do this... - if (OID->isForwardDecl()) - return CGM.getTargetData().getStructLayout(llvm::StructType::get(NULL, - NULL)); - + assert(!OID->isForwardDecl() && "Invalid interface decl!"); QualType T = CGM.getContext().getObjCInterfaceType(const_cast(OID)); const llvm::StructType *InterfaceTy = @@ -4231,6 +4227,7 @@ static int countInheritedIvars(const ObjCInterfaceDecl *OI, void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCInterfaceDecl *OID, uint32_t &InstanceStart, uint32_t &InstanceSize) { + assert(!OID->isForwardDecl() && "Invalid interface decl!"); const llvm::StructLayout *Layout = GetInterfaceDeclStructLayout(OID); int countSuperClassIvars = countInheritedIvars(OID->getSuperClass(), diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 5ab1efec03..2874f27cd3 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -668,6 +668,11 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation( CurContext->addDecl(Context, IDecl); // Remember that this needs to be removed when the scope is popped. TUScope->AddDecl(DeclPtrTy::make(IDecl)); + } else { + // Mark the interface as being completed, even if it was just as + // @class ....; + // declaration; the user cannot reopen it. + IDecl->setForwardDecl(false); } ObjCImplementationDecl* IMPDecl =