InGroup<CXX98Compat>, DefaultIgnore;
def err_non_type_template_in_nested_name_specifier : Error<
- "qualified name refers into a specialization of function template %0">;
+ "qualified name refers into a specialization of %select{function|variable}0 "
+ "template %1">;
def err_template_id_not_a_type : Error<
"template name refers to non-type template %0">;
def note_template_declared_here : Note<
return false;
}
- // FIXME: Variable templates
+ TemplateDecl *TD = Template.get().getAsTemplateDecl();
if (Template.get().getAsOverloadedTemplate() || DTN ||
- isa<FunctionTemplateDecl>(Template.get().getAsTemplateDecl())) {
+ isa<FunctionTemplateDecl>(TD) || isa<VarTemplateDecl>(TD)) {
SourceRange R(TemplateNameLoc, RAngleLoc);
if (SS.getRange().isValid())
R.setBegin(SS.getRange().getBegin());
Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier)
- << Template.get() << R;
+ << (TD && isa<VarTemplateDecl>(TD)) << Template.get() << R;
NoteAllFoundTemplates(Template.get());
return true;
}
}
namespace nested_name {
- template<typename T> int a;
- // FIXME: This triggers a crash.
- //a<int>::b c;
+ template<typename T> int a; // expected-note {{variable template 'a' declared here}}
+ a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}