ms-x86-empty-virtual-base.cpp revision dc58180432868cfa9c060d5c41114634e4b841c7
1// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
2// RUN:            | FileCheck %s
3
4extern "C" int printf(const char *fmt, ...);
5
6struct __declspec(align(8)) B0 { B0() {printf("B0 : %3d\n", ((int)this)&0xfff);} };
7struct __declspec(align(8)) B1 { B1() {printf("B1 : %3d\n", ((int)this)&0xfff);} };
8struct __declspec(align(8)) B2 { B2() {printf("B2 : %3d\n", ((int)this)&0xfff);} };
9struct __declspec(align(8)) B3 { B3() {printf("B3 : %3d\n", ((int)this)&0xfff);} };
10struct __declspec(align(8)) B4 { B4() {printf("B4 : %3d\n", ((int)this)&0xfff);} };
11
12struct C0 { int a; C0() : a(0xf00000C0) {printf("C0 : %3d\n", ((int)this)&0xfff);} };
13struct C1 { int a; C1() : a(0xf00000C1) {printf("C1 : %3d\n", ((int)this)&0xfff);} };
14struct C2 { int a; C2() : a(0xf00000C2) {printf("C2 : %3d\n", ((int)this)&0xfff);} };
15struct C3 { int a; C3() : a(0xf00000C3) {printf("C3 : %3d\n", ((int)this)&0xfff);} };
16struct C4 { int a; C4() : a(0xf00000C4) {printf("C4 : %3d\n", ((int)this)&0xfff);} };
17
18struct __declspec(align(16)) D0 { D0() {printf("D0 : %3d\n", ((int)this)&0xfff);} virtual void f() {} };
19struct D1 { D1() {printf("D1 : %3d\n", ((int)this)&0xfff);} };
20struct D2 { int a[8]; D2() {printf("D2 : %3d\n", ((int)this)&0xfff);} };
21
22struct A : virtual B0 {
23	int a;
24	A() : a(0xf000000A) {printf("X : %3d\n", ((int)this)&0xfff);}
25};
26
27// CHECK: *** Dumping AST Record Layout
28// CHECK:    0 | struct A
29// CHECK:    0 |   (A vbtable pointer)
30// CHECK:    4 |   int a
31// CHECK:    8 |   struct B0 (virtual base) (empty)
32// CHECK:      | [sizeof=8, align=8
33// CHECK:      |  nvsize=8, nvalign=4]
34
35struct B : virtual B0 {
36	B0 b0;
37	int a;
38	B() : a(0xf000000B) {printf("X : %3d\n", ((int)this)&0xfff);}
39};
40
41// CHECK: *** Dumping AST Record Layout
42// CHECK:    0 | struct B
43// CHECK:    0 |   (B vbtable pointer)
44// CHECK:    8 |   struct B0 b0 (empty)
45// CHECK:      |   [sizeof=8, align=8
46// CHECK:      |    nvsize=0, nvalign=1]
47// CHECK:   16 |   int a
48// CHECK:   24 |   struct B0 (virtual base) (empty)
49// CHECK:      | [sizeof=24, align=8
50// CHECK:      |  nvsize=24, nvalign=8]
51
52struct C : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
53	int a;
54	C() : a(0xf000000C) {printf("X : %3d\n", ((int)this)&0xfff);}
55};
56
57// CHECK: *** Dumping AST Record Layout
58// CHECK:    0 | struct C
59// CHECK:    0 |   (C vbtable pointer)
60// CHECK:    4 |   int a
61// CHECK:    8 |   struct B0 (virtual base) (empty)
62// CHECK:   16 |   struct B1 (virtual base) (empty)
63// CHECK:   24 |   struct B2 (virtual base) (empty)
64// CHECK:   32 |   struct B3 (virtual base) (empty)
65// CHECK:   40 |   struct B4 (virtual base) (empty)
66// CHECK:      | [sizeof=40, align=8
67// CHECK:      |  nvsize=8, nvalign=4]
68
69struct D {
70	B0 b0;
71	C0 c0;
72	C1 c1;
73	C2 c2;
74	B1 b1;
75	int a;
76	D() : a(0xf000000D) {printf("X : %3d\n", ((int)this)&0xfff);}
77};
78
79// CHECK: *** Dumping AST Record Layout
80// CHECK:    0 | struct D
81// CHECK:    0 |   struct B0 b0 (empty)
82// CHECK:      |   [sizeof=8, align=8
83// CHECK:      |    nvsize=0, nvalign=1]
84// CHECK:    8 |   struct C0 c0
85// CHECK:    8 |     int a
86// CHECK:      |   [sizeof=4, align=4
87// CHECK:      |    nvsize=4, nvalign=4]
88// CHECK:   12 |   struct C1 c1
89// CHECK:   12 |     int a
90// CHECK:      |   [sizeof=4, align=4
91// CHECK:      |    nvsize=4, nvalign=4]
92// CHECK:   16 |   struct C2 c2
93// CHECK:   16 |     int a
94// CHECK:      |   [sizeof=4, align=4
95// CHECK:      |    nvsize=4, nvalign=4]
96// CHECK:   24 |   struct B1 b1 (empty)
97// CHECK:      |   [sizeof=8, align=8
98// CHECK:      |    nvsize=0, nvalign=1]
99// CHECK:   32 |   int a
100// CHECK:      | [sizeof=40, align=8
101// CHECK:      |  nvsize=40, nvalign=8]
102
103struct E : virtual B0, virtual C0, virtual C1, virtual C2, virtual B1 {
104	int a;
105	E() : a(0xf000000E) {printf("X : %3d\n", ((int)this)&0xfff);}
106};
107
108// CHECK: *** Dumping AST Record Layout
109// CHECK:    0 | struct E
110// CHECK:    0 |   (E vbtable pointer)
111// CHECK:    4 |   int a
112// CHECK:    8 |   struct B0 (virtual base) (empty)
113// CHECK:    8 |   struct C0 (virtual base)
114// CHECK:    8 |     int a
115// CHECK:   12 |   struct C1 (virtual base)
116// CHECK:   12 |     int a
117// CHECK:   16 |   struct C2 (virtual base)
118// CHECK:   16 |     int a
119// CHECK:   24 |   struct B1 (virtual base) (empty)
120// CHECK:      | [sizeof=24, align=8
121// CHECK:      |  nvsize=8, nvalign=4]
122
123struct F : virtual C0, virtual B0, virtual B1, virtual C1 {
124	int a;
125	F() : a(0xf000000F) {printf("X : %3d\n", ((int)this)&0xfff);}
126};
127
128// CHECK: *** Dumping AST Record Layout
129// CHECK:    0 | struct F
130// CHECK:    0 |   (F vbtable pointer)
131// CHECK:    4 |   int a
132// CHECK:    8 |   struct C0 (virtual base)
133// CHECK:    8 |     int a
134// CHECK:   16 |   struct B0 (virtual base) (empty)
135// CHECK:   24 |   struct B1 (virtual base) (empty)
136// CHECK:   24 |   struct C1 (virtual base)
137// CHECK:   24 |     int a
138// CHECK:      | [sizeof=32, align=8
139// CHECK:      |  nvsize=8, nvalign=4]
140
141struct G : virtual C0, virtual B0, virtual B1, D0, virtual C1 {
142	int a;
143	G() : a(0xf0000010) {printf("X : %3d\n", ((int)this)&0xfff);}
144	virtual void f() {}
145};
146
147// CHECK: *** Dumping AST Record Layout
148// CHECK:    0 | struct G
149// CHECK:    0 |   struct D0 (primary base)
150// CHECK:    0 |     (D0 vftable pointer)
151// CHECK:    4 |   (G vbtable pointer)
152// CHECK:   20 |   int a
153// CHECK:   32 |   struct C0 (virtual base)
154// CHECK:   32 |     int a
155// CHECK:   40 |   struct B0 (virtual base) (empty)
156// CHECK:   56 |   struct B1 (virtual base) (empty)
157// CHECK:   56 |   struct C1 (virtual base)
158// CHECK:   56 |     int a
159// CHECK:      | [sizeof=64, align=16
160// CHECK:      |  nvsize=32, nvalign=16]
161
162struct H : virtual C0, virtual B0, virtual B1, virtual D0, virtual C1 {
163	int a;
164	H() : a(0xf0000011) {printf("X : %3d\n", ((int)this)&0xfff);}
165	virtual void f() {}
166};
167
168// CHECK: *** Dumping AST Record Layout
169// CHECK:    0 | struct H
170// CHECK:    0 |   (H vbtable pointer)
171// CHECK:    4 |   int a
172// CHECK:    8 |   struct C0 (virtual base)
173// CHECK:    8 |     int a
174// CHECK:   16 |   struct B0 (virtual base) (empty)
175// CHECK:   24 |   struct B1 (virtual base) (empty)
176// CHECK:   44 |   (vtordisp for vbase D0)
177// CHECK:   48 |   struct D0 (virtual base)
178// CHECK:   48 |     (D0 vftable pointer)
179// CHECK:   52 |   struct C1 (virtual base)
180// CHECK:   52 |     int a
181// CHECK:      | [sizeof=64, align=16
182// CHECK:      |  nvsize=8, nvalign=4]
183
184struct I : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
185	__declspec(align(32)) int a;
186	I() : a(0xf0000012) {printf("X : %3d\n", ((int)this)&0xfff);}
187};
188
189// CHECK: *** Dumping AST Record Layout
190// CHECK:    0 | struct I
191// CHECK:    0 |   (I vbtable pointer)
192// CHECK:   32 |   int a
193// CHECK:   64 |   struct B0 (virtual base) (empty)
194// CHECK:   72 |   struct B1 (virtual base) (empty)
195// CHECK:  104 |   struct B2 (virtual base) (empty)
196// CHECK:  136 |   struct B3 (virtual base) (empty)
197// CHECK:  168 |   struct B4 (virtual base) (empty)
198// CHECK:      | [sizeof=192, align=32
199// CHECK:      |  nvsize=64, nvalign=32]
200
201struct __declspec(align(32)) J : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
202	int a;
203	J() : a(0xf0000012) {printf("X : %3d\n", ((int)this)&0xfff);}
204};
205
206// CHECK: *** Dumping AST Record Layout
207// CHECK:    0 | struct J
208// CHECK:    0 |   (J vbtable pointer)
209// CHECK:    4 |   int a
210// CHECK:    8 |   struct B0 (virtual base) (empty)
211// CHECK:   40 |   struct B1 (virtual base) (empty)
212// CHECK:   72 |   struct B2 (virtual base) (empty)
213// CHECK:  104 |   struct B3 (virtual base) (empty)
214// CHECK:  136 |   struct B4 (virtual base) (empty)
215// CHECK:      | [sizeof=160, align=32
216// CHECK:      |  nvsize=8, nvalign=4]
217
218struct K : virtual D1, virtual B1, virtual B2, virtual B3, virtual B4 {
219	__declspec(align(32)) int a;
220	K() : a(0xf0000013) {printf("X : %3d\n", ((int)this)&0xfff);}
221};
222
223// CHECK: *** Dumping AST Record Layout
224// CHECK:    0 | struct K
225// CHECK:    0 |   (K vbtable pointer)
226// CHECK:   32 |   int a
227// CHECK:   64 |   struct D1 (virtual base) (empty)
228// CHECK:   72 |   struct B1 (virtual base) (empty)
229// CHECK:  104 |   struct B2 (virtual base) (empty)
230// CHECK:  136 |   struct B3 (virtual base) (empty)
231// CHECK:  168 |   struct B4 (virtual base) (empty)
232// CHECK:      | [sizeof=192, align=32
233// CHECK:      |  nvsize=64, nvalign=32]
234
235struct L : virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 {
236	__declspec(align(32)) int a;
237	L() : a(0xf0000014) {printf("X : %3d\n", ((int)this)&0xfff);}
238};
239
240// CHECK: *** Dumping AST Record Layout
241// CHECK:    0 | struct L
242// CHECK:    0 |   (L vbtable pointer)
243// CHECK:   32 |   int a
244// CHECK:   64 |   struct B1 (virtual base) (empty)
245// CHECK:   68 |   struct D1 (virtual base) (empty)
246// CHECK:  104 |   struct B2 (virtual base) (empty)
247// CHECK:  136 |   struct B3 (virtual base) (empty)
248// CHECK:  168 |   struct B4 (virtual base) (empty)
249// CHECK:      | [sizeof=192, align=32
250// CHECK:      |  nvsize=64, nvalign=32]
251
252struct M : virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 {
253	__declspec(align(32)) int a;
254	M() : a(0xf0000015) {printf("X : %3d\n", ((int)this)&0xfff);}
255};
256
257// CHECK: *** Dumping AST Record Layout
258// CHECK:    0 | struct M
259// CHECK:    0 |   (M vbtable pointer)
260// CHECK:   32 |   int a
261// CHECK:   64 |   struct B1 (virtual base) (empty)
262// CHECK:   72 |   struct B2 (virtual base) (empty)
263// CHECK:  100 |   struct D1 (virtual base) (empty)
264// CHECK:  136 |   struct B3 (virtual base) (empty)
265// CHECK:  168 |   struct B4 (virtual base) (empty)
266// CHECK:      | [sizeof=192, align=32
267// CHECK:      |  nvsize=64, nvalign=32]
268
269struct N : virtual C0, virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 {
270	__declspec(align(32)) int a;
271	N() : a(0xf0000016) {printf("X : %3d\n", ((int)this)&0xfff);}
272};
273
274// CHECK: *** Dumping AST Record Layout
275// CHECK:    0 | struct N
276// CHECK:    0 |   (N vbtable pointer)
277// CHECK:   32 |   int a
278// CHECK:   64 |   struct C0 (virtual base)
279// CHECK:   64 |     int a
280// CHECK:   72 |   struct B1 (virtual base) (empty)
281// CHECK:  100 |   struct D1 (virtual base) (empty)
282// CHECK:  136 |   struct B2 (virtual base) (empty)
283// CHECK:  168 |   struct B3 (virtual base) (empty)
284// CHECK:  200 |   struct B4 (virtual base) (empty)
285// CHECK:      | [sizeof=224, align=32
286// CHECK:      |  nvsize=64, nvalign=32]
287
288struct O : virtual C0, virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 {
289	__declspec(align(32)) int a;
290	O() : a(0xf0000017) {printf("X : %3d\n", ((int)this)&0xfff);}
291};
292
293// CHECK: *** Dumping AST Record Layout
294// CHECK:    0 | struct O
295// CHECK:    0 |   (O vbtable pointer)
296// CHECK:   32 |   int a
297// CHECK:   64 |   struct C0 (virtual base)
298// CHECK:   64 |     int a
299// CHECK:   72 |   struct B1 (virtual base) (empty)
300// CHECK:  104 |   struct B2 (virtual base) (empty)
301// CHECK:  132 |   struct D1 (virtual base) (empty)
302// CHECK:  168 |   struct B3 (virtual base) (empty)
303// CHECK:  200 |   struct B4 (virtual base) (empty)
304// CHECK:      | [sizeof=224, align=32
305// CHECK:      |  nvsize=64, nvalign=32]
306
307struct P : virtual B1, virtual C0, virtual D1, virtual B2, virtual B3, virtual B4 {
308	__declspec(align(32)) int a;
309	P() : a(0xf0000018) {printf("X : %3d\n", ((int)this)&0xfff);}
310};
311
312// CHECK: *** Dumping AST Record Layout
313// CHECK:    0 | struct P
314// CHECK:    0 |   (P vbtable pointer)
315// CHECK:   32 |   int a
316// CHECK:   64 |   struct B1 (virtual base) (empty)
317// CHECK:   64 |   struct C0 (virtual base)
318// CHECK:   64 |     int a
319// CHECK:   68 |   struct D1 (virtual base) (empty)
320// CHECK:  104 |   struct B2 (virtual base) (empty)
321// CHECK:  136 |   struct B3 (virtual base) (empty)
322// CHECK:  168 |   struct B4 (virtual base) (empty)
323// CHECK:      | [sizeof=192, align=32
324// CHECK:      |  nvsize=64, nvalign=32]
325
326struct Q : virtual B1, virtual C0, virtual B2, virtual D1, virtual B3, virtual B4 {
327	__declspec(align(32)) int a;
328	Q() : a(0xf0000019) {printf("X : %3d\n", ((int)this)&0xfff);}
329};
330
331// CHECK: *** Dumping AST Record Layout
332// CHECK:    0 | struct Q
333// CHECK:    0 |   (Q vbtable pointer)
334// CHECK:   32 |   int a
335// CHECK:   64 |   struct B1 (virtual base) (empty)
336// CHECK:   64 |   struct C0 (virtual base)
337// CHECK:   64 |     int a
338// CHECK:   72 |   struct B2 (virtual base) (empty)
339// CHECK:  100 |   struct D1 (virtual base) (empty)
340// CHECK:  136 |   struct B3 (virtual base) (empty)
341// CHECK:  168 |   struct B4 (virtual base) (empty)
342// CHECK:      | [sizeof=192, align=32
343// CHECK:      |  nvsize=64, nvalign=32]
344
345struct R : virtual B0, virtual B1, virtual B2, virtual C0, virtual B3, virtual B4 {
346	__declspec(align(32)) int a;
347	R() : a(0xf0000020) {printf("X : %3d\n", ((int)this)&0xfff);}
348};
349
350// CHECK: *** Dumping AST Record Layout
351// CHECK:    0 | struct R
352// CHECK:    0 |   (R vbtable pointer)
353// CHECK:   32 |   int a
354// CHECK:   64 |   struct B0 (virtual base) (empty)
355// CHECK:   72 |   struct B1 (virtual base) (empty)
356// CHECK:  104 |   struct B2 (virtual base) (empty)
357// CHECK:  104 |   struct C0 (virtual base)
358// CHECK:  104 |     int a
359// CHECK:  112 |   struct B3 (virtual base) (empty)
360// CHECK:  136 |   struct B4 (virtual base) (empty)
361// CHECK:      | [sizeof=160, align=32
362// CHECK:      |  nvsize=64, nvalign=32]
363
364struct S : virtual B0, virtual B1, virtual C0, virtual B2, virtual B3, virtual B4 {
365	__declspec(align(32)) int a;
366	S() : a(0xf0000021) {printf("X : %3d\n", ((int)this)&0xfff);}
367};
368
369// CHECK: *** Dumping AST Record Layout
370// CHECK:    0 | struct S
371// CHECK:    0 |   (S vbtable pointer)
372// CHECK:   32 |   int a
373// CHECK:   64 |   struct B0 (virtual base) (empty)
374// CHECK:   72 |   struct B1 (virtual base) (empty)
375// CHECK:   72 |   struct C0 (virtual base)
376// CHECK:   72 |     int a
377// CHECK:   80 |   struct B2 (virtual base) (empty)
378// CHECK:  104 |   struct B3 (virtual base) (empty)
379// CHECK:  136 |   struct B4 (virtual base) (empty)
380// CHECK:      | [sizeof=160, align=32
381// CHECK:      |  nvsize=64, nvalign=32]
382
383struct T : virtual B0, virtual B1, virtual C0, virtual D2, virtual B2, virtual B3, virtual B4 {
384	__declspec(align(16)) int a;
385	T() : a(0xf0000022) {printf("X : %3d\n", ((int)this)&0xfff);}
386};
387
388// CHECK: *** Dumping AST Record Layout
389// CHECK:    0 | struct T
390// CHECK:    0 |   (T vbtable pointer)
391// CHECK:   16 |   int a
392// CHECK:   32 |   struct B0 (virtual base) (empty)
393// CHECK:   40 |   struct B1 (virtual base) (empty)
394// CHECK:   40 |   struct C0 (virtual base)
395// CHECK:   40 |     int a
396// CHECK:   44 |   struct D2 (virtual base)
397// CHECK:   44 |     int [8] a
398// CHECK:   80 |   struct B2 (virtual base) (empty)
399// CHECK:   88 |   struct B3 (virtual base) (empty)
400// CHECK:  104 |   struct B4 (virtual base) (empty)
401// CHECK:      | [sizeof=112, align=16
402// CHECK:      |  nvsize=32, nvalign=16]
403
404struct __declspec(align(32)) U : virtual B0, virtual B1 {
405	int a;
406	U() : a(0xf0000023) {printf("X : %3d\n", ((int)this)&0xfff);}
407};
408
409// CHECK: *** Dumping AST Record Layout
410// CHECK:    0 | struct U
411// CHECK:    0 |   (U vbtable pointer)
412// CHECK:    4 |   int a
413// CHECK:    8 |   struct B0 (virtual base) (empty)
414// CHECK:   40 |   struct B1 (virtual base) (empty)
415// CHECK:      | [sizeof=64, align=32
416// CHECK:      |  nvsize=8, nvalign=4]
417
418struct __declspec(align(32)) V : virtual D1 {
419	int a;
420	V() : a(0xf0000024) {printf("X : %3d\n", ((int)this)&0xfff);}
421};
422
423// CHECK: *** Dumping AST Record Layout
424// CHECK:    0 | struct V
425// CHECK:    0 |   (V vbtable pointer)
426// CHECK:    4 |   int a
427// CHECK:    8 |   struct D1 (virtual base) (empty)
428// CHECK:      | [sizeof=32, align=32
429// CHECK:      |  nvsize=8, nvalign=4]
430
431int a[
432sizeof(A)+
433sizeof(B)+
434sizeof(C)+
435sizeof(D)+
436sizeof(E)+
437sizeof(F)+
438sizeof(G)+
439sizeof(H)+
440sizeof(I)+
441sizeof(J)+
442sizeof(K)+
443sizeof(L)+
444sizeof(M)+
445sizeof(N)+
446sizeof(O)+
447sizeof(P)+
448sizeof(Q)+
449sizeof(R)+
450sizeof(S)+
451sizeof(T)+
452sizeof(U)+
453sizeof(V)];