diff options
Diffstat (limited to 'clang/test/SemaTemplate/member-template-access-expr.cpp')
-rw-r--r-- | clang/test/SemaTemplate/member-template-access-expr.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/member-template-access-expr.cpp b/clang/test/SemaTemplate/member-template-access-expr.cpp new file mode 100644 index 0000000..c95b57d --- /dev/null +++ b/clang/test/SemaTemplate/member-template-access-expr.cpp @@ -0,0 +1,144 @@ +// 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 turns literal floating-point number into integer}} + 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(); + } + }; +} |