diff options
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 119 |
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); } //===----------------------------------------------------------------------===// |