diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-24 17:26:31 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-24 17:26:31 +0000 |
commit | 134db1fff5653c164ef41c898943521c49f6ebab (patch) | |
tree | 5d967613d702c8d384ad63d208c097939d0102b7 /lib/Serialization/ASTReaderDecl.cpp | |
parent | c01dc6fb5bae1ac60910e8fbf1d22a8fa1e691f7 (diff) |
Simplify and "robust-ify" the way that CXXRecord references point to the definition data when loaded from PCH.
Temporary disable 'test/PCH/chain-cxx.cpp' until a better way to fix it is in place.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117234 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 67 |
1 files changed, 27 insertions, 40 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 16fb2e0800..750e7236ef 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -807,50 +807,37 @@ void ASTDeclReader::ReadCXXDefinitionData( } void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { - ASTContext &C = *Reader.getContext(); - - // We need to allocate the DefinitionData struct ahead of VisitRecordDecl - // so that the other CXXRecordDecls can get a pointer even when the owner - // is still initializing. - enum DataOwnership { Data_NoDefData, Data_Owner, Data_NotOwner }; - DataOwnership DefOwnership = (DataOwnership)Record[Idx++]; - switch (DefOwnership) { - default: - assert(0 && "Out of sync with ASTDeclWriter or messed up reading"); - case Data_NoDefData: - break; - case Data_Owner: - D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); - break; - case Data_NotOwner: - D->DefinitionData - = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))->DefinitionData; - break; - } - VisitRecordDecl(D); - // Spread the DefinitionData pointer if it's the definition (it may have - // come from a chained PCH and earlier redeclarations don't know it), or - // if it just acquired a pointer that it's not supposed to have (a definition - // from a chained PCH updated it). - if (D->DefinitionData && DefOwnership != Data_NotOwner) { - llvm::SmallPtrSet<CXXRecordDecl *, 16> PrevRedecls; - PrevRedecls.insert(D); - CXXRecordDecl *Redecl = cast<CXXRecordDecl>(D->RedeclLink.getNext()); - while (!PrevRedecls.count(Redecl)) { - PrevRedecls.insert(Redecl); - assert((!Redecl->DefinitionData || - Redecl->DefinitionData == D->DefinitionData) && - "Multiple definitions in the redeclaration chain ?"); - Redecl->DefinitionData = D->DefinitionData; - Redecl = cast<CXXRecordDecl>(Redecl->RedeclLink.getNext()); - } - } + ASTContext &C = *Reader.getContext(); - if (DefOwnership == Data_Owner) { - assert(D->DefinitionData); + CXXRecordDecl *DefinitionDecl + = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); + if (D == DefinitionDecl) { + D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); ReadCXXDefinitionData(*D->DefinitionData); + // We read the definition info. Check if there are pending forward + // references that need to point to this DefinitionData pointer. + ASTReader::PendingForwardRefsMap::iterator + FindI = Reader.PendingForwardRefs.find(D); + if (FindI != Reader.PendingForwardRefs.end()) { + ASTReader::ForwardRefs &Refs = FindI->second; + for (ASTReader::ForwardRefs::iterator + I = Refs.begin(), E = Refs.end(); I != E; ++I) + (*I)->DefinitionData = D->DefinitionData; +#ifndef NDEBUG + // We later check whether PendingForwardRefs is empty to make sure all + // pending references were linked. + Reader.PendingForwardRefs.erase(D); +#endif + } + } else if (DefinitionDecl) { + if (DefinitionDecl->DefinitionData) { + D->DefinitionData = DefinitionDecl->DefinitionData; + } else { + // The definition is still initializing. + Reader.PendingForwardRefs[DefinitionDecl].push_back(D); + } } enum CXXRecKind { |