forked from OSchip/llvm-project
Give more accurate descriptions of what kind of template we found in diagnostics.
We were previouly assuming that every type template was a class template, which is not true any more. llvm-svn: 291988
This commit is contained in:
parent
e3061a4065
commit
0c062b408b
|
@ -3796,11 +3796,13 @@ def err_template_decl_ref : Error<
|
||||||
|
|
||||||
// C++ Template Argument Lists
|
// C++ Template Argument Lists
|
||||||
def err_template_missing_args : Error<
|
def err_template_missing_args : Error<
|
||||||
"use of class template %0 requires template arguments">;
|
"use of "
|
||||||
|
"%select{class template|function template|variable template|alias template|"
|
||||||
|
"template template parameter|template}0 %1 requires template arguments">;
|
||||||
def err_template_arg_list_different_arity : Error<
|
def err_template_arg_list_different_arity : Error<
|
||||||
"%select{too few|too many}0 template arguments for "
|
"%select{too few|too many}0 template arguments for "
|
||||||
"%select{class template|function template|template template parameter"
|
"%select{class template|function template|variable template|alias template|"
|
||||||
"|template}1 %2">;
|
"template template parameter|template}1 %2">;
|
||||||
def note_template_decl_here : Note<"template is declared here">;
|
def note_template_decl_here : Note<"template is declared here">;
|
||||||
def err_template_arg_must_be_type : Error<
|
def err_template_arg_must_be_type : Error<
|
||||||
"template argument for template type parameter must be a type">;
|
"template argument for template type parameter must be a type">;
|
||||||
|
|
|
@ -1689,6 +1689,18 @@ public:
|
||||||
bool IsAddressOfOperand,
|
bool IsAddressOfOperand,
|
||||||
std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
|
std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
|
||||||
|
|
||||||
|
/// Describes the detailed kind of a template name. Used in diagnostics.
|
||||||
|
enum class TemplateNameKindForDiagnostics {
|
||||||
|
ClassTemplate,
|
||||||
|
FunctionTemplate,
|
||||||
|
VarTemplate,
|
||||||
|
AliasTemplate,
|
||||||
|
TemplateTemplateParam,
|
||||||
|
DependentTemplate
|
||||||
|
};
|
||||||
|
TemplateNameKindForDiagnostics
|
||||||
|
getTemplateNameKindForDiagnostics(TemplateName Name);
|
||||||
|
|
||||||
Decl *ActOnDeclarator(Scope *S, Declarator &D);
|
Decl *ActOnDeclarator(Scope *S, Declarator &D);
|
||||||
|
|
||||||
NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
|
NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
|
||||||
|
|
|
@ -656,7 +656,8 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||||
Name, nullptr, true, TemplateResult,
|
Name, nullptr, true, TemplateResult,
|
||||||
MemberOfUnknownSpecialization) == TNK_Type_template) {
|
MemberOfUnknownSpecialization) == TNK_Type_template) {
|
||||||
TemplateName TplName = TemplateResult.get();
|
TemplateName TplName = TemplateResult.get();
|
||||||
Diag(IILoc, diag::err_template_missing_args) << TplName;
|
Diag(IILoc, diag::err_template_missing_args)
|
||||||
|
<< (int)getTemplateNameKindForDiagnostics(TplName) << TplName;
|
||||||
if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
|
if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
|
||||||
Diag(TplDecl->getLocation(), diag::note_template_decl_here)
|
Diag(TplDecl->getLocation(), diag::note_template_decl_here)
|
||||||
<< TplDecl->getTemplateParameters()->getSourceRange();
|
<< TplDecl->getTemplateParameters()->getSourceRange();
|
||||||
|
@ -1072,6 +1073,24 @@ Corrected:
|
||||||
return BuildDeclarationNameExpr(SS, Result, ADL);
|
return BuildDeclarationNameExpr(SS, Result, ADL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sema::TemplateNameKindForDiagnostics
|
||||||
|
Sema::getTemplateNameKindForDiagnostics(TemplateName Name) {
|
||||||
|
auto *TD = Name.getAsTemplateDecl();
|
||||||
|
if (!TD)
|
||||||
|
return TemplateNameKindForDiagnostics::DependentTemplate;
|
||||||
|
if (isa<ClassTemplateDecl>(TD))
|
||||||
|
return TemplateNameKindForDiagnostics::ClassTemplate;
|
||||||
|
if (isa<FunctionTemplateDecl>(TD))
|
||||||
|
return TemplateNameKindForDiagnostics::FunctionTemplate;
|
||||||
|
if (isa<VarTemplateDecl>(TD))
|
||||||
|
return TemplateNameKindForDiagnostics::VarTemplate;
|
||||||
|
if (isa<TypeAliasTemplateDecl>(TD))
|
||||||
|
return TemplateNameKindForDiagnostics::AliasTemplate;
|
||||||
|
if (isa<TemplateTemplateParmDecl>(TD))
|
||||||
|
return TemplateNameKindForDiagnostics::TemplateTemplateParam;
|
||||||
|
return TemplateNameKindForDiagnostics::DependentTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
// Determines the context to return to after temporarily entering a
|
// Determines the context to return to after temporarily entering a
|
||||||
// context. This depends in an unnecessarily complicated way on the
|
// context. This depends in an unnecessarily complicated way on the
|
||||||
// exact ordering of callbacks from the parser.
|
// exact ordering of callbacks from the parser.
|
||||||
|
|
|
@ -3326,7 +3326,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
|
||||||
SourceRange SR = AL.getSourceRange();
|
SourceRange SR = AL.getSourceRange();
|
||||||
TemplateName Name = Arg.getAsTemplate();
|
TemplateName Name = Arg.getAsTemplate();
|
||||||
Diag(SR.getBegin(), diag::err_template_missing_args)
|
Diag(SR.getBegin(), diag::err_template_missing_args)
|
||||||
<< Name << SR;
|
<< (int)getTemplateNameKindForDiagnostics(Name) << Name << SR;
|
||||||
if (TemplateDecl *Decl = Name.getAsTemplateDecl())
|
if (TemplateDecl *Decl = Name.getAsTemplateDecl())
|
||||||
Diag(Decl->getLocation(), diag::note_template_decl_here);
|
Diag(Decl->getLocation(), diag::note_template_decl_here);
|
||||||
|
|
||||||
|
@ -3911,9 +3911,7 @@ static bool diagnoseArityMismatch(Sema &S, TemplateDecl *Template,
|
||||||
TemplateArgs.getRAngleLoc());
|
TemplateArgs.getRAngleLoc());
|
||||||
S.Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
S.Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
||||||
<< (NumArgs > NumParams)
|
<< (NumArgs > NumParams)
|
||||||
<< (isa<ClassTemplateDecl>(Template)? 0 :
|
<< (int)S.getTemplateNameKindForDiagnostics(TemplateName(Template))
|
||||||
isa<FunctionTemplateDecl>(Template)? 1 :
|
|
||||||
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
|
|
||||||
<< Template << Range;
|
<< Template << Range;
|
||||||
S.Diag(Template->getLocation(), diag::note_template_decl_here)
|
S.Diag(Template->getLocation(), diag::note_template_decl_here)
|
||||||
<< Params->getSourceRange();
|
<< Params->getSourceRange();
|
||||||
|
@ -4021,9 +4019,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
||||||
// Not enough arguments for this parameter pack.
|
// Not enough arguments for this parameter pack.
|
||||||
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
||||||
<< false
|
<< false
|
||||||
<< (isa<ClassTemplateDecl>(Template)? 0 :
|
<< (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
|
||||||
isa<FunctionTemplateDecl>(Template)? 1 :
|
|
||||||
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
|
|
||||||
<< Template;
|
<< Template;
|
||||||
Diag(Template->getLocation(), diag::note_template_decl_here)
|
Diag(Template->getLocation(), diag::note_template_decl_here)
|
||||||
<< Params->getSourceRange();
|
<< Params->getSourceRange();
|
||||||
|
|
|
@ -9,7 +9,7 @@ T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
|
||||||
template int pi<int>;
|
template int pi<int>;
|
||||||
|
|
||||||
#ifndef FIXING
|
#ifndef FIXING
|
||||||
template float pi<>; // expected-error {{too few template arguments for template 'pi'}}
|
template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}}
|
||||||
template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
|
template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -254,3 +254,14 @@ namespace PR31514 {
|
||||||
|
|
||||||
tuple_size<const int> t;
|
tuple_size<const int> t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace an_alias_template_is_not_a_class_template {
|
||||||
|
template<typename T> using Foo = int; // expected-note 2{{here}}
|
||||||
|
Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}}
|
||||||
|
Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}}
|
||||||
|
|
||||||
|
template<template<typename> class Bar> void f() { // expected-note 2{{here}}
|
||||||
|
Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}}
|
||||||
|
Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue