// C++ Template Declarations
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
+def ext_template_param_shadow : ExtWarn<
+ err_template_param_shadow.Text>, InGroup<MicrosoftTemplate>;
def note_template_param_here : Note<"template parameter is declared here">;
def warn_template_export_unsupported : Warning<
"exported templates are unsupported">;
void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
- // Microsoft Visual C++ permits template parameters to be shadowed.
- if (getLangOpts().MicrosoftExt)
- return;
-
// C++ [temp.local]p4:
// A template-parameter shall not be redeclared within its
// scope (including nested scopes).
- Diag(Loc, diag::err_template_param_shadow)
- << cast<NamedDecl>(PrevDecl)->getDeclName();
+ //
+ // Make this a warning when MSVC compatibility is requested.
+ unsigned DiagId = getLangOpts().MSVCCompat ? diag::ext_template_param_shadow
+ : diag::err_template_param_shadow;
+ Diag(Loc, DiagId) << cast<NamedDecl>(PrevDecl)->getDeclName();
Diag(PrevDecl->getLocation(), diag::note_template_param_here);
}
int S::fn() { return 0; } // expected-warning {{is missing exception specification}}
}
+namespace PR43265 {
+template <int N> // expected-note {{template parameter is declared here}}
+struct Foo {
+ static const int N = 42; // expected-warning {{declaration of 'N' shadows template parameter}}
+};
+}
+
+namespace Inner_Outer_same_template_param_name {
+template <typename T> // expected-note {{template parameter is declared here}}
+struct Outmost {
+ template <typename T> // expected-warning {{declaration of 'T' shadows template parameter}}
+ struct Inner {
+ void f() {
+ T *var;
+ }
+ };
+};
+}