diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-03 17:30:10 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-03 17:30:10 +0000 |
commit | a865005c74019184e04f7fcdd4d61c31c095a4ff (patch) | |
tree | 7054e0f06ece4071c9de8c48a44ac948d95ba71a /lib/Frontend/PCHWriterDecl.cpp | |
parent | ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6b (diff) |
Apart from storing/retrieving the previous redeclaration from PCH, also store/retrieve the most recent
redeclaration. That way we are sure that the full redeclarations chain is loaded.
When using chained PCHs, first declarations point to the most recent redeclarations in the same PCH.
To address this use a REDECLS_UPDATE_LATEST record block to keep track of which first declarations need
to point to a most recent redeclaration in another PCH.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110125 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PCHWriterDecl.cpp')
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 28a82cd23f..9e9835adb4 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -92,6 +92,7 @@ namespace clang { void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, uint64_t VisibleOffset); + template <typename T> void VisitRedeclarable(Redeclarable<T> *D); // FIXME: Put in the same order is DeclNodes.td? @@ -163,7 +164,7 @@ void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) { void PCHDeclWriter::VisitTagDecl(TagDecl *D) { VisitTypeDecl(D); Record.push_back(D->getIdentifierNamespace()); - Writer.AddDeclRef(D->getPreviousDeclaration(), Record); + VisitRedeclarable(D); Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding Record.push_back(D->isDefinition()); Record.push_back(D->isEmbeddedInDeclarator()); @@ -279,7 +280,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) { // FunctionDecl's body is handled last at PCHWriterDecl::Visit, // after everything else is written. - Writer.AddDeclRef(D->getPreviousDeclaration(), Record); + VisitRedeclarable(D); Record.push_back(D->getStorageClass()); // FIXME: stable encoding Record.push_back(D->getStorageClassAsWritten()); Record.push_back(D->isInlineSpecified()); @@ -500,7 +501,7 @@ void PCHDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->isDeclaredInCondition()); Record.push_back(D->isExceptionVariable()); Record.push_back(D->isNRVOVariable()); - Writer.AddDeclRef(D->getPreviousDeclaration(), Record); + VisitRedeclarable(D); Record.push_back(D->getInit() ? 1 : 0); if (D->getInit()) Writer.AddStmt(D->getInit()); @@ -854,6 +855,18 @@ void PCHDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { Record.push_back(D->isMemberSpecialization()); Writer.AddDeclRef(D->getCommonPtr()->Latest, Record); + } else { + RedeclarableTemplateDecl *First = D->getFirstDeclaration(); + assert(First != D); + // If this is a most recent redeclaration that is pointed to by a first decl + // in a chained PCH, keep track of the association with the map so we can + // update the first decl during PCH reading. + if (First->getMostRecentDeclaration() == D && + First->getPCHLevel() > D->getPCHLevel()) { + assert(Writer.FirstLatestDecls.find(First)==Writer.FirstLatestDecls.end() + && "The latest is already set"); + Writer.FirstLatestDecls[First] = D; + } } } @@ -1016,6 +1029,29 @@ void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, Record.push_back(VisibleOffset); } +template <typename T> +void PCHDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { + enum { NoRedeclaration = 0, PointsToPrevious, PointsToLatest }; + if (D->RedeclLink.getNext() == D) { + Record.push_back(NoRedeclaration); + } else { + Record.push_back(D->RedeclLink.NextIsPrevious() ? PointsToPrevious + : PointsToLatest); + Writer.AddDeclRef(D->RedeclLink.getPointer(), Record); + } + + T *First = D->getFirstDeclaration(); + T *ThisDecl = static_cast<T*>(D); + // If this is a most recent redeclaration that is pointed to by a first decl + // in a chained PCH, keep track of the association with the map so we can + // update the first decl during PCH reading. + if (ThisDecl != First && First->getMostRecentDeclaration() == ThisDecl && + First->getPCHLevel() > ThisDecl->getPCHLevel()) { + assert(Writer.FirstLatestDecls.find(First) == Writer.FirstLatestDecls.end() + && "The latest is already set"); + Writer.FirstLatestDecls[First] = ThisDecl; + } +} //===----------------------------------------------------------------------===// // PCHWriter Implementation |