diff options
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 14 | ||||
-rw-r--r-- | test/SemaTemplate/dependent-base-classes.cpp | 28 |
4 files changed, 37 insertions, 28 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 3e9deda811..948949b7dc 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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 ('::'). diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 6006bca4b0..7a0b625206 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -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). diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 2fad8325d4..0773a0f1e4 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -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(), diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp index 79b28c2239..80d20b09b8 100644 --- a/test/SemaTemplate/dependent-base-classes.cpp +++ b/test/SemaTemplate/dependent-base-classes.cpp @@ -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}} + } + }; +} |