[modules] Avoid adding a redecl chain to the 'pending out of date' list as the

very first step in updating it.

llvm-svn: 230840
This commit is contained in:
Richard Smith 2015-02-28 05:57:02 +00:00
parent 37bd29a5e6
commit c3a532576c
2 changed files with 41 additions and 4 deletions

View File

@ -92,6 +92,13 @@ protected:
}
void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
Decl *getLatestNotUpdated() const {
assert(NextIsLatest() && "expected a canonical decl");
if (Next.is<NotKnownLatest>())
return nullptr;
return Next.get<KnownLatest>().getNotUpdated();
}
};
static DeclLink PreviousDeclLink(decl_type *D) {

View File

@ -228,6 +228,11 @@ namespace clang {
TypeIDForTypeDecl(0), NamedDeclForTagDecl(0),
TypedefNameForLinkage(nullptr), HasPendingBody(false) {}
template <typename DeclT>
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
static Decl *getMostRecentDeclImpl(...);
static Decl *getMostRecentDecl(Decl *D);
template <typename DeclT>
static void attachPreviousDeclImpl(ASTReader &Reader,
Redeclarable<DeclT> *D, Decl *Previous);
@ -2782,6 +2787,27 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
AnonymousDeclNumber, TypedefNameForLinkage);
}
template<typename DeclT>
Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *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<TYPE##Decl>(D));
#include "clang/AST/DeclNodes.inc"
}
llvm_unreachable("unknown decl kind");
}
template<typename DeclT>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
Redeclarable<DeclT> *D,
@ -3359,9 +3385,14 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
ArrayRef<Decl *> 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 {