Richard Smith | 762bb9d | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
Richard Smith | 1804174 | 2011-05-14 15:04:18 +0000 | [diff] [blame] | 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); |
Richard Smith | c0536c8 | 2012-01-25 02:14:59 +0000 | [diff] [blame] | 71 | |
| 72 | namespace PR11848 { |
| 73 | template<typename T> using U = int; |
| 74 | |
| 75 | template<typename T, typename ...Ts> |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 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); |
Richard Smith | c0536c8 | 2012-01-25 02:14:59 +0000 | [diff] [blame] | 97 | } |
| 98 | |
| 99 | template<typename ...Ts> |
| 100 | struct S { |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 101 | S(U<Ts>...ts); |
Richard Smith | c0536c8 | 2012-01-25 02:14:59 +0000 | [diff] [blame] | 102 | }; |
| 103 | |
| 104 | template<typename T> |
| 105 | struct Hidden1 { |
| 106 | template<typename ...Ts> |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 107 | Hidden1(typename T::template U<Ts> ...ts); |
Richard Smith | c0536c8 | 2012-01-25 02:14:59 +0000 | [diff] [blame] | 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 | |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 119 | Hidden1<Hide> h1; |
Richard Smith | c0536c8 | 2012-01-25 02:14:59 +0000 | [diff] [blame] | 120 | Hidden2<Hide, double, char> h2(1, 2); |
| 121 | } |
Richard Smith | 5a343d7 | 2012-07-08 04:37:51 +0000 | [diff] [blame] | 122 | |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 123 | namespace Core22036 { |
| 124 | struct X {}; |
| 125 | void h(...); |
| 126 | template<typename T> using Y = X; |
| 127 | template<typename T, typename ...Ts> struct S { |
Richard Smith | aa488ea | 2012-07-16 01:59:26 +0000 | [diff] [blame] | 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. |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 131 | void f1(Y<T> a) { h(g(a)); } // expected-error {{undeclared identifier 'g'}} |
Richard Smith | aa488ea | 2012-07-16 01:59:26 +0000 | [diff] [blame] | 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 |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 138 | }; |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 139 | } |
| 140 | |
Richard Smith | 5a343d7 | 2012-07-08 04:37:51 +0000 | [diff] [blame] | 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 | } |
Richard Smith | 6098381 | 2012-07-09 03:07:20 +0000 | [diff] [blame] | 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>()); |
Richard Smith | d8672ef | 2012-07-16 00:20:35 +0000 | [diff] [blame] | 166 | return 0; |
Richard Smith | 6098381 | 2012-07-09 03:07:20 +0000 | [diff] [blame] | 167 | } |
| 168 | } |
Eli Friedman | 10ec0e4 | 2013-07-19 19:40:38 +0000 | [diff] [blame] | 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 | } |
Eli Friedman | 5a42820 | 2013-08-15 23:59:20 +0000 | [diff] [blame] | 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 | } |