[cfe-commits] r122877 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.param/p11-0x.cpp
Douglas Gregor
dgregor at apple.com
Wed Jan 5 08:19:19 PST 2011
Author: dgregor
Date: Wed Jan 5 10:19:19 2011
New Revision: 122877
URL: http://llvm.org/viewvc/llvm-project?rev=122877&view=rev
Log:
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.
Added:
cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=122877&r1=122876&r2=122877&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jan 5 10:19:19 2011
@@ -1144,9 +1144,9 @@
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 @@
// 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 @@
// 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();
Added: cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp?rev=122877&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp Wed Jan 5 10:19:19 2011
@@ -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...>);
More information about the cfe-commits
mailing list