p5.cpp revision e41721e7dfabcc15cb50be9075a4153f1ad648ea
1// RUN: %clang_cc1 -fexceptions -std=c++0x -fblocks -fms-extensions -fsyntax-only -verify %s
2
3template<typename T, typename U> struct pair;
4template<typename ...> struct tuple;
5
6// A parameter pack whose name appears within the pattern of a pack
7// expansion is expanded by that pack expansion. An appearance of the
8// name of a parameter pack is only expanded by the innermost
9// enclosing pack expansion. The pattern of a pack expansion shall
10// name one or more parameter packs that are not expanded by a nested
11// pack expansion.
12template<typename... Types>
13struct Expansion {
14  typedef pair<Types..., int> expand_with_pacs; // okay
15  typedef pair<Types, int...> expand_no_packs;  // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
16  typedef pair<pair<Types..., int>..., int> expand_with_expanded_nested; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
17};
18
19// All of the parameter packs expanded by a pack expansion shall have
20// the same number of arguments specified.
21template<typename ...Types>
22struct ExpansionLengthMismatch {
23  template<typename ...OtherTypes>
24  struct Inner {
25    typedef tuple<pair<Types, OtherTypes>...> type; // expected-error{{pack expansion contains parameter packs 'Types' and 'OtherTypes' that have different lengths (3 vs. 2)}}
26  };
27};
28
29ExpansionLengthMismatch<int, long>::Inner<unsigned int, unsigned long>::type
30  *il_pairs;
31tuple<pair<int, unsigned int>, pair<long, unsigned long> >*il_pairs_2 = il_pairs;
32
33ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>::type // expected-note{{in instantiation of template class 'ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>' requested here}}
34  *il_pairs_bad;
35
36
37// An appearance of a name of a parameter pack that is not expanded is
38// ill-formed.
39
40// Test for unexpanded parameter packs in each of the type nodes.
41template<typename T, int N, typename ... Types>
42struct TestPPName
43  : public Types, public T  // expected-error{{base type contains unexpanded parameter pack 'Types'}}
44{
45  // BuiltinType is uninteresting
46  // FIXME: ComplexType is uninteresting?
47  // PointerType
48  typedef Types *types_pointer; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
49
50  // BlockPointerType
51  typedef Types (^block_pointer_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
52  typedef int (^block_pointer_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
53
54  // LValueReferenceType
55  typedef Types &lvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
56
57  // RValueReferenceType
58  typedef Types &&rvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
59
60  // MemberPointerType
61  typedef Types TestPPName::* member_pointer_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
62  typedef int Types::*member_pointer_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
63
64  // ConstantArrayType
65  typedef Types constant_array[17]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
66
67  // IncompleteArrayType
68  typedef Types incomplete_array[]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
69
70  // VariableArrayType
71  void f(int i) {
72    Types variable_array[i]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
73  }
74
75  // DependentSizedArrayType
76  typedef Types dependent_sized_array[N]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
77
78  // DependentSizedExtVectorType
79  typedef Types dependent_sized_ext_vector __attribute__((ext_vector_type(N))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
80
81  // VectorType is uninteresting
82
83  // ExtVectorType
84  typedef Types ext_vector __attribute__((ext_vector_type(4))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
85
86  // FunctionProtoType
87  typedef Types (function_type_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
88  typedef int (function_type_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
89
90  // FunctionNoProtoType is uninteresting
91  // UnresolvedUsingType is uninteresting
92  // ParenType is uninteresting
93  // TypedefType is uninteresting
94
95  // TypeOfExprType
96  typedef __typeof__((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
97
98  // TypeOfType
99  typedef __typeof__(Types) typeof_type;  // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
100
101  // DecltypeType
102  typedef decltype((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
103
104  // RecordType is uninteresting
105  // EnumType is uninteresting
106  // ElaboratedType is uninteresting
107
108  // TemplateTypeParmType
109  typedef Types template_type_parm; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
110
111  // SubstTemplateTypeParmType is uninteresting
112
113  // TemplateSpecializationType
114  typedef pair<Types, int> template_specialization; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
115
116  // InjectedClassName is uninteresting.
117
118  // DependentNameType
119  typedef typename Types::type dependent_name; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
120
121  // DependentTemplateSpecializationType
122  typedef typename Types::template apply<int> dependent_name_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
123  typedef typename T::template apply<Types> dependent_name_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
124
125  // ObjCObjectType is uninteresting
126  // ObjCInterfaceType is uninteresting
127  // ObjCObjectPointerType is uninteresting
128};
129
130// FIXME: Test for unexpanded parameter packs in each of the expression nodes.
131template<int ...Values>
132void test_unexpanded_in_exprs() {
133  // PredefinedExpr is uninteresting
134  // DeclRefExpr
135  Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}
136  // IntegerLiteral is uninteresting
137  // FloatingLiteral is uninteresting
138  // ImaginaryLiteral is uninteresting
139  // StringLiteral is uninteresting
140  // CharacterLiteral is uninteresting
141  (Values); // expected-error{{expression contains unexpanded parameter pack 'Values'}}
142  // UnaryOperator
143  -Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}
144  // OffsetOfExpr
145  struct OffsetMe {
146    int array[17];
147  };
148  __builtin_offsetof(OffsetMe, array[Values]); // expected-error{{expression contains unexpanded parameter pack 'Values'}}
149  // FIXME: continue this...
150}
151
152template<typename ... Types>
153void TestPPNameFunc(int i) {
154  f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
155}
156
157template<typename T, template<class> class ...Meta>
158struct TestUnexpandedTTP {
159  typedef tuple<typename Meta<T>::type> type; // expected-error{{declaration type contains unexpanded parameter pack 'Meta'}}
160};
161
162// Test for unexpanded parameter packs in declarations.
163// FIXME: Attributes?
164template<typename T, typename... Types>
165struct TestUnexpandedDecls : T{
166  void member_function(Types);  // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
167  void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
168  operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
169  Types data_member;  // expected-error{{data member type contains unexpanded parameter pack 'Types'}}
170  static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
171  unsigned bit_field : static_cast<Types>(0);  // expected-error{{bit-field size contains unexpanded parameter pack 'Types'}}
172  static_assert(static_cast<Types>(0), "Boom"); // expected-error{{static assertion contains unexpanded parameter pack 'Types'}}
173
174  enum E0 : Types {  // expected-error{{fixed underlying type contains unexpanded parameter pack 'Types'}}
175    EnumValue = static_cast<Types>(0) // expected-error{{enumerator value contains unexpanded parameter pack 'Types'}}
176  };
177
178  using typename Types::type; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
179  using Types::value; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
180  using T::operator Types; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
181
182  friend class Types::foo; // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
183  friend void friend_func(Types); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
184  friend void Types::other_friend_func(int); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
185
186  void test_initializers() {
187    T copy_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
188    T direct_init(0, static_cast<Types>(0)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
189    T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
190  }
191
192  void default_function_args(T = static_cast<Types>(0)); // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
193
194  template<typename = Types*> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
195    struct default_template_args_1;
196  template<int = static_cast<Types>(0)> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
197    struct default_template_args_2;
198  template<template<typename> class = Types::template apply> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
199    struct default_template_args_3;
200
201  template<Types value> // expected-error{{non-type template parameter type contains unexpanded parameter pack 'Types'}}
202  struct non_type_template_param_type;
203
204  void decls_in_stmts() {
205    Types t; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
206    for (Types *t = 0; ; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
207    for (; Types *t = 0; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
208    switch(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
209    while(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
210    if (Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
211    try {
212    } catch (Types*) { // expected-error{{exception type contains unexpanded parameter pack 'Types'}}
213    }
214  }
215};
216
217// FIXME: Test for unexpanded parameter packs in each of the statements.
218struct X {
219  void f(int, int);
220  template<typename ...Types>
221  void f(Types...);
222};
223
224namespace std {
225  class type_info;
226}
227
228typedef struct _GUID {
229     unsigned long  Data1;
230     unsigned short Data2;
231     unsigned short Data3;
232     unsigned char  Data4[ 8 ];
233} GUID;
234
235template<typename T, typename ...Types>
236void test_unexpanded_exprs(Types ...values) {
237  // CXXOperatorCallExpr
238  (void)(values + 0); // expected-error{{expression contains unexpanded parameter pack 'values'}}
239  (void)(0 + values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
240
241  // CXXMemberCallExpr
242  values.f(); // expected-error{{expression contains unexpanded parameter pack 'values'}}
243  X x;
244  x.f(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
245  x.Types::f(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
246  x.f<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
247
248  // CXXStaticCastExpr
249  (void)static_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
250
251  // CXXDynamicCastExpr
252  (void)dynamic_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
253
254  // CXXReinterpretCastExpr
255  (void)reinterpret_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
256
257  // CXXConstCastExpr
258  (void)const_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
259
260  // CXXTypeidExpr
261  (void)typeid(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
262  (void)typeid(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
263
264  // CXXUuidofExpr
265  (void)__uuidof(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
266  (void)__uuidof(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
267
268  // CXXThisExpr is uninteresting
269
270  // CXXThrowExpr
271  throw Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
272  throw values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
273
274  // CXXDefaultArgExpr is uninteresting
275
276  // CXXBindTemporaryExpr is uninteresting
277
278  // CXXConstructExpr is uninteresting
279
280  // CXXFunctionalCastExpr
281  (void)Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
282
283  // CXXTemporaryObjectExpr
284  (void)X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
285
286  // CXXScalarValueInitExpr is uninteresting
287
288  // CXXNewExpr
289  (void)new Types; // expected-error{{expression contains unexpanded parameter pack 'Types'}}
290  (void)new X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
291  (void)new (values) X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
292  (void)new X [values]; // expected-error{{expression contains unexpanded parameter pack 'values'}}
293
294  // CXXDeleteExpr
295  delete values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
296  delete [] values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
297
298  // CXXPseudoDestructorExpr
299  T t;
300  values.~T(); // expected-error{{expression contains unexpanded parameter pack 'values'}}
301  t.~Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
302  t.Types::~T(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
303
304  // UnaryTypeTraitExpr
305  __is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
306
307  // BinaryTypeTraitExpr
308  __is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
309  __is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
310
311  // UnresolvedLookupExpr
312  test_unexpanded_exprs(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
313  test_unexpanded_exprs<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
314
315  // DependentScopeDeclRefExpr
316  Types::test_unexpanded_exprs(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
317  T::template test_unexpanded_exprs<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
318
319  // CXXUnresolvedConstructExpr
320  Types(5); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
321
322  // CXXDependentScopeMemberExpr
323  values.foo(); // expected-error{{expression contains unexpanded parameter pack 'values'}}
324  t.foo(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
325
326  // FIXME: There's an evil ambiguity here, because we don't know if
327  // Types refers to the template type parameter pack in scope or a
328  // non-pack member.
329  //  t.Types::foo();
330
331  t.template foo<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
332
333  // UnresolvedMemberExpr
334  x.f<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
335  x.f(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
336
337  // CXXNoexceptExpr
338  noexcept(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
339
340  // PackExpansionExpr is uninteresting
341  // SizeOfPackExpr is uninteresting
342
343  // FIXME: Objective-C expressions will need to go elsewhere
344}
345
346// Test unexpanded parameter packs in partial specializations.
347template<typename ...Types>
348struct TestUnexpandedDecls<int, Types>; // expected-error{{partial specialization contains unexpanded parameter pack 'Types'}}
349
350// Test for diagnostics in the presence of multiple unexpanded
351// parameter packs.
352template<typename T, typename U> struct pair;
353
354template<typename ...OuterTypes>
355struct MemberTemplatePPNames {
356  template<typename ...InnerTypes>
357  struct Inner {
358    typedef pair<OuterTypes, InnerTypes>* types; // expected-error{{declaration type contains unexpanded parameter packs 'OuterTypes' and 'InnerTypes'}}
359
360    template<typename ...VeryInnerTypes>
361    struct VeryInner {
362      typedef pair<pair<VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types; // expected-error{{declaration type contains unexpanded parameter packs 'VeryInnerTypes', 'OuterTypes', ...}}
363    };
364  };
365};
366
367// Example from working paper
368namespace WorkingPaperExample {
369  template<typename...> struct Tuple {};
370  template<typename T1, typename T2> struct Pair {};
371
372  template<class ... Args1> struct zip {
373    template<class ... Args2> struct with {
374      typedef Tuple<Pair<Args1, Args2> ... > type; // expected-error{{pack expansion contains parameter packs 'Args1' and 'Args2' that have different lengths (1 vs. 2)}}
375    };
376  };
377
378  typedef zip<short, int>::with<unsigned short, unsigned>::type T1; // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>
379  typedef Tuple<Pair<short, unsigned short>, Pair<int, unsigned>> T1;
380
381  typedef zip<short>::with<unsigned short, unsigned>::type T2; // expected-note{{in instantiation of template class}}
382
383  template<class ... Args> void f(Args...);
384  template<class ... Args> void h(Args...);
385
386  template<class ... Args>
387  void g(Args ... args) {
388    f(const_cast<const Args*>(&args)...); // OK: "Args" and "args" are expanded within f
389    f(5 ...); // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
390    f(args); // expected-error{{expression contains unexpanded parameter pack 'args'}}
391    f(h(args ...) + args ...);
392  }
393}
394