// RUN: %clang_cc1 -fsyntax-only -verify %s template<typename U, typename T> U f0(T t) { return t.template get<U>(); } template<typename U, typename T> int &f1(T t) { // FIXME: When we pretty-print this, we lose the "template" keyword. return t.U::template get<int&>(); } struct X { template<typename T> T get(); }; void test_f0(X x) { int i = f0<int>(x); int &ir = f0<int&>(x); } struct XDerived : public X { }; void test_f1(XDerived xd) { int &ir = f1<X>(xd); } // PR5213 template <class T> struct A {}; template<class T> class B { A<T> a_; public: void destroy(); }; template<class T> void B<T>::destroy() { a_.~A<T>(); } void do_destroy_B(B<int> b) { b.destroy(); } struct X1 { int* f1(int); template<typename T> float* f1(T); static int* f2(int); template<typename T> static float* f2(T); }; void test_X1(X1 x1) { float *fp1 = x1.f1<>(17); float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}} int *ip1 = x1.f1(17); float *ip2 = x1.f1(3.14); float* (X1::*mf1)(int) = &X1::f1; float* (X1::*mf2)(int) = &X1::f1<>; float* (X1::*mf3)(float) = &X1::f1<float>; float* (*fp3)(int) = &X1::f2; float* (*fp4)(int) = &X1::f2<>; float* (*fp5)(float) = &X1::f2<float>; float* (*fp6)(int) = X1::f2; float* (*fp7)(int) = X1::f2<>; float* (*fp8)(float) = X1::f2<float>; } template<int A> struct X2 { int m; }; template<typename T> struct X3 : T { }; template<typename T> struct X4 { template<typename U> void f(X2<sizeof(X3<U>().U::m)>); }; void f(X4<X3<int> > x4i) { X2<sizeof(int)> x2; x4i.f<X2<sizeof(int)> >(x2); } template<typename T> struct X5 { template<typename U> void f(); void g() { this->f<T*>(); } }; namespace PR6021 { template< class T1, class T2 > class Outer { public: // Range operations template< class X > X tmpl( const X* = 0 ) const; struct Inner { const Outer& o; template< class X > operator X() const { return o.tmpl<X>(); } }; }; } namespace rdar8198511 { template<int, typename U> struct Base { void f(); }; template<typename T> struct X0 : Base<1, T> { }; template<typename T> struct X1 { X0<int> x0; void f() { this->x0.Base<1, int>::f(); } }; }