diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 56c33ca913d..279d081098f 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -75,6 +75,8 @@ namespace clang { : Reader(Reader), F(F), Cursor(Cursor), ThisDeclID(thisDeclID), Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { } + static void attachPreviousDecl(Decl *D, Decl *previous); + void Visit(Decl *D); void UpdateDecl(Decl *D, const RecordData &Record); @@ -981,13 +983,22 @@ void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { // can be used while this is still initializing. assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this"); - RedeclarableTemplateDecl *PrevDecl = - cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++])); - assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) && - "PrevDecl kind mismatch"); - if (PrevDecl) - D->CommonOrPrev = PrevDecl; - if (PrevDecl == 0) { + DeclID PreviousDeclID = Record[Idx++]; + DeclID FirstDeclID = PreviousDeclID ? 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()); if (RedeclarableTemplateDecl *RTD = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) { @@ -1224,10 +1235,20 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { " reading"); case NoRedeclaration: break; - case PointsToPrevious: + case PointsToPrevious: { + DeclID PreviousDeclID = Record[Idx++]; + DeclID FirstDeclID = Record[Idx++]; + // 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. D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink( - cast_or_null<T>(Reader.GetDecl(Record[Idx++]))); + cast_or_null<T>(Reader.GetDecl(FirstDeclID))); + if (PreviousDeclID != FirstDeclID) + Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D), + PreviousDeclID)); break; + } case PointsToLatest: D->RedeclLink = typename Redeclarable<T>::LatestDeclLink( cast_or_null<T>(Reader.GetDecl(Record[Idx++]))); @@ -1327,6 +1348,25 @@ ASTReader::DeclCursorForIndex(unsigned Index, DeclID ID) { return RecordLocation(F, F->DeclOffsets[Index]); } +void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) { + assert(D && previous); + if (TagDecl *TD = dyn_cast<TagDecl>(D)) { + TD->RedeclLink.setPointer(cast<TagDecl>(previous)); + } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + FD->RedeclLink.setPointer(cast<FunctionDecl>(previous)); + } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + VD->RedeclLink.setPointer(cast<VarDecl>(previous)); + } else { + RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D); + TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous); + } +} + +void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) { + Decl *previous = GetDecl(ID); + ASTDeclReader::attachPreviousDecl(D, previous); +} + /// \brief Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) { RecordLocation Loc = DeclCursorForIndex(Index, ID); |

