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