diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 103 |
1 files changed, 70 insertions, 33 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index bdedf8ac7e1..f7f93af9ce5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/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. |

