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