1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
2 | |
3 | template<typename S> |
4 | struct A { |
5 | typedef S B; |
6 | template<typename T> using C = typename T::B; |
7 | template<typename T> struct D { |
8 | template<typename U> using E = typename A<U>::template C<A<T>>; |
9 | template<typename U> using F = A<E<U>>; |
10 | template<typename U> using G = C<F<U>>; |
11 | G<T> g; |
12 | }; |
13 | typedef decltype(D<B>().g) H; |
14 | D<H> h; |
15 | template<typename T> using I = A<decltype(h.g)>; |
16 | template<typename T> using J = typename A<decltype(h.g)>::template C<I<T>>; |
17 | }; |
18 | |
19 | A<int> a; |
20 | A<char>::D<double> b; |
21 | |
22 | template<typename T> T make(); |
23 | |
24 | namespace X { |
25 | template<typename T> struct traits { |
26 | typedef T thing; |
27 | typedef decltype(val(make<thing>())) inner_ptr; |
28 | |
29 | template<typename U> using rebind_thing = typename thing::template rebind<U>; |
30 | template<typename U> using rebind = traits<rebind_thing<U>>; |
31 | |
32 | inner_ptr &&alloc(); |
33 | void free(inner_ptr&&); |
34 | }; |
35 | |
36 | template<typename T> struct ptr_traits { |
37 | typedef T *type; |
38 | }; |
39 | template<typename T> using ptr = typename ptr_traits<T>::type; |
40 | |
41 | template<typename T> struct thing { |
42 | typedef T inner; |
43 | typedef ptr<inner> inner_ptr; |
44 | typedef traits<thing<inner>> traits_type; |
45 | |
46 | template<typename U> using rebind = thing<U>; |
47 | |
48 | thing(traits_type &traits) : traits(traits), val(traits.alloc()) {} |
49 | ~thing() { traits.free(static_cast<inner_ptr&&>(val)); } |
50 | |
51 | traits_type &traits; |
52 | inner_ptr val; |
53 | |
54 | friend inner_ptr val(const thing &t) { return t.val; } |
55 | }; |
56 | |
57 | template<> struct ptr_traits<bool> { |
58 | typedef bool &type; |
59 | }; |
60 | template<> bool &traits<thing<bool>>::alloc() { static bool b; return b; } |
61 | template<> void traits<thing<bool>>::free(bool&) {} |
62 | } |
63 | |
64 | typedef X::traits<X::thing<int>> itt; |
65 | |
66 | itt::thing::traits_type itr; |
67 | itt::thing ith(itr); |
68 | |
69 | itt::rebind<bool> btr; |
70 | itt::rebind_thing<bool> btt(btr); |
71 | |
72 | namespace PR11848 { |
73 | template<typename T> using U = int; |
74 | |
75 | template<typename T, typename ...Ts> |
76 | void f1(U<T> i, U<Ts> ...is) { // expected-note 2{{couldn't infer template argument 'T'}} |
77 | return i + f1<Ts...>(is...); |
78 | } |
79 | |
80 | // FIXME: This note is technically correct, but could be better. We |
81 | // should really say that we couldn't infer template argument 'Ts'. |
82 | template<typename ...Ts> |
83 | void f2(U<Ts> ...is) { } // expected-note {{requires 0 arguments, but 1 was provided}} |
84 | |
85 | template<typename...> struct type_tuple {}; |
86 | template<typename ...Ts> |
87 | void f3(type_tuple<Ts...>, U<Ts> ...is) {} // expected-note {{requires 4 arguments, but 3 were provided}} |
88 | |
89 | void g() { |
90 | f1(U<void>()); // expected-error {{no match}} |
91 | f1(1, 2, 3, 4, 5); // expected-error {{no match}} |
92 | f2(); // ok |
93 | f2(1); // expected-error {{no match}} |
94 | f3(type_tuple<>()); |
95 | f3(type_tuple<void, void, void>(), 1, 2); // expected-error {{no match}} |
96 | f3(type_tuple<void, void, void>(), 1, 2, 3); |
97 | } |
98 | |
99 | template<typename ...Ts> |
100 | struct S { |
101 | S(U<Ts>...ts); |
102 | }; |
103 | |
104 | template<typename T> |
105 | struct Hidden1 { |
106 | template<typename ...Ts> |
107 | Hidden1(typename T::template U<Ts> ...ts); |
108 | }; |
109 | |
110 | template<typename T, typename ...Ts> |
111 | struct Hidden2 { |
112 | Hidden2(typename T::template U<Ts> ...ts); |
113 | }; |
114 | |
115 | struct Hide { |
116 | template<typename T> using U = int; |
117 | }; |
118 | |
119 | Hidden1<Hide> h1; |
120 | Hidden2<Hide, double, char> h2(1, 2); |
121 | } |
122 | |
123 | namespace Core22036 { |
124 | struct X {}; |
125 | void h(...); |
126 | template<typename T> using Y = X; |
127 | template<typename T, typename ...Ts> struct S { |
128 | // An expression can contain an unexpanded pack without being type or |
129 | // value dependent. This is true even if the expression's type is a pack |
130 | // expansion type. |
131 | void f1(Y<T> a) { h(g(a)); } // expected-error {{undeclared identifier 'g'}} |
132 | void f2(Y<Ts>...as) { h(g(as)...); } // expected-error {{undeclared identifier 'g'}} |
133 | void f3(Y<Ts>...as) { g(as...); } // ok |
134 | void f4(Ts ...ts) { h(g(sizeof(ts))...); } // expected-error {{undeclared identifier 'g'}} |
135 | // FIXME: We can reject this, since it has no valid instantiations because |
136 | // 'g' never has any associated namespaces. |
137 | void f5(Ts ...ts) { g(sizeof(ts)...); } // ok |
138 | }; |
139 | } |
140 | |
141 | namespace PR13243 { |
142 | template<typename A> struct X {}; |
143 | template<int I> struct C {}; |
144 | template<int I> using Ci = C<I>; |
145 | |
146 | template<typename A, int I> void f(X<A>, Ci<I>) {} |
147 | template void f(X<int>, C<0>); |
148 | } |
149 | |
150 | namespace PR13136 { |
151 | template <typename T, T... Numbers> |
152 | struct NumberTuple { }; |
153 | |
154 | template <unsigned int... Numbers> |
155 | using MyNumberTuple = NumberTuple<unsigned int, Numbers...>; |
156 | |
157 | template <typename U, unsigned int... Numbers> |
158 | void foo(U&&, MyNumberTuple<Numbers...>); |
159 | |
160 | template <typename U, unsigned int... Numbers> |
161 | void bar(U&&, NumberTuple<unsigned int, Numbers...>); |
162 | |
163 | int main() { |
164 | foo(1, NumberTuple<unsigned int, 0, 1>()); |
165 | bar(1, NumberTuple<unsigned int, 0, 1>()); |
166 | return 0; |
167 | } |
168 | } |
169 | |
170 | namespace PR16646 { |
171 | namespace test1 { |
172 | template <typename T> struct DefaultValue { const T value=0;}; |
173 | template <typename ... Args> struct tuple {}; |
174 | template <typename ... Args> using Zero = tuple<DefaultValue<Args> ...>; |
175 | template <typename ... Args> void f(const Zero<Args ...> &t); |
176 | void f() { |
177 | f(Zero<int,double,double>()); |
178 | } |
179 | } |
180 | |
181 | namespace test2 { |
182 | template<int x> struct X {}; |
183 | template <template<int x> class temp> struct DefaultValue { const temp<0> value; }; |
184 | template <typename ... Args> struct tuple {}; |
185 | template <template<int x> class... Args> using Zero = tuple<DefaultValue<Args> ...>; |
186 | template <template<int x> class... Args> void f(const Zero<Args ...> &t); |
187 | void f() { |
188 | f(Zero<X,X,X>()); |
189 | } |
190 | } |
191 | } |
192 | |
193 | namespace PR16904 { |
194 | template <typename,typename> |
195 | struct base { |
196 | template <typename> struct derived; |
197 | }; |
198 | // FIXME: The diagnostics here are terrible. |
199 | template <typename T, typename U, typename V> |
200 | using derived = base<T, U>::template derived<V>; // expected-error {{expected a type}} expected-error {{expected ';'}} |
201 | template <typename T, typename U, typename V> |
202 | using derived2 = ::PR16904::base<T, U>::template derived<V>; // expected-error {{expected a type}} expected-error {{expected ';'}} |
203 | } |
204 | |
205 | namespace PR14858 { |
206 | template<typename ...T> using X = int[sizeof...(T)]; |
207 | |
208 | template<typename ...U> struct Y { |
209 | using Z = X<U...>; |
210 | }; |
211 | using A = Y<int, int, int, int>::Z; |
212 | using A = int[4]; |
213 | |
214 | // FIXME: These should be treated as being redeclarations. |
215 | template<typename ...T> void f(X<T...> &) {} |
216 | template<typename ...T> void f(int(&)[sizeof...(T)]) {} |
217 | |
218 | template<typename ...T> void g(X<typename T::type...> &) {} |
219 | template<typename ...T> void g(int(&)[sizeof...(T)]) {} // ok, different |
220 | |
221 | template<typename ...T, typename ...U> void h(X<T...> &) {} |
222 | template<typename ...T, typename ...U> void h(X<U...> &) {} // ok, different |
223 | |
224 | template<typename ...T> void i(auto (T ...t) -> int(&)[sizeof...(t)]); |
225 | auto mk_arr(int, int) -> int(&)[2]; |
226 | void test_i() { i<int, int>(mk_arr); } |
227 | |
228 | #if 0 // FIXME: This causes clang to assert. |
229 | template<typename ...T> using Z = auto (T ...p) -> int (&)[sizeof...(p)]; |
230 | template<typename ...T, typename ...U> void j(Z<T..., U...> &) {} |
231 | void test_j() { j<int, int>(mk_arr); } |
232 | #endif |
233 | |
234 | template<typename ...T> struct Q { |
235 | template<typename ...U> using V = int[sizeof...(U)]; |
236 | template<typename ...U> void f(V<typename U::type..., typename T::type...> *); |
237 | }; |
238 | struct B { typedef int type; }; |
239 | void test_q(int (&a)[5]) { Q<B, B, B>().f<B, B>(&a); } |
240 | } |
241 | |
242 | namespace redecl { |
243 | template<typename> using A = int; |
244 | template<typename = void> using A = int; |
245 | A<> a; // ok |
246 | } |
247 | |
248 | namespace PR31514 { |
249 | template<typename T, typename> using EnableTupleSize = T; |
250 | |
251 | template<typename T> struct tuple_size { static const int value = 0; }; |
252 | template<typename T> struct tuple_size<EnableTupleSize<const T, decltype(tuple_size<T>::value)>> {}; |
253 | template<typename T> struct tuple_size<EnableTupleSize<volatile T, decltype(tuple_size<T>::value)>> {}; |
254 | |
255 | tuple_size<const int> t; |
256 | } |
257 | |
258 | namespace an_alias_template_is_not_a_class_template { |
259 | template<typename T> using Foo = int; // expected-note 3{{here}} |
260 | Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}} |
261 | Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}} |
262 | int z = Foo(); // expected-error {{use of alias template 'Foo' requires template arguments}} |
263 | |
264 | template<template<typename> class Bar> void f() { // expected-note 3{{here}} |
265 | Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}} |
266 | Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}} |
267 | int z = Bar(); // expected-error {{use of template template parameter 'Bar' requires template arguments}} |
268 | } |
269 | } |
270 | |