forked from OSchip/llvm-project
[modules] Don't defer performing updates if we have incomplete redecl chains.
Instead, perform them carefully immediately. llvm-svn: 215147
This commit is contained in:
parent
d45e7cec42
commit
d6db68c181
|
@ -8125,10 +8125,7 @@ void ASTReader::finishPendingActions() {
|
|||
}
|
||||
|
||||
// Perform any pending declaration updates.
|
||||
//
|
||||
// Don't do this if we have known-incomplete redecl chains: it relies on
|
||||
// being able to walk redeclaration chains.
|
||||
while (PendingDeclChains.empty() && !PendingUpdateRecords.empty()) {
|
||||
while (!PendingUpdateRecords.empty()) {
|
||||
auto Update = PendingUpdateRecords.pop_back_val();
|
||||
ReadingKindTracker ReadingKind(Read_Decl, *this);
|
||||
loadDeclUpdateRecords(Update.first, Update.second);
|
||||
|
|
|
@ -3208,9 +3208,11 @@ public:
|
|||
DeclT *operator*() { return Current; }
|
||||
|
||||
MergedRedeclIterator &operator++() {
|
||||
if (Current->isFirstDecl())
|
||||
if (Current->isFirstDecl()) {
|
||||
Canonical = Current;
|
||||
Current = Current->getPreviousDecl();
|
||||
Current = Current->getMostRecentDecl();
|
||||
} else
|
||||
Current = Current->getPreviousDecl();
|
||||
|
||||
// If we started in the merged portion, we'll reach our start position
|
||||
// eventually. Otherwise, we'll never reach it, but the second declaration
|
||||
|
@ -3234,11 +3236,34 @@ llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) {
|
|||
MergedRedeclIterator<DeclT>());
|
||||
}
|
||||
|
||||
template<typename DeclT, typename Fn>
|
||||
static void forAllLaterRedecls(DeclT *D, Fn F) {
|
||||
F(D);
|
||||
|
||||
// Check whether we've already merged D into its redeclaration chain.
|
||||
// MostRecent may or may not be nullptr if D has not been merged. If
|
||||
// not, walk the merged redecl chain and see if it's there.
|
||||
auto *MostRecent = D->getMostRecentDecl();
|
||||
bool Found = false;
|
||||
for (auto *Redecl = MostRecent; Redecl && !Found;
|
||||
Redecl = Redecl->getPreviousDecl())
|
||||
Found = (Redecl == D);
|
||||
|
||||
// If this declaration is merged, apply the functor to all later decls.
|
||||
if (Found) {
|
||||
for (auto *Redecl = MostRecent; Redecl != D;
|
||||
Redecl = Redecl->getPreviousDecl())
|
||||
F(Redecl);
|
||||
}
|
||||
}
|
||||
|
||||
void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
|
||||
const RecordData &Record) {
|
||||
while (Idx < Record.size()) {
|
||||
switch ((DeclUpdateKind)Record[Idx++]) {
|
||||
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
|
||||
// FIXME: If we also have an update record for instantiating the
|
||||
// definition of D, we need that to happen before we get here.
|
||||
Decl *MD = Reader.ReadDecl(ModuleFile, Record, Idx);
|
||||
assert(MD && "couldn't read decl from update record");
|
||||
// FIXME: We should call addHiddenDecl instead, to add the member
|
||||
|
@ -3285,12 +3310,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
|
|||
// Maintain AST consistency: any later redeclarations of this function
|
||||
// are inline if this one is. (We might have merged another declaration
|
||||
// into this one.)
|
||||
for (auto *D = FD->getMostRecentDecl(); /**/;
|
||||
D = D->getPreviousDecl()) {
|
||||
D->setImplicitlyInline();
|
||||
if (D == FD)
|
||||
break;
|
||||
}
|
||||
forAllLaterRedecls(FD, [](FunctionDecl *FD) {
|
||||
FD->setImplicitlyInline();
|
||||
});
|
||||
}
|
||||
FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
|
||||
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
|
||||
|
@ -3379,9 +3401,13 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
|
|||
}
|
||||
|
||||
case UPD_CXX_DEDUCED_RETURN_TYPE: {
|
||||
FunctionDecl *FD = cast<FunctionDecl>(D);
|
||||
Reader.Context.adjustDeducedFunctionResultType(
|
||||
FD, Reader.readType(ModuleFile, Record, Idx));
|
||||
// FIXME: Also do this when merging redecls.
|
||||
QualType DeducedResultType = Reader.readType(ModuleFile, Record, Idx);
|
||||
for (auto *Redecl : merged_redecls(D)) {
|
||||
// FIXME: If the return type is already deduced, check that it matches.
|
||||
FunctionDecl *FD = cast<FunctionDecl>(Redecl);
|
||||
Reader.Context.adjustDeducedFunctionResultType(FD, DeducedResultType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3389,17 +3415,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
|
|||
// FIXME: This doesn't send the right notifications if there are
|
||||
// ASTMutationListeners other than an ASTWriter.
|
||||
|
||||
// FIXME: We can't both pull in declarations (and thus create new pending
|
||||
// redeclaration chains) *and* walk redeclaration chains in this function.
|
||||
// We should defer the updates that require walking redecl chains.
|
||||
|
||||
// Maintain AST consistency: any later redeclarations are used too.
|
||||
for (auto *Redecl = D->getMostRecentDecl(); /**/;
|
||||
Redecl = Redecl->getPreviousDecl()) {
|
||||
Redecl->Used = true;
|
||||
if (Redecl == D)
|
||||
break;
|
||||
}
|
||||
forAllLaterRedecls(D, [](Decl *D) { D->Used = true; });
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue