aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTImporter.cpp140
-rw-r--r--lib/AST/DeclObjC.cpp108
-rw-r--r--lib/AST/DeclPrinter.cpp5
-rw-r--r--lib/Sema/SemaCodeComplete.cpp5
-rw-r--r--lib/Sema/SemaDeclObjC.cpp18
-rw-r--r--lib/Sema/SemaExprObjC.cpp11
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp103
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp62
8 files changed, 279 insertions, 173 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index e409f0a1d3..949db7972a 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -3178,7 +3178,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
}
ObjCInterfaceDecl *ToIface = MergeWithIface;
- if (!ToIface || ToIface->isForwardDecl()) {
+ if (!ToIface || !ToIface->hasDefinition()) {
if (!ToIface) {
ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getAtStartLoc()),
@@ -3187,88 +3187,98 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
D->isImplicitInterfaceDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIface);
- if (D->isInitiallyForwardDecl() && !D->isForwardDecl())
- ToIface->completedForwardDecl();
}
Importer.Imported(D, ToIface);
- if (D->getSuperClass()) {
- ObjCInterfaceDecl *Super
- = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getSuperClass()));
- if (!Super)
- return 0;
+ if (D->hasDefinition()) {
+ if (!ToIface->hasDefinition())
+ ToIface->startDefinition();
- ToIface->setSuperClass(Super);
- ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
- }
-
- // Import protocols
- SmallVector<ObjCProtocolDecl *, 4> Protocols;
- SmallVector<SourceLocation, 4> ProtocolLocs;
- ObjCInterfaceDecl::protocol_loc_iterator
- FromProtoLoc = D->protocol_loc_begin();
-
- // FIXME: Should we be usng all_referenced_protocol_begin() here?
- for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
- FromProtoEnd = D->protocol_end();
- FromProto != FromProtoEnd;
- ++FromProto, ++FromProtoLoc) {
- ObjCProtocolDecl *ToProto
- = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
- if (!ToProto)
- return 0;
- Protocols.push_back(ToProto);
- ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+ if (D->getSuperClass()) {
+ ObjCInterfaceDecl *Super
+ = cast_or_null<ObjCInterfaceDecl>(
+ Importer.Import(D->getSuperClass()));
+ if (!Super)
+ return 0;
+
+ ToIface->setSuperClass(Super);
+ ToIface->setSuperClassLoc(Importer.Import(D->getSuperClassLoc()));
+ }
+
+ // Import protocols
+ SmallVector<ObjCProtocolDecl *, 4> Protocols;
+ SmallVector<SourceLocation, 4> ProtocolLocs;
+ ObjCInterfaceDecl::protocol_loc_iterator
+ FromProtoLoc = D->protocol_loc_begin();
+
+ for (ObjCInterfaceDecl::protocol_iterator FromProto = D->protocol_begin(),
+ FromProtoEnd = D->protocol_end();
+ FromProto != FromProtoEnd;
+ ++FromProto, ++FromProtoLoc) {
+ ObjCProtocolDecl *ToProto
+ = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+ if (!ToProto)
+ return 0;
+ Protocols.push_back(ToProto);
+ ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+ }
+
+ // FIXME: If we're merging, make sure that the protocol list is the same.
+ ToIface->setProtocolList(Protocols.data(), Protocols.size(),
+ ProtocolLocs.data(), Importer.getToContext());
}
- // FIXME: If we're merging, make sure that the protocol list is the same.
- ToIface->setProtocolList(Protocols.data(), Protocols.size(),
- ProtocolLocs.data(), Importer.getToContext());
-
// Import @end range
ToIface->setAtEndRange(Importer.Import(D->getAtEndRange()));
} else {
Importer.Imported(D, ToIface);
- // Check for consistency of superclasses.
- DeclarationName FromSuperName, ToSuperName;
-
- // If the superclass hasn't been imported yet, do so before checking.
- ObjCInterfaceDecl *DSuperClass = D->getSuperClass();
- ObjCInterfaceDecl *ToIfaceSuperClass = ToIface->getSuperClass();
-
- if (DSuperClass && !ToIfaceSuperClass) {
- Decl *ImportedSuperClass = Importer.Import(DSuperClass);
- ObjCInterfaceDecl *ImportedSuperIface = cast<ObjCInterfaceDecl>(ImportedSuperClass);
- ToIface->setSuperClass(ImportedSuperIface);
- }
+ if (D->hasDefinition()) {
+ // Check for consistency of superclasses.
+ DeclarationName FromSuperName, ToSuperName;
+
+ // If the superclass hasn't been imported yet, do so before checking.
+ ObjCInterfaceDecl *DSuperClass = D->getSuperClass();
+ ObjCInterfaceDecl *ToIfaceSuperClass = ToIface->getSuperClass();
+
+ if (DSuperClass && !ToIfaceSuperClass) {
+ Decl *ImportedSuperClass = Importer.Import(DSuperClass);
+ ObjCInterfaceDecl *ImportedSuperIface
+ = cast<ObjCInterfaceDecl>(ImportedSuperClass);
+
+ ToIface->setSuperClass(ImportedSuperIface);
+ }
- if (D->getSuperClass())
- FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
- if (ToIface->getSuperClass())
- ToSuperName = ToIface->getSuperClass()->getDeclName();
- if (FromSuperName != ToSuperName) {
- Importer.ToDiag(ToIface->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
- << ToIface->getDeclName();
+ if (D->getSuperClass())
+ FromSuperName = Importer.Import(D->getSuperClass()->getDeclName());
if (ToIface->getSuperClass())
- Importer.ToDiag(ToIface->getSuperClassLoc(),
- diag::note_odr_objc_superclass)
- << ToIface->getSuperClass()->getDeclName();
- else
+ ToSuperName = ToIface->getSuperClass()->getDeclName();
+ if (FromSuperName != ToSuperName) {
Importer.ToDiag(ToIface->getLocation(),
- diag::note_odr_objc_missing_superclass);
- if (D->getSuperClass())
- Importer.FromDiag(D->getSuperClassLoc(),
+ diag::err_odr_objc_superclass_inconsistent)
+ << ToIface->getDeclName();
+ if (ToIface->getSuperClass())
+ Importer.ToDiag(ToIface->getSuperClassLoc(),
diag::note_odr_objc_superclass)
- << D->getSuperClass()->getDeclName();
- else
- Importer.FromDiag(D->getLocation(),
+ << ToIface->getSuperClass()->getDeclName();
+ else
+ Importer.ToDiag(ToIface->getLocation(),
diag::note_odr_objc_missing_superclass);
- return 0;
+ if (D->getSuperClass())
+ Importer.FromDiag(D->getSuperClassLoc(),
+ diag::note_odr_objc_superclass)
+ << D->getSuperClass()->getDeclName();
+ else
+ Importer.FromDiag(D->getLocation(),
+ diag::note_odr_objc_missing_superclass);
+ return 0;
+ }
}
}
+ if (!D->hasDefinition())
+ return ToIface;
+
// Import categories. When the categories themselves are imported, they'll
// hook themselves into this interface.
for (ObjCCategoryDecl *FromCat = D->getCategoryList(); FromCat;
@@ -3279,7 +3289,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
ImportDeclContext(D);
// If we have an @implementation, import it as well.
- if (D->getImplementation()) {
+ if ( D->getImplementation()) {
ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
Importer.Import(D->getImplementation()));
if (!Impl)
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;
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 91b011fbda..ec7d6de71a 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -905,6 +905,11 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
else
Out << "@interface " << I;
+ if (OID->isForwardDecl()) {
+ Out << "@end";
+ return;
+ }
+
// Protocols?
const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
if (!Protocols.empty()) {
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 3d2d0930d8..7e7e87a065 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -4558,7 +4558,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
}
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
- if (!IFace)
+ if (!IFace || !IFace->hasDefinition())
return;
// Add methods in protocols.
@@ -5783,6 +5783,9 @@ static void FindImplementableMethods(ASTContext &Context,
bool InOriginalClass = true) {
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
// Recurse into protocols.
+ if (!IFace->hasDefinition())
+ return;
+
const ObjCList<ObjCProtocolDecl> &Protocols
= IFace->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index b70c982955..6947d7e211 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -368,10 +368,10 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (IDecl) {
// Class already seen. Is it a forward declaration?
- if (!IDecl->isForwardDecl()) {
+ if (ObjCInterfaceDecl *Def = IDecl->getDefinition()) {
IDecl->setInvalidDecl();
Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
- Diag(IDecl->getLocation(), diag::note_previous_definition);
+ Diag(Def->getLocation(), diag::note_previous_definition);
// Create a new one; the other may be in a different DeclContex, (e.g.
// this one may be in a LinkageSpecDecl while the other is not) which
@@ -392,8 +392,6 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IDecl->setLexicalDeclContext(CurContext);
CurContext->addDecl(IDecl);
- IDecl->completedForwardDecl();
-
if (AttrList)
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
}
@@ -406,6 +404,9 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
PushOnScopeChains(IDecl, TUScope);
}
+ if (!IDecl->hasDefinition())
+ IDecl->startDefinition();
+
if (SuperName) {
// Check if a different kind of symbol declared in this scope.
PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
@@ -942,6 +943,7 @@ Decl *Sema::ActOnStartClassImplementation(
// copy them over.
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
ClassName, ClassLoc, false, true);
+ IDecl->startDefinition();
IDecl->setSuperClass(SDecl);
IDecl->setLocEnd(ClassLoc);
@@ -950,8 +952,8 @@ Decl *Sema::ActOnStartClassImplementation(
// Mark the interface as being completed, even if it was just as
// @class ....;
// declaration; the user cannot reopen it.
- if (IDecl->isForwardDecl())
- IDecl->completedForwardDecl();
+ if (!IDecl->hasDefinition())
+ IDecl->startDefinition();
}
ObjCImplementationDecl* IMPDecl =
@@ -2540,7 +2542,9 @@ private:
void searchFrom(ObjCInterfaceDecl *iface) {
// A method in a class declaration overrides declarations from
-
+ if (!iface->hasDefinition())
+ return;
+
// - categories,
for (ObjCCategoryDecl *category = iface->getCategoryList();
category; category = category->getNextClassCategory())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index fbae96071e..20c3b75431 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -512,6 +512,9 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
ObjCInterfaceDecl *ClassDecl) {
+ if (!ClassDecl->hasDefinition())
+ return 0;
+
ObjCMethodDecl *Method = 0;
while (ClassDecl && !Method) {
// If we have implementations in scope, check "private" methods.
@@ -1339,12 +1342,10 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
return ExprError();
forwardClass = OCIType->getInterfaceDecl();
+ Method = 0;
+ } else {
+ Method = ClassDecl->lookupInstanceMethod(Sel);
}
-
- // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
- // faster than the following method (which can do *many* linear searches).
- // The idea is to add class info to MethodPool.
- Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method)
// Search protocol qualifiers.
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index bdedf8ac7e..f7f93af9ce 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -556,43 +556,80 @@ void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
VisitObjCContainerDecl(ID);
ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
- ID->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
- // Read the directly referenced protocols and their SourceLocations.
- unsigned NumProtocols = Record[Idx++];
- SmallVector<ObjCProtocolDecl *, 16> Protocols;
- Protocols.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
- SmallVector<SourceLocation, 16> ProtoLocs;
- ProtoLocs.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
- ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
- Reader.getContext());
+ ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+ if (ID == Def) {
+ // Read the definition.
+ ID->allocateDefinitionData();
+
+ ObjCInterfaceDecl::DefinitionData &Data = ID->data();
+
+ // Read the superclass.
+ Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
+ Data.SuperClassLoc = ReadSourceLocation(Record, Idx);
+
+ // Read the directly referenced protocols and their SourceLocations.
+ unsigned NumProtocols = Record[Idx++];
+ SmallVector<ObjCProtocolDecl *, 16> Protocols;
+ Protocols.reserve(NumProtocols);
+ for (unsigned I = 0; I != NumProtocols; ++I)
+ Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+ SmallVector<SourceLocation, 16> ProtoLocs;
+ ProtoLocs.reserve(NumProtocols);
+ for (unsigned I = 0; I != NumProtocols; ++I)
+ ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
+ ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
+ Reader.getContext());
- // Read the transitive closure of protocols referenced by this class.
- NumProtocols = Record[Idx++];
- Protocols.clear();
- Protocols.reserve(NumProtocols);
- for (unsigned I = 0; I != NumProtocols; ++I)
- Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
- ID->AllReferencedProtocols.set(Protocols.data(), NumProtocols,
- Reader.getContext());
+ // Read the transitive closure of protocols referenced by this class.
+ NumProtocols = Record[Idx++];
+ Protocols.clear();
+ Protocols.reserve(NumProtocols);
+ for (unsigned I = 0; I != NumProtocols; ++I)
+ Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+ ID->data().AllReferencedProtocols.set(Protocols.data(), NumProtocols,
+ Reader.getContext());
- // Read the ivars.
- unsigned NumIvars = Record[Idx++];
- SmallVector<ObjCIvarDecl *, 16> IVars;
- IVars.reserve(NumIvars);
- for (unsigned I = 0; I != NumIvars; ++I)
- IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
- ID->setCategoryList(ReadDeclAs<ObjCCategoryDecl>(Record, Idx));
+ // Read the ivars.
+ unsigned NumIvars = Record[Idx++];
+ SmallVector<ObjCIvarDecl *, 16> IVars;
+ IVars.reserve(NumIvars);
+ for (unsigned I = 0; I != NumIvars; ++I)
+ IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
+
+ // Read the categories.
+ ID->setCategoryList(ReadDeclAs<ObjCCategoryDecl>(Record, Idx));
+
+ // We will rebuild this list lazily.
+ ID->setIvarList(0);
+
+ // If there are any pending forward references, make their definition data
+ // pointers point at the newly-allocated data.
+ ASTReader::PendingForwardRefsMap::iterator
+ FindI = Reader.PendingForwardRefs.find(ID);
+ if (FindI != Reader.PendingForwardRefs.end()) {
+ ASTReader::ForwardRefs &Refs = FindI->second;
+ for (ASTReader::ForwardRefs::iterator I = Refs.begin(),
+ E = Refs.end();
+ I != E; ++I)
+ cast<ObjCInterfaceDecl>(*I)->Definition = ID->Definition;
+#ifndef NDEBUG
+ // We later check whether PendingForwardRefs is empty to make sure all
+ // pending references were linked.
+ Reader.PendingForwardRefs.erase(ID);
+#endif
+
+ } else if (Def) {
+ if (Def->Definition) {
+ ID->Definition = Def->Definition;
+ } else {
+ // The definition is still initializing.
+ Reader.PendingForwardRefs[Def].push_back(ID);
+ }
+ }
+ }
- // We will rebuild this list lazily.
- ID->setIvarList(0);
ID->InitiallyForwardDecl = Record[Idx++];
- ID->ForwardDecl = Record[Idx++];
- ID->setSuperClassLoc(ReadSourceLocation(Record, Idx));
ID->setLocEnd(ReadSourceLocation(Record, Idx));
}
@@ -972,7 +1009,7 @@ void ASTDeclReader::InitializeCXXDefinitionData(CXXRecordDecl *D,
ASTReader::ForwardRefs &Refs = FindI->second;
for (ASTReader::ForwardRefs::iterator
I = Refs.begin(), E = Refs.end(); I != E; ++I)
- (*I)->DefinitionData = D->DefinitionData;
+ cast<CXXRecordDecl>(*I)->DefinitionData = D->DefinitionData;
#ifndef NDEBUG
// We later check whether PendingForwardRefs is empty to make sure all
// pending references were linked.
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 1448e59fb6..9396958659 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -449,36 +449,46 @@ void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
VisitObjCContainerDecl(D);
Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
- Writer.AddDeclRef(D->getSuperClass(), Record);
- // Write out the protocols that are directly referenced by the @interface.
- Record.push_back(D->ReferencedProtocols.size());
- for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
- PEnd = D->protocol_end();
- P != PEnd; ++P)
- Writer.AddDeclRef(*P, Record);
- for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
+ ObjCInterfaceDecl *Def = D->getDefinition();
+ Writer.AddDeclRef(Def, Record);
+
+ if (D == Def) {
+ // Write the DefinitionData
+ ObjCInterfaceDecl::DefinitionData &Data = D->data();
+
+ Writer.AddDeclRef(D->getSuperClass(), Record);
+ Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
+
+ // Write out the protocols that are directly referenced by the @interface.
+ Record.push_back(Data.ReferencedProtocols.size());
+ for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
+ PEnd = D->protocol_end();
+ P != PEnd; ++P)
+ Writer.AddDeclRef(*P, Record);
+ for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
PLEnd = D->protocol_loc_end();
- PL != PLEnd; ++PL)
- Writer.AddSourceLocation(*PL, Record);
-
- // Write out the protocols that are transitively referenced.
- Record.push_back(D->AllReferencedProtocols.size());
- for (ObjCList<ObjCProtocolDecl>::iterator
- P = D->AllReferencedProtocols.begin(),
- PEnd = D->AllReferencedProtocols.end();
- P != PEnd; ++P)
- Writer.AddDeclRef(*P, Record);
+ PL != PLEnd; ++PL)
+ Writer.AddSourceLocation(*PL, Record);
+
+ // Write out the protocols that are transitively referenced.
+ Record.push_back(Data.AllReferencedProtocols.size());
+ for (ObjCList<ObjCProtocolDecl>::iterator
+ P = Data.AllReferencedProtocols.begin(),
+ PEnd = Data.AllReferencedProtocols.end();
+ P != PEnd; ++P)
+ Writer.AddDeclRef(*P, Record);
+
+ // Write out the ivars.
+ Record.push_back(D->ivar_size());
+ for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
+ IEnd = D->ivar_end(); I != IEnd; ++I)
+ Writer.AddDeclRef(*I, Record);
+
+ Writer.AddDeclRef(D->getCategoryList(), Record);
+ }
- // Write out the ivars.
- Record.push_back(D->ivar_size());
- for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
- IEnd = D->ivar_end(); I != IEnd; ++I)
- Writer.AddDeclRef(*I, Record);
- Writer.AddDeclRef(D->getCategoryList(), Record);
Record.push_back(D->isInitiallyForwardDecl());
- Record.push_back(D->isForwardDecl());
- Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
Code = serialization::DECL_OBJC_INTERFACE;
}