diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-09 17:30:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-09 17:30:44 +0000 |
commit | c6c8e0ec96bb64f1b9f543d7c8317c6090f80a30 (patch) | |
tree | 39aea2b30aebc4a42f967293a8e28181ab8fc20e /lib/Serialization/ASTReader.cpp | |
parent | c02d62f0b82c144f7db2a71c3b4565de8c6163e5 (diff) |
Implement redeclaration merging for namespaces defined in distinct
modules. Teach name lookup into namespaces to search in each of the
merged DeclContexts as well as the (now-primary) DeclContext. This
supports the common case where two different modules put something
into the same namespace.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147778 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index df158599de..fa21bf5fdb 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -4808,15 +4808,17 @@ namespace { /// declaration context. class DeclContextNameLookupVisitor { ASTReader &Reader; + llvm::SmallVectorImpl<const DeclContext *> &Contexts; const DeclContext *DC; DeclarationName Name; SmallVectorImpl<NamedDecl *> &Decls; public: DeclContextNameLookupVisitor(ASTReader &Reader, - const DeclContext *DC, DeclarationName Name, + SmallVectorImpl<const DeclContext *> &Contexts, + DeclarationName Name, SmallVectorImpl<NamedDecl *> &Decls) - : Reader(Reader), DC(DC), Name(Name), Decls(Decls) { } + : Reader(Reader), Contexts(Contexts), Name(Name), Decls(Decls) { } static bool visit(ModuleFile &M, void *UserData) { DeclContextNameLookupVisitor *This @@ -4824,11 +4826,20 @@ namespace { // Check whether we have any visible declaration information for // this context in this module. - ModuleFile::DeclContextInfosMap::iterator Info - = M.DeclContextInfos.find(This->DC); - if (Info == M.DeclContextInfos.end() || !Info->second.NameLookupTableData) - return false; + ModuleFile::DeclContextInfosMap::iterator Info; + bool FoundInfo = false; + for (unsigned I = 0, N = This->Contexts.size(); I != N; ++I) { + Info = M.DeclContextInfos.find(This->Contexts[I]); + if (Info != M.DeclContextInfos.end() && + Info->second.NameLookupTableData) { + FoundInfo = true; + break; + } + } + if (!FoundInfo) + return false; + // Look for this name within this module. ASTDeclContextNameLookupTable *LookupTable = (ASTDeclContextNameLookupTable*)Info->second.NameLookupTableData; @@ -4870,7 +4881,24 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, DeclContext::lookup_iterator(0)); SmallVector<NamedDecl *, 64> Decls; - DeclContextNameLookupVisitor Visitor(*this, DC, Name, Decls); + + // Compute the declaration contexts we need to look into. Multiple such + // declaration contexts occur when two declaration contexts from disjoint + // modules get merged, e.g., when two namespaces with the same name are + // independently defined in separate modules. + SmallVector<const DeclContext *, 2> Contexts; + Contexts.push_back(DC); + + if (DC->isNamespace()) { + MergedDeclsMap::iterator Merged + = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC))); + if (Merged != MergedDecls.end()) { + for (unsigned I = 0, N = Merged->second.size(); I != N; ++I) + Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I]))); + } + } + + DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls); ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor); ++NumVisibleDeclContextsRead; SetExternalVisibleDeclsForName(DC, Name, Decls); |