From 1531424650e79d53b171bd7977bc41c1de9aa1e7 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 28 Feb 2015 05:57:02 +0000 Subject: [PATCH] [modules] Avoid adding a redecl chain to the 'pending out of date' list as the very first step in updating it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@230840 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Redeclarable.h | 7 ++++++ lib/Serialization/ASTReaderDecl.cpp | 38 ++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index 7aa11d4034..c798d70832 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -92,6 +92,13 @@ protected: } void markIncomplete() { Next.get().markIncomplete(); } + + Decl *getLatestNotUpdated() const { + assert(NextIsLatest() && "expected a canonical decl"); + if (Next.is()) + return nullptr; + return Next.get().getNotUpdated(); + } }; static DeclLink PreviousDeclLink(decl_type *D) { diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index c5917b6634..375bdfb392 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -228,6 +228,11 @@ namespace clang { TypeIDForTypeDecl(0), NamedDeclForTagDecl(0), TypedefNameForLinkage(nullptr), HasPendingBody(false) {} + template + static Decl *getMostRecentDeclImpl(Redeclarable *D); + static Decl *getMostRecentDeclImpl(...); + static Decl *getMostRecentDecl(Decl *D); + template static void attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, Decl *Previous); @@ -2782,6 +2787,27 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { AnonymousDeclNumber, TypedefNameForLinkage); } +template +Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable *D) { + return D->RedeclLink.getLatestNotUpdated(); +} +Decl *ASTDeclReader::getMostRecentDeclImpl(...) { + llvm_unreachable("getMostRecentDecl on non-redeclarable declaration"); +} + +Decl *ASTDeclReader::getMostRecentDecl(Decl *D) { + assert(D); + + switch (D->getKind()) { +#define ABSTRACT_DECL(TYPE) +#define DECL(TYPE, BASE) \ + case Decl::TYPE: \ + return getMostRecentDeclImpl(cast(D)); +#include "clang/AST/DeclNodes.inc" + } + llvm_unreachable("unknown decl kind"); +} + template void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, @@ -3359,9 +3385,14 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { ArrayRef Chain = Visitor.getChain(); if (Chain.empty()) return; - + // Hook up the chains. - Decl *MostRecent = CanonDecl->getMostRecentDecl(); + // + // FIXME: We have three different dispatches on decl kind here; maybe + // we should instead generate one loop per kind and dispatch up-front? + Decl *MostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); + if (!MostRecent) + MostRecent = CanonDecl; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { if (Chain[I] == CanonDecl) continue; @@ -3369,8 +3400,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent); MostRecent = Chain[I]; } - - ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent); + ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent); } namespace { -- 2.40.0