aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-12-19 18:19:24 +0000
committerDouglas Gregor <dgregor@apple.com>2011-12-19 18:19:24 +0000
commitf63b0a5f5445830a845895ee16f3affeaffd2e9d (patch)
tree9a582112577567f9e6b4583530d91304e47c1568 /lib/Serialization/ASTReaderDecl.cpp
parent79ac2da646ed6285fc64d6c9e7ba13f1f237be0d (diff)
Re-implement (de-)serialization of redeclaration chains for
redeclaration templates (RedeclarableTemplateDecl), similarly to the way (de-)serialization is implemented for Redeclarable<T>. In the process, found a simpler formulation for handling redeclaration chains and implemented that in both places. The new test establishes that we're building the redeclaration chains properly. However, the FIXME indicates where we're tickling a different bug that has to do with us not setting the DefinitionData pointer properly in redeclarations that we detected after the definition itself was deserialized. The (separable) fix for that bug is forthcoming. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146883 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp119
1 files changed, 54 insertions, 65 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 3e08d99ae6..35cd8478d5 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1162,53 +1162,55 @@ void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
// Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
// can be used while this is still initializing.
-
- assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this");
- DeclID PreviousDeclID = ReadDeclID(Record, Idx);
- DeclID FirstDeclID = PreviousDeclID ? ReadDeclID(Record, Idx) : 0;
- // We delay loading of the redeclaration chain to avoid deeply nested calls.
- // We temporarily set the first (canonical) declaration as the previous one
- // which is the one that matters and mark the real previous DeclID to be
- // loaded & attached later on.
- RedeclarableTemplateDecl *FirstDecl =
- cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(FirstDeclID));
- assert((FirstDecl == 0 || FirstDecl->getKind() == D->getKind()) &&
- "FirstDecl kind mismatch");
- if (FirstDecl) {
- D->CommonOrPrev = FirstDecl;
- // Mark the real previous DeclID to be loaded & attached later on.
- if (PreviousDeclID != FirstDeclID)
- Reader.PendingPreviousDecls.push_back(std::make_pair(D, PreviousDeclID));
- } else {
- D->CommonOrPrev = D->newCommon(Reader.getContext());
+ enum RedeclKind { FirstDeclaration, PointsToPrevious };
+ RedeclKind Kind = (RedeclKind)Record[Idx++];
+
+ // Determine the first declaration ID.
+ DeclID FirstDeclID;
+ switch (Kind) {
+ case FirstDeclaration: {
+ FirstDeclID = ThisDeclID;
+
+ // Since this is the first declaration of the template, fill in the
+ // information for the 'common' pointer.
+ if (D->CommonOrPrev.isNull()) {
+ RedeclarableTemplateDecl::CommonBase *Common
+ = D->newCommon(Reader.getContext());
+ Common->Latest = D;
+ D->CommonOrPrev = Common;
+ }
+
if (RedeclarableTemplateDecl *RTD
- = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
+ = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
assert(RTD->getKind() == D->getKind() &&
"InstantiatedFromMemberTemplate kind mismatch");
D->setInstantiatedFromMemberTemplateImpl(RTD);
if (Record[Idx++])
D->setMemberSpecialization();
}
-
- RedeclarableTemplateDecl *LatestDecl
- = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx);
-
- // This decl is a first one and the latest declaration that it points to is
- // in the same AST file. However, if this actually needs to point to a
- // redeclaration in another AST file, we need to update it by checking
- // the FirstLatestDeclIDs map which tracks this kind of decls.
- assert(Reader.GetDecl(ThisDeclID) == D && "Invalid ThisDeclID ?");
- ASTReader::FirstLatestDeclIDMap::iterator I
- = Reader.FirstLatestDeclIDs.find(ThisDeclID);
- if (I != Reader.FirstLatestDeclIDs.end()) {
- if (Decl *NewLatest = Reader.GetDecl(I->second))
- LatestDecl = cast<RedeclarableTemplateDecl>(NewLatest);
- }
-
- assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
- D->getCommonPtr()->Latest = LatestDecl;
+ break;
}
-
+
+ case PointsToPrevious: {
+ FirstDeclID = ReadDeclID(Record, Idx);
+ DeclID PrevDeclID = ReadDeclID(Record, Idx);
+
+ RedeclarableTemplateDecl *FirstDecl
+ = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(FirstDeclID));
+
+ // We delay loading of the redeclaration chain to avoid deeply nested calls.
+ // We temporarily set the first (canonical) declaration as the previous one
+ // which is the one that matters and mark the real previous DeclID to be
+ // loaded and attached later on.
+ D->CommonOrPrev = FirstDecl;
+
+ // Make a note that we need to wire up this declaration to its
+ // previous declaration, later.
+ Reader.PendingPreviousDecls.push_back(std::make_pair(D, PrevDeclID));
+ break;
+ }
+ }
+
VisitTemplateDecl(D);
D->IdentifierNamespace = Record[Idx++];
}
@@ -1410,37 +1412,20 @@ ASTDeclReader::VisitDeclContext(DeclContext *DC) {
template <typename T>
void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
- enum RedeclKind { OnlyDeclaration = 0, FirstInFile, PointsToPrevious };
+ enum RedeclKind { FirstDeclaration = 0, PointsToPrevious };
RedeclKind Kind = (RedeclKind)Record[Idx++];
- // If this is the only known declaration of this entity, this module file
- // has no additional redeclaration information. However, other module
- // files might have redeclarations.
- if (Kind == OnlyDeclaration) {
- if (Reader.PendingDeclChainsKnown.insert(ThisDeclID))
- Reader.PendingDeclChains.push_back(ThisDeclID);
- return;
- }
-
- // Read the first declaration ID, and note that we need to reconstruct
- // the redeclaration chain once we hit the top level.
- DeclID FirstDeclID = ReadDeclID(Record, Idx);
- if (Reader.PendingDeclChainsKnown.insert(FirstDeclID))
- Reader.PendingDeclChains.push_back(FirstDeclID);
-
- T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
-
+ DeclID FirstDeclID;
switch (Kind) {
- case OnlyDeclaration:
- llvm_unreachable("only declaration handled above");
-
- case FirstInFile:
- if (FirstDecl != D)
- D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl);
+ case FirstDeclaration:
+ FirstDeclID = ThisDeclID;
break;
case PointsToPrevious: {
- DeclID PreviousDeclID = ReadDeclID(Record, Idx);
+ FirstDeclID = ReadDeclID(Record, Idx);
+ DeclID PrevDeclID = ReadDeclID(Record, Idx);
+
+ T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
// We delay loading of the redeclaration chain to avoid deeply nested calls.
// We temporarily set the first (canonical) declaration as the previous one
@@ -1451,10 +1436,14 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
// Make a note that we need to wire up this declaration to its
// previous declaration, later.
Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
- PreviousDeclID));
+ PrevDeclID));
break;
}
}
+
+ // Note that we need to load the other declaration chains for this ID.
+ if (Reader.PendingDeclChainsKnown.insert(ThisDeclID))
+ Reader.PendingDeclChains.push_back(ThisDeclID);
}
//===----------------------------------------------------------------------===//