diff options
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 33 | ||||
-rw-r--r-- | test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp | 19 |
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(); +} |