diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 140 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 108 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 11 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 103 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 62 |
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; } |