r215147 - [modules] Don't defer performing updates if we have incomplete redecl chains.
Richard Smith
richard-llvm at metafoo.co.uk
Thu Aug 7 13:58:41 PDT 2014
Author: rsmith
Date: Thu Aug 7 15:58:41 2014
New Revision: 215147
URL: http://llvm.org/viewvc/llvm-project?rev=215147&view=rev
Log:
[modules] Don't defer performing updates if we have incomplete redecl chains.
Instead, perform them carefully immediately.
Modified:
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=215147&r1=215146&r2=215147&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Aug 7 15:58:41 2014
@@ -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);
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=215147&r1=215146&r2=215147&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Aug 7 15:58:41 2014
@@ -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<MergedRedeclIterato
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,
// 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,
}
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,
// 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;
}
More information about the cfe-commits
mailing list