From: Douglas Gregor Date: Mon, 9 Jan 2012 17:38:47 +0000 (+0000) Subject: Implement merging of namespace-scope declarations across modules, so X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0fdc09fe680787b855cf20183c4bd3b83f2c907f;p=clang Implement merging of namespace-scope declarations across modules, so that we can merge, for example, two occurrences of namespace N { void f(); } in two disjoint modules. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147780 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index ffd768a94d..f6c9bfaa57 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1741,14 +1741,14 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } ASTDeclReader::FindExistingResult::~FindExistingResult() { - if (!AddResult) + if (!AddResult || Existing) return; DeclContext *DC = New->getDeclContext()->getRedeclContext(); if (DC->isTranslationUnit() && Reader.SemaObj) { - if (!Existing) { - Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName()); - } + Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName()); + } else if (DC->isNamespace()) { + DC->addDecl(New); } } @@ -1775,7 +1775,13 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { } } - // FIXME: Search in the DeclContext. + if (DC->isNamespace()) { + for (DeclContext::lookup_result R = DC->lookup(Name); + R.first != R.second; ++R.first) { + if (isSameEntity(*R.first, D)) + return FindExistingResult(Reader, D, *R.first); + } + } return FindExistingResult(Reader, D, /*Existing=*/0); } diff --git a/test/Modules/Inputs/namespaces-left.h b/test/Modules/Inputs/namespaces-left.h index 6835cda0c4..ea2ae2b9ce 100644 --- a/test/Modules/Inputs/namespaces-left.h +++ b/test/Modules/Inputs/namespaces-left.h @@ -25,3 +25,15 @@ namespace N6 { namespace N7 { int &f(int); } + +namespace N8 { + int &f(int); +} + +namespace N9 { + int &f(int); +} + +namespace N10 { + int &f(int); +} diff --git a/test/Modules/Inputs/namespaces-right.h b/test/Modules/Inputs/namespaces-right.h index 0afef073c3..d103c00c82 100644 --- a/test/Modules/Inputs/namespaces-right.h +++ b/test/Modules/Inputs/namespaces-right.h @@ -27,3 +27,15 @@ namespace N6 { namespace N7 { double &f(double); } + +namespace N8 { + int &f(int); +} + +namespace N9 { + int &f(int); +} + +namespace N10 { + int &f(int); +} diff --git a/test/Modules/namespaces.cpp b/test/Modules/namespaces.cpp index e1a8d6e8b0..9ef966ac01 100644 --- a/test/Modules/namespaces.cpp +++ b/test/Modules/namespaces.cpp @@ -5,6 +5,8 @@ namespace N6 { char &f(char); } +namespace N8 { } + @import namespaces_left; @import namespaces_right; @@ -23,6 +25,10 @@ namespace N5 { char &f(char); } +namespace N10 { + int &f(int); +} + void testMerged() { int &ir1 = N5::f(17); int &ir2 = N6::f(17); @@ -34,3 +40,10 @@ void testMerged() { char &cr2 = N6::f('b'); } +// Test merging of declarations within namespaces that themselves were +// merged without a common first declaration. +void testMergedMerged() { + int &ir1 = N8::f(17); + int &ir2 = N9::f(17); + int &ir3 = N10::f(17); +}