forked from OSchip/llvm-project
Implement C++0x [temp.param]p11 for non-type and template template
parameter packs. Also, the "no template parameters after a template parameter pack" rule only applies to primary class templates. llvm-svn: 122877
This commit is contained in:
parent
6a78995369
commit
0018cdc105
|
@ -1144,9 +1144,9 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
|
|||
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) {
|
||||
// If a template parameter of a primary class template is a template
|
||||
// parameter pack, it shall be the last template parameter.
|
||||
if (SawParameterPack && TPC == TPC_ClassTemplate) {
|
||||
Diag(ParameterPackLoc,
|
||||
diag::err_template_param_pack_must_be_last_template_parameter);
|
||||
Invalid = true;
|
||||
|
@ -1211,7 +1211,12 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
|
|||
// Merge default arguments for non-type template parameters
|
||||
NonTypeTemplateParmDecl *OldNonTypeParm
|
||||
= OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0;
|
||||
if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
|
||||
if (NewNonTypeParm->isParameterPack()) {
|
||||
assert(!NewNonTypeParm->hasDefaultArgument() &&
|
||||
"Parameter packs can't have a default argument!");
|
||||
SawParameterPack = true;
|
||||
ParameterPackLoc = NewNonTypeParm->getLocation();
|
||||
} else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
|
||||
NewNonTypeParm->hasDefaultArgument()) {
|
||||
OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
|
||||
NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc();
|
||||
|
@ -1254,7 +1259,12 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
|
|||
// Merge default arguments for template template parameters
|
||||
TemplateTemplateParmDecl *OldTemplateParm
|
||||
= OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0;
|
||||
if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
|
||||
if (NewTemplateParm->isParameterPack()) {
|
||||
assert(!NewTemplateParm->hasDefaultArgument() &&
|
||||
"Parameter packs can't have a default argument!");
|
||||
SawParameterPack = true;
|
||||
ParameterPackLoc = NewTemplateParm->getLocation();
|
||||
} else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
|
||||
NewTemplateParm->hasDefaultArgument()) {
|
||||
OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation();
|
||||
NewDefaultLoc = NewTemplateParm->getDefaultArgument().getLocation();
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
|
||||
|
||||
// If a template-parameter of a class template has a default
|
||||
// template-argument, each subsequent template-parameter shall either
|
||||
// have a default template-argument supplied or be a template
|
||||
// parameter pack.
|
||||
template<typename> struct vector;
|
||||
|
||||
template<typename T = int, typename ...Types> struct X2t;
|
||||
template<int V = 0, int ...Values> struct X2nt;
|
||||
template<template<class> class M = vector, template<class> class... Metas>
|
||||
struct X2tt;
|
||||
|
||||
// If a template-parameter of a primary class template is a template
|
||||
// parameter pack, it shall be the last template-parameter .
|
||||
template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
|
||||
int After>
|
||||
struct X0t;
|
||||
|
||||
template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
|
||||
int After>
|
||||
struct X0nt;
|
||||
|
||||
template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
|
||||
int After>
|
||||
struct X0tt;
|
||||
|
||||
// [ Note: These are not requirements for function templates or class
|
||||
// template partial specializations because template arguments can be
|
||||
// deduced (14.8.2). -- end note]
|
||||
template<typename... Types> struct X1t;
|
||||
template<typename ...Types, typename T> struct X1t<T, Types...> { };
|
||||
|
||||
template<int... Values> struct X1nt;
|
||||
template<int ...Values, int V> struct X1nt<V, Values...> { };
|
||||
|
||||
// FIXME: Need template template argument packs!
|
||||
// template<template<int> class... Meta> struct X1tt;
|
||||
// template<template<int> class... Meta, template<int> class M>
|
||||
// struct X1tt<M, Meta...> { };
|
||||
|
||||
template<typename ...Types, typename T>
|
||||
void f1t(X1t<T, Types...>);
|
||||
|
||||
template<int ...Values, int V>
|
||||
void f1nt(X1nt<V, Values...>);
|
||||
|
||||
// FIXME: Need template template argument packs!
|
||||
// template<template<int> class... Meta, template<int> class M>
|
||||
// void f1tt(X1tt<M, Meta...>);
|
Loading…
Reference in New Issue