aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp22
-rw-r--r--lib/Sema/SemaTemplate.cpp14
-rw-r--r--test/SemaTemplate/dependent-base-classes.cpp28
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}}
+ }
+ };
+}