aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r--lib/AST/DeclObjC.cpp108
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;