diff options
author | Anders Carlsson <andersca@mac.com> | 2009-06-12 23:20:15 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-06-12 23:20:15 +0000 |
commit | 327865db532313adf09819360207d016fe65f87c (patch) | |
tree | 68ea31455faaa6c6f8ec8266a79d2b50e1bba62d | |
parent | 508caaec3b154d639faf23b1a7181f61ac1c3f42 (diff) | |
download | bcm5719-llvm-327865db532313adf09819360207d016fe65f87c.tar.gz bcm5719-llvm-327865db532313adf09819360207d016fe65f87c.zip |
A parameter pack must always come last in a class template.
llvm-svn: 73269
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 19 | ||||
-rw-r--r-- | clang/test/SemaTemplate/variadic-class-template-1.cpp | 3 |
3 files changed, 22 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 865b1ce4f3c..5780959058a 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index e1b2084469b..54c61f6cd9b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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(); diff --git a/clang/test/SemaTemplate/variadic-class-template-1.cpp b/clang/test/SemaTemplate/variadic-class-template-1.cpp index b811423e1f5..6df90500669 100644 --- a/clang/test/SemaTemplate/variadic-class-template-1.cpp +++ b/clang/test/SemaTemplate/variadic-class-template-1.cpp @@ -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}} |