]> granicus.if.org Git - clang/commitdiff
Teach Sema::ActOnDependentTemplateName that a dependent template name
authorDouglas Gregor <dgregor@apple.com>
Tue, 19 Jan 2010 16:01:07 +0000 (16:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 19 Jan 2010 16:01:07 +0000 (16:01 +0000)
in a member access expression referring into the current instantiation
need not be resolved at template definition *if* the current
instantiation has any dependent base classes. Fixes PR6081.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93877 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaCXXScopeSpec.cpp
lib/Sema/SemaTemplate.cpp
test/SemaTemplate/dependent-base-classes.cpp

index 3e9deda811fe5e4e36d10cb171ba835e9576321b..948949b7dcb9cf90857d81ea291d8589c33340a5 100644 (file)
@@ -2053,7 +2053,6 @@ public:
   bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
   CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
   bool isUnknownSpecialization(const CXXScopeSpec &SS);
-  bool isCurrentInstantiationWithDependentBases(const CXXScopeSpec &SS);
 
   /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
   /// global scope ('::').
index 6006bca4b0be4e1cb29f9b2e6c9d0e4b94906204..7a0b6252064dba90b81085d2f115c7756719adf3 100644 (file)
@@ -210,28 +210,6 @@ bool Sema::isUnknownSpecialization(const CXXScopeSpec &SS) {
   return getCurrentInstantiationOf(NNS) == 0;
 }
 
-/// \brief Determine whether the given scope specifier refers to a
-/// current instantiation that has any dependent base clases.
-///
-/// This check is typically used when we've performed lookup into the
-/// current instantiation of a template, but that lookup failed. When
-/// there are dependent bases present, however, the lookup needs to be
-/// delayed until template instantiation time.
-bool Sema::isCurrentInstantiationWithDependentBases(const CXXScopeSpec &SS) {
-  if (!SS.isSet())
-    return false;
-
-  NestedNameSpecifier *NNS = (NestedNameSpecifier*)SS.getScopeRep();
-  if (!NNS->isDependent())
-    return false;
-
-  CXXRecordDecl *CurrentInstantiation = getCurrentInstantiationOf(NNS);
-  if (!CurrentInstantiation)
-    return false;
-
-  return CurrentInstantiation->hasAnyDependentBases();
-}
-
 /// \brief If the given nested name specifier refers to the current
 /// instantiation, return the declaration that corresponds to that
 /// current instantiation (C++0x [temp.dep.type]p1).
index 2fad8325d4dda930c6fe53c6c19f1766cbe72faa..0773a0f1e4dee4f1a385385a5df7d4dd62b2c52d 100644 (file)
@@ -1586,9 +1586,12 @@ Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
                                  UnqualifiedId &Name,
                                  TypeTy *ObjectType,
                                  bool EnteringContext) {
-  if ((ObjectType &&
-       computeDeclContext(QualType::getFromOpaquePtr(ObjectType))) ||
-      (SS.isSet() && computeDeclContext(SS, EnteringContext))) {
+  DeclContext *LookupCtx = 0;
+  if (SS.isSet())
+    LookupCtx = computeDeclContext(SS, EnteringContext);
+  if (!LookupCtx && ObjectType)
+    LookupCtx = computeDeclContext(QualType::getFromOpaquePtr(ObjectType));
+  if (LookupCtx) {
     // C++0x [temp.names]p5:
     //   If a name prefixed by the keyword template is not the name of
     //   a template, the program is ill-formed. [Note: the keyword
@@ -1608,8 +1611,9 @@ Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
     TemplateTy Template;
     TemplateNameKind TNK = isTemplateName(0, SS, Name, ObjectType,
                                           EnteringContext, Template);
-    if (TNK == TNK_Non_template && 
-        isCurrentInstantiationWithDependentBases(SS)) {
+    if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
+        isa<CXXRecordDecl>(LookupCtx) &&
+        cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) {
       // This is a dependent template.
     } else if (TNK == TNK_Non_template) {
       Diag(Name.getSourceRange().getBegin(), 
index 79b28c2239fe1025396a6f364cc0b9740a18002a..80d20b09b82a9633a1c251cf88d6c1abf8efa246 100644 (file)
@@ -82,3 +82,31 @@ namespace Ambig {
 
   Derived<int> di; // expected-note{{instantiation of}}
 }
+
+namespace PR6081 {
+  template<typename T>
+  struct A { };
+
+  template<typename T>
+  class B : public A<T> 
+  {
+  public:
+    template< class X >
+    void f0(const X & k)
+    {
+      this->template f1<int>()(k);
+    }
+  };
+
+  template<typename T>
+  class C
+  {
+  public:
+    template< class X >
+    void f0(const X & k)
+    {
+      this->template f1<int>()(k); // expected-error{{'f1' following the 'template' keyword does not refer to a template}} \
+      // FIXME: expected-error{{unqualified-id}}
+    }
+  };
+}