A parameter pack must always come last in a class template.

llvm-svn: 73269
This commit is contained in:
Anders Carlsson 2009-06-12 23:20:15 +00:00
parent 508caaec3b
commit 327865db53
3 changed files with 22 additions and 2 deletions

View File

@ -836,6 +836,8 @@ def err_template_kw_refers_to_function_template : Error<
// C++0x Variadic Templates
def err_template_param_pack_default_arg : Error<
"template parameter pack cannot have a default argument">;
def err_template_param_pack_must_be_last_template_parameter : Error<
"template parameter pack must be the last template parameter">;
def err_unexpected_typedef : Error<
"unexpected type name %0: expected expression">;

View File

@ -591,6 +591,9 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
bool SawDefaultArgument = false;
SourceLocation PreviousDefaultArgLoc;
bool SawParameterPack = false;
SourceLocation ParameterPackLoc;
// Dummy initialization to avoid warnings.
TemplateParameterList::iterator OldParam = NewParams->end();
if (OldParams)
@ -607,13 +610,27 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
// Variables used to diagnose missing default arguments
bool MissingDefaultArg = false;
// C++0x [temp.param]p11:
// If a template parameter of a class template is a template parameter pack,
// it must be the last template parameter.
if (SawParameterPack) {
Diag(ParameterPackLoc,
diag::err_template_param_pack_must_be_last_template_parameter);
Invalid = true;
}
// Merge default arguments for template type parameters.
if (TemplateTypeParmDecl *NewTypeParm
= dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
TemplateTypeParmDecl *OldTypeParm
= OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0;
if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
if (NewTypeParm->isParameterPack()) {
assert(!NewTypeParm->hasDefaultArgument() &&
"Parameter packs can't have a default argument!");
SawParameterPack = true;
ParameterPackLoc = NewTypeParm->getLocation();
} else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
NewTypeParm->hasDefaultArgument()) {
OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();

View File

@ -1,3 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
template<typename... Args = int> struct S { }; // expected-error{{template parameter pack cannot have a default argument}}
template<typename ... Args = int> struct S1 { }; // expected-error{{template parameter pack cannot have a default argument}}
template<typename ... Args, typename T> struct S2 { }; // expected-error{{template parameter pack must be the last template parameter}}