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