summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-04-08 23:11:25 +0000
committerDouglas Gregor <dgregor@apple.com>2013-04-08 23:11:25 +0000
commitcc9406c055e329dde1b1aeb610e449ae6981863a (patch)
tree0298c9daa665acb6024d6f5f68d6875d7d48b4db /clang/lib/Sema/SemaLookup.cpp
parent065fd35268423856a28def9b2341cb5010c8814f (diff)
downloadbcm5719-llvm-cc9406c055e329dde1b1aeb610e449ae6981863a.tar.gz
bcm5719-llvm-cc9406c055e329dde1b1aeb610e449ae6981863a.zip
<rdar://problem/13540899> Collect using directives from all of the semantic contexts not represented by scopes.
This fixes a regression I introduced in r178136, where we would not consider the using directives from the semantic declaration contexts that aren't represented by the lexical scopes (Scope) when performing unqualified name lookup. This lead to horribly funny diagnostics like "no identifier named 'foo'; did you mean 'foo'?". llvm-svn: 179067
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r--clang/lib/Sema/SemaLookup.cpp33
1 files changed, 25 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index df9fdeb40d6..ebe28944062 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud