xref: /aosp_15_r20/external/clang/test/SemaTemplate/instantiate-declref.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li namespace N {
3*67e74705SXin Li   struct Outer {
4*67e74705SXin Li     struct Inner {
5*67e74705SXin Li       template<typename T>
6*67e74705SXin Li       struct InnerTemplate {
7*67e74705SXin Li         struct VeryInner {
8*67e74705SXin Li           typedef T type;
9*67e74705SXin Li 
10*67e74705SXin Li           static enum K1 { K1Val = sizeof(T) } Kind1;
11*67e74705SXin Li           static enum { K2Val = sizeof(T)*2 } Kind2;
12*67e74705SXin Li           enum { K3Val = sizeof(T)*2 } Kind3;
13*67e74705SXin Li 
fooN::Outer::Inner::InnerTemplate::VeryInner14*67e74705SXin Li           void foo() {
15*67e74705SXin Li             K1 k1 = K1Val;
16*67e74705SXin Li             Kind1 = K1Val;
17*67e74705SXin Li             Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
18*67e74705SXin Li             Kind3 = K3Val;
19*67e74705SXin Li           }
20*67e74705SXin Li 
21*67e74705SXin Li           struct UeberInner {
barN::Outer::Inner::InnerTemplate::VeryInner::UeberInner22*67e74705SXin Li             void bar() {
23*67e74705SXin Li               K1 k1 = K1Val;
24*67e74705SXin Li               Kind1 = K1Val;
25*67e74705SXin Li               Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
26*67e74705SXin Li 
27*67e74705SXin Li               InnerTemplate t;
28*67e74705SXin Li               InnerTemplate<type> t2;
29*67e74705SXin Li             }
30*67e74705SXin Li           };
31*67e74705SXin Li         };
32*67e74705SXin Li       };
33*67e74705SXin Li     };
34*67e74705SXin Li   };
35*67e74705SXin Li }
36*67e74705SXin Li 
37*67e74705SXin Li typedef int INT;
38*67e74705SXin Li template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
39*67e74705SXin Li template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
40*67e74705SXin Li 
41*67e74705SXin Li namespace N2 {
42*67e74705SXin Li   struct Outer2 {
43*67e74705SXin Li     template<typename T, typename U = T>
44*67e74705SXin Li     struct Inner {
fooN2::Outer2::Inner45*67e74705SXin Li       void foo() {
46*67e74705SXin Li         enum { K1Val = sizeof(T) } k1;
47*67e74705SXin Li         enum K2 { K2Val = sizeof(T)*2 } k2a;
48*67e74705SXin Li 
49*67e74705SXin Li         K2 k2b = K2Val;
50*67e74705SXin Li 
51*67e74705SXin Li         struct S { T x, y; } s1;
52*67e74705SXin Li         struct { U x, y; } s2;
53*67e74705SXin Li         s1.x = s2.x; // expected-error{{incompatible}}
54*67e74705SXin Li 
55*67e74705SXin Li         typedef T type;
56*67e74705SXin Li         type t2 = s1.x;
57*67e74705SXin Li 
58*67e74705SXin Li         typedef struct { T z; } type2;
59*67e74705SXin Li         type2 t3 = { s1.x };
60*67e74705SXin Li 
61*67e74705SXin Li         Inner i1;
62*67e74705SXin Li         i1.foo();
63*67e74705SXin Li         Inner<T> i2;
64*67e74705SXin Li         i2.foo();
65*67e74705SXin Li       }
66*67e74705SXin Li     };
67*67e74705SXin Li   };
68*67e74705SXin Li }
69*67e74705SXin Li 
70*67e74705SXin Li template struct N2::Outer2::Inner<float>;
71*67e74705SXin Li template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
72*67e74705SXin Li 
73*67e74705SXin Li // Test dependent pointer-to-member expressions.
74*67e74705SXin Li template<typename T>
75*67e74705SXin Li struct smart_ptr {
76*67e74705SXin Li   struct safe_bool {
77*67e74705SXin Li     int member;
78*67e74705SXin Li   };
79*67e74705SXin Li 
operator int safe_bool::*smart_ptr80*67e74705SXin Li   operator int safe_bool::*() const {
81*67e74705SXin Li     return ptr? &safe_bool::member : 0;
82*67e74705SXin Li   }
83*67e74705SXin Li 
84*67e74705SXin Li   T* ptr;
85*67e74705SXin Li };
86*67e74705SXin Li 
test_smart_ptr(smart_ptr<int> p)87*67e74705SXin Li void test_smart_ptr(smart_ptr<int> p) {
88*67e74705SXin Li   if (p) { }
89*67e74705SXin Li }
90*67e74705SXin Li 
91*67e74705SXin Li // PR5517
92*67e74705SXin Li namespace test0 {
93*67e74705SXin Li   template <int K> struct X {
Xtest0::X94*67e74705SXin Li     X() { extern void x(); }
95*67e74705SXin Li   };
g()96*67e74705SXin Li   void g() { X<2>(); }
97*67e74705SXin Li }
98*67e74705SXin Li 
99*67e74705SXin Li // <rdar://problem/8302161>
100*67e74705SXin Li namespace test1 {
f(T const & t)101*67e74705SXin Li   template <typename T> void f(T const &t) {
102*67e74705SXin Li     union { char c; T t_; };
103*67e74705SXin Li     c = 'a'; // <- this shouldn't silently fail to instantiate
104*67e74705SXin Li     T::foo(); // expected-error {{has no members}}
105*67e74705SXin Li   }
106*67e74705SXin Li   template void f(int const &); // expected-note {{requested here}}
107*67e74705SXin Li }
108*67e74705SXin Li 
109*67e74705SXin Li namespace test2 {
f()110*67e74705SXin Li   template<typename T> void f() {
111*67e74705SXin Li     T::error; // expected-error {{no member}}
112*67e74705SXin Li   }
g()113*67e74705SXin Li   void g() {
114*67e74705SXin Li     // This counts as an odr-use, so should trigger the instantiation of f<int>.
115*67e74705SXin Li     (void)&f<int>; // expected-note {{here}}
116*67e74705SXin Li   }
117*67e74705SXin Li }
118