xref: /aosp_15_r20/external/clang/test/CodeGenCXX/vtable-key-function-arm.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
3*67e74705SXin Li 
4*67e74705SXin Li // The 'a' variants ask for the vtable first.
5*67e74705SXin Li // The 'b' variants ask for the vtable second.
6*67e74705SXin Li // The 'c' variants ask for the vtable third.
7*67e74705SXin Li // We do a separate CHECK-LATE pass because the RTTI definition gets
8*67e74705SXin Li // changed after the fact, which causes reordering of the globals.
9*67e74705SXin Li 
10*67e74705SXin Li // These are not separated into namespaces because the way that Sema
11*67e74705SXin Li // currently reports namespaces to IR-generation (i.e., en masse for
12*67e74705SXin Li // the entire namespace at once) subverts the ordering that we're
13*67e74705SXin Li // trying to test.
14*67e74705SXin Li 
15*67e74705SXin Li namespace std { class type_info; }
16*67e74705SXin Li extern void use(const std::type_info &rtti);
17*67e74705SXin Li 
18*67e74705SXin Li /*** Test0a ******************************************************************/
19*67e74705SXin Li 
20*67e74705SXin Li struct Test0a {
21*67e74705SXin Li   Test0a();
22*67e74705SXin Li   virtual inline void foo();
23*67e74705SXin Li   virtual void bar();
24*67e74705SXin Li };
25*67e74705SXin Li 
26*67e74705SXin Li // V-table should be defined externally.
Test0a()27*67e74705SXin Li Test0a::Test0a() { use(typeid(Test0a)); }
28*67e74705SXin Li // CHECK: @_ZTV6Test0a = external unnamed_addr constant
29*67e74705SXin Li // CHECK: @_ZTI6Test0a = external constant
30*67e74705SXin Li 
31*67e74705SXin Li // This is still not a key function.
foo()32*67e74705SXin Li void Test0a::foo() {}
33*67e74705SXin Li 
34*67e74705SXin Li /*** Test0b ******************************************************************/
35*67e74705SXin Li 
36*67e74705SXin Li struct Test0b {
37*67e74705SXin Li   Test0b();
38*67e74705SXin Li   virtual inline void foo();
39*67e74705SXin Li   virtual void bar();
40*67e74705SXin Li };
41*67e74705SXin Li 
42*67e74705SXin Li // This is still not a key function.
foo()43*67e74705SXin Li void Test0b::foo() {}
44*67e74705SXin Li 
45*67e74705SXin Li // V-table should be defined externally.
Test0b()46*67e74705SXin Li Test0b::Test0b() { use(typeid(Test0b)); }
47*67e74705SXin Li // CHECK: @_ZTV6Test0b = external unnamed_addr constant
48*67e74705SXin Li // CHECK: @_ZTI6Test0b = external constant
49*67e74705SXin Li 
50*67e74705SXin Li /*** Test1a ******************************************************************/
51*67e74705SXin Li 
52*67e74705SXin Li struct Test1a {
53*67e74705SXin Li   Test1a();
54*67e74705SXin Li   virtual void foo();
55*67e74705SXin Li   virtual void bar();
56*67e74705SXin Li };
57*67e74705SXin Li 
58*67e74705SXin Li // V-table should be defined externally.
Test1a()59*67e74705SXin Li Test1a::Test1a() { use(typeid(Test1a)); }
60*67e74705SXin Li // CHECK: @_ZTV6Test1a = external unnamed_addr constant
61*67e74705SXin Li // CHECK: @_ZTI6Test1a = external constant
62*67e74705SXin Li 
63*67e74705SXin Li // 'bar' becomes the key function when 'foo' is defined inline.
foo()64*67e74705SXin Li inline void Test1a::foo() {}
65*67e74705SXin Li 
66*67e74705SXin Li /*** Test1b ******************************************************************/
67*67e74705SXin Li 
68*67e74705SXin Li struct Test1b {
69*67e74705SXin Li   Test1b();
70*67e74705SXin Li   virtual void foo();
71*67e74705SXin Li   virtual void bar();
72*67e74705SXin Li };
73*67e74705SXin Li 
74*67e74705SXin Li // 'bar' becomes the key function when 'foo' is defined inline.
foo()75*67e74705SXin Li inline void Test1b::foo() {}
76*67e74705SXin Li 
77*67e74705SXin Li // V-table should be defined externally.
Test1b()78*67e74705SXin Li Test1b::Test1b() { use(typeid(Test1b)); }
79*67e74705SXin Li // CHECK: @_ZTV6Test1b = external unnamed_addr constant
80*67e74705SXin Li // CHECK: @_ZTI6Test1b = external constant
81*67e74705SXin Li 
82*67e74705SXin Li /*** Test2a ******************************************************************/
83*67e74705SXin Li 
84*67e74705SXin Li struct Test2a {
85*67e74705SXin Li   Test2a();
86*67e74705SXin Li   virtual void foo();
87*67e74705SXin Li   virtual void bar();
88*67e74705SXin Li };
89*67e74705SXin Li 
90*67e74705SXin Li // V-table should be defined with strong linkage.
Test2a()91*67e74705SXin Li Test2a::Test2a() { use(typeid(Test2a)); }
92*67e74705SXin Li // CHECK:      @_ZTV6Test2a = unnamed_addr constant
93*67e74705SXin Li // CHECK-LATE: @_ZTS6Test2a = constant
94*67e74705SXin Li // CHECK-LATE: @_ZTI6Test2a = constant
95*67e74705SXin Li 
96*67e74705SXin Li // 'bar' becomes the key function when 'foo' is defined inline.
bar()97*67e74705SXin Li void Test2a::bar() {}
foo()98*67e74705SXin Li inline void Test2a::foo() {}
99*67e74705SXin Li 
100*67e74705SXin Li /*** Test2b ******************************************************************/
101*67e74705SXin Li 
102*67e74705SXin Li struct Test2b {
103*67e74705SXin Li   Test2b();
104*67e74705SXin Li   virtual void foo();
105*67e74705SXin Li   virtual void bar();
106*67e74705SXin Li };
107*67e74705SXin Li 
108*67e74705SXin Li // 'bar' becomes the key function when 'foo' is defined inline.
bar()109*67e74705SXin Li void Test2b::bar() {}
110*67e74705SXin Li 
111*67e74705SXin Li // V-table should be defined with strong linkage.
Test2b()112*67e74705SXin Li Test2b::Test2b() { use(typeid(Test2b)); }
113*67e74705SXin Li // CHECK:      @_ZTV6Test2b = unnamed_addr constant
114*67e74705SXin Li // CHECK-LATE: @_ZTS6Test2b = constant
115*67e74705SXin Li // CHECK-LATE: @_ZTI6Test2b = constant
116*67e74705SXin Li 
foo()117*67e74705SXin Li inline void Test2b::foo() {}
118*67e74705SXin Li 
119*67e74705SXin Li /*** Test2c ******************************************************************/
120*67e74705SXin Li 
121*67e74705SXin Li struct Test2c {
122*67e74705SXin Li   Test2c();
123*67e74705SXin Li   virtual void foo();
124*67e74705SXin Li   virtual void bar();
125*67e74705SXin Li };
126*67e74705SXin Li 
127*67e74705SXin Li // 'bar' becomes the key function when 'foo' is defined inline.
bar()128*67e74705SXin Li void Test2c::bar() {}
foo()129*67e74705SXin Li inline void Test2c::foo() {}
130*67e74705SXin Li 
131*67e74705SXin Li // V-table should be defined with strong linkage.
Test2c()132*67e74705SXin Li Test2c::Test2c() { use(typeid(Test2c)); }
133*67e74705SXin Li // CHECK: @_ZTV6Test2c = unnamed_addr constant
134*67e74705SXin Li // CHECK: @_ZTS6Test2c = constant
135*67e74705SXin Li // CHECK: @_ZTI6Test2c = constant
136*67e74705SXin Li 
137*67e74705SXin Li /*** Test3a ******************************************************************/
138*67e74705SXin Li 
139*67e74705SXin Li struct Test3a {
140*67e74705SXin Li   Test3a();
141*67e74705SXin Li   virtual void foo();
142*67e74705SXin Li   virtual void bar();
143*67e74705SXin Li };
144*67e74705SXin Li 
145*67e74705SXin Li // V-table should be defined with weak linkage.
Test3a()146*67e74705SXin Li Test3a::Test3a() { use(typeid(Test3a)); }
147*67e74705SXin Li // CHECK:      @_ZTV6Test3a = linkonce_odr unnamed_addr constant
148*67e74705SXin Li // CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant
149*67e74705SXin Li // CHECK-LATE: @_ZTI6Test3a = linkonce_odr constant
150*67e74705SXin Li 
151*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()152*67e74705SXin Li inline void Test3a::bar() {}
foo()153*67e74705SXin Li inline void Test3a::foo() {}
154*67e74705SXin Li 
155*67e74705SXin Li /*** Test3b ******************************************************************/
156*67e74705SXin Li 
157*67e74705SXin Li struct Test3b {
158*67e74705SXin Li   Test3b();
159*67e74705SXin Li   virtual void foo();
160*67e74705SXin Li   virtual void bar();
161*67e74705SXin Li };
162*67e74705SXin Li 
163*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()164*67e74705SXin Li inline void Test3b::bar() {}
165*67e74705SXin Li 
166*67e74705SXin Li // V-table should be defined with weak linkage.
Test3b()167*67e74705SXin Li Test3b::Test3b() { use(typeid(Test3b)); }
168*67e74705SXin Li // CHECK:      @_ZTV6Test3b = linkonce_odr unnamed_addr constant
169*67e74705SXin Li // CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant
170*67e74705SXin Li // CHECK-LATE: @_ZTI6Test3b = linkonce_odr constant
171*67e74705SXin Li 
foo()172*67e74705SXin Li inline void Test3b::foo() {}
173*67e74705SXin Li 
174*67e74705SXin Li /*** Test3c ******************************************************************/
175*67e74705SXin Li 
176*67e74705SXin Li struct Test3c {
177*67e74705SXin Li   Test3c();
178*67e74705SXin Li   virtual void foo();
179*67e74705SXin Li   virtual void bar();
180*67e74705SXin Li };
181*67e74705SXin Li 
182*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()183*67e74705SXin Li inline void Test3c::bar() {}
foo()184*67e74705SXin Li inline void Test3c::foo() {}
185*67e74705SXin Li 
186*67e74705SXin Li // V-table should be defined with weak linkage.
Test3c()187*67e74705SXin Li Test3c::Test3c() { use(typeid(Test3c)); }
188*67e74705SXin Li // CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant
189*67e74705SXin Li // CHECK: @_ZTS6Test3c = linkonce_odr constant
190*67e74705SXin Li // CHECK: @_ZTI6Test3c = linkonce_odr constant
191*67e74705SXin Li 
192*67e74705SXin Li /*** Test4a ******************************************************************/
193*67e74705SXin Li 
194*67e74705SXin Li template <class T> struct Test4a {
195*67e74705SXin Li   Test4a();
196*67e74705SXin Li   virtual void foo();
197*67e74705SXin Li   virtual void bar();
198*67e74705SXin Li };
199*67e74705SXin Li 
200*67e74705SXin Li // V-table should be defined with weak linkage.
Test4a()201*67e74705SXin Li template <> Test4a<int>::Test4a() { use(typeid(Test4a)); }
202*67e74705SXin Li // CHECK: @_ZTV6Test4aIiE = linkonce_odr unnamed_addr constant
203*67e74705SXin Li // CHECK: @_ZTS6Test4aIiE = linkonce_odr constant
204*67e74705SXin Li // CHECK: @_ZTI6Test4aIiE = linkonce_odr constant
205*67e74705SXin Li 
206*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()207*67e74705SXin Li template <> inline void Test4a<int>::bar() {}
foo()208*67e74705SXin Li template <> inline void Test4a<int>::foo() {}
209*67e74705SXin Li 
210*67e74705SXin Li /*** Test4b ******************************************************************/
211*67e74705SXin Li 
212*67e74705SXin Li template <class T> struct Test4b {
213*67e74705SXin Li   Test4b();
214*67e74705SXin Li   virtual void foo();
215*67e74705SXin Li   virtual void bar();
216*67e74705SXin Li };
217*67e74705SXin Li 
218*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()219*67e74705SXin Li template <> inline void Test4b<int>::bar() {}
220*67e74705SXin Li 
221*67e74705SXin Li // V-table should be defined with weak linkage.
Test4b()222*67e74705SXin Li template <> Test4b<int>::Test4b() { use(typeid(Test4b)); }
223*67e74705SXin Li // CHECK: @_ZTV6Test4bIiE = linkonce_odr unnamed_addr constant
224*67e74705SXin Li // CHECK: @_ZTS6Test4bIiE = linkonce_odr constant
225*67e74705SXin Li // CHECK: @_ZTI6Test4bIiE = linkonce_odr constant
226*67e74705SXin Li 
foo()227*67e74705SXin Li template <> inline void Test4b<int>::foo() {}
228*67e74705SXin Li 
229*67e74705SXin Li /*** Test4c ******************************************************************/
230*67e74705SXin Li 
231*67e74705SXin Li template <class T> struct Test4c {
232*67e74705SXin Li   Test4c();
233*67e74705SXin Li   virtual void foo();
234*67e74705SXin Li   virtual void bar();
235*67e74705SXin Li };
236*67e74705SXin Li 
237*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()238*67e74705SXin Li template <> inline void Test4c<int>::bar() {}
foo()239*67e74705SXin Li template <> inline void Test4c<int>::foo() {}
240*67e74705SXin Li 
241*67e74705SXin Li // V-table should be defined with weak linkage.
Test4c()242*67e74705SXin Li template <> Test4c<int>::Test4c() { use(typeid(Test4c)); }
243*67e74705SXin Li // CHECK: @_ZTV6Test4cIiE = linkonce_odr unnamed_addr constant
244*67e74705SXin Li // CHECK: @_ZTS6Test4cIiE = linkonce_odr constant
245*67e74705SXin Li // CHECK: @_ZTI6Test4cIiE = linkonce_odr constant
246*67e74705SXin Li 
247*67e74705SXin Li /*** Test5a ******************************************************************/
248*67e74705SXin Li 
249*67e74705SXin Li template <class T> struct Test5a {
250*67e74705SXin Li   Test5a();
251*67e74705SXin Li   virtual void foo();
252*67e74705SXin Li   virtual void bar();
253*67e74705SXin Li };
254*67e74705SXin Li 
255*67e74705SXin Li template <> inline void Test5a<int>::bar();
256*67e74705SXin Li template <> inline void Test5a<int>::foo();
257*67e74705SXin Li 
258*67e74705SXin Li // V-table should be defined with weak linkage.
Test5a()259*67e74705SXin Li template <> Test5a<int>::Test5a() { use(typeid(Test5a)); }
260*67e74705SXin Li // CHECK: @_ZTV6Test5aIiE = linkonce_odr unnamed_addr constant
261*67e74705SXin Li // CHECK: @_ZTS6Test5aIiE = linkonce_odr constant
262*67e74705SXin Li // CHECK: @_ZTI6Test5aIiE = linkonce_odr constant
263*67e74705SXin Li 
264*67e74705SXin Li // There ceases to be a key function after these declarations.
bar()265*67e74705SXin Li template <> inline void Test5a<int>::bar() {}
foo()266*67e74705SXin Li template <> inline void Test5a<int>::foo() {}
267*67e74705SXin Li 
268*67e74705SXin Li /*** Test5b ******************************************************************/
269*67e74705SXin Li 
270*67e74705SXin Li template <class T> struct Test5b {
271*67e74705SXin Li   Test5b();
272*67e74705SXin Li   virtual void foo();
273*67e74705SXin Li   virtual void bar();
274*67e74705SXin Li };
275*67e74705SXin Li 
276*67e74705SXin Li // There ceases to be a key function after these declarations.
277*67e74705SXin Li template <> inline void Test5a<int>::bar();
bar()278*67e74705SXin Li template <> inline void Test5b<int>::bar() {}
279*67e74705SXin Li 
280*67e74705SXin Li // V-table should be defined with weak linkage.
Test5b()281*67e74705SXin Li template <> Test5b<int>::Test5b() { use(typeid(Test5b)); }
282*67e74705SXin Li // CHECK: @_ZTV6Test5bIiE = linkonce_odr unnamed_addr constant
283*67e74705SXin Li // CHECK: @_ZTS6Test5bIiE = linkonce_odr constant
284*67e74705SXin Li // CHECK: @_ZTI6Test5bIiE = linkonce_odr constant
285*67e74705SXin Li 
286*67e74705SXin Li template <> inline void Test5a<int>::foo();
foo()287*67e74705SXin Li template <> inline void Test5b<int>::foo() {}
288*67e74705SXin Li 
289*67e74705SXin Li /*** Test5c ******************************************************************/
290*67e74705SXin Li 
291*67e74705SXin Li template <class T> struct Test5c {
292*67e74705SXin Li   Test5c();
293*67e74705SXin Li   virtual void foo();
294*67e74705SXin Li   virtual void bar();
295*67e74705SXin Li };
296*67e74705SXin Li 
297*67e74705SXin Li // There ceases to be a key function after these declarations.
298*67e74705SXin Li template <> inline void Test5a<int>::bar();
299*67e74705SXin Li template <> inline void Test5a<int>::foo();
bar()300*67e74705SXin Li template <> inline void Test5c<int>::bar() {}
foo()301*67e74705SXin Li template <> inline void Test5c<int>::foo() {}
302*67e74705SXin Li 
303*67e74705SXin Li // V-table should be defined with weak linkage.
Test5c()304*67e74705SXin Li template <> Test5c<int>::Test5c() { use(typeid(Test5c)); }
305*67e74705SXin Li // CHECK: @_ZTV6Test5cIiE = linkonce_odr unnamed_addr constant
306*67e74705SXin Li // CHECK: @_ZTS6Test5cIiE = linkonce_odr constant
307*67e74705SXin Li // CHECK: @_ZTI6Test5cIiE = linkonce_odr constant
308