xref: /aosp_15_r20/external/clang/test/SemaTemplate/member-template-access-expr.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li template<typename U, typename T>
f0(T t)3*67e74705SXin Li U f0(T t) {
4*67e74705SXin Li   return t.template get<U>();
5*67e74705SXin Li }
6*67e74705SXin Li 
7*67e74705SXin Li template<typename U, typename T>
f1(T t)8*67e74705SXin Li int &f1(T t) {
9*67e74705SXin Li   // FIXME: When we pretty-print this, we lose the "template" keyword.
10*67e74705SXin Li   return t.U::template get<int&>();
11*67e74705SXin Li }
12*67e74705SXin Li 
13*67e74705SXin Li struct X {
14*67e74705SXin Li   template<typename T> T get();
15*67e74705SXin Li };
16*67e74705SXin Li 
test_f0(X x)17*67e74705SXin Li void test_f0(X x) {
18*67e74705SXin Li   int i = f0<int>(x);
19*67e74705SXin Li   int &ir = f0<int&>(x);
20*67e74705SXin Li }
21*67e74705SXin Li 
22*67e74705SXin Li struct XDerived : public X {
23*67e74705SXin Li };
24*67e74705SXin Li 
test_f1(XDerived xd)25*67e74705SXin Li void test_f1(XDerived xd) {
26*67e74705SXin Li   int &ir = f1<X>(xd);
27*67e74705SXin Li }
28*67e74705SXin Li 
29*67e74705SXin Li // PR5213
30*67e74705SXin Li template <class T>
31*67e74705SXin Li struct A {};
32*67e74705SXin Li 
33*67e74705SXin Li template<class T>
34*67e74705SXin Li class B
35*67e74705SXin Li {
36*67e74705SXin Li   A<T> a_;
37*67e74705SXin Li 
38*67e74705SXin Li public:
39*67e74705SXin Li   void destroy();
40*67e74705SXin Li };
41*67e74705SXin Li 
42*67e74705SXin Li template<class T>
43*67e74705SXin Li void
destroy()44*67e74705SXin Li B<T>::destroy()
45*67e74705SXin Li {
46*67e74705SXin Li   a_.~A<T>();
47*67e74705SXin Li }
48*67e74705SXin Li 
do_destroy_B(B<int> b)49*67e74705SXin Li void do_destroy_B(B<int> b) {
50*67e74705SXin Li   b.destroy();
51*67e74705SXin Li }
52*67e74705SXin Li 
53*67e74705SXin Li struct X1 {
54*67e74705SXin Li   int* f1(int);
55*67e74705SXin Li   template<typename T> float* f1(T);
56*67e74705SXin Li 
57*67e74705SXin Li   static int* f2(int);
58*67e74705SXin Li   template<typename T> static float* f2(T);
59*67e74705SXin Li };
60*67e74705SXin Li 
test_X1(X1 x1)61*67e74705SXin Li void test_X1(X1 x1) {
62*67e74705SXin Li   float *fp1 = x1.f1<>(17);
63*67e74705SXin Li   float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}}
64*67e74705SXin Li   int *ip1 = x1.f1(17);
65*67e74705SXin Li   float *ip2 = x1.f1(3.14);
66*67e74705SXin Li 
67*67e74705SXin Li   float* (X1::*mf1)(int) = &X1::f1;
68*67e74705SXin Li   float* (X1::*mf2)(int) = &X1::f1<>;
69*67e74705SXin Li   float* (X1::*mf3)(float) = &X1::f1<float>;
70*67e74705SXin Li 
71*67e74705SXin Li   float* (*fp3)(int) = &X1::f2;
72*67e74705SXin Li   float* (*fp4)(int) = &X1::f2<>;
73*67e74705SXin Li   float* (*fp5)(float) = &X1::f2<float>;
74*67e74705SXin Li   float* (*fp6)(int) = X1::f2;
75*67e74705SXin Li   float* (*fp7)(int) = X1::f2<>;
76*67e74705SXin Li   float* (*fp8)(float) = X1::f2<float>;
77*67e74705SXin Li }
78*67e74705SXin Li 
79*67e74705SXin Li template<int A> struct X2 {
80*67e74705SXin Li   int m;
81*67e74705SXin Li };
82*67e74705SXin Li 
83*67e74705SXin Li template<typename T>
84*67e74705SXin Li struct X3 : T { };
85*67e74705SXin Li 
86*67e74705SXin Li template<typename T>
87*67e74705SXin Li struct X4 {
88*67e74705SXin Li   template<typename U>
89*67e74705SXin Li   void f(X2<sizeof(X3<U>().U::m)>);
90*67e74705SXin Li };
91*67e74705SXin Li 
f(X4<X3<int>> x4i)92*67e74705SXin Li void f(X4<X3<int> > x4i) {
93*67e74705SXin Li   X2<sizeof(int)> x2;
94*67e74705SXin Li   x4i.f<X2<sizeof(int)> >(x2);
95*67e74705SXin Li }
96*67e74705SXin Li 
97*67e74705SXin Li template<typename T>
98*67e74705SXin Li struct X5 {
99*67e74705SXin Li   template<typename U>
100*67e74705SXin Li   void f();
101*67e74705SXin Li 
gX5102*67e74705SXin Li   void g() {
103*67e74705SXin Li     this->f<T*>();
104*67e74705SXin Li   }
105*67e74705SXin Li };
106*67e74705SXin Li 
107*67e74705SXin Li namespace PR6021 {
108*67e74705SXin Li   template< class T1, class T2 >
109*67e74705SXin Li   class Outer
110*67e74705SXin Li   {
111*67e74705SXin Li   public: // Range operations
112*67e74705SXin Li     template< class X > X tmpl( const X* = 0 ) const;
113*67e74705SXin Li 
114*67e74705SXin Li     struct Inner
115*67e74705SXin Li     {
116*67e74705SXin Li       const Outer& o;
117*67e74705SXin Li 
118*67e74705SXin Li       template< class X >
operator XPR6021::Outer::Inner119*67e74705SXin Li       operator X() const
120*67e74705SXin Li       {
121*67e74705SXin Li         return o.tmpl<X>();
122*67e74705SXin Li       }
123*67e74705SXin Li     };
124*67e74705SXin Li   };
125*67e74705SXin Li }
126*67e74705SXin Li 
127*67e74705SXin Li namespace rdar8198511 {
128*67e74705SXin Li   template<int, typename U>
129*67e74705SXin Li   struct Base {
130*67e74705SXin Li     void f();
131*67e74705SXin Li   };
132*67e74705SXin Li 
133*67e74705SXin Li   template<typename T>
134*67e74705SXin Li   struct X0 : Base<1, T> { };
135*67e74705SXin Li 
136*67e74705SXin Li   template<typename T>
137*67e74705SXin Li   struct X1 {
138*67e74705SXin Li     X0<int> x0;
139*67e74705SXin Li 
frdar8198511::X1140*67e74705SXin Li     void f() {
141*67e74705SXin Li       this->x0.Base<1, int>::f();
142*67e74705SXin Li     }
143*67e74705SXin Li   };
144*67e74705SXin Li }
145