1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc // Template argument deduction with template template parameters. 4*f4a2713aSLionel Sambuc template<typename T, template<T> class A> 5*f4a2713aSLionel Sambuc struct X0 { 6*f4a2713aSLionel Sambuc static const unsigned value = 0; 7*f4a2713aSLionel Sambuc }; 8*f4a2713aSLionel Sambuc 9*f4a2713aSLionel Sambuc template<template<int> class A> 10*f4a2713aSLionel Sambuc struct X0<int, A> { 11*f4a2713aSLionel Sambuc static const unsigned value = 1; 12*f4a2713aSLionel Sambuc }; 13*f4a2713aSLionel Sambuc 14*f4a2713aSLionel Sambuc template<int> struct X0i; 15*f4a2713aSLionel Sambuc template<long> struct X0l; 16*f4a2713aSLionel Sambuc int array_x0a[X0<long, X0l>::value == 0? 1 : -1]; 17*f4a2713aSLionel Sambuc int array_x0b[X0<int, X0i>::value == 1? 1 : -1]; 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc template<typename T, typename U> 20*f4a2713aSLionel Sambuc struct is_same { 21*f4a2713aSLionel Sambuc static const bool value = false; 22*f4a2713aSLionel Sambuc }; 23*f4a2713aSLionel Sambuc 24*f4a2713aSLionel Sambuc template<typename T> 25*f4a2713aSLionel Sambuc struct is_same<T, T> { 26*f4a2713aSLionel Sambuc static const bool value = true; 27*f4a2713aSLionel Sambuc }; 28*f4a2713aSLionel Sambuc 29*f4a2713aSLionel Sambuc template<typename T> struct allocator { }; 30*f4a2713aSLionel Sambuc template<typename T, typename Alloc = allocator<T> > struct vector {}; 31*f4a2713aSLionel Sambuc 32*f4a2713aSLionel Sambuc // Fun with meta-lambdas! 33*f4a2713aSLionel Sambuc struct _1 {}; 34*f4a2713aSLionel Sambuc struct _2 {}; 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambuc // Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. 37*f4a2713aSLionel Sambuc template<typename T, typename Arg1, typename Arg2> 38*f4a2713aSLionel Sambuc struct Replace { 39*f4a2713aSLionel Sambuc typedef T type; 40*f4a2713aSLionel Sambuc }; 41*f4a2713aSLionel Sambuc 42*f4a2713aSLionel Sambuc // Replacement of the whole type. 43*f4a2713aSLionel Sambuc template<typename Arg1, typename Arg2> 44*f4a2713aSLionel Sambuc struct Replace<_1, Arg1, Arg2> { 45*f4a2713aSLionel Sambuc typedef Arg1 type; 46*f4a2713aSLionel Sambuc }; 47*f4a2713aSLionel Sambuc 48*f4a2713aSLionel Sambuc template<typename Arg1, typename Arg2> 49*f4a2713aSLionel Sambuc struct Replace<_2, Arg1, Arg2> { 50*f4a2713aSLionel Sambuc typedef Arg2 type; 51*f4a2713aSLionel Sambuc }; 52*f4a2713aSLionel Sambuc 53*f4a2713aSLionel Sambuc // Replacement through cv-qualifiers 54*f4a2713aSLionel Sambuc template<typename T, typename Arg1, typename Arg2> 55*f4a2713aSLionel Sambuc struct Replace<const T, Arg1, Arg2> { 56*f4a2713aSLionel Sambuc typedef typename Replace<T, Arg1, Arg2>::type const type; 57*f4a2713aSLionel Sambuc }; 58*f4a2713aSLionel Sambuc 59*f4a2713aSLionel Sambuc // Replacement of templates 60*f4a2713aSLionel Sambuc template<template<typename> class TT, typename T1, typename Arg1, typename Arg2> 61*f4a2713aSLionel Sambuc struct Replace<TT<T1>, Arg1, Arg2> { 62*f4a2713aSLionel Sambuc typedef TT<typename Replace<T1, Arg1, Arg2>::type> type; 63*f4a2713aSLionel Sambuc }; 64*f4a2713aSLionel Sambuc 65*f4a2713aSLionel Sambuc template<template<typename, typename> class TT, typename T1, typename T2, 66*f4a2713aSLionel Sambuc typename Arg1, typename Arg2> 67*f4a2713aSLionel Sambuc struct Replace<TT<T1, T2>, Arg1, Arg2> { 68*f4a2713aSLionel Sambuc typedef TT<typename Replace<T1, Arg1, Arg2>::type, 69*f4a2713aSLionel Sambuc typename Replace<T2, Arg1, Arg2>::type> type; 70*f4a2713aSLionel Sambuc }; 71*f4a2713aSLionel Sambuc 72*f4a2713aSLionel Sambuc // Just for kicks... 73*f4a2713aSLionel Sambuc template<template<typename, typename> class TT, typename T1, 74*f4a2713aSLionel Sambuc typename Arg1, typename Arg2> 75*f4a2713aSLionel Sambuc struct Replace<TT<T1, _2>, Arg1, Arg2> { 76*f4a2713aSLionel Sambuc typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type; 77*f4a2713aSLionel Sambuc }; 78*f4a2713aSLionel Sambuc 79*f4a2713aSLionel Sambuc int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1]; 80*f4a2713aSLionel Sambuc int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1]; 81*f4a2713aSLionel Sambuc int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1]; 82*f4a2713aSLionel Sambuc int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1]; 83*f4a2713aSLionel Sambuc int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1]; 84*f4a2713aSLionel Sambuc 85*f4a2713aSLionel Sambuc // PR5911 86*f4a2713aSLionel Sambuc template <typename T, int N> void f(const T (&a)[N]); 87*f4a2713aSLionel Sambuc int iarr[] = { 1 }; 88*f4a2713aSLionel Sambuc void test_PR5911() { f(iarr); } 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel Sambuc // Must not examine base classes of incomplete type during template argument 91*f4a2713aSLionel Sambuc // deduction. 92*f4a2713aSLionel Sambuc namespace PR6257 { 93*f4a2713aSLionel Sambuc template <typename T> struct X { 94*f4a2713aSLionel Sambuc template <typename U> X(const X<U>& u); 95*f4a2713aSLionel Sambuc }; 96*f4a2713aSLionel Sambuc struct A; 97*f4a2713aSLionel Sambuc void f(A& a); 98*f4a2713aSLionel Sambuc void f(const X<A>& a); 99*f4a2713aSLionel Sambuc void test(A& a) { (void)f(a); } 100*f4a2713aSLionel Sambuc } 101*f4a2713aSLionel Sambuc 102*f4a2713aSLionel Sambuc // PR7463 103*f4a2713aSLionel Sambuc namespace PR7463 { 104*f4a2713aSLionel Sambuc const int f (); 105*f4a2713aSLionel Sambuc template <typename T_> void g (T_&); // expected-note{{T_ = int}} 106*f4a2713aSLionel Sambuc void h (void) { g(f()); } // expected-error{{no matching function for call}} 107*f4a2713aSLionel Sambuc } 108*f4a2713aSLionel Sambuc 109*f4a2713aSLionel Sambuc namespace test0 { 110*f4a2713aSLionel Sambuc template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'char'}} 111*f4a2713aSLionel Sambuc char *char_maker(); 112*f4a2713aSLionel Sambuc void test() { 113*f4a2713aSLionel Sambuc make(char_maker); // expected-error {{no matching function for call to 'make'}} 114*f4a2713aSLionel Sambuc } 115*f4a2713aSLionel Sambuc } 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc namespace test1 { 118*f4a2713aSLionel Sambuc template<typename T> void foo(const T a[3][3]); 119*f4a2713aSLionel Sambuc void test() { 120*f4a2713aSLionel Sambuc int a[3][3]; 121*f4a2713aSLionel Sambuc foo(a); 122*f4a2713aSLionel Sambuc } 123*f4a2713aSLionel Sambuc } 124*f4a2713aSLionel Sambuc 125*f4a2713aSLionel Sambuc // PR7708 126*f4a2713aSLionel Sambuc namespace test2 { 127*f4a2713aSLionel Sambuc template<typename T> struct Const { typedef void const type; }; 128*f4a2713aSLionel Sambuc 129*f4a2713aSLionel Sambuc template<typename T> void f(T, typename Const<T>::type*); 130*f4a2713aSLionel Sambuc template<typename T> void f(T, void const *); 131*f4a2713aSLionel Sambuc 132*f4a2713aSLionel Sambuc void test() { 133*f4a2713aSLionel Sambuc void *p = 0; 134*f4a2713aSLionel Sambuc f(0, p); 135*f4a2713aSLionel Sambuc } 136*f4a2713aSLionel Sambuc } 137*f4a2713aSLionel Sambuc 138*f4a2713aSLionel Sambuc // rdar://problem/8537391 139*f4a2713aSLionel Sambuc namespace test3 { 140*f4a2713aSLionel Sambuc struct Foo { 141*f4a2713aSLionel Sambuc template <void F(char)> static inline void foo(); 142*f4a2713aSLionel Sambuc }; 143*f4a2713aSLionel Sambuc 144*f4a2713aSLionel Sambuc class Bar { 145*f4a2713aSLionel Sambuc template<typename T> static inline void wobble(T ch); 146*f4a2713aSLionel Sambuc 147*f4a2713aSLionel Sambuc public: 148*f4a2713aSLionel Sambuc static void madness() { 149*f4a2713aSLionel Sambuc Foo::foo<wobble<char> >(); 150*f4a2713aSLionel Sambuc } 151*f4a2713aSLionel Sambuc }; 152*f4a2713aSLionel Sambuc } 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc // Verify that we can deduce enum-typed arguments correctly. 155*f4a2713aSLionel Sambuc namespace test14 { 156*f4a2713aSLionel Sambuc enum E { E0, E1 }; 157*f4a2713aSLionel Sambuc template <E> struct A {}; 158*f4a2713aSLionel Sambuc template <E e> void foo(const A<e> &a) {} 159*f4a2713aSLionel Sambuc 160*f4a2713aSLionel Sambuc void test() { 161*f4a2713aSLionel Sambuc A<E0> a; 162*f4a2713aSLionel Sambuc foo(a); 163*f4a2713aSLionel Sambuc } 164*f4a2713aSLionel Sambuc } 165