diff options
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r-- | lib/AST/DeclObjC.cpp | 183 |
1 files changed, 89 insertions, 94 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index adb0e7d..d952cc3 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -21,14 +21,8 @@ using namespace clang; // ObjCListBase //===----------------------------------------------------------------------===// -void ObjCListBase::Destroy(ASTContext &Ctx) { - Ctx.Deallocate(List); - NumElts = 0; - List = 0; -} - void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { - assert(List == 0 && "Elements already set!"); + List = 0; if (Elts == 0) return; // Setting to an empty list is a noop. @@ -47,12 +41,6 @@ void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, set(InList, Elts, Ctx); } -void ObjCProtocolList::Destroy(ASTContext &Ctx) { - Ctx.Deallocate(Locations); - Locations = 0; - ObjCList<ObjCProtocolDecl>::Destroy(Ctx); -} - //===----------------------------------------------------------------------===// // ObjCInterfaceDecl //===----------------------------------------------------------------------===// @@ -132,8 +120,9 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { return P; // Look through protocols. - for (ObjCInterfaceDecl::protocol_iterator - I = OID->protocol_begin(), E = OID->protocol_end(); I != E; ++I) + for (ObjCInterfaceDecl::all_protocol_iterator + I = OID->all_referenced_protocol_begin(), + E = OID->all_referenced_protocol_end(); I != E; ++I) if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) return P; @@ -169,8 +158,9 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( return PD; // Look through protocols. - for (ObjCInterfaceDecl::protocol_iterator - I = protocol_begin(), E = protocol_end(); I != E; ++I) + for (ObjCInterfaceDecl::all_protocol_iterator + I = all_referenced_protocol_begin(), + E = all_referenced_protocol_end(); I != E; ++I) if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) return P; @@ -179,23 +169,23 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( void ObjCInterfaceDecl::mergeClassExtensionProtocolList( ObjCProtocolDecl *const* ExtList, unsigned ExtNum, - const SourceLocation *Locs, ASTContext &C) { - if (ReferencedProtocols.empty()) { - ReferencedProtocols.set(ExtList, ExtNum, Locs, C); + if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) { + AllReferencedProtocols.set(ExtList, ExtNum, C); return; } + // Check for duplicate protocol in class's protocol list. - // This is (O)2. But it is extremely rare and number of protocols in + // This is O(n*m). But it is extremely rare and number of protocols in // class or its extension are very few. llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs; - llvm::SmallVector<SourceLocation, 8> ProtocolLocs; for (unsigned i = 0; i < ExtNum; i++) { bool protocolExists = false; ObjCProtocolDecl *ProtoInExtension = ExtList[i]; - for (protocol_iterator p = protocol_begin(), e = protocol_end(); - p != e; p++) { + for (all_protocol_iterator + p = all_referenced_protocol_begin(), + e = all_referenced_protocol_end(); p != e; ++p) { ObjCProtocolDecl *Proto = (*p); if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) { protocolExists = true; @@ -204,23 +194,20 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList( } // Do we want to warn on a protocol in extension class which // already exist in the class? Probably not. - if (!protocolExists) { + if (!protocolExists) ProtocolRefs.push_back(ProtoInExtension); - ProtocolLocs.push_back(Locs[i]); - } } + if (ProtocolRefs.empty()) return; + // Merge ProtocolRefs into class's protocol list; - protocol_loc_iterator pl = protocol_loc_begin(); - for (protocol_iterator p = protocol_begin(), e = protocol_end(); - p != e; ++p, ++pl) { + for (all_protocol_iterator p = all_referenced_protocol_begin(), + e = all_referenced_protocol_end(); p != e; ++p) { ProtocolRefs.push_back(*p); - ProtocolLocs.push_back(*pl); } - ReferencedProtocols.Destroy(C); - unsigned NumProtoRefs = ProtocolRefs.size(); - setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C); + + AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(), C); } /// getFirstClassExtension - Find first class extension of the given class. @@ -339,27 +326,17 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, bool isInstance, bool isVariadic, bool isSynthesized, + bool isDefined, ImplementationControl impControl, unsigned numSelectorArgs) { return new (C) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, ResultTInfo, contextDecl, isInstance, - isVariadic, isSynthesized, impControl, + isVariadic, isSynthesized, isDefined, + impControl, numSelectorArgs); } -void ObjCMethodDecl::Destroy(ASTContext &C) { - if (Body) Body->Destroy(C); - if (SelfDecl) SelfDecl->Destroy(C); - - for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) - if (*I) (*I)->Destroy(C); - - ParamInfo.Destroy(C); - - Decl::Destroy(C); -} - /// \brief A definition will return its interface declaration. /// An interface declaration will return its definition. /// Otherwise it will return itself. @@ -465,22 +442,11 @@ ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, SourceLocation CLoc, bool FD, bool isInternal) : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id), TypeForDecl(0), SuperClass(0), - CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal), + CategoryList(0), IvarList(0), + ForwardDecl(FD), InternalInterface(isInternal), ClassLoc(CLoc) { } -void ObjCInterfaceDecl::Destroy(ASTContext &C) { - for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I) - if (*I) (*I)->Destroy(C); - - // FIXME: CategoryList? - - // FIXME: Because there is no clear ownership - // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they - // reference, we destroy ObjCPropertyDecls in ~TranslationUnit. - Decl::Destroy(C); -} - ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { return getASTContext().getObjCImplementation( const_cast<ObjCInterfaceDecl*>(this)); @@ -490,6 +456,49 @@ void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) { getASTContext().setObjCImplementation(this, ImplD); } +/// all_declared_ivar_begin - return first ivar declared in this class, +/// its extensions and its implementation. Lazily build the list on first +/// access. +ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { + if (IvarList) + return IvarList; + + ObjCIvarDecl *curIvar = 0; + if (!ivar_empty()) { + ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end(); + IvarList = (*I); ++I; + for (curIvar = IvarList; I != E; curIvar = *I, ++I) + curIvar->setNextIvar(*I); + } + + for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl; + CDecl = CDecl->getNextClassExtension()) { + if (!CDecl->ivar_empty()) { + ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(), + E = CDecl->ivar_end(); + if (!IvarList) { + IvarList = (*I); ++I; + curIvar = IvarList; + } + for ( ;I != E; curIvar = *I, ++I) + curIvar->setNextIvar(*I); + } + } + + if (ObjCImplementationDecl *ImplDecl = getImplementation()) { + if (!ImplDecl->ivar_empty()) { + ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(), + E = ImplDecl->ivar_end(); + if (!IvarList) { + IvarList = (*I); ++I; + curIvar = IvarList; + } + for ( ;I != E; curIvar = *I, ++I) + curIvar->setNextIvar(*I); + } + } + return IvarList; +} /// FindCategoryDeclaration - Finds category declaration in the list of /// categories for this class and returns it. Name of the category is passed @@ -575,7 +584,8 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto, ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - AccessControl ac, Expr *BW) { + AccessControl ac, Expr *BW, + bool synthesized) { if (DC) { // Ivar's can only appear in interfaces, implementations (via synthesized // properties), and class extensions (via direct declaration, or synthesized @@ -590,9 +600,26 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) || isa<ObjCCategoryDecl>(DC)) && "Invalid ivar decl context!"); + // Once a new ivar is created in any of class/class-extension/implementation + // decl contexts, the previously built IvarList must be rebuilt. + ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC); + if (!ID) { + if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC)) { + ID = IM->getClassInterface(); + if (BW) + IM->setHasSynthBitfield(true); + } + else { + ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC); + ID = CD->getClassInterface(); + if (BW) + CD->setHasSynthBitfield(true); + } + } + ID->setIvarList(0); } - return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW); + return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized); } const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const { @@ -630,11 +657,6 @@ ObjCAtDefsFieldDecl return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); } -void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { - this->~ObjCAtDefsFieldDecl(); - C.Deallocate((void *)this); -} - //===----------------------------------------------------------------------===// // ObjCProtocolDecl //===----------------------------------------------------------------------===// @@ -645,11 +667,6 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, return new (C) ObjCProtocolDecl(DC, L, Id); } -void ObjCProtocolDecl::Destroy(ASTContext &C) { - ReferencedProtocols.Destroy(C); - ObjCContainerDecl::Destroy(C); -} - ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) { ObjCProtocolDecl *PDecl = this; @@ -709,23 +726,6 @@ ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C); } -void ObjCClassDecl::Destroy(ASTContext &C) { - // ObjCInterfaceDecls registered with a DeclContext will get destroyed - // when the DeclContext is destroyed. For those created only by a forward - // declaration, the first @class that created the ObjCInterfaceDecl gets - // to destroy it. - // FIXME: Note that this ownership role is very brittle; a better - // polict is surely need in the future. - for (iterator I = begin(), E = end(); I !=E ; ++I) { - ObjCInterfaceDecl *ID = I->getInterface(); - if (ID->isForwardDecl() && ID->getLocStart() == getLocStart()) - ID->Destroy(C); - } - - C.Deallocate(ForwardDecls); - Decl::Destroy(C); -} - SourceRange ObjCClassDecl::getSourceRange() const { // FIXME: We should include the semicolon assert(NumDecls); @@ -754,11 +754,6 @@ ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C); } -void ObjCForwardProtocolDecl::Destroy(ASTContext &C) { - ReferencedProtocols.Destroy(C); - Decl::Destroy(C); -} - //===----------------------------------------------------------------------===// // ObjCCategoryDecl //===----------------------------------------------------------------------===// |