diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-12 23:21:45 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-02-12 23:21:45 +0000 |
commit | 8807e830373233ac31be4bf4ddbe6e854e8ebae5 (patch) | |
tree | 48f1f961ca1921e7d9030a014b0d6e9d333b8a54 /clang/lib/Serialization/ASTReaderDecl.cpp | |
parent | 5779f840005af201df8f60dfab514e4cafdebd8e (diff) | |
download | bcm5719-llvm-8807e830373233ac31be4bf4ddbe6e854e8ebae5.tar.gz bcm5719-llvm-8807e830373233ac31be4bf4ddbe6e854e8ebae5.zip |
[modules] When collecting declarations to complete a redeclaration chain for an
entity, put the originally-canonical decl IDs in the right places in the redecl
chain rather than reordering them all to the start. If we don't ensure that the
redecl chain order is consistent with the topological module order, we can fail
to make a declaration visible if later declarations are in more IDNSs than
earlier ones (for instance, because the earlier decls are invisible friends).
llvm-svn: 228978
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 5fc99b53122..8c16dfde872 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3264,47 +3264,53 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { } namespace { - /// \brief Module visitor class that finds all of the redeclarations of a - /// + /// \brief Module visitor class that finds all of the redeclarations of a + /// redeclarable declaration. class RedeclChainVisitor { ASTReader &Reader; SmallVectorImpl<DeclID> &SearchDecls; llvm::SmallPtrSetImpl<Decl *> &Deserialized; GlobalDeclID CanonID; SmallVector<Decl *, 4> Chain; - + public: RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls, llvm::SmallPtrSetImpl<Decl *> &Deserialized, GlobalDeclID CanonID) : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized), - CanonID(CanonID) { - for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) - addToChain(Reader.GetDecl(SearchDecls[I])); + CanonID(CanonID) { + // Ensure that the canonical ID goes at the start of the chain. + addToChain(Reader.GetDecl(CanonID)); } - + static bool visit(ModuleFile &M, bool Preorder, void *UserData) { if (Preorder) return false; - + return static_cast<RedeclChainVisitor *>(UserData)->visit(M); } - + void addToChain(Decl *D) { if (!D) return; - + if (Deserialized.erase(D)) Chain.push_back(D); } - + void searchForID(ModuleFile &M, GlobalDeclID GlobalID) { // Map global ID of the first declaration down to the local ID // used in this module file. DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID); if (!ID) return; - + + // If the search decl was from this module, add it to the chain before any + // of its redeclarations in this module or users of it, and after any from + // imported modules. + if (CanonID != GlobalID && Reader.isDeclIDFromModule(GlobalID, M)) + addToChain(Reader.GetDecl(GlobalID)); + // Perform a binary search to find the local redeclarations for this // declaration (if any). const LocalRedeclarationsInfo Compare = { ID, 0 }; |