summaryrefslogtreecommitdiff
path: root/clang/test/SemaTemplate/member-template-access-expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaTemplate/member-template-access-expr.cpp')
-rw-r--r--clang/test/SemaTemplate/member-template-access-expr.cpp144
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();
+ }
+ };
+}