Home | History | Annotate | Download | only in SemaTemplate
      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