From c7e863f888bbcb2c6508acf193e74195c1b230e9 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 25 Jun 2013 22:21:36 +0000 Subject: [PATCH] PR8302: Check for shadowing a template parameter when declaring a template template parameter. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184884 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 42 ++++++++++++++----------------- test/Parser/cxx-template-decl.cpp | 13 ++++++++++ 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 6c0658f05f..0075223d7b 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -534,6 +534,15 @@ void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn, TemplateArgsIn[I])); } +static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S, + SourceLocation Loc, + IdentifierInfo *Name) { + NamedDecl *PrevDecl = SemaRef.LookupSingleName( + S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForRedeclaration); + if (PrevDecl && PrevDecl->isTemplateParameter()) + SemaRef.DiagnoseTemplateParameterShadow(Loc, PrevDecl); +} + /// ActOnTypeParameter - Called when a C++ template type parameter /// (e.g., "typename T") has been parsed. Typename specifies whether /// the keyword "typename" was used to declare the type parameter @@ -555,16 +564,6 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, "Template type parameter not in template parameter scope!"); bool Invalid = false; - if (ParamName) { - NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc, - LookupOrdinaryName, - ForRedeclaration); - if (PrevDecl && PrevDecl->isTemplateParameter()) { - DiagnoseTemplateParameterShadow(ParamNameLoc, PrevDecl); - PrevDecl = 0; - } - } - SourceLocation Loc = ParamNameLoc; if (!ParamName) Loc = KeyLoc; @@ -578,6 +577,8 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, Param->setInvalidDecl(); if (ParamName) { + maybeDiagnoseTemplateParameterShadow(*this, S, ParamNameLoc, ParamName); + // Add the template parameter into the current scope. S->AddDecl(Param); IdResolver.AddDecl(Param); @@ -683,23 +684,13 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, "Non-type template parameter not in template parameter scope!"); bool Invalid = false; - IdentifierInfo *ParamName = D.getIdentifier(); - if (ParamName) { - NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(), - LookupOrdinaryName, - ForRedeclaration); - if (PrevDecl && PrevDecl->isTemplateParameter()) { - DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); - PrevDecl = 0; - } - } - T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc()); if (T.isNull()) { T = Context.IntTy; // Recover with an 'int' type. Invalid = true; } + IdentifierInfo *ParamName = D.getIdentifier(); bool IsParameterPack = D.hasEllipsis(); NonTypeTemplateParmDecl *Param = NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(), @@ -708,11 +699,14 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, Depth, Position, ParamName, T, IsParameterPack, TInfo); Param->setAccess(AS_public); - + if (Invalid) Param->setInvalidDecl(); - if (D.getIdentifier()) { + if (ParamName) { + maybeDiagnoseTemplateParameterShadow(*this, S, D.getIdentifierLoc(), + ParamName); + // Add the template parameter into the current scope. S->AddDecl(Param); IdResolver.AddDecl(Param); @@ -774,6 +768,8 @@ Decl *Sema::ActOnTemplateTemplateParameter(Scope* S, // If the template template parameter has a name, then link the identifier // into the scope and lookup mechanisms. if (Name) { + maybeDiagnoseTemplateParameterShadow(*this, S, NameLoc, Name); + S->AddDecl(Param); IdResolver.AddDecl(Param); } diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp index 7e931a31fa..7200c9d78f 100644 --- a/test/Parser/cxx-template-decl.cpp +++ b/test/Parser/cxx-template-decl.cpp @@ -85,6 +85,19 @@ struct shadow5 { int T(int, float); // expected-error{{shadows}} }; +template // expected-error{{declaration of 'T' shadows template parameter}} +void shadow6(); + +template class T> // expected-error{{declaration of 'T' shadows template parameter}} +void shadow7(); + +// PR8302 +template class T> struct shadow8 { // expected-note{{template parameter is declared here}} + template class T> struct inner; // expected-error{{declaration of 'T' shadows template parameter}} +}; + // Non-type template parameters in scope template void f(int& i) { -- 2.40.0