[cfe-commits] r104117 - in /cfe/trunk: lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp test/CXX/temp/temp.names/p2.cpp

Chandler Carruth chandlerc at gmail.com
Wed May 19 02:39:06 PDT 2010


Author: chandlerc
Date: Wed May 19 04:39:06 2010
New Revision: 104117

URL: http://llvm.org/viewvc/llvm-project?rev=104117&view=rev
Log:
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.

Added:
    cfe/trunk/test/CXX/temp/temp.names/p2.cpp
Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=104117&r1=104116&r2=104117&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed May 19 04:39:06 2010
@@ -1077,17 +1077,12 @@
   // 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);

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=104117&r1=104116&r2=104117&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed May 19 04:39:06 2010
@@ -665,6 +665,8 @@
   //
   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 @@
     }
     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

Added: cfe/trunk/test/CXX/temp/temp.names/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.names/p2.cpp?rev=104117&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.names/p2.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.names/p2.cpp Wed May 19 04:39:06 2010
@@ -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>); }
+  };
+}





More information about the cfe-commits mailing list