[cfe-commits] r103766 - in /cfe/trunk: lib/Sema/SemaLookup.cpp test/SemaCXX/nested-name-spec.cpp test/SemaTemplate/nested-name-spec-template.cpp
Douglas Gregor
dgregor at apple.com
Thu May 13 21:53:42 PDT 2010
Author: dgregor
Date: Thu May 13 23:53:42 2010
New Revision: 103766
URL: http://llvm.org/viewvc/llvm-project?rev=103766&view=rev
Log:
Make sure to search semantic scopes and appropriate template-parameter
scopes during unqualified name lookup that has fallen out to namespace
scope. Fixes PR7133.
Modified:
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/SemaCXX/nested-name-spec.cpp
cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=103766&r1=103765&r2=103766&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu May 13 23:53:42 2010
@@ -761,10 +761,6 @@
// 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,23 +774,59 @@
}
}
- // 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.");
-
- // Look into context considering using-directives.
- if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs))
- Found = true;
- }
-
- if (Found) {
+ if (Found && S->isTemplateParamScope()) {
R.resolveKind();
return 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;
+
+ 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())
return false;
}
Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=103766&r1=103765&r2=103766&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Thu May 13 23:53:42 2010
@@ -228,3 +228,19 @@
A::execute(path); // expected-error {{incomplete type 'test3::A' named in nested name specifier}}
}
}
+
+namespace PR7133 {
+ namespace A {
+ class Foo;
+ }
+
+ namespace A {
+ namespace B {
+ bool foo(Foo &);
+ }
+ }
+
+ bool A::B::foo(Foo &) {
+ return false;
+ }
+}
Modified: cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp?rev=103766&r1=103765&r2=103766&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp Thu May 13 23:53:42 2010
@@ -64,3 +64,10 @@
template <class T>
T pair<T>::* const pair<T>::mem_array[2] = { &pair<T>::x, &pair<T>::y };
}
+
+typedef int T;
+namespace N1 {
+ template<typename T> T f0();
+}
+
+template<typename T> T N1::f0() { }
More information about the cfe-commits
mailing list