aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaLookup.cpp33
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp19
2 files changed, 44 insertions, 8 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index df9fdeb40d..ebe2894406 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -884,6 +884,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
// }
// }
//
+ UnqualUsingDirectiveSet UDirs;
+ bool VisitedUsingDirectives = false;
DeclContext *OutsideOfTemplateParamDC = 0;
for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());
@@ -957,9 +959,24 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
// If this is a file context, we need to perform unqualified name
// lookup considering using directives.
if (Ctx->isFileContext()) {
- UnqualUsingDirectiveSet UDirs;
- UDirs.visit(Ctx, Ctx);
- UDirs.done();
+ // If we haven't handled using directives yet, do so now.
+ if (!VisitedUsingDirectives) {
+ // Add using directives from this context up to the top level.
+ for (DeclContext *UCtx = Ctx; UCtx; UCtx = UCtx->getParent())
+ UDirs.visit(UCtx, UCtx);
+
+ // Find the innermost file scope, so we can add using directives
+ // from local scopes.
+ Scope *InnermostFileScope = S;
+ while (InnermostFileScope &&
+ !isNamespaceOrTranslationUnitScope(InnermostFileScope))
+ InnermostFileScope = InnermostFileScope->getParent();
+ UDirs.visitScopeChain(Initial, InnermostFileScope);
+
+ UDirs.done();
+
+ VisitedUsingDirectives = true;
+ }
if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) {
R.resolveKind();
@@ -994,11 +1011,11 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
//
// FIXME: Cache this sorted list in Scope structure, and DeclContext, so we
// don't build it for each lookup!
-
- UnqualUsingDirectiveSet UDirs;
- UDirs.visitScopeChain(Initial, S);
- UDirs.done();
-
+ if (!VisitedUsingDirectives) {
+ UDirs.visitScopeChain(Initial, S);
+ UDirs.done();
+ }
+
// Lookup namespace scope, and global scope.
// Unqualified name lookup in C++ requires looking into scopes
// that aren't strictly lexical, and therefore we walk through the
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
index 7da3087e7d..272ad8568c 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
@@ -47,3 +47,22 @@ class Other {
void Other::foo(YFloat a, YFloat b) {
YFloat c = a - b;
}
+
+// <rdar://problem/13540899>
+namespace Other {
+ void other_foo();
+}
+
+namespace M2 {
+ using namespace Other;
+
+ namespace MInner {
+ class Bar {
+ void bar();
+ };
+ }
+}
+
+void M2::MInner::Bar::bar() {
+ other_foo();
+}