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
"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;
Param->setInvalidDecl();
if (ParamName) {
+ maybeDiagnoseTemplateParameterShadow(*this, S, ParamNameLoc, ParamName);
+
// Add the template parameter into the current scope.
S->AddDecl(Param);
IdResolver.AddDecl(Param);
"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(),
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);
// 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);
}
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) {