1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s 2*67e74705SXin Li template<typename U, typename T> f0(T t)3*67e74705SXin LiU f0(T t) { 4*67e74705SXin Li return t.template get<U>(); 5*67e74705SXin Li } 6*67e74705SXin Li 7*67e74705SXin Li template<typename U, typename T> f1(T t)8*67e74705SXin Liint &f1(T t) { 9*67e74705SXin Li // FIXME: When we pretty-print this, we lose the "template" keyword. 10*67e74705SXin Li return t.U::template get<int&>(); 11*67e74705SXin Li } 12*67e74705SXin Li 13*67e74705SXin Li struct X { 14*67e74705SXin Li template<typename T> T get(); 15*67e74705SXin Li }; 16*67e74705SXin Li test_f0(X x)17*67e74705SXin Livoid test_f0(X x) { 18*67e74705SXin Li int i = f0<int>(x); 19*67e74705SXin Li int &ir = f0<int&>(x); 20*67e74705SXin Li } 21*67e74705SXin Li 22*67e74705SXin Li struct XDerived : public X { 23*67e74705SXin Li }; 24*67e74705SXin Li test_f1(XDerived xd)25*67e74705SXin Livoid test_f1(XDerived xd) { 26*67e74705SXin Li int &ir = f1<X>(xd); 27*67e74705SXin Li } 28*67e74705SXin Li 29*67e74705SXin Li // PR5213 30*67e74705SXin Li template <class T> 31*67e74705SXin Li struct A {}; 32*67e74705SXin Li 33*67e74705SXin Li template<class T> 34*67e74705SXin Li class B 35*67e74705SXin Li { 36*67e74705SXin Li A<T> a_; 37*67e74705SXin Li 38*67e74705SXin Li public: 39*67e74705SXin Li void destroy(); 40*67e74705SXin Li }; 41*67e74705SXin Li 42*67e74705SXin Li template<class T> 43*67e74705SXin Li void destroy()44*67e74705SXin LiB<T>::destroy() 45*67e74705SXin Li { 46*67e74705SXin Li a_.~A<T>(); 47*67e74705SXin Li } 48*67e74705SXin Li do_destroy_B(B<int> b)49*67e74705SXin Livoid do_destroy_B(B<int> b) { 50*67e74705SXin Li b.destroy(); 51*67e74705SXin Li } 52*67e74705SXin Li 53*67e74705SXin Li struct X1 { 54*67e74705SXin Li int* f1(int); 55*67e74705SXin Li template<typename T> float* f1(T); 56*67e74705SXin Li 57*67e74705SXin Li static int* f2(int); 58*67e74705SXin Li template<typename T> static float* f2(T); 59*67e74705SXin Li }; 60*67e74705SXin Li test_X1(X1 x1)61*67e74705SXin Livoid test_X1(X1 x1) { 62*67e74705SXin Li float *fp1 = x1.f1<>(17); 63*67e74705SXin Li float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}} 64*67e74705SXin Li int *ip1 = x1.f1(17); 65*67e74705SXin Li float *ip2 = x1.f1(3.14); 66*67e74705SXin Li 67*67e74705SXin Li float* (X1::*mf1)(int) = &X1::f1; 68*67e74705SXin Li float* (X1::*mf2)(int) = &X1::f1<>; 69*67e74705SXin Li float* (X1::*mf3)(float) = &X1::f1<float>; 70*67e74705SXin Li 71*67e74705SXin Li float* (*fp3)(int) = &X1::f2; 72*67e74705SXin Li float* (*fp4)(int) = &X1::f2<>; 73*67e74705SXin Li float* (*fp5)(float) = &X1::f2<float>; 74*67e74705SXin Li float* (*fp6)(int) = X1::f2; 75*67e74705SXin Li float* (*fp7)(int) = X1::f2<>; 76*67e74705SXin Li float* (*fp8)(float) = X1::f2<float>; 77*67e74705SXin Li } 78*67e74705SXin Li 79*67e74705SXin Li template<int A> struct X2 { 80*67e74705SXin Li int m; 81*67e74705SXin Li }; 82*67e74705SXin Li 83*67e74705SXin Li template<typename T> 84*67e74705SXin Li struct X3 : T { }; 85*67e74705SXin Li 86*67e74705SXin Li template<typename T> 87*67e74705SXin Li struct X4 { 88*67e74705SXin Li template<typename U> 89*67e74705SXin Li void f(X2<sizeof(X3<U>().U::m)>); 90*67e74705SXin Li }; 91*67e74705SXin Li f(X4<X3<int>> x4i)92*67e74705SXin Livoid f(X4<X3<int> > x4i) { 93*67e74705SXin Li X2<sizeof(int)> x2; 94*67e74705SXin Li x4i.f<X2<sizeof(int)> >(x2); 95*67e74705SXin Li } 96*67e74705SXin Li 97*67e74705SXin Li template<typename T> 98*67e74705SXin Li struct X5 { 99*67e74705SXin Li template<typename U> 100*67e74705SXin Li void f(); 101*67e74705SXin Li gX5102*67e74705SXin Li void g() { 103*67e74705SXin Li this->f<T*>(); 104*67e74705SXin Li } 105*67e74705SXin Li }; 106*67e74705SXin Li 107*67e74705SXin Li namespace PR6021 { 108*67e74705SXin Li template< class T1, class T2 > 109*67e74705SXin Li class Outer 110*67e74705SXin Li { 111*67e74705SXin Li public: // Range operations 112*67e74705SXin Li template< class X > X tmpl( const X* = 0 ) const; 113*67e74705SXin Li 114*67e74705SXin Li struct Inner 115*67e74705SXin Li { 116*67e74705SXin Li const Outer& o; 117*67e74705SXin Li 118*67e74705SXin Li template< class X > operator XPR6021::Outer::Inner119*67e74705SXin Li operator X() const 120*67e74705SXin Li { 121*67e74705SXin Li return o.tmpl<X>(); 122*67e74705SXin Li } 123*67e74705SXin Li }; 124*67e74705SXin Li }; 125*67e74705SXin Li } 126*67e74705SXin Li 127*67e74705SXin Li namespace rdar8198511 { 128*67e74705SXin Li template<int, typename U> 129*67e74705SXin Li struct Base { 130*67e74705SXin Li void f(); 131*67e74705SXin Li }; 132*67e74705SXin Li 133*67e74705SXin Li template<typename T> 134*67e74705SXin Li struct X0 : Base<1, T> { }; 135*67e74705SXin Li 136*67e74705SXin Li template<typename T> 137*67e74705SXin Li struct X1 { 138*67e74705SXin Li X0<int> x0; 139*67e74705SXin Li frdar8198511::X1140*67e74705SXin Li void f() { 141*67e74705SXin Li this->x0.Base<1, int>::f(); 142*67e74705SXin Li } 143*67e74705SXin Li }; 144*67e74705SXin Li } 145