aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-05-19 09:39:06 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-05-19 09:39:06 +0000
commitc3f984fa13364520f4a2c447d1d213db77db3309 (patch)
treea0f3699e3d4f69d89a2cbbf687e0454a67c09367
parenta89064aa4695d9a2fec24efcc74ca0e795aaa17c (diff)
Provide a naming class for UnresolvedLookupExprs, even when occuring on
template names. We were completely missing naming classes for many unqualified lookups, but this didn't trigger code paths that need it. This removes part of an optimization that re-uses the template name lookup done by the parser to determine if explicit template arguments actually form a template-id. Unfortunately the technique for avoiding the duplicate lookup lost needed data such as the class context in which the lookup succeeded. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104117 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp17
-rw-r--r--lib/Sema/SemaLookup.cpp5
-rw-r--r--test/CXX/temp/temp.names/p2.cpp13
3 files changed, 23 insertions, 12 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5e1f21b4c3..94aa6b09fe 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1077,17 +1077,12 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
// Perform the required lookup.
LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
if (TemplateArgs) {
- // Just re-use the lookup done by isTemplateName.
- DecomposeTemplateName(R, Id);
-
- // Re-derive the naming class.
- if (SS.isSet()) {
- NestedNameSpecifier *Qualifier
- = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
- if (const Type *Ty = Qualifier->getAsType())
- if (CXXRecordDecl *NamingClass = Ty->getAsCXXRecordDecl())
- R.setNamingClass(NamingClass);
- }
+ // Lookup the template name again to correctly establish the context in
+ // which it was found. This is really unfortunate as we already did the
+ // lookup to determine that it was a template name in the first place. If
+ // this becomes a performance hit, we can work harder to preserve those
+ // results until we get here but it's likely not worth it.
+ LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false);
} else {
bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 774a82b7c7..b25ecb1e06 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -665,6 +665,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
//
DeclContext *OutsideOfTemplateParamDC = 0;
for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
+ DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());
+
// Check whether the IdResolver has anything in this scope.
bool Found = false;
for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
@@ -675,10 +677,11 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
}
if (Found) {
R.resolveKind();
+ if (S->isClassScope())
+ R.setNamingClass(dyn_cast<CXXRecordDecl>(Ctx));
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
diff --git a/test/CXX/temp/temp.names/p2.cpp b/test/CXX/temp/temp.names/p2.cpp
new file mode 100644
index 0000000000..8666b61a4e
--- /dev/null
+++ b/test/CXX/temp/temp.names/p2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Ensure that when enforcing access control an unqualified template name with
+// explicit template arguments, we don't loose the context of the name lookup
+// because of the required early lookup to determine if it names a template.
+namespace PR7163 {
+ template <typename R, typename P> void h(R (*func)(P)) {}
+ class C {
+ template <typename T> static void g(T*) {};
+ public:
+ void f() { h(g<int>); }
+ };
+}