xref: /aosp_15_r20/external/clang/test/CodeGenCXX/vtable-available-externally.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o %t
2*67e74705SXin Li // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -O2 -disable-llvm-optzns -emit-llvm -o %t.opt
3*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
4*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
5*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
6*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST8 %s < %t.opt
7*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST9 %s < %t.opt
8*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST10 %s < %t.opt
9*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST11 %s < %t.opt
10*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST12 %s < %t.opt
11*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST13 %s < %t.opt
12*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST14 %s < %t.opt
13*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
14*67e74705SXin Li // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
15*67e74705SXin Li 
16*67e74705SXin Li #include <typeinfo>
17*67e74705SXin Li 
18*67e74705SXin Li // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
19*67e74705SXin Li namespace Test1 {
20*67e74705SXin Li 
21*67e74705SXin Li struct A {
22*67e74705SXin Li   A();
23*67e74705SXin Li   virtual void f();
~ATest1::A24*67e74705SXin Li   virtual ~A() { }
25*67e74705SXin Li };
26*67e74705SXin Li 
A()27*67e74705SXin Li A::A() { }
28*67e74705SXin Li 
f(A * a)29*67e74705SXin Li void f(A* a) {
30*67e74705SXin Li   a->f();
31*67e74705SXin Li };
32*67e74705SXin Li 
33*67e74705SXin Li // CHECK-LABEL: define void @_ZN5Test11gEv
34*67e74705SXin Li // CHECK: call void @_ZN5Test11A1fEv
g()35*67e74705SXin Li void g() {
36*67e74705SXin Li   A a;
37*67e74705SXin Li   f(&a);
38*67e74705SXin Li }
39*67e74705SXin Li 
40*67e74705SXin Li }
41*67e74705SXin Li 
42*67e74705SXin Li // Test2::A's key function (f) is defined in this translation unit, but when
43*67e74705SXin Li // we're doing codegen for the typeid(A) call, we don't know that yet.
44*67e74705SXin Li // This tests mainly that the typeinfo and typename constants have their linkage
45*67e74705SXin Li // updated correctly.
46*67e74705SXin Li 
47*67e74705SXin Li // CHECK-TEST2: @_ZTSN5Test21AE = constant
48*67e74705SXin Li // CHECK-TEST2: @_ZTIN5Test21AE = constant
49*67e74705SXin Li // CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
50*67e74705SXin Li namespace Test2 {
51*67e74705SXin Li   struct A {
52*67e74705SXin Li     virtual void f();
53*67e74705SXin Li   };
54*67e74705SXin Li 
g()55*67e74705SXin Li   const std::type_info &g() {
56*67e74705SXin Li     return typeid(A);
57*67e74705SXin Li   };
58*67e74705SXin Li 
f()59*67e74705SXin Li   void A::f() { }
60*67e74705SXin Li }
61*67e74705SXin Li 
62*67e74705SXin Li // Test that we don't assert on this test.
63*67e74705SXin Li namespace Test3 {
64*67e74705SXin Li 
65*67e74705SXin Li struct A {
66*67e74705SXin Li   virtual void f();
~ATest3::A67*67e74705SXin Li   virtual ~A() { }
68*67e74705SXin Li };
69*67e74705SXin Li 
70*67e74705SXin Li struct B : A {
71*67e74705SXin Li   B();
72*67e74705SXin Li   virtual void f();
73*67e74705SXin Li };
74*67e74705SXin Li 
B()75*67e74705SXin Li B::B() { }
76*67e74705SXin Li 
g(A * a)77*67e74705SXin Li void g(A* a) {
78*67e74705SXin Li   a->f();
79*67e74705SXin Li };
80*67e74705SXin Li 
81*67e74705SXin Li }
82*67e74705SXin Li 
83*67e74705SXin Li // PR9114, test that we don't try to instantiate RefPtr<Node>.
84*67e74705SXin Li namespace Test4 {
85*67e74705SXin Li 
86*67e74705SXin Li template <class T> struct RefPtr {
87*67e74705SXin Li   T* p;
~RefPtrTest4::RefPtr88*67e74705SXin Li   ~RefPtr() {
89*67e74705SXin Li     p->deref();
90*67e74705SXin Li   }
91*67e74705SXin Li };
92*67e74705SXin Li 
93*67e74705SXin Li struct A {
94*67e74705SXin Li   virtual ~A();
95*67e74705SXin Li };
96*67e74705SXin Li 
97*67e74705SXin Li struct Node;
98*67e74705SXin Li 
99*67e74705SXin Li struct B : A {
100*67e74705SXin Li   virtual void deref();
101*67e74705SXin Li   RefPtr<Node> m;
102*67e74705SXin Li };
103*67e74705SXin Li 
f()104*67e74705SXin Li void f() {
105*67e74705SXin Li   RefPtr<B> b;
106*67e74705SXin Li }
107*67e74705SXin Li 
108*67e74705SXin Li }
109*67e74705SXin Li 
110*67e74705SXin Li // PR9130, test that we emit a definition of A::f.
111*67e74705SXin Li // CHECK-TEST5-LABEL: define linkonce_odr void @_ZN5Test51A1fEv
112*67e74705SXin Li namespace Test5 {
113*67e74705SXin Li 
114*67e74705SXin Li struct A {
fTest5::A115*67e74705SXin Li   virtual void f() { }
116*67e74705SXin Li };
117*67e74705SXin Li 
118*67e74705SXin Li struct B : A {
119*67e74705SXin Li   virtual ~B();
120*67e74705SXin Li };
121*67e74705SXin Li 
~B()122*67e74705SXin Li B::~B() { }
123*67e74705SXin Li 
124*67e74705SXin Li }
125*67e74705SXin Li 
126*67e74705SXin Li // Check that we don't assert on this test.
127*67e74705SXin Li namespace Test6 {
128*67e74705SXin Li 
129*67e74705SXin Li struct A {
130*67e74705SXin Li   virtual ~A();
131*67e74705SXin Li   int a;
132*67e74705SXin Li };
133*67e74705SXin Li 
134*67e74705SXin Li struct B {
135*67e74705SXin Li   virtual ~B();
136*67e74705SXin Li   int b;
137*67e74705SXin Li };
138*67e74705SXin Li 
139*67e74705SXin Li struct C : A, B {
140*67e74705SXin Li   C();
141*67e74705SXin Li };
142*67e74705SXin Li 
143*67e74705SXin Li struct D : C {
144*67e74705SXin Li   virtual void f();
145*67e74705SXin Li   D();
146*67e74705SXin Li };
147*67e74705SXin Li 
D()148*67e74705SXin Li D::D() { }
149*67e74705SXin Li 
150*67e74705SXin Li }
151*67e74705SXin Li 
152*67e74705SXin Li namespace Test7 {
153*67e74705SXin Li 
154*67e74705SXin Li struct c1 {};
155*67e74705SXin Li struct c10 : c1{
156*67e74705SXin Li   virtual void foo ();
157*67e74705SXin Li };
158*67e74705SXin Li struct c11 : c10, c1{
159*67e74705SXin Li   virtual void f6 ();
160*67e74705SXin Li };
161*67e74705SXin Li struct c28 : virtual c11{
162*67e74705SXin Li   void f6 ();
163*67e74705SXin Li };
164*67e74705SXin Li }
165*67e74705SXin Li 
166*67e74705SXin Li namespace Test8 {
167*67e74705SXin Li // CHECK-TEST8: @_ZTVN5Test81YE = available_externally unnamed_addr constant
168*67e74705SXin Li // vtable for X is not generated because there are no stores here
169*67e74705SXin Li struct X {
170*67e74705SXin Li   X();
171*67e74705SXin Li   virtual void foo();
172*67e74705SXin Li };
173*67e74705SXin Li struct Y : X {
174*67e74705SXin Li   void foo();
175*67e74705SXin Li };
176*67e74705SXin Li 
g(X * p)177*67e74705SXin Li void g(X* p) { p->foo(); }
f()178*67e74705SXin Li void f() {
179*67e74705SXin Li   Y y;
180*67e74705SXin Li   g(&y);
181*67e74705SXin Li   X x;
182*67e74705SXin Li   g(&x);
183*67e74705SXin Li }
184*67e74705SXin Li 
185*67e74705SXin Li }  // Test8
186*67e74705SXin Li 
187*67e74705SXin Li namespace Test9 {
188*67e74705SXin Li // All virtual functions are outline, so we can assume that it will
189*67e74705SXin Li // be generated in translation unit where foo is defined.
190*67e74705SXin Li // CHECK-TEST9-DAG: @_ZTVN5Test91AE = available_externally unnamed_addr constant
191*67e74705SXin Li // CHECK-TEST9-DAG: @_ZTVN5Test91BE = available_externally unnamed_addr constant
192*67e74705SXin Li struct A {
193*67e74705SXin Li   virtual void foo();
194*67e74705SXin Li   virtual void bar();
195*67e74705SXin Li };
bar()196*67e74705SXin Li void A::bar() {}
197*67e74705SXin Li 
198*67e74705SXin Li struct B : A {
199*67e74705SXin Li   void foo();
200*67e74705SXin Li };
201*67e74705SXin Li 
g()202*67e74705SXin Li void g() {
203*67e74705SXin Li   A a;
204*67e74705SXin Li   a.foo();
205*67e74705SXin Li   B b;
206*67e74705SXin Li   b.foo();
207*67e74705SXin Li }
208*67e74705SXin Li 
209*67e74705SXin Li }  // Test9
210*67e74705SXin Li 
211*67e74705SXin Li namespace Test10 {
212*67e74705SXin Li 
213*67e74705SXin Li // because A's key function is defined here, vtable is generated in this TU
214*67e74705SXin Li // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
215*67e74705SXin Li struct A {
216*67e74705SXin Li   virtual void foo();
217*67e74705SXin Li   virtual void bar();
218*67e74705SXin Li };
foo()219*67e74705SXin Li void A::foo() {}
220*67e74705SXin Li 
221*67e74705SXin Li // Because key function is inline we will generate vtable as linkonce_odr.
222*67e74705SXin Li // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
223*67e74705SXin Li struct D : A {
224*67e74705SXin Li   void bar();
225*67e74705SXin Li };
bar()226*67e74705SXin Li inline void D::bar() {}
227*67e74705SXin Li 
228*67e74705SXin Li // Because B has outline all virtual functions, we can refer to them.
229*67e74705SXin Li // CHECK-TEST10-DAG: @_ZTVN6Test101BE = available_externally unnamed_addr constant
230*67e74705SXin Li struct B : A {
231*67e74705SXin Li   void foo();
232*67e74705SXin Li   void bar();
233*67e74705SXin Li };
234*67e74705SXin Li 
235*67e74705SXin Li // C's key function (car) is outline, but C has inline virtual function so we
236*67e74705SXin Li // can't guarantee that we will be able to refer to bar from name
237*67e74705SXin Li // so (at the moment) we can't emit vtable available_externally.
238*67e74705SXin Li // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
239*67e74705SXin Li struct C : A {
barTest10::C240*67e74705SXin Li   void bar() {}               // defined in body - not key function
241*67e74705SXin Li   virtual inline void gar();  // inline in body - not key function
242*67e74705SXin Li   virtual void car();
243*67e74705SXin Li };
244*67e74705SXin Li 
245*67e74705SXin Li // no key function, vtable will be generated everywhere it will be used
246*67e74705SXin Li // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
247*67e74705SXin Li struct E : A {};
248*67e74705SXin Li 
g(A & a)249*67e74705SXin Li void g(A& a) {
250*67e74705SXin Li   a.foo();
251*67e74705SXin Li   a.bar();
252*67e74705SXin Li }
253*67e74705SXin Li 
f()254*67e74705SXin Li void f() {
255*67e74705SXin Li   A a;
256*67e74705SXin Li   g(a);
257*67e74705SXin Li   B b;
258*67e74705SXin Li   g(b);
259*67e74705SXin Li   C c;
260*67e74705SXin Li   g(c);
261*67e74705SXin Li   D d;
262*67e74705SXin Li   g(d);
263*67e74705SXin Li   E e;
264*67e74705SXin Li   g(e);
265*67e74705SXin Li }
266*67e74705SXin Li 
267*67e74705SXin Li }  // Test10
268*67e74705SXin Li 
269*67e74705SXin Li namespace Test11 {
270*67e74705SXin Li struct D;
271*67e74705SXin Li // Can emit C's vtable available_externally.
272*67e74705SXin Li // CHECK-TEST11: @_ZTVN6Test111CE = available_externally unnamed_addr constant
273*67e74705SXin Li struct C {
274*67e74705SXin Li   virtual D& operator=(const D&);
275*67e74705SXin Li };
276*67e74705SXin Li 
277*67e74705SXin Li // Cannot emit B's vtable available_externally, because we cannot create
278*67e74705SXin Li // a reference to the inline virtual B::operator= function.
279*67e74705SXin Li // CHECK-TEST11: @_ZTVN6Test111DE = external unnamed_addr constant
280*67e74705SXin Li struct D : C {
281*67e74705SXin Li   virtual void key();
282*67e74705SXin Li };
283*67e74705SXin Li D f();
284*67e74705SXin Li 
g(D & a)285*67e74705SXin Li void g(D& a) {
286*67e74705SXin Li   C c;
287*67e74705SXin Li   c = a;
288*67e74705SXin Li   a.key();
289*67e74705SXin Li   a.key();
290*67e74705SXin Li }
g()291*67e74705SXin Li void g() {
292*67e74705SXin Li   D d;
293*67e74705SXin Li   d = f();
294*67e74705SXin Li   g(d);
295*67e74705SXin Li }
296*67e74705SXin Li }  // Test 11
297*67e74705SXin Li 
298*67e74705SXin Li namespace Test12 {
299*67e74705SXin Li 
300*67e74705SXin Li // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
301*67e74705SXin Li struct A {
302*67e74705SXin Li   virtual void foo();
~ATest12::A303*67e74705SXin Li   virtual ~A() {}
304*67e74705SXin Li };
305*67e74705SXin Li // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
306*67e74705SXin Li struct B : A {
307*67e74705SXin Li   void foo();
308*67e74705SXin Li };
309*67e74705SXin Li 
g()310*67e74705SXin Li void g() {
311*67e74705SXin Li   A a;
312*67e74705SXin Li   a.foo();
313*67e74705SXin Li   B b;
314*67e74705SXin Li   b.foo();
315*67e74705SXin Li }
316*67e74705SXin Li }
317*67e74705SXin Li 
318*67e74705SXin Li namespace Test13 {
319*67e74705SXin Li 
320*67e74705SXin Li // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
321*67e74705SXin Li // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
322*67e74705SXin Li struct A {
323*67e74705SXin Li   virtual ~A();
324*67e74705SXin Li };
325*67e74705SXin Li struct B : A {
326*67e74705SXin Li   virtual void f();
327*67e74705SXin Li   void operator delete(void *);
~BTest13::B328*67e74705SXin Li   ~B() {}
329*67e74705SXin Li };
330*67e74705SXin Li 
g()331*67e74705SXin Li void g() {
332*67e74705SXin Li   A *b = new B;
333*67e74705SXin Li }
334*67e74705SXin Li }
335*67e74705SXin Li 
336*67e74705SXin Li namespace Test14 {
337*67e74705SXin Li 
338*67e74705SXin Li // CHECK-TEST14: @_ZTVN6Test141AE = available_externally unnamed_addr constant
339*67e74705SXin Li struct A {
340*67e74705SXin Li   virtual void f();
341*67e74705SXin Li   void operator delete(void *);
342*67e74705SXin Li   ~A();
343*67e74705SXin Li };
344*67e74705SXin Li 
g()345*67e74705SXin Li void g() {
346*67e74705SXin Li   A *b = new A;
347*67e74705SXin Li   delete b;
348*67e74705SXin Li }
349*67e74705SXin Li }
350*67e74705SXin Li 
351*67e74705SXin Li namespace Test15 {
352*67e74705SXin Li // In this test D's vtable has two slots for function f(), but uses only one,
353*67e74705SXin Li // so the second slot is set to null.
354*67e74705SXin Li // CHECK-TEST15: @_ZTVN6Test151DE = available_externally unnamed_addr constant
fTest15::A355*67e74705SXin Li struct A { virtual void f() {} };
356*67e74705SXin Li struct B : virtual A {};
357*67e74705SXin Li struct C : virtual A {};
358*67e74705SXin Li struct D : B, C {
359*67e74705SXin Li   virtual void g();
360*67e74705SXin Li   void f();
361*67e74705SXin Li };
362*67e74705SXin Li 
test()363*67e74705SXin Li void test() {
364*67e74705SXin Li   D * d = new D;
365*67e74705SXin Li   d->f();
366*67e74705SXin Li }
367*67e74705SXin Li }
368*67e74705SXin Li 
369*67e74705SXin Li namespace Test16 {
370*67e74705SXin Li // S has virtual method that is hidden, because of it we can't
371*67e74705SXin Li // generate available_externally vtable for it.
372*67e74705SXin Li // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
373*67e74705SXin Li // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
374*67e74705SXin Li 
375*67e74705SXin Li struct S {
376*67e74705SXin Li   __attribute__((visibility("hidden"))) virtual void doStuff();
377*67e74705SXin Li };
378*67e74705SXin Li 
379*67e74705SXin Li struct S2 {
380*67e74705SXin Li   virtual void doStuff();
381*67e74705SXin Li   __attribute__((visibility("hidden"))) void unused();
382*67e74705SXin Li 
383*67e74705SXin Li };
384*67e74705SXin Li 
test()385*67e74705SXin Li void test() {
386*67e74705SXin Li   S *s = new S;
387*67e74705SXin Li   s->doStuff();
388*67e74705SXin Li 
389*67e74705SXin Li   S2 *s2 = new S2;
390*67e74705SXin Li   s2->doStuff();
391*67e74705SXin Li }
392*67e74705SXin Li }
393*67e74705SXin Li 
394