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