1// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
2// RUN:            | FileCheck %s
3// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
4// RUN:            | FileCheck %s
5
6extern "C" int printf(const char *fmt, ...);
7
8struct __declspec(align(8)) B0 { B0() {printf("B0 : %p\n", this);} };
9struct __declspec(align(8)) B1 { B1() {printf("B1 : %p\n", this);} };
10struct __declspec(align(8)) B2 { B2() {printf("B2 : %p\n", this);} };
11struct __declspec(align(8)) B3 { B3() {printf("B3 : %p\n", this);} };
12struct __declspec(align(8)) B4 { B4() {printf("B4 : %p\n", this);} };
13
14struct C0 { int a; C0() : a(0xf00000C0) {printf("C0 : %p\n", this);} };
15struct C1 { int a; C1() : a(0xf00000C1) {printf("C1 : %p\n", this);} };
16struct C2 { int a; C2() : a(0xf00000C2) {printf("C2 : %p\n", this);} };
17struct C3 { int a; C3() : a(0xf00000C3) {printf("C3 : %p\n", this);} };
18struct C4 { int a; C4() : a(0xf00000C4) {printf("C4 : %p\n", this);} };
19
20struct A : B0 {
21	int a;
22	A() : a(0xf000000A) {printf("X : %p\n", this);}
23};
24
25// CHECK: *** Dumping AST Record Layout
26// CHECK: *** Dumping AST Record Layout
27// CHECK-NEXT:    0 | struct A
28// CHECK-NEXT:    0 |   struct B0 (base) (empty)
29// CHECK-NEXT:    0 |   int a
30// CHECK-NEXT:      | [sizeof=8, align=8
31// CHECK-NEXT:      |  nvsize=8, nvalign=8]
32
33struct B : B0 {
34	B0 b0;
35	int a;
36	B() : a(0xf000000B) {printf("X : %p\n", this);}
37};
38
39// CHECK: *** Dumping AST Record Layout
40// CHECK-NEXT:    0 | struct B
41// CHECK-NEXT:    0 |   struct B0 (base) (empty)
42// CHECK-NEXT:    0 |   struct B0 b0 (empty)
43// CHECK:         8 |   int a
44// CHECK-NEXT:      | [sizeof=16, align=8
45// CHECK-NEXT:      |  nvsize=16, nvalign=8]
46
47struct C : B0, B1, B2, B3, B4 {
48	int a;
49	C() : a(0xf000000C) {printf("X : %p\n", this);}
50};
51
52// CHECK: *** Dumping AST Record Layout
53// CHECK: *** Dumping AST Record Layout
54// CHECK: *** Dumping AST Record Layout
55// CHECK: *** Dumping AST Record Layout
56// CHECK: *** Dumping AST Record Layout
57// CHECK-NEXT:    0 | struct C
58// CHECK-NEXT:    0 |   struct B0 (base) (empty)
59// CHECK-NEXT:    8 |   struct B1 (base) (empty)
60// CHECK-NEXT:   16 |   struct B2 (base) (empty)
61// CHECK-NEXT:   24 |   struct B3 (base) (empty)
62// CHECK-NEXT:   32 |   struct B4 (base) (empty)
63// CHECK-NEXT:   32 |   int a
64// CHECK-NEXT:      | [sizeof=40, align=8
65// CHECK-NEXT:      |  nvsize=40, nvalign=8]
66
67struct D {
68	B0 b0;
69	C0 c0;
70	C1 c1;
71	C2 c2;
72	B1 b1;
73	int a;
74	D() : a(0xf000000D) {printf("X : %p\n", this);}
75};
76
77// CHECK: *** Dumping AST Record Layout
78// CHECK: *** Dumping AST Record Layout
79// CHECK: *** Dumping AST Record Layout
80// CHECK: *** Dumping AST Record Layout
81// CHECK-NEXT:    0 | struct D
82// CHECK-NEXT:    0 |   struct B0 b0 (empty)
83// CHECK:         8 |   struct C0 c0
84// CHECK-NEXT:    8 |     int a
85// CHECK:        12 |   struct C1 c1
86// CHECK-NEXT:   12 |     int a
87// CHECK:        16 |   struct C2 c2
88// CHECK-NEXT:   16 |     int a
89// CHECK:        24 |   struct B1 b1 (empty)
90// CHECK:        32 |   int a
91// CHECK-NEXT:      | [sizeof=40, align=8
92// CHECK-NEXT:      |  nvsize=40, nvalign=8]
93
94struct E : B0, C0, C1, C2, B1 {
95	int a;
96	E() : a(0xf000000E) {printf("X : %p\n", this);}
97};
98
99// CHECK: *** Dumping AST Record Layout
100// CHECK-NEXT:    0 | struct E
101// CHECK-NEXT:    0 |   struct B0 (base) (empty)
102// CHECK-NEXT:    0 |   struct C0 (base)
103// CHECK-NEXT:    0 |     int a
104// CHECK-NEXT:    4 |   struct C1 (base)
105// CHECK-NEXT:    4 |     int a
106// CHECK-NEXT:    8 |   struct C2 (base)
107// CHECK-NEXT:    8 |     int a
108// CHECK-NEXT:   16 |   struct B1 (base) (empty)
109// CHECK-NEXT:   16 |   int a
110// CHECK-NEXT:      | [sizeof=24, align=8
111// CHECK-NEXT:      |  nvsize=24, nvalign=8]
112
113struct F : C0, B0, B1, C1 {
114	int a;
115	F() : a(0xf000000F) {printf("X : %p\n", this);}
116};
117
118// CHECK: *** Dumping AST Record Layout
119// CHECK-NEXT:    0 | struct F
120// CHECK-NEXT:    0 |   struct C0 (base)
121// CHECK-NEXT:    0 |     int a
122// CHECK-NEXT:    8 |   struct B0 (base) (empty)
123// CHECK-NEXT:   16 |   struct B1 (base) (empty)
124// CHECK-NEXT:   16 |   struct C1 (base)
125// CHECK-NEXT:   16 |     int a
126// CHECK-NEXT:   20 |   int a
127// CHECK-NEXT:      | [sizeof=24, align=8
128// CHECK-NEXT:      |  nvsize=24, nvalign=8]
129
130struct G : B0, B1, B2, B3, B4 {
131	__declspec(align(32)) int a;
132	G() : a(0xf0000011) {printf("X : %p\n", this);}
133};
134
135// CHECK: *** Dumping AST Record Layout
136// CHECK-NEXT:    0 | struct G
137// CHECK-NEXT:    0 |   struct B0 (base) (empty)
138// CHECK-NEXT:    8 |   struct B1 (base) (empty)
139// CHECK-NEXT:   16 |   struct B2 (base) (empty)
140// CHECK-NEXT:   24 |   struct B3 (base) (empty)
141// CHECK-NEXT:   32 |   struct B4 (base) (empty)
142// CHECK-NEXT:   32 |   int a
143// CHECK-NEXT:      | [sizeof=64, align=32
144// CHECK-NEXT:      |  nvsize=64, nvalign=32]
145
146struct __declspec(align(32)) H : B0, B1, B2, B3, B4 {
147	int a;
148	H() : a(0xf0000011) {printf("X : %p\n", this);}
149};
150
151// CHECK: *** Dumping AST Record Layout
152// CHECK-NEXT:    0 | struct H
153// CHECK-NEXT:    0 |   struct B0 (base) (empty)
154// CHECK-NEXT:    8 |   struct B1 (base) (empty)
155// CHECK-NEXT:   16 |   struct B2 (base) (empty)
156// CHECK-NEXT:   24 |   struct B3 (base) (empty)
157// CHECK-NEXT:   32 |   struct B4 (base) (empty)
158// CHECK-NEXT:   32 |   int a
159// CHECK-NEXT:      | [sizeof=64, align=32
160// CHECK-NEXT:      |  nvsize=40, nvalign=32]
161
162struct I {
163  int i0[0];
164};
165
166// CHECK: *** Dumping AST Record Layout
167// CHECK-NEXT:    0 | struct I
168// CHECK-NEXT:    0 |   int [0] i0
169// CHECK-NEXT:      | [sizeof={{1|4}}, align=4,
170// CHECK-NEXT:      |  nvsize=0, nvalign=4]
171
172struct J : I {
173  int j;
174};
175
176// CHECK: *** Dumping AST Record Layout
177// CHECK-NEXT:   0 | struct J
178// CHECK-NEXT:   0 |   struct I (base)
179// CHECK-NEXT:   0 |     int [0] i0
180// CHECK-NEXT:   0 |   int j
181// CHECK-NEXT:     | [sizeof=4, align=4,
182// CHECK-NEXT:     |  nvsize=4, nvalign=4]
183
184int a[
185sizeof(A)+
186sizeof(B)+
187sizeof(C)+
188sizeof(D)+
189sizeof(E)+
190sizeof(F)+
191sizeof(G)+
192sizeof(H)+
193sizeof(I)+
194sizeof(J)];
195