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