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