ms-x86-pack-and-align.cpp revision 176edba5311f6eff0cad2631449885ddf4fbc9ea
1// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
2// RUN:            | FileCheck %s
3// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
4// RUN:            | FileCheck %s -check-prefix CHECK-X64
5
6extern "C" int printf(const char *fmt, ...);
7char buffer[419430400];
8
9struct A {
10	char a;
11	A() {
12		printf("A   = %d\n", (int)((char*)this - buffer));
13		printf("A.a = %d\n", (int)((char*)&a - buffer));
14	}
15};
16
17struct B {
18	__declspec(align(4)) long long a;
19	B() {
20		printf("B   = %d\n", (int)((char*)this - buffer));
21		printf("B.a = %d\n", (int)((char*)&a - buffer));
22	}
23};
24
25#pragma pack(push, 2)
26struct X {
27	B a;
28	char b;
29	int c;
30	X() {
31		printf("X   = %d\n", (int)((char*)this - buffer));
32		printf("X.a = %d\n", (int)((char*)&a - buffer));
33		printf("X.b = %d\n", (int)((char*)&b - buffer));
34		printf("X.c = %d\n", (int)((char*)&c - buffer));
35	}
36};
37
38// CHECK: *** Dumping AST Record Layout
39// CHECK: *** Dumping AST Record Layout
40// CHECK-NEXT:    0 | struct X
41// CHECK-NEXT:    0 |   struct B a
42// CHECK-NEXT:    0 |     long long a
43// CHECK-NEXT:      |   [sizeof=8, align=8
44// CHECK-NEXT:      |    nvsize=8, nvalign=8]
45// CHECK-NEXT:    8 |   char b
46// CHECK-NEXT:   10 |   int c
47// CHECK-NEXT:      | [sizeof=16, align=4
48// CHECK-NEXT:      |  nvsize=14, nvalign=4]
49// CHECK-X64: *** Dumping AST Record Layout
50// CHECK-X64: *** Dumping AST Record Layout
51// CHECK-X64-NEXT:    0 | struct X
52// CHECK-X64-NEXT:    0 |   struct B a
53// CHECK-X64-NEXT:    0 |     long long a
54// CHECK-X64-NEXT:      |   [sizeof=8, align=8
55// CHECK-X64-NEXT:      |    nvsize=8, nvalign=8]
56// CHECK-X64-NEXT:    8 |   char b
57// CHECK-X64-NEXT:   10 |   int c
58// CHECK-X64-NEXT:      | [sizeof=16, align=4
59// CHECK-X64-NEXT:      |  nvsize=14, nvalign=4]
60
61struct Y : A, B {
62	char a;
63	int b;
64	Y() {
65		printf("Y   = %d\n", (int)((char*)this - buffer));
66		printf("Y.a = %d\n", (int)((char*)&a - buffer));
67		printf("Y.b = %d\n", (int)((char*)&b - buffer));
68	}
69};
70
71// CHECK: *** Dumping AST Record Layout
72// CHECK: *** Dumping AST Record Layout
73// CHECK-NEXT:    0 | struct Y
74// CHECK-NEXT:    0 |   struct A (base)
75// CHECK-NEXT:    0 |     char a
76// CHECK-NEXT:    4 |   struct B (base)
77// CHECK-NEXT:    4 |     long long a
78// CHECK-NEXT:   12 |   char a
79// CHECK-NEXT:   14 |   int b
80// CHECK-NEXT:      | [sizeof=20, align=4
81// CHECK-NEXT:      |  nvsize=18, nvalign=4]
82// CHECK-X64: *** Dumping AST Record Layout
83// CHECK-X64: *** Dumping AST Record Layout
84// CHECK-X64-NEXT:    0 | struct Y
85// CHECK-X64-NEXT:    0 |   struct A (base)
86// CHECK-X64-NEXT:    0 |     char a
87// CHECK-X64-NEXT:    4 |   struct B (base)
88// CHECK-X64-NEXT:    4 |     long long a
89// CHECK-X64-NEXT:   12 |   char a
90// CHECK-X64-NEXT:   14 |   int b
91// CHECK-X64-NEXT:      | [sizeof=20, align=4
92// CHECK-X64-NEXT:      |  nvsize=18, nvalign=4]
93
94struct Z : virtual B {
95	char a;
96	int b;
97	Z() {
98		printf("Z   = %d\n", (int)((char*)this - buffer));
99		printf("Z.a = %d\n", (int)((char*)&a - buffer));
100		printf("Z.b = %d\n", (int)((char*)&b - buffer));
101	}
102};
103
104// CHECK: *** Dumping AST Record Layout
105// CHECK-NEXT:    0 | struct Z
106// CHECK-NEXT:    0 |   (Z vbtable pointer)
107// CHECK-NEXT:    4 |   char a
108// CHECK-NEXT:    6 |   int b
109// CHECK-NEXT:   12 |   struct B (virtual base)
110// CHECK-NEXT:   12 |     long long a
111// CHECK-NEXT:      | [sizeof=20, align=4
112// CHECK-NEXT:      |  nvsize=10, nvalign=4]
113// CHECK-X64: *** Dumping AST Record Layout
114// CHECK-X64-NEXT:    0 | struct Z
115// CHECK-X64-NEXT:    0 |   (Z vbtable pointer)
116// CHECK-X64-NEXT:    8 |   char a
117// CHECK-X64-NEXT:   10 |   int b
118// CHECK-X64-NEXT:   16 |   struct B (virtual base)
119// CHECK-X64-NEXT:   16 |     long long a
120// CHECK-X64-NEXT:      | [sizeof=24, align=4
121// CHECK-X64-NEXT:      |  nvsize=14, nvalign=4]
122
123#pragma pack(pop)
124
125struct A1 { long long a; };
126#pragma pack(push, 1)
127struct B1 : virtual A1 { char a; };
128#pragma pack(pop)
129struct C1 : B1 {};
130
131// CHECK: *** Dumping AST Record Layout
132// CHECK: *** Dumping AST Record Layout
133// CHECK: *** Dumping AST Record Layout
134// CHECK-NEXT:    0 | struct C1
135// CHECK-NEXT:    0 |   struct B1 (base)
136// CHECK-NEXT:    0 |     (B1 vbtable pointer)
137// CHECK-NEXT:    4 |     char a
138// CHECK-NEXT:    8 |   struct A1 (virtual base)
139// CHECK-NEXT:    8 |     long long a
140// CHECK-NEXT:      | [sizeof=16, align=8
141// CHECK-NEXT:      |  nvsize=5, nvalign=8]
142// CHECK-X64: *** Dumping AST Record Layout
143// CHECK-X64: *** Dumping AST Record Layout
144// CHECK-X64: *** Dumping AST Record Layout
145// CHECK-X64-NEXT:    0 | struct C1
146// CHECK-X64-NEXT:    0 |   struct B1 (base)
147// CHECK-X64-NEXT:    0 |     (B1 vbtable pointer)
148// CHECK-X64-NEXT:    8 |     char a
149// CHECK-X64-NEXT:   16 |   struct A1 (virtual base)
150// CHECK-X64-NEXT:   16 |     long long a
151// CHECK-X64-NEXT:      | [sizeof=24, align=8
152// CHECK-X64-NEXT:      |  nvsize=9, nvalign=8]
153
154struct CA0 {
155	CA0() {}
156};
157struct CA1 : virtual CA0 {
158	CA1() {}
159};
160#pragma pack(push, 1)
161struct CA2 : public CA1, public CA0 {
162	virtual void CA2Method() {}
163	CA2() {}
164};
165#pragma pack(pop)
166
167// CHECK: *** Dumping AST Record Layout
168// CHECK: *** Dumping AST Record Layout
169// CHECK: *** Dumping AST Record Layout
170// CHECK-NEXT:    0 | struct CA2
171// CHECK-NEXT:    0 |   (CA2 vftable pointer)
172// CHECK-NEXT:    4 |   struct CA1 (base)
173// CHECK-NEXT:    4 |     (CA1 vbtable pointer)
174// CHECK-NEXT:    9 |   struct CA0 (base) (empty)
175// CHECK-NEXT:    9 |   struct CA0 (virtual base) (empty)
176// CHECK-NEXT:      | [sizeof=9, align=1
177// CHECK-NEXT:      |  nvsize=9, nvalign=1]
178// CHECK-X64: *** Dumping AST Record Layout
179// CHECK-X64: *** Dumping AST Record Layout
180// CHECK-X64: *** Dumping AST Record Layout
181// CHECK-X64-NEXT:    0 | struct CA2
182// CHECK-X64-NEXT:    0 |   (CA2 vftable pointer)
183// CHECK-X64-NEXT:    8 |   struct CA1 (base)
184// CHECK-X64-NEXT:    8 |     (CA1 vbtable pointer)
185// CHECK-X64-NEXT:   17 |   struct CA0 (base) (empty)
186// CHECK-X64-NEXT:   17 |   struct CA0 (virtual base) (empty)
187// CHECK-X64-NEXT:      | [sizeof=17, align=1
188// CHECK-X64-NEXT:      |  nvsize=17, nvalign=1]
189
190#pragma pack(16)
191struct YA {
192	__declspec(align(32)) char : 1;
193};
194// CHECK: *** Dumping AST Record Layout
195// CHECK-NEXT:    0 | struct YA (empty)
196// CHECK-NEXT:    0 |   char
197// CHECK-NEXT:      | [sizeof=32, align=32
198// CHECK-NEXT:      |  nvsize=32, nvalign=32]
199// CHECK-X64: *** Dumping AST Record Layout
200// CHECK-X64-NEXT:    0 | struct YA (empty)
201// CHECK-X64-NEXT:    0 |   char
202// CHECK-X64-NEXT:      | [sizeof=32, align=32
203// CHECK-X64-NEXT:      |  nvsize=32, nvalign=32]
204
205#pragma pack(1)
206struct YB {
207	char a;
208	YA b;
209};
210// CHECK: *** Dumping AST Record Layout
211// CHECK-NEXT:    0 | struct YB
212// CHECK-NEXT:    0 |   char a
213// CHECK-NEXT:    1 |   struct YA b (empty)
214// CHECK-NEXT:    1 |     char
215// CHECK-NEXT:      |   [sizeof=32, align=32
216// CHECK-NEXT:      |    nvsize=32, nvalign=32]
217// CHECK-NEXT:      | [sizeof=33, align=1
218// CHECK-NEXT:      |  nvsize=33, nvalign=1]
219// CHECK-X64: *** Dumping AST Record Layout
220// CHECK-X64-NEXT:    0 | struct YB
221// CHECK-X64-NEXT:    0 |   char a
222// CHECK-X64-NEXT:    1 |   struct YA b (empty)
223// CHECK-X64-NEXT:    1 |     char
224// CHECK-X64-NEXT:      |   [sizeof=32, align=32
225// CHECK-X64-NEXT:      |    nvsize=32, nvalign=32]
226// CHECK-X64-NEXT:      | [sizeof=33, align=1
227// CHECK-X64-NEXT:      |  nvsize=33, nvalign=1]
228
229#pragma pack(8)
230struct YC {
231	__declspec(align(32)) char : 1;
232};
233// CHECK: *** Dumping AST Record Layout
234// CHECK-NEXT:    0 | struct YC (empty)
235// CHECK-NEXT:    0 |   char
236// CHECK-NEXT:      | [sizeof=32, align=32
237// CHECK-NEXT:      |  nvsize=32, nvalign=32]
238// CHECK-X64: *** Dumping AST Record Layout
239// CHECK-X64-NEXT:    0 | struct YC (empty)
240// CHECK-X64-NEXT:    0 |   char
241// CHECK-X64-NEXT:      | [sizeof=8, align=32
242// CHECK-X64-NEXT:      |  nvsize=8, nvalign=32]
243
244#pragma pack(1)
245struct YD {
246	char a;
247	YC b;
248};
249// CHECK: *** Dumping AST Record Layout
250// CHECK-NEXT:    0 | struct YD
251// CHECK-NEXT:    0 |   char a
252// CHECK-NEXT:    1 |   struct YC b (empty)
253// CHECK-NEXT:    1 |     char
254// CHECK-NEXT:      |   [sizeof=32, align=32
255// CHECK-NEXT:      |    nvsize=32, nvalign=32]
256// CHECK-NEXT:      | [sizeof=33, align=1
257// CHECK-NEXT:      |  nvsize=33, nvalign=1]
258// CHECK-X64: *** Dumping AST Record Layout
259// CHECK-X64-NEXT:    0 | struct YD
260// CHECK-X64-NEXT:    0 |   char a
261// CHECK-X64-NEXT:    1 |   struct YC b (empty)
262// CHECK-X64-NEXT:    1 |     char
263// CHECK-X64-NEXT:      |   [sizeof=8, align=32
264// CHECK-X64-NEXT:      |    nvsize=8, nvalign=32]
265// CHECK-X64-NEXT:      | [sizeof=9, align=1
266// CHECK-X64-NEXT:      |  nvsize=9, nvalign=1]
267
268#pragma pack(4)
269struct YE {
270	__declspec(align(32)) char : 1;
271};
272// CHECK: *** Dumping AST Record Layout
273// CHECK-NEXT:    0 | struct YE (empty)
274// CHECK-NEXT:    0 |   char
275// CHECK-NEXT:      | [sizeof=4, align=32
276// CHECK-NEXT:      |  nvsize=4, nvalign=32]
277// CHECK-X64: *** Dumping AST Record Layout
278// CHECK-X64-NEXT:    0 | struct YE (empty)
279// CHECK-X64-NEXT:    0 |   char
280// CHECK-X64-NEXT:      | [sizeof=4, align=32
281// CHECK-X64-NEXT:      |  nvsize=4, nvalign=32]
282
283#pragma pack(1)
284struct YF {
285	char a;
286	YE b;
287};
288// CHECK: *** Dumping AST Record Layout
289// CHECK-NEXT:    0 | struct YF
290// CHECK-NEXT:    0 |   char a
291// CHECK-NEXT:    1 |   struct YE b (empty)
292// CHECK-NEXT:    1 |     char
293// CHECK-NEXT:      |   [sizeof=4, align=32
294// CHECK-NEXT:      |    nvsize=4, nvalign=32]
295// CHECK-NEXT:      | [sizeof=5, align=1
296// CHECK-NEXT:      |  nvsize=5, nvalign=1]
297// CHECK-X64: *** Dumping AST Record Layout
298// CHECK-X64-NEXT:    0 | struct YF
299// CHECK-X64-NEXT:    0 |   char a
300// CHECK-X64-NEXT:    1 |   struct YE b (empty)
301// CHECK-X64-NEXT:    1 |     char
302// CHECK-X64-NEXT:      |   [sizeof=4, align=32
303// CHECK-X64-NEXT:      |    nvsize=4, nvalign=32]
304// CHECK-X64-NEXT:      | [sizeof=5, align=1
305// CHECK-X64-NEXT:      |  nvsize=5, nvalign=1]
306
307#pragma pack(16)
308struct __declspec(align(16)) D0 { char a; };
309#pragma pack(1)
310struct D1 : public D0 { char a; };
311#pragma pack(16)
312struct D2 : D1 { char a; };
313
314// CHECK: *** Dumping AST Record Layout
315// CHECK: *** Dumping AST Record Layout
316// CHECK: *** Dumping AST Record Layout
317// CHECK-NEXT:    0 | struct D2
318// CHECK-NEXT:    0 |   struct D1 (base)
319// CHECK-NEXT:    0 |     struct D0 (base)
320// CHECK-NEXT:    0 |       char a
321// CHECK-NEXT:    1 |     char a
322// CHECK-NEXT:    2 |   char a
323// CHECK-NEXT:      | [sizeof=16, align=16
324// CHECK-NEXT:      |  nvsize=16, nvalign=16]
325// CHECK-X64: *** Dumping AST Record Layout
326// CHECK-X64: *** Dumping AST Record Layout
327// CHECK-X64: *** Dumping AST Record Layout
328// CHECK-X64-NEXT:    0 | struct D2
329// CHECK-X64-NEXT:    0 |   struct D1 (base)
330// CHECK-X64-NEXT:    0 |     struct D0 (base)
331// CHECK-X64-NEXT:    0 |       char a
332// CHECK-X64-NEXT:    1 |     char a
333// CHECK-X64-NEXT:    2 |   char a
334// CHECK-X64-NEXT:      | [sizeof=16, align=16
335// CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
336
337#pragma pack()
338struct JA { char a; };
339#pragma pack(1)
340struct JB { __declspec(align(4)) char a; };
341#pragma pack()
342struct JC : JB, JA { };
343
344// CHECK: *** Dumping AST Record Layout
345// CHECK: *** Dumping AST Record Layout
346// CHECK: *** Dumping AST Record Layout
347// CHECK-NEXT:    0 | struct JC
348// CHECK-NEXT:    0 |   struct JB (base)
349// CHECK-NEXT:    0 |     char a
350// CHECK-NEXT:    1 |   struct JA (base)
351// CHECK-NEXT:    1 |     char a
352// CHECK-NEXT:      | [sizeof=4, align=4
353// CHECK-NEXT:      |  nvsize=4, nvalign=4]
354// CHECK-X64: *** Dumping AST Record Layout
355// CHECK-X64: *** Dumping AST Record Layout
356// CHECK-X64: *** Dumping AST Record Layout
357// CHECK-X64-NEXT:    0 | struct JC
358// CHECK-X64-NEXT:    0 |   struct JB (base)
359// CHECK-X64-NEXT:    0 |     char a
360// CHECK-X64-NEXT:    1 |   struct JA (base)
361// CHECK-X64-NEXT:    1 |     char a
362// CHECK-X64-NEXT:      | [sizeof=4, align=4
363// CHECK-X64-NEXT:      |  nvsize=4, nvalign=4]
364
365#pragma pack()
366struct KA { char a; };
367#pragma pack(1)
368struct KB : KA { __declspec(align(2)) char a; };
369
370// CHECK: *** Dumping AST Record Layout
371// CHECK: *** Dumping AST Record Layout
372// CHECK-NEXT:    0 | struct KB
373// CHECK-NEXT:    0 |   struct KA (base)
374// CHECK-NEXT:    0 |     char a
375// CHECK-NEXT:    2 |   char a
376// CHECK-NEXT:      | [sizeof=4, align=2
377// CHECK-NEXT:      |  nvsize=3, nvalign=2]
378// CHECK-X64: *** Dumping AST Record Layout
379// CHECK-X64: *** Dumping AST Record Layout
380// CHECK-X64-NEXT:    0 | struct KB
381// CHECK-X64-NEXT:    0 |   struct KA (base)
382// CHECK-X64-NEXT:    0 |     char a
383// CHECK-X64-NEXT:    2 |   char a
384// CHECK-X64-NEXT:      | [sizeof=4, align=2
385// CHECK-X64-NEXT:      |  nvsize=3, nvalign=2]
386
387#pragma pack(1)
388struct L {
389  virtual void fun() {}
390  __declspec(align(256)) int Field;
391};
392
393// CHECK: *** Dumping AST Record Layout
394// CHECK-NEXT:    0 | struct L
395// CHECK-NEXT:    0 |   (L vftable pointer)
396// CHECK-NEXT:  256 |   int Field
397// CHECK-NEXT:      | [sizeof=512, align=256
398// CHECK-NEXT:      |  nvsize=260, nvalign=256]
399// CHECK-X64: *** Dumping AST Record Layout
400// CHECK-X64-NEXT:    0 | struct L
401// CHECK-X64-NEXT:    0 |   (L vftable pointer)
402// CHECK-X64-NEXT:  256 |   int Field
403// CHECK-X64-NEXT:      | [sizeof=512, align=256
404// CHECK-X64-NEXT:      |  nvsize=260, nvalign=256]
405
406#pragma pack()
407struct MA {};
408#pragma pack(1)
409struct MB : virtual MA {
410  __declspec(align(256)) int Field;
411};
412
413// CHECK: *** Dumping AST Record Layout
414// CHECK: *** Dumping AST Record Layout
415// CHECK-NEXT:    0 | struct MB
416// CHECK-NEXT:    0 |   (MB vbtable pointer)
417// CHECK-NEXT:  256 |   int Field
418// CHECK-NEXT:  260 |   struct MA (virtual base) (empty)
419// CHECK-NEXT:      | [sizeof=512, align=256
420// CHECK-NEXT:      |  nvsize=260, nvalign=256]
421// CHECK-X64: *** Dumping AST Record Layout
422// CHECK-X64: *** Dumping AST Record Layout
423// CHECK-X64-NEXT:    0 | struct MB
424// CHECK-X64-NEXT:    0 |   (MB vbtable pointer)
425// CHECK-X64-NEXT:  256 |   int Field
426// CHECK-X64-NEXT:  260 |   struct MA (virtual base) (empty)
427// CHECK-X64-NEXT:      | [sizeof=512, align=256
428// CHECK-X64-NEXT:      |  nvsize=260, nvalign=256]
429
430struct RA {};
431#pragma pack(1)
432struct __declspec(align(8)) RB0 {
433	__declspec(align(1024)) int b : 3;
434};
435
436struct __declspec(align(8)) RB1 {
437	__declspec(align(1024)) int b : 3;
438	virtual void f() {}
439};
440
441struct __declspec(align(8)) RB2 : virtual RA {
442	__declspec(align(1024)) int b : 3;
443};
444
445struct __declspec(align(8)) RB3 : virtual RA {
446	__declspec(align(1024)) int b : 3;
447	virtual void f() {}
448};
449
450struct RC {
451	char _;
452	__declspec(align(1024)) int c : 3;
453};
454struct RE {
455	char _;
456	RC c;
457};
458#pragma pack()
459
460// CHECK: *** Dumping AST Record Layout
461// CHECK-NEXT:    0 | struct RB0
462// CHECK-NEXT:    0 |   int b
463// CHECK-NEXT:      | [sizeof=8, align=1024
464// CHECK-NEXT:      |  nvsize=4, nvalign=1024]
465// CHECK: *** Dumping AST Record Layout
466// CHECK-NEXT:    0 | struct RB1
467// CHECK-NEXT:    0 |   (RB1 vftable pointer)
468// CHECK-NEXT: 1024 |   int b
469// CHECK-NEXT:      | [sizeof=1032, align=1024
470// CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
471// CHECK: *** Dumping AST Record Layout
472// CHECK: *** Dumping AST Record Layout
473// CHECK-NEXT:    0 | struct RB2
474// CHECK-NEXT:    0 |   (RB2 vbtable pointer)
475// CHECK-NEXT: 1024 |   int b
476// CHECK-NEXT: 1028 |   struct RA (virtual base) (empty)
477// CHECK-NEXT:      | [sizeof=1032, align=1024
478// CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
479// CHECK: *** Dumping AST Record Layout
480// CHECK-NEXT:    0 | struct RB3
481// CHECK-NEXT:    0 |   (RB3 vftable pointer)
482// CHECK-NEXT: 1024 |   (RB3 vbtable pointer)
483// CHECK-NEXT: 2048 |   int b
484// CHECK-NEXT: 2052 |   struct RA (virtual base) (empty)
485// CHECK-NEXT:      | [sizeof=2056, align=1024
486// CHECK-NEXT:      |  nvsize=2052, nvalign=1024]
487// CHECK: *** Dumping AST Record Layout
488// CHECK-NEXT:    0 | struct RC
489// CHECK-NEXT:    0 |   char _
490// CHECK-NEXT: 1024 |   int c
491// CHECK-NEXT:      | [sizeof=1028, align=1024
492// CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
493// CHECK: *** Dumping AST Record Layout
494// CHECK-NEXT:    0 | struct RE
495// CHECK-NEXT:    0 |   char _
496// CHECK-NEXT:    1 |   struct RC c
497// CHECK-NEXT:    1 |     char _
498// CHECK-NEXT: 1025 |     int c
499// CHECK-NEXT:      |   [sizeof=1028, align=1024
500// CHECK-NEXT:      |    nvsize=1028, nvalign=1024]
501// CHECK-NEXT:      | [sizeof=1029, align=1
502// CHECK-NEXT:      |  nvsize=1029, nvalign=1]
503// CHECK-X64: *** Dumping AST Record Layout
504// CHECK-X64-NEXT:    0 | struct RB0
505// CHECK-X64-NEXT:    0 |   int b
506// CHECK-X64-NEXT:      | [sizeof=8, align=1024
507// CHECK-X64-NEXT:      |  nvsize=4, nvalign=1024]
508// CHECK-X64: *** Dumping AST Record Layout
509// CHECK-X64-NEXT:    0 | struct RB1
510// CHECK-X64-NEXT:    0 |   (RB1 vftable pointer)
511// CHECK-X64-NEXT: 1024 |   int b
512// CHECK-X64-NEXT:      | [sizeof=1032, align=1024
513// CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
514// CHECK-X64: *** Dumping AST Record Layout
515// CHECK-X64: *** Dumping AST Record Layout
516// CHECK-X64-NEXT:    0 | struct RB2
517// CHECK-X64-NEXT:    0 |   (RB2 vbtable pointer)
518// CHECK-X64-NEXT: 1024 |   int b
519// CHECK-X64-NEXT: 1028 |   struct RA (virtual base) (empty)
520// CHECK-X64-NEXT:      | [sizeof=1032, align=1024
521// CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
522// CHECK-X64: *** Dumping AST Record Layout
523// CHECK-X64-NEXT:    0 | struct RB3
524// CHECK-X64-NEXT:    0 |   (RB3 vftable pointer)
525// CHECK-X64-NEXT: 1024 |   (RB3 vbtable pointer)
526// CHECK-X64-NEXT: 2048 |   int b
527// CHECK-X64-NEXT: 2052 |   struct RA (virtual base) (empty)
528// CHECK-X64-NEXT:      | [sizeof=2056, align=1024
529// CHECK-X64-NEXT:      |  nvsize=2052, nvalign=1024]
530// CHECK-X64: *** Dumping AST Record Layout
531// CHECK-X64-NEXT:    0 | struct RC
532// CHECK-X64-NEXT:    0 |   char _
533// CHECK-X64-NEXT: 1024 |   int c
534// CHECK-X64-NEXT:      | [sizeof=1028, align=1024
535// CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
536// CHECK-X64: *** Dumping AST Record Layout
537// CHECK-X64-NEXT:    0 | struct RE
538// CHECK-X64-NEXT:    0 |   char _
539// CHECK-X64-NEXT:    1 |   struct RC c
540// CHECK-X64-NEXT:    1 |     char _
541// CHECK-X64-NEXT: 1025 |     int c
542// CHECK-X64-NEXT:      |   [sizeof=1028, align=1024
543// CHECK-X64-NEXT:      |    nvsize=1028, nvalign=1024]
544// CHECK-X64-NEXT:      | [sizeof=1029, align=1
545// CHECK-X64-NEXT:      |  nvsize=1029, nvalign=1]
546
547struct NA {};
548struct NB {};
549#pragma pack(push, 1)
550struct NC : virtual NA, virtual NB {};
551#pragma pack(pop)
552struct ND : NC {};
553
554// CHECK: *** Dumping AST Record Layout
555// CHECK-NEXT:    0 | struct NA (empty)
556// CHECK-NEXT:      | [sizeof=1, align=1
557// CHECK-NEXT:      |  nvsize=0, nvalign=1]
558// CHECK: *** Dumping AST Record Layout
559// CHECK-NEXT:    0 | struct NB (empty)
560// CHECK-NEXT:      | [sizeof=1, align=1
561// CHECK-NEXT:      |  nvsize=0, nvalign=1]
562// CHECK: *** Dumping AST Record Layout
563// CHECK-NEXT:    0 | struct NC
564// CHECK-NEXT:    0 |   (NC vbtable pointer)
565// CHECK-NEXT:    4 |   struct NA (virtual base) (empty)
566// CHECK-NEXT:    8 |   struct NB (virtual base) (empty)
567// CHECK-NEXT:      | [sizeof=8, align=1
568// CHECK-NEXT:      |  nvsize=4, nvalign=1]
569// CHECK: *** Dumping AST Record Layout
570// CHECK-NEXT:    0 | struct ND
571// CHECK-NEXT:    0 |   struct NC (base)
572// CHECK-NEXT:    0 |     (NC vbtable pointer)
573// CHECK-NEXT:    4 |   struct NA (virtual base) (empty)
574// CHECK-NEXT:    8 |   struct NB (virtual base) (empty)
575// CHECK-NEXT:      | [sizeof=8, align=4
576// CHECK-NEXT:      |  nvsize=4, nvalign=4]
577// CHECK-X64: *** Dumping AST Record Layout
578// CHECK-X64-NEXT:    0 | struct NA (empty)
579// CHECK-X64-NEXT:      | [sizeof=1, align=1
580// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
581// CHECK-X64: *** Dumping AST Record Layout
582// CHECK-X64-NEXT:    0 | struct NB (empty)
583// CHECK-X64-NEXT:      | [sizeof=1, align=1
584// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
585// CHECK-X64: *** Dumping AST Record Layout
586// CHECK-X64-NEXT:    0 | struct NC
587// CHECK-X64-NEXT:    0 |   (NC vbtable pointer)
588// CHECK-X64-NEXT:    8 |   struct NA (virtual base) (empty)
589// CHECK-X64-NEXT:   12 |   struct NB (virtual base) (empty)
590// CHECK-X64-NEXT:      | [sizeof=12, align=1
591// CHECK-X64-NEXT:      |  nvsize=8, nvalign=1]
592// CHECK-X64: *** Dumping AST Record Layout
593// CHECK-X64-NEXT:    0 | struct ND
594// CHECK-X64-NEXT:    0 |   struct NC (base)
595// CHECK-X64-NEXT:    0 |     (NC vbtable pointer)
596// CHECK-X64-NEXT:    8 |   struct NA (virtual base) (empty)
597// CHECK-X64-NEXT:   12 |   struct NB (virtual base) (empty)
598// CHECK-X64-NEXT:      | [sizeof=12, align=4
599// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
600
601struct OA {};
602struct OB {};
603struct OC : virtual OA, virtual OB {};
604#pragma pack(push, 1)
605struct OD : OC {};
606#pragma pack(pop)
607
608// CHECK: *** Dumping AST Record Layout
609// CHECK-NEXT:    0 | struct OA (empty)
610// CHECK-NEXT:      | [sizeof=1, align=1
611// CHECK-NEXT:      |  nvsize=0, nvalign=1]
612// CHECK: *** Dumping AST Record Layout
613// CHECK-NEXT:    0 | struct OB (empty)
614// CHECK-NEXT:      | [sizeof=1, align=1
615// CHECK-NEXT:      |  nvsize=0, nvalign=1]
616// CHECK: *** Dumping AST Record Layout
617// CHECK-NEXT:    0 | struct OC
618// CHECK-NEXT:    0 |   (OC vbtable pointer)
619// CHECK-NEXT:    4 |   struct OA (virtual base) (empty)
620// CHECK-NEXT:    8 |   struct OB (virtual base) (empty)
621// CHECK-NEXT:      | [sizeof=8, align=4
622// CHECK-NEXT:      |  nvsize=4, nvalign=4]
623// CHECK: *** Dumping AST Record Layout
624// CHECK-NEXT:    0 | struct OD
625// CHECK-NEXT:    0 |   struct OC (base)
626// CHECK-NEXT:    0 |     (OC vbtable pointer)
627// CHECK-NEXT:    4 |   struct OA (virtual base) (empty)
628// CHECK-NEXT:    8 |   struct OB (virtual base) (empty)
629// CHECK-NEXT:      | [sizeof=8, align=1
630// CHECK-NEXT:      |  nvsize=4, nvalign=1]
631// CHECK-X64: *** Dumping AST Record Layout
632// CHECK-X64-NEXT:    0 | struct OA (empty)
633// CHECK-X64-NEXT:      | [sizeof=1, align=1
634// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
635// CHECK-X64: *** Dumping AST Record Layout
636// CHECK-X64-NEXT:    0 | struct OB (empty)
637// CHECK-X64-NEXT:      | [sizeof=1, align=1
638// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
639// CHECK-X64: *** Dumping AST Record Layout
640// CHECK-X64-NEXT:    0 | struct OC
641// CHECK-X64-NEXT:    0 |   (OC vbtable pointer)
642// CHECK-X64-NEXT:    8 |   struct OA (virtual base) (empty)
643// CHECK-X64-NEXT:   12 |   struct OB (virtual base) (empty)
644// CHECK-X64-NEXT:      | [sizeof=16, align=8
645// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
646// CHECK-X64: *** Dumping AST Record Layout
647// CHECK-X64-NEXT:    0 | struct OD
648// CHECK-X64-NEXT:    0 |   struct OC (base)
649// CHECK-X64-NEXT:    0 |     (OC vbtable pointer)
650// CHECK-X64-NEXT:    8 |   struct OA (virtual base) (empty)
651// CHECK-X64-NEXT:   12 |   struct OB (virtual base) (empty)
652// CHECK-X64-NEXT:      | [sizeof=12, align=1
653// CHECK-X64-NEXT:      |  nvsize=8, nvalign=1]
654
655struct __declspec(align(4)) PA {
656  int c;
657};
658
659typedef __declspec(align(8)) PA PB;
660
661#pragma pack(push, 1)
662struct PC {
663  char a;
664  PB x;
665};
666#pragma pack(pop)
667
668// CHECK: *** Dumping AST Record Layout
669// CHECK:         0 | struct PC
670// CHECK-NEXT:    0 |   char a
671// CHECK-NEXT:    8 |   struct PA x
672// CHECK-NEXT:    8 |     int c
673// CHECK-NEXT:      |   [sizeof=4, align=4
674// CHECK-NEXT:      |    nvsize=4, nvalign=4]
675// CHECK-NEXT:      | [sizeof=16, align=8
676// CHECK-NEXT:      |  nvsize=12, nvalign=8]
677// CHECK-X64: *** Dumping AST Record Layout
678// CHECK-X64:         0 | struct PC
679// CHECK-X64-NEXT:    0 |   char a
680// CHECK-X64-NEXT:    8 |   struct PA x
681// CHECK-X64-NEXT:    8 |     int c
682// CHECK-X64-NEXT:      |   [sizeof=4, align=4
683// CHECK-X64-NEXT:      |    nvsize=4, nvalign=4]
684// CHECK-X64-NEXT:      | [sizeof=16, align=8
685// CHECK-X64-NEXT:      |  nvsize=12, nvalign=8]
686
687typedef PB PD;
688
689#pragma pack(push, 1)
690struct PE {
691  char a;
692  PD x;
693};
694#pragma pack(pop)
695
696// CHECK: *** Dumping AST Record Layout
697// CHECK:         0 | struct PE
698// CHECK-NEXT:    0 |   char a
699// CHECK-NEXT:    8 |   struct PA x
700// CHECK-NEXT:    8 |     int c
701// CHECK-NEXT:      |   [sizeof=4, align=4
702// CHECK-NEXT:      |    nvsize=4, nvalign=4]
703// CHECK-NEXT:      | [sizeof=16, align=8
704// CHECK-NEXT:      |  nvsize=12, nvalign=8]
705// CHECK-X64: *** Dumping AST Record Layout
706// CHECK-X64:         0 | struct PE
707// CHECK-X64-NEXT:    0 |   char a
708// CHECK-X64-NEXT:    8 |   struct PA x
709// CHECK-X64-NEXT:    8 |     int c
710// CHECK-X64-NEXT:      |   [sizeof=4, align=4
711// CHECK-X64-NEXT:      |    nvsize=4, nvalign=4]
712// CHECK-X64-NEXT:      | [sizeof=16, align=8
713// CHECK-X64-NEXT:      |  nvsize=12, nvalign=8]
714
715typedef int __declspec(align(2)) QA;
716#pragma pack(push, 1)
717struct QB {
718  char a;
719  QA b;
720};
721#pragma pack(pop)
722
723// CHECK: *** Dumping AST Record Layout
724// CHECK-NEXT:    0 | struct QB
725// CHECK-NEXT:    0 |   char a
726// CHECK-NEXT:    2 |   QA b
727// CHECK-NEXT:      | [sizeof=6, align=2
728// CHECK-NEXT:      |  nvsize=6, nvalign=2]
729// CHECK-X64: *** Dumping AST Record Layout
730// CHECK-X64-NEXT:    0 | struct QB
731// CHECK-X64-NEXT:    0 |   char a
732// CHECK-X64-NEXT:    2 |   QA b
733// CHECK-X64-NEXT:      | [sizeof=6, align=2
734// CHECK-X64-NEXT:      |  nvsize=6, nvalign=2]
735
736struct QC {
737  char a;
738  QA b;
739};
740
741// CHECK: *** Dumping AST Record Layout
742// CHECK-NEXT:    0 | struct QC
743// CHECK-NEXT:    0 |   char a
744// CHECK-NEXT:    4 |   QA b
745// CHECK-NEXT:      | [sizeof=8, align=4
746// CHECK-NEXT:      |  nvsize=8, nvalign=4]
747// CHECK-X64: *** Dumping AST Record Layout
748// CHECK-X64-NEXT:    0 | struct QC
749// CHECK-X64-NEXT:    0 |   char a
750// CHECK-X64-NEXT:    4 |   QA b
751// CHECK-X64-NEXT:      | [sizeof=8, align=4
752// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
753
754struct QD {
755  char a;
756  QA b : 3;
757};
758
759// CHECK: *** Dumping AST Record Layout
760// CHECK-NEXT:    0 | struct QD
761// CHECK-NEXT:    0 |   char a
762// CHECK-NEXT:    4 |   QA b
763// CHECK-NEXT:      | [sizeof=8, align=4
764// CHECK-NEXT:      |  nvsize=8, nvalign=4]
765// CHECK-X64: *** Dumping AST Record Layout
766// CHECK-X64-NEXT:    0 | struct QD
767// CHECK-X64-NEXT:    0 |   char a
768// CHECK-X64-NEXT:    4 |   QA b
769// CHECK-X64-NEXT:      | [sizeof=8, align=4
770// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
771
772struct __declspec(align(4)) EmptyAlignedLongLongMemb {
773  long long FlexArrayMemb[0];
774};
775
776// CHECK: *** Dumping AST Record Layout
777// CHECK-NEXT:    0 | struct EmptyAlignedLongLongMemb
778// CHECK-NEXT:    0 |   long long [0] FlexArrayMemb
779// CHECK-NEXT:      | [sizeof=8, align=8
780// CHECK-NEXT:      |  nvsize=0, nvalign=8]
781// CHECK-X64: *** Dumping AST Record Layout
782// CHECK-X64-NEXT:    0 | struct EmptyAlignedLongLongMemb
783// CHECK-X64-NEXT:    0 |   long long [0] FlexArrayMemb
784// CHECK-X64-NEXT:      | [sizeof=8, align=8
785// CHECK-X64-NEXT:      |  nvsize=0, nvalign=8]
786
787#pragma pack(1)
788struct __declspec(align(4)) EmptyPackedAlignedLongLongMemb {
789  long long FlexArrayMemb[0];
790};
791#pragma pack()
792
793// CHECK: *** Dumping AST Record Layout
794// CHECK-NEXT:    0 | struct EmptyPackedAlignedLongLongMemb
795// CHECK-NEXT:    0 |   long long [0] FlexArrayMemb
796// CHECK-NEXT:      | [sizeof=4, align=4
797// CHECK-NEXT:      |  nvsize=0, nvalign=4]
798// CHECK-X64: *** Dumping AST Record Layout
799// CHECK-X64-NEXT:    0 | struct EmptyPackedAlignedLongLongMemb
800// CHECK-X64-NEXT:    0 |   long long [0] FlexArrayMemb
801// CHECK-X64-NEXT:      | [sizeof=4, align=4
802// CHECK-X64-NEXT:      |  nvsize=0, nvalign=4]
803
804int a[
805sizeof(X)+
806sizeof(Y)+
807sizeof(Z)+
808sizeof(C1)+
809sizeof(CA2)+
810sizeof(YA)+
811sizeof(YB)+
812sizeof(YC)+
813sizeof(YD)+
814sizeof(YE)+
815sizeof(YF)+
816sizeof(YF)+
817sizeof(D2)+
818sizeof(JC)+
819sizeof(KB)+
820sizeof(L)+
821sizeof(MB)+
822sizeof(RB0)+
823sizeof(RB1)+
824sizeof(RB2)+
825sizeof(RB3)+
826sizeof(RC)+
827sizeof(RE)+
828sizeof(ND)+
829sizeof(OD)+
830sizeof(PC)+
831sizeof(PE)+
832sizeof(QB)+
833sizeof(QC)+
834sizeof(QD)+
835sizeof(EmptyAlignedLongLongMemb)+
836sizeof(EmptyPackedAlignedLongLongMemb)+
8370];
838