18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s 2308047d3SDouglas Gregor template<typename U, typename T> f0(T t)3308047d3SDouglas GregorU f0(T t) { 4308047d3SDouglas Gregor return t.template get<U>(); 5308047d3SDouglas Gregor } 6308047d3SDouglas Gregor 7308047d3SDouglas Gregor template<typename U, typename T> f1(T t)8308047d3SDouglas Gregorint &f1(T t) { 9308047d3SDouglas Gregor // FIXME: When we pretty-print this, we lose the "template" keyword. 10308047d3SDouglas Gregor return t.U::template get<int&>(); 11308047d3SDouglas Gregor } 12308047d3SDouglas Gregor 13308047d3SDouglas Gregor struct X { 14308047d3SDouglas Gregor template<typename T> T get(); 15308047d3SDouglas Gregor }; 16308047d3SDouglas Gregor test_f0(X x)17308047d3SDouglas Gregorvoid test_f0(X x) { 18308047d3SDouglas Gregor int i = f0<int>(x); 19308047d3SDouglas Gregor int &ir = f0<int&>(x); 20308047d3SDouglas Gregor } 21308047d3SDouglas Gregor 22308047d3SDouglas Gregor struct XDerived : public X { 23308047d3SDouglas Gregor }; 24308047d3SDouglas Gregor test_f1(XDerived xd)25308047d3SDouglas Gregorvoid test_f1(XDerived xd) { 26a5cb6da0SDouglas Gregor int &ir = f1<X>(xd); 27308047d3SDouglas Gregor } 28308047d3SDouglas Gregor 29c59e5619SDouglas Gregor // PR5213 30c59e5619SDouglas Gregor template <class T> 31c59e5619SDouglas Gregor struct A {}; 32c59e5619SDouglas Gregor 33c59e5619SDouglas Gregor template<class T> 34c59e5619SDouglas Gregor class B 35c59e5619SDouglas Gregor { 36c59e5619SDouglas Gregor A<T> a_; 37c59e5619SDouglas Gregor 38c59e5619SDouglas Gregor public: 39c59e5619SDouglas Gregor void destroy(); 40c59e5619SDouglas Gregor }; 41c59e5619SDouglas Gregor 42c59e5619SDouglas Gregor template<class T> 43c59e5619SDouglas Gregor void destroy()44c59e5619SDouglas GregorB<T>::destroy() 45c59e5619SDouglas Gregor { 46c59e5619SDouglas Gregor a_.~A<T>(); 47c59e5619SDouglas Gregor } 48c59e5619SDouglas Gregor do_destroy_B(B<int> b)49c59e5619SDouglas Gregorvoid do_destroy_B(B<int> b) { 50c59e5619SDouglas Gregor b.destroy(); 51c59e5619SDouglas Gregor } 52d3319842SDouglas Gregor 53d3319842SDouglas Gregor struct X1 { 54d3319842SDouglas Gregor int* f1(int); 55d3319842SDouglas Gregor template<typename T> float* f1(T); 56d3319842SDouglas Gregor 57d3319842SDouglas Gregor static int* f2(int); 58d3319842SDouglas Gregor template<typename T> static float* f2(T); 59d3319842SDouglas Gregor }; 60d3319842SDouglas Gregor test_X1(X1 x1)61d3319842SDouglas Gregorvoid test_X1(X1 x1) { 62d3319842SDouglas Gregor float *fp1 = x1.f1<>(17); 63*7555b6a4SDavid Blaikie float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}} 64d3319842SDouglas Gregor int *ip1 = x1.f1(17); 65d3319842SDouglas Gregor float *ip2 = x1.f1(3.14); 66d3319842SDouglas Gregor 67d3319842SDouglas Gregor float* (X1::*mf1)(int) = &X1::f1; 68d3319842SDouglas Gregor float* (X1::*mf2)(int) = &X1::f1<>; 69d3319842SDouglas Gregor float* (X1::*mf3)(float) = &X1::f1<float>; 70d3319842SDouglas Gregor 71d3319842SDouglas Gregor float* (*fp3)(int) = &X1::f2; 72d3319842SDouglas Gregor float* (*fp4)(int) = &X1::f2<>; 73d3319842SDouglas Gregor float* (*fp5)(float) = &X1::f2<float>; 74d3319842SDouglas Gregor float* (*fp6)(int) = X1::f2; 75d3319842SDouglas Gregor float* (*fp7)(int) = X1::f2<>; 76d3319842SDouglas Gregor float* (*fp8)(float) = X1::f2<float>; 77d3319842SDouglas Gregor } 78954de179SDouglas Gregor 79954de179SDouglas Gregor template<int A> struct X2 { 80954de179SDouglas Gregor int m; 81954de179SDouglas Gregor }; 82954de179SDouglas Gregor 83954de179SDouglas Gregor template<typename T> 84954de179SDouglas Gregor struct X3 : T { }; 85954de179SDouglas Gregor 86954de179SDouglas Gregor template<typename T> 87954de179SDouglas Gregor struct X4 { 88954de179SDouglas Gregor template<typename U> 89954de179SDouglas Gregor void f(X2<sizeof(X3<U>().U::m)>); 90954de179SDouglas Gregor }; 91954de179SDouglas Gregor f(X4<X3<int>> x4i)92954de179SDouglas Gregorvoid f(X4<X3<int> > x4i) { 93954de179SDouglas Gregor X2<sizeof(int)> x2; 94954de179SDouglas Gregor x4i.f<X2<sizeof(int)> >(x2); 95954de179SDouglas Gregor } 9641127188SDouglas Gregor 9741127188SDouglas Gregor template<typename T> 9841127188SDouglas Gregor struct X5 { 9941127188SDouglas Gregor template<typename U> 10041127188SDouglas Gregor void f(); 10141127188SDouglas Gregor gX510241127188SDouglas Gregor void g() { 10341127188SDouglas Gregor this->f<T*>(); 10441127188SDouglas Gregor } 10541127188SDouglas Gregor }; 10627b174f4SDouglas Gregor 10727b174f4SDouglas Gregor namespace PR6021 { 10827b174f4SDouglas Gregor template< class T1, class T2 > 10927b174f4SDouglas Gregor class Outer 11027b174f4SDouglas Gregor { 11127b174f4SDouglas Gregor public: // Range operations 11227b174f4SDouglas Gregor template< class X > X tmpl( const X* = 0 ) const; 11327b174f4SDouglas Gregor 11427b174f4SDouglas Gregor struct Inner 11527b174f4SDouglas Gregor { 11627b174f4SDouglas Gregor const Outer& o; 11727b174f4SDouglas Gregor 11827b174f4SDouglas Gregor template< class X > operator XPR6021::Outer::Inner11927b174f4SDouglas Gregor operator X() const 12027b174f4SDouglas Gregor { 12127b174f4SDouglas Gregor return o.tmpl<X>(); 12227b174f4SDouglas Gregor } 12327b174f4SDouglas Gregor }; 12427b174f4SDouglas Gregor }; 12527b174f4SDouglas Gregor } 126fc6c3e73SDouglas Gregor 127fc6c3e73SDouglas Gregor namespace rdar8198511 { 128fc6c3e73SDouglas Gregor template<int, typename U> 129fc6c3e73SDouglas Gregor struct Base { 130fc6c3e73SDouglas Gregor void f(); 131fc6c3e73SDouglas Gregor }; 132fc6c3e73SDouglas Gregor 133fc6c3e73SDouglas Gregor template<typename T> 134fc6c3e73SDouglas Gregor struct X0 : Base<1, T> { }; 135fc6c3e73SDouglas Gregor 136fc6c3e73SDouglas Gregor template<typename T> 137fc6c3e73SDouglas Gregor struct X1 { 138fc6c3e73SDouglas Gregor X0<int> x0; 139fc6c3e73SDouglas Gregor frdar8198511::X1140fc6c3e73SDouglas Gregor void f() { 141fc6c3e73SDouglas Gregor this->x0.Base<1, int>::f(); 142fc6c3e73SDouglas Gregor } 143fc6c3e73SDouglas Gregor }; 144fc6c3e73SDouglas Gregor } 145