diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-20 23:39:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-20 23:39:24 +0000 |
commit | ade9bcd72e8de54b5a9c571047322f59e130cf89 (patch) | |
tree | 18eecf055a109d8a31fceb70413832e8e62d2008 /clang | |
parent | 5305dc0be1ac8502a6da9b53d81ae59a071d04ee (diff) | |
download | bcm5719-llvm-ade9bcd72e8de54b5a9c571047322f59e130cf89.tar.gz bcm5719-llvm-ade9bcd72e8de54b5a9c571047322f59e130cf89.zip |
Cope with extraneous "template" keyword when providing an out-of-line
definition of a member template (or a member thereof). Fixes PR5566.
llvm-svn: 89512
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Parse/Action.h | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 6 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp | 1 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp | 11 |
8 files changed, 31 insertions, 11 deletions
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 018cc145403..abe50d05bcc 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -1685,10 +1685,14 @@ public: /// \param ObjectType if this dependent template name occurs in the /// context of a member access expression, the type of the object being /// accessed. + /// + /// \param EnteringContext whether we are entering the context of this + /// template. virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc, const CXXScopeSpec &SS, UnqualifiedId &Name, - TypeTy *ObjectType) { + TypeTy *ObjectType, + bool EnteringContext) { return TemplateTy(); } diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 145c8616eb8..992211dad75 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -148,7 +148,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, TPA.Commit(); TemplateTy Template = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName, - ObjectType); + ObjectType, EnteringContext); if (!Template) break; if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, @@ -774,7 +774,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, TemplateName.setIdentifier(Name, NameLoc); if (ObjectType) { Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, - TemplateName, ObjectType); + TemplateName, ObjectType, + EnteringContext); TNK = TNK_Dependent_template_name; if (!Template.get()) return true; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 16b1c800800..5be4ca82f72 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -851,7 +851,8 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { if (isEndOfTemplateArgument(Tok)) { TemplateTy Template = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, - /*ObjectType=*/0); + /*ObjectType=*/0, + /*EnteringContext=*/false); if (Template.get()) return ParsedTemplateArgument(SS, Template, Name.StartLocation); } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 6e74f9277a1..2d3f9fc8cb2 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -2293,7 +2293,8 @@ public: virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc, const CXXScopeSpec &SS, UnqualifiedId &Name, - TypeTy *ObjectType); + TypeTy *ObjectType, + bool EnteringContext); bool CheckClassTemplatePartialSpecializationArgs( TemplateParameterList *TemplateParams, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 8d77b1ff9b8..f0133438941 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1381,10 +1381,11 @@ Sema::TemplateTy Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc, const CXXScopeSpec &SS, UnqualifiedId &Name, - TypeTy *ObjectType) { + TypeTy *ObjectType, + bool EnteringContext) { if ((ObjectType && computeDeclContext(QualType::getFromOpaquePtr(ObjectType))) || - (SS.isSet() && computeDeclContext(SS, false))) { + (SS.isSet() && computeDeclContext(SS, EnteringContext))) { // 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 @@ -1403,7 +1404,7 @@ Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc, // rules, even in C++03 mode, retroactively applying the DR. TemplateTy Template; TemplateNameKind TNK = isTemplateName(0, SS, Name, ObjectType, - false, Template); + EnteringContext, Template); if (TNK == TNK_Non_template) { Diag(Name.getSourceRange().getBegin(), diag::err_template_kw_refers_to_non_template) diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 579937ead76..5018b1544e4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -5349,7 +5349,8 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier, /*FIXME:*/getDerived().getBaseLocation(), SS, Name, - ObjectType.getAsOpaquePtr()) + ObjectType.getAsOpaquePtr(), + /*EnteringContext=*/false) .template getAsVal<TemplateName>(); } @@ -5369,7 +5370,8 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier, /*FIXME:*/getDerived().getBaseLocation(), SS, Name, - ObjectType.getAsOpaquePtr()) + ObjectType.getAsOpaquePtr(), + /*EnteringContext=*/false) .template getAsVal<TemplateName>(); } diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp index b63c56c40fe..90bb16256c5 100644 --- a/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - template<typename T, int N> struct A; diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp index 725b61c2716..2d52994dc97 100644 --- a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp @@ -66,3 +66,14 @@ X0<T, U>::operator T*() const { namespace N { template <class X> class A {void a();}; } namespace N { template <class X> void A<X>::a() {} } + +// PR5566 +template<typename T> +struct X1 { + template<typename U> + struct B { void f(); }; +}; + +template<typename T> +template<typename U> +void X1<T>::template B<U>::f() { } |