diff options
| -rw-r--r-- | clang/lib/Sema/Sema.h | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaCXXScopeSpec.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 14 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/dependent-base-classes.cpp | 28 | 
4 files changed, 37 insertions, 28 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 3e9deda811f..948949b7dcb 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 6006bca4b0b..7a0b6252064 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 2fad8325d4d..0773a0f1e4d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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/clang/test/SemaTemplate/dependent-base-classes.cpp b/clang/test/SemaTemplate/dependent-base-classes.cpp index 79b28c2239f..80d20b09b82 100644 --- a/clang/test/SemaTemplate/dependent-base-classes.cpp +++ b/clang/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}} +    } +  }; +}  | 

