diff options
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r-- | lib/AST/DeclObjC.cpp | 108 |
1 files changed, 72 insertions, 36 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 38efadf3b5..decbd54c6d 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -154,7 +154,11 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { ObjCPropertyDecl * ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( IdentifierInfo *PropertyId) const { - if (ExternallyCompleted) + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) LoadExternalDefinition(); if (ObjCPropertyDecl *PD = @@ -175,11 +179,12 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList( ObjCProtocolDecl *const* ExtList, unsigned ExtNum, ASTContext &C) { - if (ExternallyCompleted) + if (data().ExternallyCompleted) LoadExternalDefinition(); - if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) { - AllReferencedProtocols.set(ExtList, ExtNum, C); + if (data().AllReferencedProtocols.empty() && + data().ReferencedProtocols.empty()) { + data().AllReferencedProtocols.set(ExtList, ExtNum, C); return; } @@ -214,12 +219,16 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList( ProtocolRefs.push_back(*p); } - AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(), C); + data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C); } -void ObjCInterfaceDecl::completedForwardDecl() { - assert(isForwardDecl() && "Only valid to call for forward refs"); - ForwardDecl = false; +void ObjCInterfaceDecl::allocateDefinitionData() { + assert(!hasDefinition() && "ObjC class already has a definition"); + Definition = new (getASTContext()) DefinitionData(); +} + +void ObjCInterfaceDecl::startDefinition() { + allocateDefinitionData(); if (ASTMutationListener *L = getASTContext().getASTMutationListener()) L->CompletedObjCForwardRef(this); } @@ -244,7 +253,11 @@ const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const { ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { - if (ExternallyCompleted) + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) LoadExternalDefinition(); ObjCInterfaceDecl* ClassDecl = this; @@ -271,7 +284,11 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, /// the it returns NULL. ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( const IdentifierInfo*ICName) { - if (ExternallyCompleted) + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) LoadExternalDefinition(); ObjCInterfaceDecl* ClassDecl = this; @@ -287,10 +304,14 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( /// the class, its categories, and its super classes (using a linear search). ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, bool isInstance) const { + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + const ObjCInterfaceDecl* ClassDecl = this; ObjCMethodDecl *MethodDecl = 0; - if (ExternallyCompleted) + if (data().ExternallyCompleted) LoadExternalDefinition(); while (ClassDecl != NULL) { @@ -328,7 +349,11 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod( const Selector &Sel, bool Instance) { - if (ExternallyCompleted) + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) LoadExternalDefinition(); ObjCMethodDecl *Method = 0; @@ -651,16 +676,14 @@ ObjCInterfaceDecl:: ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, SourceLocation CLoc, bool FD, bool isInternal) : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc), - TypeForDecl(0), SuperClass(0), - CategoryList(0), IvarList(0), - InitiallyForwardDecl(FD), ForwardDecl(FD), - ExternallyCompleted(false) { + TypeForDecl(0), Definition(), InitiallyForwardDecl(FD) +{ setImplicit(isInternal); } void ObjCInterfaceDecl::LoadExternalDefinition() const { - assert(ExternallyCompleted && "Class is not externally completed"); - ExternallyCompleted = false; + assert(data().ExternallyCompleted && "Class is not externally completed"); + data().ExternallyCompleted = false; getASTContext().getExternalSource()->CompleteType( const_cast<ObjCInterfaceDecl *>(this)); } @@ -668,13 +691,17 @@ void ObjCInterfaceDecl::LoadExternalDefinition() const { void ObjCInterfaceDecl::setExternallyCompleted() { assert(getASTContext().getExternalSource() && "Class can't be externally completed without an external source"); - assert(!ForwardDecl && + assert(hasDefinition() && "Forward declarations can't be externally completed"); - ExternallyCompleted = true; + data().ExternallyCompleted = true; } ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { - if (ExternallyCompleted) + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().ExternallyCompleted) LoadExternalDefinition(); return getASTContext().getObjCImplementation( @@ -689,14 +716,18 @@ void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) { /// its extensions and its implementation. Lazily build the list on first /// access. ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { - if (IvarList) - return IvarList; + // FIXME: Should make sure no callers ever do this. + if (!hasDefinition()) + return 0; + + if (data().IvarList) + return data().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) + data().IvarList = (*I); ++I; + for (curIvar = data().IvarList; I != E; curIvar = *I, ++I) curIvar->setNextIvar(*I); } @@ -705,9 +736,9 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { if (!CDecl->ivar_empty()) { ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(), E = CDecl->ivar_end(); - if (!IvarList) { - IvarList = (*I); ++I; - curIvar = IvarList; + if (!data().IvarList) { + data().IvarList = (*I); ++I; + curIvar = data().IvarList; } for ( ;I != E; curIvar = *I, ++I) curIvar->setNextIvar(*I); @@ -718,15 +749,15 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { if (!ImplDecl->ivar_empty()) { ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(), E = ImplDecl->ivar_end(); - if (!IvarList) { - IvarList = (*I); ++I; - curIvar = IvarList; + if (!data().IvarList) { + data().IvarList = (*I); ++I; + curIvar = data().IvarList; } for ( ;I != E; curIvar = *I, ++I) curIvar->setNextIvar(*I); } } - return IvarList; + return data().IvarList; } /// FindCategoryDeclaration - Finds category declaration in the list of @@ -735,7 +766,7 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { /// ObjCCategoryDecl * ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { - if (ExternallyCompleted) + if (data().ExternallyCompleted) LoadExternalDefinition(); for (ObjCCategoryDecl *Category = getCategoryList(); @@ -770,6 +801,9 @@ ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const { bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID) { + if (!hasDefinition()) + return false; + ObjCInterfaceDecl *IDecl = this; // 1st, look up the class. const ObjCList<ObjCProtocolDecl> &Protocols = @@ -997,9 +1031,11 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, if (IDecl) { // Link this category into its class's category list. CatDecl->NextClassCategory = IDecl->getCategoryList(); - IDecl->setCategoryList(CatDecl); - if (ASTMutationListener *L = C.getASTMutationListener()) - L->AddedObjCCategoryToInterface(CatDecl, IDecl); + if (IDecl->hasDefinition()) { + IDecl->setCategoryList(CatDecl); + if (ASTMutationListener *L = C.getASTMutationListener()) + L->AddedObjCCategoryToInterface(CatDecl, IDecl); + } } return CatDecl; |