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