: 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);
// 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++]))) {
" 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++])));
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);
// getCommonPtr() can be used while this is still initializing.
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+ if (D->getPreviousDeclaration())
+ Writer.AddDeclRef(D->getFirstDeclaration(), Record);
+
if (D->getPreviousDeclaration() == 0) {
// This TemplateDecl owns the CommonPtr; write it.
assert(D->isCanonicalDecl());
if (D->RedeclLink.getNext() == D) {
Record.push_back(NoRedeclaration);
} else {
- Record.push_back(D->RedeclLink.NextIsPrevious() ? PointsToPrevious
- : PointsToLatest);
- Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
+ if (D->RedeclLink.NextIsPrevious()) {
+ Record.push_back(PointsToPrevious);
+ Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
+ Writer.AddDeclRef(D->getFirstDeclaration(), Record);
+ } else {
+ Record.push_back(PointsToLatest);
+ Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
+ }
}
T *First = D->getFirstDeclaration();