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