diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-14 04:53:42 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-14 04:53:42 +0000 |
commit | 00b4b039f02d338ae4774797053235a7e65abbde (patch) | |
tree | 38467b42cae543045e427d18e9203b7539486172 /lib/Sema/SemaLookup.cpp | |
parent | ca4aa379fcae53c50760cdf3632d8d801b795046 (diff) |
Make sure to search semantic scopes and appropriate template-parameter
scopes during unqualified name lookup that has fallen out to namespace
scope. Fixes PR7133.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103766 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 337a4a3ce3..31c33e963c 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -761,10 +761,6 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { // context as well as walking through the scopes. for (; S; S = S->getParent()) { - DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity()); - if (Ctx && Ctx->isTransparentContext()) - continue; - // Check whether the IdResolver has anything in this scope. bool Found = false; for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) { @@ -778,21 +774,57 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { } } - // If we have a context, and it's not a context stashed in the - // template parameter scope for an out-of-line definition, also - // look into that context. - if (Ctx && !(Found && S && S->isTemplateParamScope())) { - assert(Ctx->isFileContext() && - "We should have been looking only at file context here already."); + if (Found && S->isTemplateParamScope()) { + R.resolveKind(); + return true; + } - // Look into context considering using-directives. - if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) - Found = true; + DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity()); + if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC && + S->getParent() && !S->getParent()->isTemplateParamScope()) { + // We've just searched the last template parameter scope and + // found nothing, so look into the the contexts between the + // lexical and semantic declaration contexts returned by + // findOuterContext(). This implements the name lookup behavior + // of C++ [temp.local]p8. + Ctx = OutsideOfTemplateParamDC; + OutsideOfTemplateParamDC = 0; } + + if (Ctx) { + DeclContext *OuterCtx; + bool SearchAfterTemplateScope; + llvm::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S); + if (SearchAfterTemplateScope) + OutsideOfTemplateParamDC = OuterCtx; - if (Found) { - R.resolveKind(); - return true; + for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) { + // We do not directly look into transparent contexts, since + // those entities will be found in the nearest enclosing + // non-transparent context. + if (Ctx->isTransparentContext()) + continue; + + // If we have a context, and it's not a context stashed in the + // template parameter scope for an out-of-line definition, also + // look into that context. + if (!(Found && S && S->isTemplateParamScope())) { + assert(Ctx->isFileContext() && + "We should have been looking only at file context here already."); + + // Look into context considering using-directives. + if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) + Found = true; + } + + if (Found) { + R.resolveKind(); + return true; + } + + if (R.isForRedeclaration() && !Ctx->isTransparentContext()) + return false; + } } if (R.isForRedeclaration() && Ctx && !Ctx->isTransparentContext()) |