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 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
4 // RUN:            | FileCheck %s -check-prefix CHECK-X64
5 
6 extern "C" int printf(const char *fmt, ...);
7 
8 struct B0 { B0() { printf("B0 = %p\n", this); } };
9 struct B1 { B1() { printf("B1 = %p\n", this); } };
10 struct B2 { B2() { printf("B2 = %p\n", this); } };
11 struct B3 { B3() { printf("B3 = %p\n", this); } };
12 struct B4 { B4() { printf("B4 = %p\n", this); } };
13 struct B5 { B5() { printf("B5 = %p\n", this); } };
14 struct __declspec(align(2)) B6 { B6() { printf("B6 = %p\n", this); } };
15 struct __declspec(align(16)) B7 { B7() { printf("B7 = %p\n", this); } };
16 struct B8 { char c[5]; B8() { printf("B8 = %p\n", this); } };
17 struct B9 { char c[6]; B9() { printf("B9 = %p\n", this); } };
18 struct B10 { char c[7]; B10() { printf("B10 = %p\n", this); } };
19 struct B11 { char c[8]; B11() { printf("B11 = %p\n", this); } };
20 struct B0X { B0X() { printf("B0 = %p\n", this); } };
21 struct B1X { B1X() { printf("B1 = %p\n", this); } };
22 struct __declspec(align(16)) B2X { B2X() { printf("B2 = %p\n", this); } };
23 struct __declspec(align(2)) B3X { B3X() { printf("B3 = %p\n", this); } };
24 struct B4X { B4X() { printf("B4 = %p\n", this); } };
25 struct B5X { B5X() { printf("B5 = %p\n", this); } };
26 struct B6X { B6X() { printf("B6 = %p\n", this); } };
27 struct B8X { short a; B8X() : a(0xf00000B8) { printf("B8 = %p\n", this); } };
28 
29 struct AA : B8, B1, virtual B0 {
30 	int a;
31 	AA() : a(0xf00000AA) { printf("AA = %p\n", this); }
32 };
33 
34 // CHECK: *** Dumping AST Record Layout
35 // CHECK:    0 | struct AA
36 // CHECK:    0 |   struct B8 (base)
37 // CHECK:    0 |     char [5] c
38 // CHECK:   13 |   struct B1 (base) (empty)
39 // CHECK:    8 |   (AA vbtable pointer)
40 // CHECK:   16 |   int a
41 // CHECK:   20 |   struct B0 (virtual base) (empty)
42 // CHECK:      | [sizeof=20, align=4
43 // CHECK:      |  nvsize=20, nvalign=4]
44 // CHECK-X64: *** Dumping AST Record Layout
45 // CHECK-X64:    0 | struct AA
46 // CHECK-X64:    0 |   struct B8 (base)
47 // CHECK-X64:    0 |     char [5] c
48 // CHECK-X64:   17 |   struct B1 (base) (empty)
49 // CHECK-X64:    8 |   (AA vbtable pointer)
50 // CHECK-X64:   20 |   int a
51 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
52 // CHECK-X64:      | [sizeof=24, align=8
53 // CHECK-X64:      |  nvsize=24, nvalign=8]
54 
55 struct AB : B8, B1, virtual B0 {
56 	short a;
57 	AB() : a(0xf00000AB) { printf("AB = %p\n", this); }
58 };
59 
60 // CHECK: *** Dumping AST Record Layout
61 // CHECK:    0 | struct AB
62 // CHECK:    0 |   struct B8 (base)
63 // CHECK:    0 |     char [5] c
64 // CHECK:   13 |   struct B1 (base) (empty)
65 // CHECK:    8 |   (AB vbtable pointer)
66 // CHECK:   14 |   short a
67 // CHECK:   16 |   struct B0 (virtual base) (empty)
68 // CHECK:      | [sizeof=16, align=4
69 // CHECK:      |  nvsize=16, nvalign=4]
70 // CHECK-X64: *** Dumping AST Record Layout
71 // CHECK-X64:    0 | struct AB
72 // CHECK-X64:    0 |   struct B8 (base)
73 // CHECK-X64:    0 |     char [5] c
74 // CHECK-X64:   17 |   struct B1 (base) (empty)
75 // CHECK-X64:    8 |   (AB vbtable pointer)
76 // CHECK-X64:   18 |   short a
77 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
78 // CHECK-X64:      | [sizeof=24, align=8
79 // CHECK-X64:      |  nvsize=24, nvalign=8]
80 
81 struct AC : B8, B1, virtual B0 {
82 	char a;
83 	AC() : a(0xf00000AC) { printf("AC = %p\n", this); }
84 };
85 
86 // CHECK: *** Dumping AST Record Layout
87 // CHECK:    0 | struct AC
88 // CHECK:    0 |   struct B8 (base)
89 // CHECK:    0 |     char [5] c
90 // CHECK:   12 |   struct B1 (base) (empty)
91 // CHECK:    8 |   (AC vbtable pointer)
92 // CHECK:   12 |   char a
93 // CHECK:   16 |   struct B0 (virtual base) (empty)
94 // CHECK:      | [sizeof=16, align=4
95 // CHECK:      |  nvsize=16, nvalign=4]
96 // CHECK-X64: *** Dumping AST Record Layout
97 // CHECK-X64:    0 | struct AC
98 // CHECK-X64:    0 |   struct B8 (base)
99 // CHECK-X64:    0 |     char [5] c
100 // CHECK-X64:   16 |   struct B1 (base) (empty)
101 // CHECK-X64:    8 |   (AC vbtable pointer)
102 // CHECK-X64:   16 |   char a
103 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
104 // CHECK-X64:      | [sizeof=24, align=8
105 // CHECK-X64:      |  nvsize=24, nvalign=8]
106 
107 struct AD : B8, B1, virtual B0 {
108 	AD() { printf("AD = %p\n", this); }
109 };
110 
111 // CHECK: *** Dumping AST Record Layout
112 // CHECK:    0 | struct AD
113 // CHECK:    0 |   struct B8 (base)
114 // CHECK:    0 |     char [5] c
115 // CHECK:   12 |   struct B1 (base) (empty)
116 // CHECK:    8 |   (AD vbtable pointer)
117 // CHECK:   12 |   struct B0 (virtual base) (empty)
118 // CHECK:      | [sizeof=12, align=4
119 // CHECK:      |  nvsize=12, nvalign=4]
120 // CHECK-X64: *** Dumping AST Record Layout
121 // CHECK-X64:    0 | struct AD
122 // CHECK-X64:    0 |   struct B8 (base)
123 // CHECK-X64:    0 |     char [5] c
124 // CHECK-X64:   16 |   struct B1 (base) (empty)
125 // CHECK-X64:    8 |   (AD vbtable pointer)
126 // CHECK-X64:   16 |   struct B0 (virtual base) (empty)
127 // CHECK-X64:      | [sizeof=16, align=8
128 // CHECK-X64:      |  nvsize=16, nvalign=8]
129 
130 struct AA1 : B9, B1, virtual B0 {
131 	int a;
132 	AA1() : a(0xf0000AA1) { printf("AA1 = %p\n", this); }
133 };
134 
135 // CHECK: *** Dumping AST Record Layout
136 // CHECK:    0 | struct AA1
137 // CHECK:    0 |   struct B9 (base)
138 // CHECK:    0 |     char [6] c
139 // CHECK:   14 |   struct B1 (base) (empty)
140 // CHECK:    8 |   (AA1 vbtable pointer)
141 // CHECK:   16 |   int a
142 // CHECK:   20 |   struct B0 (virtual base) (empty)
143 // CHECK:      | [sizeof=20, align=4
144 // CHECK:      |  nvsize=20, nvalign=4]
145 // CHECK-X64: *** Dumping AST Record Layout
146 // CHECK-X64:    0 | struct AA1
147 // CHECK-X64:    0 |   struct B9 (base)
148 // CHECK-X64:    0 |     char [6] c
149 // CHECK-X64:   18 |   struct B1 (base) (empty)
150 // CHECK-X64:    8 |   (AA1 vbtable pointer)
151 // CHECK-X64:   20 |   int a
152 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
153 // CHECK-X64:      | [sizeof=24, align=8
154 // CHECK-X64:      |  nvsize=24, nvalign=8]
155 
156 struct AB1 : B9, B1, virtual B0 {
157 	short a;
158 	AB1() : a(0xf0000AB1) { printf("AB1 = %p\n", this); }
159 };
160 
161 // CHECK: *** Dumping AST Record Layout
162 // CHECK:    0 | struct AB1
163 // CHECK:    0 |   struct B9 (base)
164 // CHECK:    0 |     char [6] c
165 // CHECK:   12 |   struct B1 (base) (empty)
166 // CHECK:    8 |   (AB1 vbtable pointer)
167 // CHECK:   12 |   short a
168 // CHECK:   16 |   struct B0 (virtual base) (empty)
169 // CHECK:      | [sizeof=16, align=4
170 // CHECK:      |  nvsize=16, nvalign=4]
171 // CHECK-X64: *** Dumping AST Record Layout
172 // CHECK-X64:    0 | struct AB1
173 // CHECK-X64:    0 |   struct B9 (base)
174 // CHECK-X64:    0 |     char [6] c
175 // CHECK-X64:   16 |   struct B1 (base) (empty)
176 // CHECK-X64:    8 |   (AB1 vbtable pointer)
177 // CHECK-X64:   16 |   short a
178 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
179 // CHECK-X64:      | [sizeof=24, align=8
180 // CHECK-X64:      |  nvsize=24, nvalign=8]
181 
182 struct AC1 : B9, B1, virtual B0 {
183 	char a;
184 	AC1() : a(0xf0000AC1) { printf("AC1 = %p\n", this); }
185 };
186 
187 // CHECK: *** Dumping AST Record Layout
188 // CHECK:    0 | struct AC1
189 // CHECK:    0 |   struct B9 (base)
190 // CHECK:    0 |     char [6] c
191 // CHECK:   12 |   struct B1 (base) (empty)
192 // CHECK:    8 |   (AC1 vbtable pointer)
193 // CHECK:   12 |   char a
194 // CHECK:   16 |   struct B0 (virtual base) (empty)
195 // CHECK:      | [sizeof=16, align=4
196 // CHECK:      |  nvsize=16, nvalign=4]
197 // CHECK-X64: *** Dumping AST Record Layout
198 // CHECK-X64:    0 | struct AC1
199 // CHECK-X64:    0 |   struct B9 (base)
200 // CHECK-X64:    0 |     char [6] c
201 // CHECK-X64:   16 |   struct B1 (base) (empty)
202 // CHECK-X64:    8 |   (AC1 vbtable pointer)
203 // CHECK-X64:   16 |   char a
204 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
205 // CHECK-X64:      | [sizeof=24, align=8
206 // CHECK-X64:      |  nvsize=24, nvalign=8]
207 
208 struct AD1 : B9, B1, virtual B0 {
209 	AD1() { printf("AD1 = %p\n", this); }
210 };
211 
212 // CHECK: *** Dumping AST Record Layout
213 // CHECK:    0 | struct AD1
214 // CHECK:    0 |   struct B9 (base)
215 // CHECK:    0 |     char [6] c
216 // CHECK:   12 |   struct B1 (base) (empty)
217 // CHECK:    8 |   (AD1 vbtable pointer)
218 // CHECK:   12 |   struct B0 (virtual base) (empty)
219 // CHECK:      | [sizeof=12, align=4
220 // CHECK:      |  nvsize=12, nvalign=4]
221 // CHECK-X64: *** Dumping AST Record Layout
222 // CHECK-X64:    0 | struct AD1
223 // CHECK-X64:    0 |   struct B9 (base)
224 // CHECK-X64:    0 |     char [6] c
225 // CHECK-X64:   16 |   struct B1 (base) (empty)
226 // CHECK-X64:    8 |   (AD1 vbtable pointer)
227 // CHECK-X64:   16 |   struct B0 (virtual base) (empty)
228 // CHECK-X64:      | [sizeof=16, align=8
229 // CHECK-X64:      |  nvsize=16, nvalign=8]
230 
231 struct AA2 : B10, B1, virtual B0 {
232 	int a;
233 	AA2() : a(0xf0000AA2) { printf("AA2 = %p\n", this); }
234 };
235 
236 // CHECK: *** Dumping AST Record Layout
237 // CHECK:    0 | struct AA2
238 // CHECK:    0 |   struct B10 (base)
239 // CHECK:    0 |     char [7] c
240 // CHECK:   15 |   struct B1 (base) (empty)
241 // CHECK:    8 |   (AA2 vbtable pointer)
242 // CHECK:   16 |   int a
243 // CHECK:   20 |   struct B0 (virtual base) (empty)
244 // CHECK:      | [sizeof=20, align=4
245 // CHECK:      |  nvsize=20, nvalign=4]
246 // CHECK-X64: *** Dumping AST Record Layout
247 // CHECK-X64:    0 | struct AA2
248 // CHECK-X64:    0 |   struct B10 (base)
249 // CHECK-X64:    0 |     char [7] c
250 // CHECK-X64:   19 |   struct B1 (base) (empty)
251 // CHECK-X64:    8 |   (AA2 vbtable pointer)
252 // CHECK-X64:   20 |   int a
253 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
254 // CHECK-X64:      | [sizeof=24, align=8
255 // CHECK-X64:      |  nvsize=24, nvalign=8]
256 
257 struct AB2 : B10, B1, virtual B0 {
258 	short a;
259 	AB2() : a(0xf0000AB2) { printf("AB2 = %p\n", this); }
260 };
261 
262 // CHECK: *** Dumping AST Record Layout
263 // CHECK:    0 | struct AB2
264 // CHECK:    0 |   struct B10 (base)
265 // CHECK:    0 |     char [7] c
266 // CHECK:   13 |   struct B1 (base) (empty)
267 // CHECK:    8 |   (AB2 vbtable pointer)
268 // CHECK:   14 |   short a
269 // CHECK:   16 |   struct B0 (virtual base) (empty)
270 // CHECK:      | [sizeof=16, align=4
271 // CHECK:      |  nvsize=16, nvalign=4]
272 // CHECK-X64: *** Dumping AST Record Layout
273 // CHECK-X64:    0 | struct AB2
274 // CHECK-X64:    0 |   struct B10 (base)
275 // CHECK-X64:    0 |     char [7] c
276 // CHECK-X64:   17 |   struct B1 (base) (empty)
277 // CHECK-X64:    8 |   (AB2 vbtable pointer)
278 // CHECK-X64:   18 |   short a
279 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
280 // CHECK-X64:      | [sizeof=24, align=8
281 // CHECK-X64:      |  nvsize=24, nvalign=8]
282 
283 struct AC2 : B10, B1, virtual B0 {
284 	char a;
285 	AC2() : a(0xf0000AC2) { printf("AC2 = %p\n", this); }
286 };
287 
288 // CHECK: *** Dumping AST Record Layout
289 // CHECK:    0 | struct AC2
290 // CHECK:    0 |   struct B10 (base)
291 // CHECK:    0 |     char [7] c
292 // CHECK:   12 |   struct B1 (base) (empty)
293 // CHECK:    8 |   (AC2 vbtable pointer)
294 // CHECK:   12 |   char a
295 // CHECK:   16 |   struct B0 (virtual base) (empty)
296 // CHECK:      | [sizeof=16, align=4
297 // CHECK:      |  nvsize=16, nvalign=4]
298 // CHECK-X64: *** Dumping AST Record Layout
299 // CHECK-X64:    0 | struct AC2
300 // CHECK-X64:    0 |   struct B10 (base)
301 // CHECK-X64:    0 |     char [7] c
302 // CHECK-X64:   16 |   struct B1 (base) (empty)
303 // CHECK-X64:    8 |   (AC2 vbtable pointer)
304 // CHECK-X64:   16 |   char a
305 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
306 // CHECK-X64:      | [sizeof=24, align=8
307 // CHECK-X64:      |  nvsize=24, nvalign=8]
308 
309 struct AD2 : B10, B1, virtual B0 {
310 	AD2() { printf("AD2 = %p\n", this); }
311 };
312 
313 // CHECK: *** Dumping AST Record Layout
314 // CHECK:    0 | struct AD2
315 // CHECK:    0 |   struct B10 (base)
316 // CHECK:    0 |     char [7] c
317 // CHECK:   12 |   struct B1 (base) (empty)
318 // CHECK:    8 |   (AD2 vbtable pointer)
319 // CHECK:   12 |   struct B0 (virtual base) (empty)
320 // CHECK:      | [sizeof=12, align=4
321 // CHECK:      |  nvsize=12, nvalign=4]
322 // CHECK-X64: *** Dumping AST Record Layout
323 // CHECK-X64:    0 | struct AD2
324 // CHECK-X64:    0 |   struct B10 (base)
325 // CHECK-X64:    0 |     char [7] c
326 // CHECK-X64:   16 |   struct B1 (base) (empty)
327 // CHECK-X64:    8 |   (AD2 vbtable pointer)
328 // CHECK-X64:   16 |   struct B0 (virtual base) (empty)
329 // CHECK-X64:      | [sizeof=16, align=8
330 // CHECK-X64:      |  nvsize=16, nvalign=8]
331 
332 struct AA3 : B11, B1, virtual B0 {
333 	int a;
334 	AA3() : a(0xf0000AA3) { printf("AA3 = %p\n", this); }
335 };
336 
337 // CHECK: *** Dumping AST Record Layout
338 // CHECK:    0 | struct AA3
339 // CHECK:    0 |   struct B11 (base)
340 // CHECK:    0 |     char [8] c
341 // CHECK:   12 |   struct B1 (base) (empty)
342 // CHECK:    8 |   (AA3 vbtable pointer)
343 // CHECK:   12 |   int a
344 // CHECK:   16 |   struct B0 (virtual base) (empty)
345 // CHECK:      | [sizeof=16, align=4
346 // CHECK:      |  nvsize=16, nvalign=4]
347 // CHECK-X64: *** Dumping AST Record Layout
348 // CHECK-X64:    0 | struct AA3
349 // CHECK-X64:    0 |   struct B11 (base)
350 // CHECK-X64:    0 |     char [8] c
351 // CHECK-X64:   16 |   struct B1 (base) (empty)
352 // CHECK-X64:    8 |   (AA3 vbtable pointer)
353 // CHECK-X64:   16 |   int a
354 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
355 // CHECK-X64:      | [sizeof=24, align=8
356 // CHECK-X64:      |  nvsize=24, nvalign=8]
357 
358 struct AB3 : B11, B1, virtual B0 {
359 	short a;
360 	AB3() : a(0xf0000AB3) { printf("AB3 = %p\n", this); }
361 };
362 
363 // CHECK: *** Dumping AST Record Layout
364 // CHECK:    0 | struct AB3
365 // CHECK:    0 |   struct B11 (base)
366 // CHECK:    0 |     char [8] c
367 // CHECK:   12 |   struct B1 (base) (empty)
368 // CHECK:    8 |   (AB3 vbtable pointer)
369 // CHECK:   12 |   short a
370 // CHECK:   16 |   struct B0 (virtual base) (empty)
371 // CHECK:      | [sizeof=16, align=4
372 // CHECK:      |  nvsize=16, nvalign=4]
373 // CHECK-X64: *** Dumping AST Record Layout
374 // CHECK-X64:    0 | struct AB3
375 // CHECK-X64:    0 |   struct B11 (base)
376 // CHECK-X64:    0 |     char [8] c
377 // CHECK-X64:   16 |   struct B1 (base) (empty)
378 // CHECK-X64:    8 |   (AB3 vbtable pointer)
379 // CHECK-X64:   16 |   short a
380 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
381 // CHECK-X64:      | [sizeof=24, align=8
382 // CHECK-X64:      |  nvsize=24, nvalign=8]
383 
384 struct AC3 : B11, B1, virtual B0 {
385 	char a;
386 	AC3() : a(0xf0000AC3) { printf("AC3 = %p\n", this); }
387 };
388 
389 // CHECK: *** Dumping AST Record Layout
390 // CHECK:    0 | struct AC3
391 // CHECK:    0 |   struct B11 (base)
392 // CHECK:    0 |     char [8] c
393 // CHECK:   12 |   struct B1 (base) (empty)
394 // CHECK:    8 |   (AC3 vbtable pointer)
395 // CHECK:   12 |   char a
396 // CHECK:   16 |   struct B0 (virtual base) (empty)
397 // CHECK:      | [sizeof=16, align=4
398 // CHECK:      |  nvsize=16, nvalign=4]
399 // CHECK-X64: *** Dumping AST Record Layout
400 // CHECK-X64:    0 | struct AC3
401 // CHECK-X64:    0 |   struct B11 (base)
402 // CHECK-X64:    0 |     char [8] c
403 // CHECK-X64:   16 |   struct B1 (base) (empty)
404 // CHECK-X64:    8 |   (AC3 vbtable pointer)
405 // CHECK-X64:   16 |   char a
406 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
407 // CHECK-X64:      | [sizeof=24, align=8
408 // CHECK-X64:      |  nvsize=24, nvalign=8]
409 
410 struct AD3 : B11, B1, virtual B0 {
411 	AD3() { printf("AD3 = %p\n", this); }
412 };
413 
414 // CHECK: *** Dumping AST Record Layout
415 // CHECK:    0 | struct AD3
416 // CHECK:    0 |   struct B11 (base)
417 // CHECK:    0 |     char [8] c
418 // CHECK:   12 |   struct B1 (base) (empty)
419 // CHECK:    8 |   (AD3 vbtable pointer)
420 // CHECK:   12 |   struct B0 (virtual base) (empty)
421 // CHECK:      | [sizeof=12, align=4
422 // CHECK:      |  nvsize=12, nvalign=4]
423 // CHECK-X64: *** Dumping AST Record Layout
424 // CHECK-X64:    0 | struct AD3
425 // CHECK-X64:    0 |   struct B11 (base)
426 // CHECK-X64:    0 |     char [8] c
427 // CHECK-X64:   16 |   struct B1 (base) (empty)
428 // CHECK-X64:    8 |   (AD3 vbtable pointer)
429 // CHECK-X64:   16 |   struct B0 (virtual base) (empty)
430 // CHECK-X64:      | [sizeof=16, align=8
431 // CHECK-X64:      |  nvsize=16, nvalign=8]
432 
433 struct B : B1, B2, virtual B0 {
434 	B() { printf("B = %p\n", this); }
435 };
436 
437 // CHECK: *** Dumping AST Record Layout
438 // CHECK:    0 | struct B
439 // CHECK:    0 |   struct B1 (base) (empty)
440 // CHECK:    8 |   struct B2 (base) (empty)
441 // CHECK:    4 |   (B vbtable pointer)
442 // CHECK:    8 |   struct B0 (virtual base) (empty)
443 // CHECK:      | [sizeof=8, align=4
444 // CHECK:      |  nvsize=8, nvalign=4]
445 // CHECK-X64: *** Dumping AST Record Layout
446 // CHECK-X64:    0 | struct B
447 // CHECK-X64:    0 |   struct B1 (base) (empty)
448 // CHECK-X64:   16 |   struct B2 (base) (empty)
449 // CHECK-X64:    8 |   (B vbtable pointer)
450 // CHECK-X64:   16 |   struct B0 (virtual base) (empty)
451 // CHECK-X64:      | [sizeof=16, align=8
452 // CHECK-X64:      |  nvsize=16, nvalign=8]
453 
454 struct C : B1, B2, B3, virtual B0 {
455 	char a;
456 	C() : a(0xf000000C) { printf("C = %p\n", this); }
457 };
458 
459 // CHECK: *** Dumping AST Record Layout
460 // CHECK:    0 | struct C
461 // CHECK:    0 |   struct B1 (base) (empty)
462 // CHECK:    1 |   struct B2 (base) (empty)
463 // CHECK:    8 |   struct B3 (base) (empty)
464 // CHECK:    4 |   (C vbtable pointer)
465 // CHECK:    8 |   char a
466 // CHECK:   12 |   struct B0 (virtual base) (empty)
467 // CHECK:      | [sizeof=12, align=4
468 // CHECK:      |  nvsize=12, nvalign=4]
469 // CHECK-X64: *** Dumping AST Record Layout
470 // CHECK-X64:    0 | struct C
471 // CHECK-X64:    0 |   struct B1 (base) (empty)
472 // CHECK-X64:    1 |   struct B2 (base) (empty)
473 // CHECK-X64:   16 |   struct B3 (base) (empty)
474 // CHECK-X64:    8 |   (C vbtable pointer)
475 // CHECK-X64:   16 |   char a
476 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
477 // CHECK-X64:      | [sizeof=24, align=8
478 // CHECK-X64:      |  nvsize=24, nvalign=8]
479 
480 struct D : B1, B2, B3, B4, B5, virtual B0 {
481 	int a;
482 	D() : a(0xf000000D) { printf("D = %p\n", this); }
483 };
484 
485 // CHECK: *** Dumping AST Record Layout
486 // CHECK:    0 | struct D
487 // CHECK:    0 |   struct B1 (base) (empty)
488 // CHECK:    1 |   struct B2 (base) (empty)
489 // CHECK:    2 |   struct B3 (base) (empty)
490 // CHECK:    3 |   struct B4 (base) (empty)
491 // CHECK:    8 |   struct B5 (base) (empty)
492 // CHECK:    4 |   (D vbtable pointer)
493 // CHECK:    8 |   int a
494 // CHECK:   12 |   struct B0 (virtual base) (empty)
495 // CHECK:      | [sizeof=12, align=4
496 // CHECK:      |  nvsize=12, nvalign=4]
497 // CHECK-X64: *** Dumping AST Record Layout
498 // CHECK-X64:    0 | struct D
499 // CHECK-X64:    0 |   struct B1 (base) (empty)
500 // CHECK-X64:    1 |   struct B2 (base) (empty)
501 // CHECK-X64:    2 |   struct B3 (base) (empty)
502 // CHECK-X64:    3 |   struct B4 (base) (empty)
503 // CHECK-X64:   16 |   struct B5 (base) (empty)
504 // CHECK-X64:    8 |   (D vbtable pointer)
505 // CHECK-X64:   16 |   int a
506 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
507 // CHECK-X64:      | [sizeof=24, align=8
508 // CHECK-X64:      |  nvsize=24, nvalign=8]
509 
510 struct E : B1, B6, B3, B4, B5, virtual B0 {
511 	int a;
512 	E() : a(0xf000000E) { printf("E = %p\n", this); }
513 };
514 
515 // CHECK: *** Dumping AST Record Layout
516 // CHECK:    0 | struct E
517 // CHECK:    0 |   struct B1 (base) (empty)
518 // CHECK:    2 |   struct B6 (base) (empty)
519 // CHECK:    3 |   struct B3 (base) (empty)
520 // CHECK:    4 |   struct B4 (base) (empty)
521 // CHECK:   13 |   struct B5 (base) (empty)
522 // CHECK:    8 |   (E vbtable pointer)
523 // CHECK:   16 |   int a
524 // CHECK:   20 |   struct B0 (virtual base) (empty)
525 // CHECK:      | [sizeof=20, align=4
526 // CHECK:      |  nvsize=20, nvalign=4]
527 // CHECK-X64: *** Dumping AST Record Layout
528 // CHECK-X64:    0 | struct E
529 // CHECK-X64:    0 |   struct B1 (base) (empty)
530 // CHECK-X64:    2 |   struct B6 (base) (empty)
531 // CHECK-X64:    3 |   struct B3 (base) (empty)
532 // CHECK-X64:    4 |   struct B4 (base) (empty)
533 // CHECK-X64:   17 |   struct B5 (base) (empty)
534 // CHECK-X64:    8 |   (E vbtable pointer)
535 // CHECK-X64:   20 |   int a
536 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
537 // CHECK-X64:      | [sizeof=24, align=8
538 // CHECK-X64:      |  nvsize=24, nvalign=8]
539 
540 struct F : B1, B6, B4, B8, B5, virtual B0 {
541 	int a;
542 	F() : a(0xf000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); }
543 };
544 
545 // CHECK: *** Dumping AST Record Layout
546 // CHECK:    0 | struct F
547 // CHECK:    0 |   struct B1 (base) (empty)
548 // CHECK:    2 |   struct B6 (base) (empty)
549 // CHECK:    3 |   struct B4 (base) (empty)
550 // CHECK:    3 |   struct B8 (base)
551 // CHECK:    3 |     char [5] c
552 // CHECK:   12 |   struct B5 (base) (empty)
553 // CHECK:    8 |   (F vbtable pointer)
554 // CHECK:   12 |   int a
555 // CHECK:   16 |   struct B0 (virtual base) (empty)
556 // CHECK:      | [sizeof=16, align=4
557 // CHECK:      |  nvsize=16, nvalign=4]
558 // CHECK-X64: *** Dumping AST Record Layout
559 // CHECK-X64:    0 | struct F
560 // CHECK-X64:    0 |   struct B1 (base) (empty)
561 // CHECK-X64:    2 |   struct B6 (base) (empty)
562 // CHECK-X64:    3 |   struct B4 (base) (empty)
563 // CHECK-X64:    3 |   struct B8 (base)
564 // CHECK-X64:    3 |     char [5] c
565 // CHECK-X64:   16 |   struct B5 (base) (empty)
566 // CHECK-X64:    8 |   (F vbtable pointer)
567 // CHECK-X64:   16 |   int a
568 // CHECK-X64:   24 |   struct B0 (virtual base) (empty)
569 // CHECK-X64:      | [sizeof=24, align=8
570 // CHECK-X64:      |  nvsize=24, nvalign=8]
571 
572 struct G : B8, B1, virtual B0 {
573 	int a;
574 	__declspec(align(16)) int a1;
575 	G() : a(0xf0000010), a1(0xf0000010) { printf("G = %p\n", this); }
576 };
577 
578 // CHECK: *** Dumping AST Record Layout
579 // CHECK:    0 | struct G
580 // CHECK:    0 |   struct B8 (base)
581 // CHECK:    0 |     char [5] c
582 // CHECK:   21 |   struct B1 (base) (empty)
583 // CHECK:    8 |   (G vbtable pointer)
584 // CHECK:   24 |   int a
585 // CHECK:   32 |   int a1
586 // CHECK:   48 |   struct B0 (virtual base) (empty)
587 // CHECK:      | [sizeof=48, align=16
588 // CHECK:      |  nvsize=48, nvalign=16]
589 // CHECK-X64: *** Dumping AST Record Layout
590 // CHECK-X64:    0 | struct G
591 // CHECK-X64:    0 |   struct B8 (base)
592 // CHECK-X64:    0 |     char [5] c
593 // CHECK-X64:   16 |   struct B1 (base) (empty)
594 // CHECK-X64:    8 |   (G vbtable pointer)
595 // CHECK-X64:   16 |   int a
596 // CHECK-X64:   32 |   int a1
597 // CHECK-X64:   48 |   struct B0 (virtual base) (empty)
598 // CHECK-X64:      | [sizeof=48, align=16
599 // CHECK-X64:      |  nvsize=48, nvalign=16]
600 
601 struct AX : B1X, B2X, B3X, B4X, virtual B0X {
602 	int a;
603 	AX() : a(0xf000000A) { printf(" A = %p\n", this); }
604 };
605 
606 // CHECK: *** Dumping AST Record Layout
607 // CHECK:    0 | struct AX
608 // CHECK:    0 |   struct B1X (base) (empty)
609 // CHECK:   16 |   struct B2X (base) (empty)
610 // CHECK:   18 |   struct B3X (base) (empty)
611 // CHECK:   35 |   struct B4X (base) (empty)
612 // CHECK:   20 |   (AX vbtable pointer)
613 // CHECK:   36 |   int a
614 // CHECK:   48 |   struct B0X (virtual base) (empty)
615 // CHECK:      | [sizeof=48, align=16
616 // CHECK:      |  nvsize=48, nvalign=16]
617 // CHECK-X64: *** Dumping AST Record Layout
618 // CHECK-X64:    0 | struct AX
619 // CHECK-X64:    0 |   struct B1X (base) (empty)
620 // CHECK-X64:   16 |   struct B2X (base) (empty)
621 // CHECK-X64:   18 |   struct B3X (base) (empty)
622 // CHECK-X64:   33 |   struct B4X (base) (empty)
623 // CHECK-X64:   24 |   (AX vbtable pointer)
624 // CHECK-X64:   36 |   int a
625 // CHECK-X64:   48 |   struct B0X (virtual base) (empty)
626 // CHECK-X64:      | [sizeof=48, align=16
627 // CHECK-X64:      |  nvsize=48, nvalign=16]
628 
629 struct BX : B2X, B1X, B3X, B4X, virtual B0X {
630 	int a;
631 	BX() : a(0xf000000B) { printf(" B = %p\n", this); }
632 };
633 
634 // CHECK: *** Dumping AST Record Layout
635 // CHECK:    0 | struct BX
636 // CHECK:    0 |   struct B2X (base) (empty)
637 // CHECK:    1 |   struct B1X (base) (empty)
638 // CHECK:    2 |   struct B3X (base) (empty)
639 // CHECK:   19 |   struct B4X (base) (empty)
640 // CHECK:    4 |   (BX vbtable pointer)
641 // CHECK:   20 |   int a
642 // CHECK:   32 |   struct B0X (virtual base) (empty)
643 // CHECK:      | [sizeof=32, align=16
644 // CHECK:      |  nvsize=32, nvalign=16]
645 // CHECK-X64: *** Dumping AST Record Layout
646 // CHECK-X64:    0 | struct BX
647 // CHECK-X64:    0 |   struct B2X (base) (empty)
648 // CHECK-X64:    1 |   struct B1X (base) (empty)
649 // CHECK-X64:    2 |   struct B3X (base) (empty)
650 // CHECK-X64:   17 |   struct B4X (base) (empty)
651 // CHECK-X64:    8 |   (BX vbtable pointer)
652 // CHECK-X64:   20 |   int a
653 // CHECK-X64:   32 |   struct B0X (virtual base) (empty)
654 // CHECK-X64:      | [sizeof=32, align=16
655 // CHECK-X64:      |  nvsize=32, nvalign=16]
656 
657 struct CX : B1X, B3X, B2X, virtual B0X {
658 	int a;
659 	CX() : a(0xf000000C) { printf(" C = %p\n", this); }
660 };
661 
662 // CHECK: *** Dumping AST Record Layout
663 // CHECK:    0 | struct CX
664 // CHECK:    0 |   struct B1X (base) (empty)
665 // CHECK:    2 |   struct B3X (base) (empty)
666 // CHECK:   32 |   struct B2X (base) (empty)
667 // CHECK:    4 |   (CX vbtable pointer)
668 // CHECK:   32 |   int a
669 // CHECK:   48 |   struct B0X (virtual base) (empty)
670 // CHECK:      | [sizeof=48, align=16
671 // CHECK:      |  nvsize=48, nvalign=16]
672 // CHECK-X64: *** Dumping AST Record Layout
673 // CHECK-X64:    0 | struct CX
674 // CHECK-X64:    0 |   struct B1X (base) (empty)
675 // CHECK-X64:    2 |   struct B3X (base) (empty)
676 // CHECK-X64:   32 |   struct B2X (base) (empty)
677 // CHECK-X64:    8 |   (CX vbtable pointer)
678 // CHECK-X64:   32 |   int a
679 // CHECK-X64:   48 |   struct B0X (virtual base) (empty)
680 // CHECK-X64:      | [sizeof=48, align=16
681 // CHECK-X64:      |  nvsize=48, nvalign=16]
682 
683 struct DX : B8X, B1X, virtual B0X {
684 	int a;
685 	DX() : a(0xf000000D) { printf(" D = %p\n", this); }
686 };
687 
688 // CHECK: *** Dumping AST Record Layout
689 // CHECK:    0 | struct DX
690 // CHECK:    0 |   struct B8X (base)
691 // CHECK:    0 |     short a
692 // CHECK:   10 |   struct B1X (base) (empty)
693 // CHECK:    4 |   (DX vbtable pointer)
694 // CHECK:   12 |   int a
695 // CHECK:   16 |   struct B0X (virtual base) (empty)
696 // CHECK:      | [sizeof=16, align=4
697 // CHECK:      |  nvsize=16, nvalign=4]
698 // CHECK-X64: *** Dumping AST Record Layout
699 // CHECK-X64:    0 | struct DX
700 // CHECK-X64:    0 |   struct B8X (base)
701 // CHECK-X64:    0 |     short a
702 // CHECK-X64:   18 |   struct B1X (base) (empty)
703 // CHECK-X64:    8 |   (DX vbtable pointer)
704 // CHECK-X64:   20 |   int a
705 // CHECK-X64:   24 |   struct B0X (virtual base) (empty)
706 // CHECK-X64:      | [sizeof=24, align=8
707 // CHECK-X64:      |  nvsize=24, nvalign=8]
708 
709 int a[
710 sizeof(AA)+
711 sizeof(AB)+
712 sizeof(AC)+
713 sizeof(AD)+
714 sizeof(AA1)+
715 sizeof(AB1)+
716 sizeof(AC1)+
717 sizeof(AD1)+
718 sizeof(AA2)+
719 sizeof(AB2)+
720 sizeof(AC2)+
721 sizeof(AD2)+
722 sizeof(AA3)+
723 sizeof(AB3)+
724 sizeof(AC3)+
725 sizeof(AD3)+
726 sizeof(B)+
727 sizeof(C)+
728 sizeof(D)+
729 sizeof(E)+
730 sizeof(F)+
731 sizeof(G)+
732 sizeof(AX)+
733 sizeof(BX)+
734 sizeof(CX)+
735 sizeof(DX)];
736