alias-templates.cpp revision c0536c8294fc4453f0f1d1cf24a62bfc725fd492
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 2 3template<typename S> 4struct 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 19A<int> a; 20A<char>::D<double> b; 21 22template<typename T> T make(); 23 24namespace 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 64typedef X::traits<X::thing<int>> itt; 65 66itt::thing::traits_type itr; 67itt::thing ith(itr); 68 69itt::rebind<bool> btr; 70itt::rebind_thing<bool> btt(btr); 71 72namespace PR11848 { 73 template<typename T> using U = int; 74 75 template<typename T, typename ...Ts> 76 void f(U<T> i, U<Ts> ...is) { // expected-error {{type 'U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}} 77 return i + f<Ts...>(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} 78 } 79 80 template<typename ...Ts> 81 struct S { 82 S(U<Ts>...ts); // expected-error {{does not contain any unexpanded parameter packs}} 83 }; 84 85 template<typename T> 86 struct Hidden1 { 87 template<typename ...Ts> 88 Hidden1(typename T::template U<Ts> ...ts); 89 }; 90 91 template<typename T, typename ...Ts> 92 struct Hidden2 { 93 Hidden2(typename T::template U<Ts> ...ts); 94 }; 95 96 struct Hide { 97 template<typename T> using U = int; 98 }; 99 100 // FIXME: This case crashes clang at the moment. 101 //Hidden1<Hide> h1; 102 Hidden2<Hide, double, char> h2(1, 2); 103} 104