diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-07 20:58:41 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-07 20:58:41 +0000 |
commit | d6db68c181b9774ea4a3f02fd2cb3f22d93e0095 (patch) | |
tree | 33d3567822955ecce9268090e68227fe3366c1f1 /clang/lib/Serialization/ASTReaderDecl.cpp | |
parent | d45e7cec42aeef87eef76996186597b9a5663de8 (diff) | |
download | bcm5719-llvm-d6db68c181b9774ea4a3f02fd2cb3f22d93e0095.tar.gz bcm5719-llvm-d6db68c181b9774ea4a3f02fd2cb3f22d93e0095.zip |
[modules] Don't defer performing updates if we have incomplete redecl chains.
Instead, perform them carefully immediately.
llvm-svn: 215147
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 078e9c86f2e..b153043082f 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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; } |