p5.cpp revision 7536dd5e6c99584481b7dab68b7e7d8df9c54054
1// RUN: %clang_cc1 -std=c++0x -fblocks -fsyntax-only -verify %s
2
3template<typename T, typename U> struct pair;
4
5// A parameter pack whose name appears within the pattern of a pack
6// expansion is expanded by that pack expansion. An appearance of the
7// name of a parameter pack is only expanded by the innermost
8// enclosing pack expansion. The pattern of a pack expansion shall
9// name one or more parameter packs that are not expanded by a nested
10// pack expansion.
11template<typename... Types>
12struct Expansion {
13  typedef pair<Types..., int> expand_with_pacs; // okay
14  typedef pair<Types, int...> expand_no_packs;  // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
15  typedef pair<pair<Types..., int>..., int> expand_with_expanded_nested; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
16};
17
18// An appearance of a name of a parameter pack that is not expanded is
19// ill-formed.
20
21// Test for unexpanded parameter packs in each of the type nodes.
22template<typename T, int N, typename ... Types>
23struct TestPPName
24  : public Types, public T  // expected-error{{base type contains unexpanded parameter pack 'Types'}}
25{
26  // BuiltinType is uninteresting
27  // FIXME: ComplexType is uninteresting?
28  // PointerType
29  typedef Types *types_pointer; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
30
31  // BlockPointerType
32  typedef Types (^block_pointer_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
33  typedef int (^block_pointer_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
34
35  // LValueReferenceType
36  typedef Types &lvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
37
38  // RValueReferenceType
39  typedef Types &&rvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
40
41  // MemberPointerType
42  typedef Types TestPPName::* member_pointer_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
43  typedef int Types::*member_pointer_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
44
45  // ConstantArrayType
46  typedef Types constant_array[17]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
47
48  // IncompleteArrayType
49  typedef Types incomplete_array[]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
50
51  // VariableArrayType
52  void f(int i) {
53    Types variable_array[i]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
54  }
55
56  // DependentSizedArrayType
57  typedef Types dependent_sized_array[N]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
58
59  // DependentSizedExtVectorType
60  typedef Types dependent_sized_ext_vector __attribute__((ext_vector_type(N))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
61
62  // VectorType is uninteresting
63
64  // ExtVectorType
65  typedef Types ext_vector __attribute__((ext_vector_type(4))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
66
67  // FunctionProtoType
68  typedef Types (function_type_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
69  typedef int (function_type_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
70
71  // FunctionNoProtoType is uninteresting
72  // UnresolvedUsingType is uninteresting
73  // ParenType is uninteresting
74  // TypedefType is uninteresting
75
76  // TypeOfExprType
77  typedef __typeof__((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
78
79  // TypeOfType
80  typedef __typeof__(Types) typeof_type;  // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
81
82  // DecltypeType
83  typedef decltype((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
84
85  // RecordType is uninteresting
86  // EnumType is uninteresting
87  // ElaboratedType is uninteresting
88
89  // TemplateTypeParmType
90  typedef Types template_type_parm; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
91
92  // SubstTemplateTypeParmType is uninteresting
93
94  // TemplateSpecializationType
95  typedef pair<Types, int> template_specialization; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
96
97  // InjectedClassName is uninteresting.
98
99  // DependentNameType
100  typedef typename Types::type dependent_name; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
101
102  // DependentTemplateSpecializationType
103  typedef typename Types::template apply<int> dependent_name_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
104  typedef typename T::template apply<Types> dependent_name_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
105
106  // ObjCObjectType is uninteresting
107  // ObjCInterfaceType is uninteresting
108  // ObjCObjectPointerType is uninteresting
109};
110
111// FIXME: Test for unexpanded parameter packs in each of the expression nodes.
112
113template<typename ... Types>
114void TestPPNameFunc(int i) {
115  f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
116}
117
118// Test for unexpanded parameter packs in declarations.
119// FIXME: Attributes?
120template<typename T, typename... Types>
121struct TestUnexpandedDecls : T{
122  void member_function(Types);  // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
123  void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
124  operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
125  Types data_member;  // expected-error{{data member type contains unexpanded parameter pack 'Types'}}
126  static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
127  unsigned bit_field : static_cast<Types>(0);  // expected-error{{bit-field size contains unexpanded parameter pack 'Types'}}
128  static_assert(static_cast<Types>(0), "Boom"); // expected-error{{static assertion contains unexpanded parameter pack 'Types'}}
129
130  enum E0 : Types {  // expected-error{{fixed underlying type contains unexpanded parameter pack 'Types'}}
131    EnumValue = static_cast<Types>(0) // expected-error{{enumerator value contains unexpanded parameter pack 'Types'}}
132  };
133
134  using typename Types::type; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
135  using Types::value; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
136  using T::operator Types; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
137
138  friend class Types::foo; // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
139  friend void friend_func(Types); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
140  friend void Types::other_friend_func(int); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
141
142  void test_initializers() {
143    T copy_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
144    T direct_init(0, static_cast<Types>(0)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
145    T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
146  }
147
148  void default_function_args(T = static_cast<Types>(0)); // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
149
150  template<typename = Types*> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
151    struct default_template_args_1;
152  template<int = static_cast<Types>(0)> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
153    struct default_template_args_2;
154  template<template<typename> class = Types::template apply> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
155    struct default_template_args_3;
156
157  template<Types value> // expected-error{{non-type template parameter type contains unexpanded parameter pack 'Types'}}
158  struct non_type_template_param_type;
159
160  void decls_in_stmts() {
161    Types t; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
162    for (Types *t = 0; ; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
163    for (; Types *t = 0; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
164    switch(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
165    while(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
166    if (Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
167    try {
168    } catch (Types*) { // expected-error{{exception type contains unexpanded parameter pack 'Types'}}
169    }
170  }
171};
172
173// FIXME: Test for unexpanded parameter packs in each of the statements.
174
175// FIXME: Once we have template argument deduction, we can test
176// unexpanded parameter packs in partial specializations.
177// template<typename ...Types>
178// struct TestUnexpandedDecls<int, Types>;
179
180// Test for diagnostics in the presence of multiple unexpanded
181// parameter packs.
182template<typename T, typename U> struct pair;
183
184template<typename ...OuterTypes>
185struct MemberTemplatePPNames {
186  template<typename ...InnerTypes>
187  struct Inner {
188    typedef pair<OuterTypes, InnerTypes>* types; // expected-error{{declaration type contains unexpanded parameter packs 'OuterTypes' and 'InnerTypes'}}
189
190    template<typename ...VeryInnerTypes>
191    struct VeryInner {
192      typedef pair<pair<VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types; // expected-error{{declaration type contains unexpanded parameter packs 'VeryInnerTypes', 'OuterTypes', ...}}
193    };
194  };
195};
196
197