xref: /llvm-project/clang/test/SemaTemplate/member-template-access-expr.cpp (revision 7555b6a4e51e9cb0c54da10b8951104306cfdcbb)
18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s
2308047d3SDouglas Gregor template<typename U, typename T>
f0(T t)3308047d3SDouglas Gregor U 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 Gregor int &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 Gregor void 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 Gregor void 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 Gregor B<T>::destroy()
45c59e5619SDouglas Gregor {
46c59e5619SDouglas Gregor   a_.~A<T>();
47c59e5619SDouglas Gregor }
48c59e5619SDouglas Gregor 
do_destroy_B(B<int> b)49c59e5619SDouglas Gregor void 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 Gregor void 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 Gregor void 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