summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-25 22:21:36 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-25 22:21:36 +0000
commitb80d54049b1a299254f142bfb886a90fa4774cd3 (patch)
tree6cc80f57e29a4f89d005bebe4607afd97cc0ba23
parent35779955b3b845f0d72d0b63bda482c5f64f21f0 (diff)
downloadbcm5719-llvm-b80d54049b1a299254f142bfb886a90fa4774cd3.tar.gz
bcm5719-llvm-b80d54049b1a299254f142bfb886a90fa4774cd3.zip
PR8302: Check for shadowing a template parameter when declaring a template
template parameter. llvm-svn: 184884
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp42
-rw-r--r--clang/test/Parser/cxx-template-decl.cpp13
2 files changed, 32 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6c0658f05fb..0075223d7b3 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/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/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp
index 7e931a31fa2..7200c9d78f7 100644
--- a/clang/test/Parser/cxx-template-decl.cpp
+++ b/clang/test/Parser/cxx-template-decl.cpp
@@ -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) {
OpenPOWER on IntegriCloud