From: Fariborz Jahanian Date: Fri, 19 Feb 2010 00:31:17 +0000 (+0000) Subject: Patch removes IVars list from ObjCInterfaceDecl and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11062e11236b7bc689dad150e8b490fd6b063ec3;p=clang Patch removes IVars list from ObjCInterfaceDecl and instead relies on their DeclContext for iteration, etc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96638 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 2ed9fd7080..ec3fa2343e 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -882,9 +882,8 @@ public: llvm::SmallVectorImpl &Fields); void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI, - llvm::SmallVectorImpl &Ivars, - bool CollectSynthesized = true); - void CollectSynthesizedIvars(const ObjCInterfaceDecl *OI, + llvm::SmallVectorImpl &Ivars); + void CollectNonClassIvars(const ObjCInterfaceDecl *OI, llvm::SmallVectorImpl &Ivars); void CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD, llvm::SmallVectorImpl &Ivars); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index e562d352e0..686c1eb2f8 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -494,11 +494,13 @@ public: } unsigned protocol_size() const { return ReferencedProtocols.size(); } - typedef ObjCList::iterator ivar_iterator; - ivar_iterator ivar_begin() const { return IVars.begin(); } - ivar_iterator ivar_end() const { return IVars.end(); } - unsigned ivar_size() const { return IVars.size(); } - bool ivar_empty() const { return IVars.empty(); } + typedef specific_decl_iterator ivar_iterator; + ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); } + ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); } + unsigned ivar_size() const { + return std::distance(ivar_begin(), ivar_end()); + } + bool ivar_empty() const { return ivar_begin() == ivar_end(); } /// setProtocolList - Set the list of protocols that this interface /// implements. @@ -514,10 +516,6 @@ public: const SourceLocation *Locs, ASTContext &C); - void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) { - IVars.set(List, Num, C); - } - bool isForwardDecl() const { return ForwardDecl; } void setForwardDecl(bool val) { ForwardDecl = val; } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c23babb9a4..74212fe785 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -872,14 +872,13 @@ void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, /// Collect all ivars, including those synthesized, in the current class. /// void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI, - llvm::SmallVectorImpl &Ivars, - bool CollectSynthesized) { + llvm::SmallVectorImpl &Ivars) { for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), E = OI->ivar_end(); I != E; ++I) { Ivars.push_back(*I); } - if (CollectSynthesized) - CollectSynthesizedIvars(OI, Ivars); + + CollectNonClassIvars(OI, Ivars); } void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD, @@ -895,10 +894,11 @@ void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD, CollectProtocolSynthesizedIvars(*P, Ivars); } -/// CollectSynthesizedIvars - -/// This routine collect synthesized ivars for the designated class. +/// CollectNonClassIvars - +/// This routine collects all other ivars which are not declared in the class. +/// This includes synthesized ivars and those in class's implementation. /// -void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI, +void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI, llvm::SmallVectorImpl &Ivars) { for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(), E = OI->prop_end(); I != E; ++I) { @@ -912,6 +912,13 @@ void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI, ObjCProtocolDecl *PD = (*P); CollectProtocolSynthesizedIvars(PD, Ivars); } + + // Also add any ivar defined in this class's implementation + if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) { + for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(), + E = ImplDecl->ivar_end(); I != E; ++I) + Ivars.push_back(*I); + } } /// CollectInheritedProtocols - Collect all protocols in current class and diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 50acd15fde..10c5089f22 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -487,6 +487,7 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { FinishLayout(); } +// FIXME. Impl is no longer needed. void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D, const ObjCImplementationDecl *Impl) { if (ObjCInterfaceDecl *SD = D->getSuperClass()) { @@ -508,10 +509,9 @@ void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D, if (const AlignedAttr *AA = D->getAttr()) UpdateAlignment(AA->getMaxAlignment()); - // Layout each ivar sequentially. llvm::SmallVector Ivars; - Ctx.ShallowCollectObjCIvars(D, Ivars, Impl); + Ctx.ShallowCollectObjCIvars(D, Ivars); for (unsigned i = 0, e = Ivars.size(); i != e; ++i) LayoutField(Ivars[i]); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index b16a510f98..5f9c51813a 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -3293,7 +3293,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout( // Add this implementations synthesized ivars. llvm::SmallVector Ivars; - CGM.getContext().CollectSynthesizedIvars(OI, Ivars); + CGM.getContext().CollectNonClassIvars(OI, Ivars); for (unsigned k = 0, e = Ivars.size(); k != e; ++k) RecFields.push_back(cast(Ivars[k])); diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index cadc542765..af69664fe1 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -235,7 +235,6 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { IVars.reserve(NumIvars); for (unsigned I = 0; I != NumIvars; ++I) IVars.push_back(cast(Reader.GetDecl(Record[Idx++]))); - ID->setIVarList(IVars.data(), NumIvars, *Reader.getContext()); ID->setCategoryList( cast_or_null(Reader.GetDecl(Record[Idx++]))); ID->setForwardDecl(Record[Idx++]); diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 5d99491cd6..fff8b54ba6 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -3534,12 +3534,12 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, ObjCInterfaceDecl::ivar_iterator IVI, IVE; llvm::SmallVector IVars; if (!IDecl->ivar_empty()) { - for (ObjCImplementationDecl::ivar_iterator + for (ObjCInterfaceDecl::ivar_iterator IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end(); IV != IVEnd; ++IV) IVars.push_back(*IV); - IVI = IVars.begin(); - IVE = IVars.end(); + IVI = IDecl->ivar_begin(); + IVE = IDecl->ivar_end(); } else { IVI = CDecl->ivar_begin(); IVE = CDecl->ivar_end(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 949669aa57..847602d802 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5641,7 +5641,6 @@ void Sema::ActOnFields(Scope* S, ObjCIvarDecl **ClsFields = reinterpret_cast(RecFields.data()); if (ObjCInterfaceDecl *ID = dyn_cast(EnclosingDecl)) { - ID->setIVarList(ClsFields, RecFields.size(), Context); ID->setLocEnd(RBrac); // Add ivar's to class's DeclContext. for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index a7e0145a52..cd64e66481 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -821,12 +821,12 @@ void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, /// (legacy objective-c @implementation decl without an @interface decl). /// Add implementations's ivar to the synthesize class's ivar list. if (IDecl->isImplicitInterfaceDecl()) { - IDecl->setIVarList(ivars, numIvars, Context); IDecl->setLocEnd(RBrace); // Add ivar's to class's DeclContext. for (unsigned i = 0, e = numIvars; i != e; ++i) { ivars[i]->setLexicalDeclContext(ImpDecl); IDecl->makeDeclVisibleInContext(ivars[i], false); + ImpDecl->addDecl(ivars[i]); } return; @@ -2446,8 +2446,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, PropertyIvar, PropType, /*Dinfo=*/0, ObjCIvarDecl::Public, (Expr *)0); - Ivar->setLexicalDeclContext(IDecl); - IDecl->addDecl(Ivar); + IDecl->makeDeclVisibleInContext(Ivar, false); property->setPropertyIvarDecl(Ivar); if (!getLangOptions().ObjCNonFragileABI) Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; diff --git a/test/CodeGenObjC/stand-alone-implementation.m b/test/CodeGenObjC/stand-alone-implementation.m new file mode 100644 index 0000000000..a51949578b --- /dev/null +++ b/test/CodeGenObjC/stand-alone-implementation.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s + +// radar 7547942 +// Allow injection of ivars into implementation's implicit class. + +@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}} +{ + id IVAR1; + id IVAR2; +} +- (id) Meth { return IVAR1; } +@end + +// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR1" +// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR2" +