r184884 - PR8302: Check for shadowing a template parameter when declaring a template

Richard Smith richard-llvm at metafoo.co.uk
Tue Jun 25 15:21:36 PDT 2013


Author: rsmith
Date: Tue Jun 25 17:21:36 2013
New Revision: 184884

URL: http://llvm.org/viewvc/llvm-project?rev=184884&view=rev
Log:
PR8302: Check for shadowing a template parameter when declaring a template
template parameter.

Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/Parser/cxx-template-decl.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=184884&r1=184883&r2=184884&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jun 25 17:21:36 2013
@@ -534,6 +534,15 @@ void Sema::translateTemplateArguments(co
                                                       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,
          "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,
     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::ActOnNonTypeTemplateParamete
          "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::ActOnNonTypeTemplateParamete
                                       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::ActOnTemplateTemplateParamet
   // 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);
   }

Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=184884&r1=184883&r2=184884&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Tue Jun 25 17:21:36 2013
@@ -85,6 +85,19 @@ struct shadow5 {
   int T(int, float); // expected-error{{shadows}}
 };
 
+template<typename T, // expected-note{{template parameter is declared here}}
+         T T> // expected-error{{declaration of 'T' shadows template parameter}}
+void shadow6();
+
+template<typename T, // expected-note{{template parameter is declared here}}
+         template<typename> class T> // expected-error{{declaration of 'T' shadows template parameter}}
+void shadow7();
+
+// PR8302
+template<template<typename> class T> struct shadow8 { // expected-note{{template parameter is declared here}}
+  template<template<typename> class T> struct inner; // expected-error{{declaration of 'T' shadows template parameter}}
+};
+
 // Non-type template parameters in scope
 template<int Size> 
 void f(int& i) {





More information about the cfe-commits mailing list