Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 52b862c

Browse files
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291988 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3afc8a3 commit 52b862c

File tree

6 files changed

+52
-12
lines changed

6 files changed

+52
-12
lines changed

include/clang/Basic/DiagnosticSemaKinds.td

+5-3
Original file line numberDiff line numberDiff line change
@@ -3796,11 +3796,13 @@ def err_template_decl_ref : Error<
37963796

37973797
// C++ Template Argument Lists
37983798
def err_template_missing_args : Error<
3799-
"use of class template %0 requires template arguments">;
3799+
"use of "
3800+
"%select{class template|function template|variable template|alias template|"
3801+
"template template parameter|template}0 %1 requires template arguments">;
38003802
def err_template_arg_list_different_arity : Error<
38013803
"%select{too few|too many}0 template arguments for "
3802-
"%select{class template|function template|template template parameter"
3803-
"|template}1 %2">;
3804+
"%select{class template|function template|variable template|alias template|"
3805+
"template template parameter|template}1 %2">;
38043806
def note_template_decl_here : Note<"template is declared here">;
38053807
def err_template_arg_must_be_type : Error<
38063808
"template argument for template type parameter must be a type">;

include/clang/Sema/Sema.h

+12
Original file line numberDiff line numberDiff line change
@@ -1689,6 +1689,18 @@ class Sema {
16891689
bool IsAddressOfOperand,
16901690
std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
16911691

1692+
/// Describes the detailed kind of a template name. Used in diagnostics.
1693+
enum class TemplateNameKindForDiagnostics {
1694+
ClassTemplate,
1695+
FunctionTemplate,
1696+
VarTemplate,
1697+
AliasTemplate,
1698+
TemplateTemplateParam,
1699+
DependentTemplate
1700+
};
1701+
TemplateNameKindForDiagnostics
1702+
getTemplateNameKindForDiagnostics(TemplateName Name);
1703+
16921704
Decl *ActOnDeclarator(Scope *S, Declarator &D);
16931705

16941706
NamedDecl *HandleDeclarator(Scope *S, Declarator &D,

lib/Sema/SemaDecl.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,8 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
656656
Name, nullptr, true, TemplateResult,
657657
MemberOfUnknownSpecialization) == TNK_Type_template) {
658658
TemplateName TplName = TemplateResult.get();
659-
Diag(IILoc, diag::err_template_missing_args) << TplName;
659+
Diag(IILoc, diag::err_template_missing_args)
660+
<< (int)getTemplateNameKindForDiagnostics(TplName) << TplName;
660661
if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
661662
Diag(TplDecl->getLocation(), diag::note_template_decl_here)
662663
<< TplDecl->getTemplateParameters()->getSourceRange();
@@ -1072,6 +1073,24 @@ Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
10721073
return BuildDeclarationNameExpr(SS, Result, ADL);
10731074
}
10741075

1076+
Sema::TemplateNameKindForDiagnostics
1077+
Sema::getTemplateNameKindForDiagnostics(TemplateName Name) {
1078+
auto *TD = Name.getAsTemplateDecl();
1079+
if (!TD)
1080+
return TemplateNameKindForDiagnostics::DependentTemplate;
1081+
if (isa<ClassTemplateDecl>(TD))
1082+
return TemplateNameKindForDiagnostics::ClassTemplate;
1083+
if (isa<FunctionTemplateDecl>(TD))
1084+
return TemplateNameKindForDiagnostics::FunctionTemplate;
1085+
if (isa<VarTemplateDecl>(TD))
1086+
return TemplateNameKindForDiagnostics::VarTemplate;
1087+
if (isa<TypeAliasTemplateDecl>(TD))
1088+
return TemplateNameKindForDiagnostics::AliasTemplate;
1089+
if (isa<TemplateTemplateParmDecl>(TD))
1090+
return TemplateNameKindForDiagnostics::TemplateTemplateParam;
1091+
return TemplateNameKindForDiagnostics::DependentTemplate;
1092+
}
1093+
10751094
// Determines the context to return to after temporarily entering a
10761095
// context. This depends in an unnecessarily complicated way on the
10771096
// exact ordering of callbacks from the parser.

lib/Sema/SemaTemplate.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -3326,7 +3326,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
33263326
SourceRange SR = AL.getSourceRange();
33273327
TemplateName Name = Arg.getAsTemplate();
33283328
Diag(SR.getBegin(), diag::err_template_missing_args)
3329-
<< Name << SR;
3329+
<< (int)getTemplateNameKindForDiagnostics(Name) << Name << SR;
33303330
if (TemplateDecl *Decl = Name.getAsTemplateDecl())
33313331
Diag(Decl->getLocation(), diag::note_template_decl_here);
33323332

@@ -3911,9 +3911,7 @@ static bool diagnoseArityMismatch(Sema &S, TemplateDecl *Template,
39113911
TemplateArgs.getRAngleLoc());
39123912
S.Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
39133913
<< (NumArgs > NumParams)
3914-
<< (isa<ClassTemplateDecl>(Template)? 0 :
3915-
isa<FunctionTemplateDecl>(Template)? 1 :
3916-
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
3914+
<< (int)S.getTemplateNameKindForDiagnostics(TemplateName(Template))
39173915
<< Template << Range;
39183916
S.Diag(Template->getLocation(), diag::note_template_decl_here)
39193917
<< Params->getSourceRange();
@@ -4021,9 +4019,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
40214019
// Not enough arguments for this parameter pack.
40224020
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
40234021
<< false
4024-
<< (isa<ClassTemplateDecl>(Template)? 0 :
4025-
isa<FunctionTemplateDecl>(Template)? 1 :
4026-
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
4022+
<< (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
40274023
<< Template;
40284024
Diag(Template->getLocation(), diag::note_template_decl_here)
40294025
<< Params->getSourceRange();

test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
99
template int pi<int>;
1010

1111
#ifndef FIXING
12-
template float pi<>; // expected-error {{too few template arguments for template 'pi'}}
12+
template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}}
1313
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}}
1414
#endif
1515

test/SemaTemplate/alias-templates.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,14 @@ namespace PR31514 {
254254

255255
tuple_size<const int> t;
256256
}
257+
258+
namespace an_alias_template_is_not_a_class_template {
259+
template<typename T> using Foo = int; // expected-note 2{{here}}
260+
Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}}
261+
Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}}
262+
263+
template<template<typename> class Bar> void f() { // expected-note 2{{here}}
264+
Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}}
265+
Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}}
266+
}
267+
}

0 commit comments

Comments
 (0)