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