xref: /aosp_15_r20/external/clang/test/CodeGenCXX/microsoft-abi-vbtables.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li // See microsoft-abi-structors.cpp for constructor codegen tests.
4*67e74705SXin Li 
5*67e74705SXin Li namespace Test1 {
6*67e74705SXin Li // Classic diamond, fully virtual.
7*67e74705SXin Li struct A { int a; };
8*67e74705SXin Li struct B : virtual A { int b; };
9*67e74705SXin Li struct C : virtual A { int c; };
10*67e74705SXin Li struct D : virtual B, virtual C { int d; };
11*67e74705SXin Li D d; // Force vbtable emission.
12*67e74705SXin Li 
13*67e74705SXin Li // Layout should be:
14*67e74705SXin Li // D: vbptr D
15*67e74705SXin Li //    int d
16*67e74705SXin Li // A: int a
17*67e74705SXin Li // B: vbptr B
18*67e74705SXin Li //    int b
19*67e74705SXin Li // C: vbptr C
20*67e74705SXin Li //    int c
21*67e74705SXin Li 
22*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test1@@7B01@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 8, i32 12, i32 20]
23*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test1@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
24*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test1@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -12]
25*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
26*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
27*67e74705SXin Li }
28*67e74705SXin Li 
29*67e74705SXin Li namespace Test2 {
30*67e74705SXin Li // Classic diamond, only A is virtual.
31*67e74705SXin Li struct A { int a; };
32*67e74705SXin Li struct B : virtual A { int b; };
33*67e74705SXin Li struct C : virtual A { int c; };
34*67e74705SXin Li struct D : B, C { int d; };
35*67e74705SXin Li D d; // Force vbtable emission.
36*67e74705SXin Li 
37*67e74705SXin Li // Layout should be:
38*67e74705SXin Li // B: vbptr B
39*67e74705SXin Li //    int b
40*67e74705SXin Li // C: vbptr C
41*67e74705SXin Li //    int c
42*67e74705SXin Li // D: int d
43*67e74705SXin Li // A: int a
44*67e74705SXin Li 
45*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test2@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]
46*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test2@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 12]
47*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
48*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
49*67e74705SXin Li }
50*67e74705SXin Li 
51*67e74705SXin Li namespace Test3 {
52*67e74705SXin Li struct A { int a; };
53*67e74705SXin Li struct B { int b; };
54*67e74705SXin Li struct C : virtual A, virtual B { int c; };
55*67e74705SXin Li C c;
56*67e74705SXin Li 
57*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test3@@7B@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li namespace Test4 {
61*67e74705SXin Li // Test reusing a vbptr from a non-virtual base.
62*67e74705SXin Li struct A { int a; };
63*67e74705SXin Li struct B : virtual A { int b; };
64*67e74705SXin Li struct C : B, virtual A { int c; };
65*67e74705SXin Li C c; // Force vbtable emission.
66*67e74705SXin Li 
67*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
68*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
69*67e74705SXin Li }
70*67e74705SXin Li 
71*67e74705SXin Li namespace Test5 {
72*67e74705SXin Li // Test multiple base subobjects of the same type when that type has a virtual
73*67e74705SXin Li // base.
74*67e74705SXin Li struct A { int a; };
75*67e74705SXin Li struct B : virtual A { int b; };
76*67e74705SXin Li struct C : B { int c; };
77*67e74705SXin Li struct D : B, C { int d; };
78*67e74705SXin Li D d; // Force vbtable emission.
79*67e74705SXin Li 
80*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test5@@7BB@1@@"
81*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test5@@7BC@1@@"
82*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test5@@7B@"
83*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test5@@7B@"
84*67e74705SXin Li }
85*67e74705SXin Li 
86*67e74705SXin Li namespace Test6 {
87*67e74705SXin Li // Test that we skip unneeded base path component names.
88*67e74705SXin Li struct A { int a; };
89*67e74705SXin Li struct B : virtual A { int b; };
90*67e74705SXin Li struct C : B { int c; };
91*67e74705SXin Li struct D : B, C { int d; };
92*67e74705SXin Li struct E : D { int e; };
93*67e74705SXin Li struct F : E, B, C { int f; };
94*67e74705SXin Li struct G : F, virtual E { int g; };
95*67e74705SXin Li G g;
96*67e74705SXin Li 
97*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test6@@7BB@1@E@1@F@1@@" =
98*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test6@@7BC@1@E@1@F@1@@" =
99*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test6@@7BB@1@F@1@@" =
100*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test6@@7BC@1@F@1@@" =
101*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test6@@7BB@1@E@1@@" =
102*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test6@@7BC@1@E@1@@" =
103*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test6@@7BB@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 52]
104*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test6@@7BC@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 44]
105*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]
106*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]
107*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
108*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
109*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 28]
110*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]
111*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]
112*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]
113*67e74705SXin Li }
114*67e74705SXin Li 
115*67e74705SXin Li namespace Test7 {
116*67e74705SXin Li // Test a non-virtual base which reuses the vbptr of another base.
117*67e74705SXin Li struct A { int a; };
118*67e74705SXin Li struct B { int b; };
119*67e74705SXin Li struct C { int c; };
120*67e74705SXin Li struct D : virtual A { int d; };
121*67e74705SXin Li struct E : B, D, virtual A, virtual C { int e; };
122*67e74705SXin Li E o;
123*67e74705SXin Li 
124*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test7@@7B@" = {{.*}} [3 x i32] [i32 0, i32 12, i32 16]
125*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test7@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
126*67e74705SXin Li }
127*67e74705SXin Li 
128*67e74705SXin Li namespace Test8 {
129*67e74705SXin Li // Test a virtual base which reuses the vbptr of another base.
130*67e74705SXin Li struct A { int a; };
131*67e74705SXin Li struct B : virtual A { int b; };
132*67e74705SXin Li struct C : B { int c; };
133*67e74705SXin Li struct D : virtual C { int d; };
134*67e74705SXin Li D o;
135*67e74705SXin Li 
136*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test8@@7B01@@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
137*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test8@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
138*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
139*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
140*67e74705SXin Li }
141*67e74705SXin Li 
142*67e74705SXin Li namespace Test9 {
143*67e74705SXin Li // D has to add to B's vbtable because D has more morally virtual bases than B.
144*67e74705SXin Li // D then takes B's vbptr and the vbtable is named for D, not B.
145*67e74705SXin Li struct A { int a; };
146*67e74705SXin Li struct B : virtual A { int b; };
147*67e74705SXin Li struct C : virtual B { int c; };
148*67e74705SXin Li struct BB : B { int bb; };  // Indirection =/
149*67e74705SXin Li struct D : BB, C { int d; };
150*67e74705SXin Li struct E : virtual D { };
151*67e74705SXin Li E e;
152*67e74705SXin Li 
153*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test9@@7B01@@" =
154*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test9@@7BD@1@@" =
155*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test9@@7BC@1@@" =
156*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test9@@7BB@1@@" =
157*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test9@@7B@" =
158*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test9@@7BC@1@@" =
159*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test9@@7BB@1@@" =
160*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test9@@7B01@@" =
161*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test9@@7BB@1@@" =
162*67e74705SXin Li // CHECK-DAG: @"\01??_8BB@Test9@@7B@" =
163*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test9@@7B@" =
164*67e74705SXin Li }
165*67e74705SXin Li 
166*67e74705SXin Li namespace Test10 {
167*67e74705SXin Li struct A { int a; };
168*67e74705SXin Li struct B { int b; };
169*67e74705SXin Li struct C : virtual A { int c; };
170*67e74705SXin Li struct D : B, C { int d; };
171*67e74705SXin Li D d;
172*67e74705SXin Li 
173*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test10@@7B@" =
174*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test10@@7B@" =
175*67e74705SXin Li 
176*67e74705SXin Li }
177*67e74705SXin Li 
178*67e74705SXin Li namespace Test11 {
179*67e74705SXin Li // Typical diamond with an extra single inheritance indirection for B and C.
180*67e74705SXin Li struct A { int a; };
181*67e74705SXin Li struct B : virtual A { int b; };
182*67e74705SXin Li struct C : virtual A { int c; };
183*67e74705SXin Li struct D : B { int d; };
184*67e74705SXin Li struct E : C { int e; };
185*67e74705SXin Li struct F : D, E { int f; };
186*67e74705SXin Li F f;
187*67e74705SXin Li 
188*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test11@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 28]
189*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test11@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]
190*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]
191*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
192*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]
193*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
194*67e74705SXin Li 
195*67e74705SXin Li }
196*67e74705SXin Li 
197*67e74705SXin Li namespace Test12 {
198*67e74705SXin Li // Another vbptr inside a virtual base.
199*67e74705SXin Li struct A { int a; };
200*67e74705SXin Li struct B : virtual A { int b; };
201*67e74705SXin Li struct C : virtual B { int c; };
202*67e74705SXin Li struct D : C, B { int d; };
203*67e74705SXin Li struct E : D, C, B { int e; };
204*67e74705SXin Li E e;
205*67e74705SXin Li 
206*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test12@@7BC@1@D@1@@" =
207*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test12@@7BB@1@D@1@@" =
208*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test12@@7BD@1@@" =
209*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test12@@7BC@1@@" =
210*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test12@@7BB@1@@" =
211*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test12@@7B01@@" =
212*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test12@@7BB@1@@" =
213*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test12@@7BC@1@@" =
214*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test12@@7BB@1@@" =
215*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test12@@7B@" =
216*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test12@@7B@" =
217*67e74705SXin Li }
218*67e74705SXin Li 
219*67e74705SXin Li namespace Test13 {
220*67e74705SXin Li struct A { int a; };
221*67e74705SXin Li struct B : virtual A { int b; };
222*67e74705SXin Li struct C : virtual B { int c; };
223*67e74705SXin Li struct D : virtual C { int d; };
224*67e74705SXin Li struct E : D, C, B { int e; };
225*67e74705SXin Li E e;
226*67e74705SXin Li 
227*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test13@@7BD@1@@" =
228*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test13@@7BC@1@D@1@@" =
229*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test13@@7BB@1@D@1@@" =
230*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test13@@7BC@1@@" =
231*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test13@@7BB@1@@" =
232*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test13@@7B@" =
233*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test13@@7BC@1@@" =
234*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test13@@7BB@1@@" =
235*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test13@@7B01@@" =
236*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test13@@7BB@1@@" =
237*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test13@@7B@" =
238*67e74705SXin Li }
239*67e74705SXin Li 
240*67e74705SXin Li namespace Test14 {
241*67e74705SXin Li struct A { int a; };
242*67e74705SXin Li struct B : virtual A { int b; };
243*67e74705SXin Li struct C : virtual B { int c; };
244*67e74705SXin Li struct D : virtual C { int d; };
245*67e74705SXin Li struct E : D, virtual C, virtual B { int e; };
246*67e74705SXin Li E e;
247*67e74705SXin Li 
248*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test14@@7B@" =
249*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test14@@7BC@1@@" =
250*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test14@@7BB@1@@" =
251*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test14@@7B@" =
252*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test14@@7BC@1@@" =
253*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test14@@7BB@1@@" =
254*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test14@@7B01@@" =
255*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test14@@7BB@1@@" =
256*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test14@@7B@" =
257*67e74705SXin Li }
258*67e74705SXin Li 
259*67e74705SXin Li namespace Test15 {
260*67e74705SXin Li struct A { int a; };
261*67e74705SXin Li struct B : virtual A { int b; };
262*67e74705SXin Li struct C : virtual A { int c; };
263*67e74705SXin Li struct D : virtual B { int d; };
264*67e74705SXin Li struct E : D, C, B { int e; };
265*67e74705SXin Li E e;
266*67e74705SXin Li 
267*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test15@@7BD@1@@" =
268*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test15@@7BB@1@D@1@@" =
269*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test15@@7BC@1@@" =
270*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test15@@7BB@1@@" =
271*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test15@@7B@" =
272*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test15@@7B01@@" =
273*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test15@@7BB@1@@" =
274*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test15@@7B@" =
275*67e74705SXin Li }
276*67e74705SXin Li 
277*67e74705SXin Li namespace Test16 {
278*67e74705SXin Li struct A { int a; };
279*67e74705SXin Li struct B : virtual A { int b; };
280*67e74705SXin Li struct C : virtual B { int c; }; // ambig
281*67e74705SXin Li struct D : virtual C { int d; };
282*67e74705SXin Li struct E : virtual D { int e; }; // ambig
283*67e74705SXin Li struct F : E, D, C, B { int f; };  // ambig
284*67e74705SXin Li F f;
285*67e74705SXin Li 
286*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BE@1@@" =
287*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BD@1@E@1@@" =
288*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BC@1@E@1@@" =
289*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BB@1@E@1@@" =
290*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BD@1@@" =
291*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BC@1@@" =
292*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test16@@7BB@1@@" =
293*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test16@@7B01@@" =
294*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test16@@7BD@1@@" =
295*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test16@@7BC@1@@" =
296*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test16@@7BB@1@@" =
297*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test16@@7B@" =
298*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test16@@7BC@1@@" =
299*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test16@@7BB@1@@" =
300*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test16@@7B01@@" =
301*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test16@@7BB@1@@" =
302*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test16@@7B@" =
303*67e74705SXin Li }
304*67e74705SXin Li 
305*67e74705SXin Li namespace Test17 {
306*67e74705SXin Li // This test case has an interesting alternating pattern of using "vbtable of B"
307*67e74705SXin Li // and "vbtable of C for C".  This may be the key to the underlying algorithm.
308*67e74705SXin Li struct A { int a; };
309*67e74705SXin Li struct B : virtual A { int b; };
310*67e74705SXin Li struct C : virtual B { int c; }; // ambig
311*67e74705SXin Li struct D : virtual C { int d; };
312*67e74705SXin Li struct E : virtual D { int e; }; // ambig
313*67e74705SXin Li struct F : virtual E { int f; };
314*67e74705SXin Li struct G : virtual F { int g; }; // ambig
315*67e74705SXin Li struct H : virtual G { int h; };
316*67e74705SXin Li struct I : virtual H { int i; }; // ambig
317*67e74705SXin Li struct J : virtual I { int j; };
318*67e74705SXin Li struct K : virtual J { int k; }; // ambig
319*67e74705SXin Li K k;
320*67e74705SXin Li 
321*67e74705SXin Li // CHECK-DAG: @"\01??_8K@Test17@@7B01@@" =
322*67e74705SXin Li // CHECK-DAG: @"\01??_8J@Test17@@7B@" =
323*67e74705SXin Li // CHECK-DAG: @"\01??_8I@Test17@@7B01@@" =
324*67e74705SXin Li // CHECK-DAG: @"\01??_8H@Test17@@7B@" =
325*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test17@@7B01@@" =
326*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test17@@7B@" =
327*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test17@@7B01@@" =
328*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test17@@7B@" =
329*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test17@@7B01@@" =
330*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test17@@7B@" =
331*67e74705SXin Li }
332*67e74705SXin Li 
333*67e74705SXin Li namespace Test18 {
334*67e74705SXin Li struct A { int a; };
335*67e74705SXin Li struct B : virtual A { int b; };
336*67e74705SXin Li struct C : B { int c; };
337*67e74705SXin Li struct D : C, B { int d; };
338*67e74705SXin Li struct E : D, C, B { int e; };
339*67e74705SXin Li E e;
340*67e74705SXin Li 
341*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test18@@7BC@1@D@1@@" =
342*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test18@@7BB@1@D@1@@" =
343*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test18@@7BC@1@@" =
344*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test18@@7BB@1@@" =
345*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test18@@7B@" =
346*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test18@@7B@" =
347*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test18@@7BC@1@@" =
348*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test18@@7BB@1@@" =
349*67e74705SXin Li }
350*67e74705SXin Li 
351*67e74705SXin Li namespace Test19 {
352*67e74705SXin Li struct A { int a; };
353*67e74705SXin Li struct B : virtual A { int b; };
354*67e74705SXin Li struct C : virtual B { int c; };
355*67e74705SXin Li struct D : virtual C, virtual B { int d; };
356*67e74705SXin Li struct E : virtual D, virtual C, virtual B { int e; };
357*67e74705SXin Li E e;
358*67e74705SXin Li 
359*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test19@@7B01@@" =
360*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test19@@7BD@1@@" =
361*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test19@@7BC@1@@" =
362*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test19@@7BB@1@@" =
363*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test19@@7B@" =
364*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test19@@7BC@1@@" =
365*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test19@@7BB@1@@" =
366*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test19@@7B01@@" =
367*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test19@@7BB@1@@" =
368*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test19@@7B@" =
369*67e74705SXin Li }
370*67e74705SXin Li 
371*67e74705SXin Li namespace Test20 {
372*67e74705SXin Li // E has no direct vbases, but it adds to C's vbtable anyway.
373*67e74705SXin Li struct A { int a; };
374*67e74705SXin Li struct B { int b; };
375*67e74705SXin Li struct C : virtual A { int c; };
376*67e74705SXin Li struct D : virtual B { int d; };
377*67e74705SXin Li struct E : C, D { int e; };
378*67e74705SXin Li E f;
379*67e74705SXin Li 
380*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test20@@7BC@1@@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 20, i32 24]
381*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test20@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]
382*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
383*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
384*67e74705SXin Li }
385*67e74705SXin Li 
386*67e74705SXin Li namespace Test21 {
387*67e74705SXin Li struct A { int a; };
388*67e74705SXin Li struct B : virtual A { int b; };
389*67e74705SXin Li struct C : B { int c; };
390*67e74705SXin Li struct D : B { int d; };
391*67e74705SXin Li struct E : C, D { int e; };
392*67e74705SXin Li struct F : virtual E { int f; };
393*67e74705SXin Li struct G : E { int g; };
394*67e74705SXin Li struct H : F, G { int h; };
395*67e74705SXin Li H h;
396*67e74705SXin Li 
397*67e74705SXin Li // CHECK-DAG: @"\01??_8H@Test21@@7B@" =
398*67e74705SXin Li // CHECK-DAG: @"\01??_8H@Test21@@7BC@1@F@1@@" =
399*67e74705SXin Li // CHECK-DAG: @"\01??_8H@Test21@@7BD@1@F@1@@" =
400*67e74705SXin Li // CHECK-DAG: @"\01??_8H@Test21@@7BC@1@G@1@@" =
401*67e74705SXin Li // CHECK-DAG: @"\01??_8H@Test21@@7BD@1@G@1@@" =
402*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test21@@7BC@1@@" =
403*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test21@@7BD@1@@" =
404*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test21@@7B@" =
405*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test21@@7BC@1@@" =
406*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test21@@7BD@1@@" =
407*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test21@@7BC@1@@" =
408*67e74705SXin Li // CHECK-DAG: @"\01??_8E@Test21@@7BD@1@@" =
409*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test21@@7B@" =
410*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test21@@7B@" =
411*67e74705SXin Li // CHECK-DAG: @"\01??_8C@Test21@@7B@" =
412*67e74705SXin Li }
413*67e74705SXin Li 
414*67e74705SXin Li namespace Test22 {
415*67e74705SXin Li struct A { int a; };
416*67e74705SXin Li struct B : virtual A { int b; };
417*67e74705SXin Li struct C { int c; };
418*67e74705SXin Li struct D : B, virtual C { int d; };
419*67e74705SXin Li D d;
420*67e74705SXin Li 
421*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test22@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 12, i32 16]
422*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test22@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
423*67e74705SXin Li }
424*67e74705SXin Li 
425*67e74705SXin Li namespace Test23 {
426*67e74705SXin Li struct A { int a; };
427*67e74705SXin Li struct B : virtual A { int b; };
428*67e74705SXin Li struct C { int c; };
429*67e74705SXin Li // Note the unusual order of bases. It forces C to be laid out before A.
430*67e74705SXin Li struct D : virtual C, B { int d; };
431*67e74705SXin Li D d;
432*67e74705SXin Li 
433*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test23@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]
434*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test23@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
435*67e74705SXin Li }
436*67e74705SXin Li 
437*67e74705SXin Li namespace Test24 {
438*67e74705SXin Li struct A { int a; };
439*67e74705SXin Li struct B : virtual A { int b; };
440*67e74705SXin Li struct C { int c; };
441*67e74705SXin Li struct D : virtual C, B {
442*67e74705SXin Li   virtual void f();  // Issues a vfptr, but the vbptr is still shared with B.
443*67e74705SXin Li   int d;
444*67e74705SXin Li };
445*67e74705SXin Li D d;
446*67e74705SXin Li 
447*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test24@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]
448*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test24@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
449*67e74705SXin Li }
450*67e74705SXin Li 
451*67e74705SXin Li namespace Test25 {
452*67e74705SXin Li struct A { int a; };
453*67e74705SXin Li struct B : virtual A {
454*67e74705SXin Li   virtual void f();  // Issues a vfptr.
455*67e74705SXin Li   int b;
456*67e74705SXin Li };
457*67e74705SXin Li struct C { int c; };
458*67e74705SXin Li struct D : virtual C, B { int d; };
459*67e74705SXin Li D d;
460*67e74705SXin Li 
461*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test25@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 -4, i32 16, i32 12]
462*67e74705SXin Li // CHECK-DAG: @"\01??_8B@Test25@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 8]
463*67e74705SXin Li }
464*67e74705SXin Li 
465*67e74705SXin Li namespace Test26 {
466*67e74705SXin Li struct A { int a; };
467*67e74705SXin Li struct B { int b; };
468*67e74705SXin Li struct C { int c; };
469*67e74705SXin Li struct D : virtual A { int d; };
470*67e74705SXin Li struct E : virtual B {
471*67e74705SXin Li   virtual void foo();  // Issues a vfptr.
472*67e74705SXin Li   int e;
473*67e74705SXin Li };
474*67e74705SXin Li struct F: virtual C, D, E { int f; };
475*67e74705SXin Li F f;
476*67e74705SXin Li // F reuses the D's vbptr, even though D is laid out after E.
477*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test26@@7BD@1@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 16, i32 12, i32 20]
478*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test26@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 28]
479*67e74705SXin Li }
480*67e74705SXin Li 
481*67e74705SXin Li namespace Test27 {
482*67e74705SXin Li // PR17748
483*67e74705SXin Li struct A {};
484*67e74705SXin Li struct B : virtual A {};
485*67e74705SXin Li struct C : virtual B {};
486*67e74705SXin Li struct D : C, B {};
487*67e74705SXin Li struct E : D {};
488*67e74705SXin Li struct F : C, E {};
489*67e74705SXin Li struct G : F, D, C, B {};
490*67e74705SXin Li G x;
491*67e74705SXin Li 
492*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BB@1@@" =
493*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BB@1@F@1@@" =
494*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@@" =
495*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@D@1@@" =
496*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@E@1@@" =
497*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@F@1@@" =
498*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BD@1@@" =
499*67e74705SXin Li // CHECK-DAG: @"\01??_8G@Test27@@7BF@1@@" =
500*67e74705SXin Li }
501*67e74705SXin Li 
502*67e74705SXin Li namespace Test28 {
503*67e74705SXin Li // PR17748
504*67e74705SXin Li struct A {};
505*67e74705SXin Li struct B : virtual A {};
506*67e74705SXin Li struct C : virtual B {};
507*67e74705SXin Li struct D : C, B {};
508*67e74705SXin Li struct E : C, D {};
509*67e74705SXin Li struct F : virtual E, virtual D, virtual C {};
510*67e74705SXin Li F x;
511*67e74705SXin Li 
512*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7B01@@" =
513*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BB@1@@" =
514*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@@" =
515*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@D@1@@" =
516*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@D@1@E@1@@" =
517*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@E@1@@" =
518*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BD@1@@" =
519*67e74705SXin Li // CHECK-DAG: @"\01??_8F@Test28@@7BE@1@@" =
520*67e74705SXin Li }
521*67e74705SXin Li 
522*67e74705SXin Li namespace Test29 {
523*67e74705SXin Li struct A {};
524*67e74705SXin Li struct B : virtual A {};
525*67e74705SXin Li struct C : virtual B {};
526*67e74705SXin Li struct D : C {};
527*67e74705SXin Li D d;
528*67e74705SXin Li 
529*67e74705SXin Li // CHECK-DAG: @"\01??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer
530*67e74705SXin Li }
531*67e74705SXin Li 
532*67e74705SXin Li namespace Test30 {
533*67e74705SXin Li struct A {};
534*67e74705SXin Li template <class> struct B : virtual A {
BTest30::B535*67e74705SXin Li   B() {}
536*67e74705SXin Li };
537*67e74705SXin Li 
538*67e74705SXin Li extern template class B<int>;
539*67e74705SXin Li template B<int>::B();
540*67e74705SXin Li // CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat
541*67e74705SXin Li }
542