xref: /aosp_15_r20/external/clang/test/Sema/ms_bitfield_layout.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts %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 %s 2>/dev/null \
4*67e74705SXin Li // RUN:            | FileCheck %s
5*67e74705SXin Li 
6*67e74705SXin Li typedef struct A {
7*67e74705SXin Li 	char x;
8*67e74705SXin Li 	int a : 22;
9*67e74705SXin Li 	int : 0;
10*67e74705SXin Li 	int c : 10;
11*67e74705SXin Li 	char b : 3;
12*67e74705SXin Li 	char d: 4;
13*67e74705SXin Li 	short y;
14*67e74705SXin Li } A;
15*67e74705SXin Li 
16*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
17*67e74705SXin Li // CHECK-NEXT:      0 | struct A
18*67e74705SXin Li // CHECK-NEXT:      0 |   char x
19*67e74705SXin Li // CHECK-NEXT: 4:0-21 |   int a
20*67e74705SXin Li // CHECK-NEXT:    8:- |   int
21*67e74705SXin Li // CHECK-NEXT:  8:0-9 |   int c
22*67e74705SXin Li // CHECK-NEXT: 12:0-2 |   char b
23*67e74705SXin Li // CHECK-NEXT: 12:3-6 |   char d
24*67e74705SXin Li // CHECK-NEXT:     14 |   short y
25*67e74705SXin Li // CHECK-NEXT:        | [sizeof=16, align=4]
26*67e74705SXin Li 
27*67e74705SXin Li typedef struct B {
28*67e74705SXin Li 	char x;
29*67e74705SXin Li 	int : 0;
30*67e74705SXin Li 	short a : 4;
31*67e74705SXin Li 	char y;
32*67e74705SXin Li } B;
33*67e74705SXin Li 
34*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
35*67e74705SXin Li // CHECK-NEXT:      0 | struct B
36*67e74705SXin Li // CHECK-NEXT:      0 |   char x
37*67e74705SXin Li // CHECK-NEXT:    1:- |   int
38*67e74705SXin Li // CHECK-NEXT:  2:0-3 |   short a
39*67e74705SXin Li // CHECK-NEXT:      4 |   char y
40*67e74705SXin Li // CHECK-NEXT:        | [sizeof=6, align=2]
41*67e74705SXin Li 
42*67e74705SXin Li typedef struct C {
43*67e74705SXin Li 	char x;
44*67e74705SXin Li 	short a : 4;
45*67e74705SXin Li 	int : 0;
46*67e74705SXin Li 	char y;
47*67e74705SXin Li } C;
48*67e74705SXin Li 
49*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
50*67e74705SXin Li // CHECK-NEXT:      0 | struct C
51*67e74705SXin Li // CHECK-NEXT:      0 |   char x
52*67e74705SXin Li // CHECK-NEXT:  2:0-3 |   short a
53*67e74705SXin Li // CHECK-NEXT:    4:- |   int
54*67e74705SXin Li // CHECK-NEXT:      4 |   char y
55*67e74705SXin Li // CHECK-NEXT:        | [sizeof=8, align=4]
56*67e74705SXin Li 
57*67e74705SXin Li typedef struct D {
58*67e74705SXin Li 	char x;
59*67e74705SXin Li 	short : 0;
60*67e74705SXin Li 	int : 0;
61*67e74705SXin Li 	char y;
62*67e74705SXin Li } D;
63*67e74705SXin Li 
64*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
65*67e74705SXin Li // CHECK-NEXT:      0 | struct D
66*67e74705SXin Li // CHECK-NEXT:      0 |   char x
67*67e74705SXin Li // CHECK-NEXT:    1:- |   short
68*67e74705SXin Li // CHECK-NEXT:    1:- |   int
69*67e74705SXin Li // CHECK-NEXT:      1 |   char y
70*67e74705SXin Li // CHECK-NEXT:        | [sizeof=2, align=1]
71*67e74705SXin Li 
72*67e74705SXin Li typedef union E {
73*67e74705SXin Li 	char x;
74*67e74705SXin Li 	long long a : 3;
75*67e74705SXin Li 	int b : 3;
76*67e74705SXin Li 	long long : 0;
77*67e74705SXin Li 	short y;
78*67e74705SXin Li } E;
79*67e74705SXin Li 
80*67e74705SXin Li 
81*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
82*67e74705SXin Li // CHECK-NEXT:      0 | union E
83*67e74705SXin Li // CHECK-NEXT:      0 |   char x
84*67e74705SXin Li // CHECK-NEXT:  0:0-2 |   long long a
85*67e74705SXin Li // CHECK-NEXT:  0:0-2 |   int b
86*67e74705SXin Li // CHECK-NEXT:    0:- |   long long
87*67e74705SXin Li // CHECK-NEXT:      0 |   short
88*67e74705SXin Li // CHECK-NEXT:        | [sizeof=8, align=2]
89*67e74705SXin Li 
90*67e74705SXin Li typedef struct F {
91*67e74705SXin Li 	char x;
92*67e74705SXin Li 	char a : 3;
93*67e74705SXin Li 	char b : 3;
94*67e74705SXin Li 	char c : 3;
95*67e74705SXin Li 	short d : 6;
96*67e74705SXin Li 	short e : 6;
97*67e74705SXin Li 	short f : 6;
98*67e74705SXin Li 	short g : 11;
99*67e74705SXin Li 	short h : 11;
100*67e74705SXin Li 	short i : 11;
101*67e74705SXin Li 	short y;
102*67e74705SXin Li } F;
103*67e74705SXin Li 
104*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
105*67e74705SXin Li // CHECK-NEXT:      0 | struct F
106*67e74705SXin Li // CHECK-NEXT:      0 |   char x
107*67e74705SXin Li // CHECK-NEXT:  1:0-2 |   char a
108*67e74705SXin Li // CHECK-NEXT:  1:3-5 |   char b
109*67e74705SXin Li // CHECK-NEXT:  2:0-2 |   char c
110*67e74705SXin Li // CHECK-NEXT:  4:0-5 |   short d
111*67e74705SXin Li // CHECK-NEXT: 4:6-11 |   short e
112*67e74705SXin Li // CHECK-NEXT:  6:0-5 |   short f
113*67e74705SXin Li // CHECK-NEXT: 8:0-10 |   short g
114*67e74705SXin Li // CHECK-NEXT:10:0-10 |   short h
115*67e74705SXin Li // CHECK-NEXT:12:0-10 |   short i
116*67e74705SXin Li // CHECK-NEXT:     14 |   short y
117*67e74705SXin Li // CHECK-NEXT:        | [sizeof=16, align=2]
118*67e74705SXin Li 
119*67e74705SXin Li typedef union G {
120*67e74705SXin Li 	char x;
121*67e74705SXin Li 	int a : 3;
122*67e74705SXin Li 	int : 0;
123*67e74705SXin Li 	long long : 0;
124*67e74705SXin Li 	short y;
125*67e74705SXin Li } G;
126*67e74705SXin Li 
127*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
128*67e74705SXin Li // CHECK-NEXT:      0 | union G
129*67e74705SXin Li // CHECK-NEXT:      0 |   char x
130*67e74705SXin Li // CHECK-NEXT:  0:0-2 |   int a
131*67e74705SXin Li // CHECK-NEXT:    0:- |   int
132*67e74705SXin Li // CHECK-NEXT:    0:- |   long long
133*67e74705SXin Li // CHECK-NEXT:      0 |   short y
134*67e74705SXin Li // CHECK-NEXT:        | [sizeof=4, align=2]
135*67e74705SXin Li 
136*67e74705SXin Li typedef struct H {
137*67e74705SXin Li 	unsigned short a : 1;
138*67e74705SXin Li 	unsigned char : 0;
139*67e74705SXin Li 	unsigned long : 0;
140*67e74705SXin Li 	unsigned short c : 1;
141*67e74705SXin Li } H;
142*67e74705SXin Li 
143*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
144*67e74705SXin Li // CHECK-NEXT:      0 | struct H
145*67e74705SXin Li // CHECK-NEXT:  0:0-0 |   unsigned short a
146*67e74705SXin Li // CHECK-NEXT:    2:- |   unsigned char
147*67e74705SXin Li // CHECK-NEXT:    2:- |   unsigned long
148*67e74705SXin Li // CHECK-NEXT:  2:0-0 |   unsigned short c
149*67e74705SXin Li // CHECK-NEXT:        | [sizeof=4, align=2]
150*67e74705SXin Li 
151*67e74705SXin Li typedef struct I {
152*67e74705SXin Li 	short : 8;
153*67e74705SXin Li 	__declspec(align(16)) short : 8;
154*67e74705SXin Li } I;
155*67e74705SXin Li 
156*67e74705SXin Li 
157*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
158*67e74705SXin Li // CHECK-NEXT:      0 | struct I
159*67e74705SXin Li // CHECK-NEXT:  0:0-7 |   short
160*67e74705SXin Li // CHECK-NEXT:  1:0-7 |   short
161*67e74705SXin Li // CHECK-NEXT:        | [sizeof=2, align=2]
162*67e74705SXin Li 
163*67e74705SXin Li #pragma pack(push, 1)
164*67e74705SXin Li 
165*67e74705SXin Li typedef struct A1 {
166*67e74705SXin Li 	char x;
167*67e74705SXin Li 	int a : 22;
168*67e74705SXin Li 	int : 0;
169*67e74705SXin Li 	int c : 10;
170*67e74705SXin Li 	char b : 3;
171*67e74705SXin Li 	char d: 4;
172*67e74705SXin Li 	short y;
173*67e74705SXin Li } A1;
174*67e74705SXin Li 
175*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
176*67e74705SXin Li // CHECK-NEXT:      0 | struct A1
177*67e74705SXin Li // CHECK-NEXT:      0 |   char x
178*67e74705SXin Li // CHECK-NEXT: 1:0-21 |   int a
179*67e74705SXin Li // CHECK-NEXT:    5:- |   int
180*67e74705SXin Li // CHECK-NEXT:  5:0-9 |   int c
181*67e74705SXin Li // CHECK-NEXT:  9:0-2 |   char b
182*67e74705SXin Li // CHECK-NEXT:  9:3-6 |   char d
183*67e74705SXin Li // CHECK-NEXT:     10 |   short y
184*67e74705SXin Li // CHECK-NEXT:        | [sizeof=12, align=1]
185*67e74705SXin Li 
186*67e74705SXin Li typedef struct B1 {
187*67e74705SXin Li 	char x;
188*67e74705SXin Li 	int : 0;
189*67e74705SXin Li 	short a : 4;
190*67e74705SXin Li 	char y;
191*67e74705SXin Li } B1;
192*67e74705SXin Li 
193*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
194*67e74705SXin Li // CHECK-NEXT:      0 | struct B1
195*67e74705SXin Li // CHECK-NEXT:      0 |   char x
196*67e74705SXin Li // CHECK-NEXT:    1:- |   int
197*67e74705SXin Li // CHECK-NEXT:  1:0-3 |   short
198*67e74705SXin Li // CHECK-NEXT:      3 |   char y
199*67e74705SXin Li // CHECK-NEXT:        | [sizeof=4, align=1]
200*67e74705SXin Li 
201*67e74705SXin Li typedef struct C1 {
202*67e74705SXin Li 	char x;
203*67e74705SXin Li 	short a : 4;
204*67e74705SXin Li 	int : 0;
205*67e74705SXin Li 	char y;
206*67e74705SXin Li } C1;
207*67e74705SXin Li 
208*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
209*67e74705SXin Li // CHECK-NEXT:      0 | struct C1
210*67e74705SXin Li // CHECK-NEXT:      0 |   char x
211*67e74705SXin Li // CHECK-NEXT:  1:0-3 |   short
212*67e74705SXin Li // CHECK-NEXT:    3:- |   int
213*67e74705SXin Li // CHECK-NEXT:      3 |   char y
214*67e74705SXin Li // CHECK-NEXT:        | [sizeof=4, align=1]
215*67e74705SXin Li 
216*67e74705SXin Li typedef struct D1 {
217*67e74705SXin Li 	char x;
218*67e74705SXin Li 	short : 0;
219*67e74705SXin Li 	int : 0;
220*67e74705SXin Li 	char y;
221*67e74705SXin Li } D1;
222*67e74705SXin Li 
223*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
224*67e74705SXin Li // CHECK-NEXT:      0 | struct D1
225*67e74705SXin Li // CHECK-NEXT:      0 |   char x
226*67e74705SXin Li // CHECK-NEXT:    1:- |   short
227*67e74705SXin Li // CHECK-NEXT:    1:- |   int
228*67e74705SXin Li // CHECK-NEXT:      1 |   char y
229*67e74705SXin Li // CHECK-NEXT:        | [sizeof=2, align=1]
230*67e74705SXin Li 
231*67e74705SXin Li typedef union E1 {
232*67e74705SXin Li 	char x;
233*67e74705SXin Li 	long long a : 3;
234*67e74705SXin Li 	int b : 3;
235*67e74705SXin Li 	long long : 0;
236*67e74705SXin Li 	short y;
237*67e74705SXin Li } E1;
238*67e74705SXin Li 
239*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
240*67e74705SXin Li // CHECK-NEXT:      0 | union E1
241*67e74705SXin Li // CHECK-NEXT:      0 |   char x
242*67e74705SXin Li // CHECK-NEXT:  0:0-2 |   long long a
243*67e74705SXin Li // CHECK-NEXT:  0:0-2 |   int b
244*67e74705SXin Li // CHECK-NEXT:    0:- |   long long
245*67e74705SXin Li // CHECK-NEXT:      0 |   short y
246*67e74705SXin Li // CHECK-NEXT:        | [sizeof=8, align=1]
247*67e74705SXin Li 
248*67e74705SXin Li typedef struct F1 {
249*67e74705SXin Li 	char x;
250*67e74705SXin Li 	char a : 3;
251*67e74705SXin Li 	char b : 3;
252*67e74705SXin Li 	char c : 3;
253*67e74705SXin Li 	short d : 6;
254*67e74705SXin Li 	short e : 6;
255*67e74705SXin Li 	short f : 6;
256*67e74705SXin Li 	short g : 11;
257*67e74705SXin Li 	short h : 11;
258*67e74705SXin Li 	short i : 11;
259*67e74705SXin Li 	short y;
260*67e74705SXin Li } F1;
261*67e74705SXin Li 
262*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
263*67e74705SXin Li // CHECK-NEXT:      0 | struct F1
264*67e74705SXin Li // CHECK-NEXT:      0 |   char x
265*67e74705SXin Li // CHECK-NEXT:  1:0-2 |   char a
266*67e74705SXin Li // CHECK-NEXT:  1:3-5 |   char b
267*67e74705SXin Li // CHECK-NEXT:  2:0-2 |   char c
268*67e74705SXin Li // CHECK-NEXT:  3:0-5 |   short d
269*67e74705SXin Li // CHECK-NEXT: 3:6-11 |   short e
270*67e74705SXin Li // CHECK-NEXT:  5:0-5 |   short f
271*67e74705SXin Li // CHECK-NEXT: 7:0-10 |   short g
272*67e74705SXin Li // CHECK-NEXT: 9:0-10 |   short h
273*67e74705SXin Li // CHECK-NEXT:11:0-10 |   short i
274*67e74705SXin Li // CHECK-NEXT:     13 |   short y
275*67e74705SXin Li // CHECK-NEXT:        | [sizeof=15, align=1]
276*67e74705SXin Li 
277*67e74705SXin Li typedef union G1 {
278*67e74705SXin Li 	char x;
279*67e74705SXin Li 	int a : 3;
280*67e74705SXin Li 	int : 0;
281*67e74705SXin Li 	long long : 0;
282*67e74705SXin Li 	short y;
283*67e74705SXin Li } G1;
284*67e74705SXin Li 
285*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
286*67e74705SXin Li // CHECK-NEXT:      0 | union G1
287*67e74705SXin Li // CHECK-NEXT:      0 |   char x
288*67e74705SXin Li // CHECK-NEXT:  0:0-2 |   int a
289*67e74705SXin Li // CHECK-NEXT:    0:- |   int
290*67e74705SXin Li // CHECK-NEXT:    0:- |   long long
291*67e74705SXin Li // CHECK-NEXT:      0 |   short y
292*67e74705SXin Li // CHECK-NEXT:        | [sizeof=4, align=1]
293*67e74705SXin Li 
294*67e74705SXin Li typedef struct H1 {
295*67e74705SXin Li 	unsigned long a : 1;
296*67e74705SXin Li 	unsigned char : 0;
297*67e74705SXin Li 	unsigned long : 0;
298*67e74705SXin Li 	unsigned long c : 1;
299*67e74705SXin Li } H1;
300*67e74705SXin Li 
301*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
302*67e74705SXin Li // CHECK-NEXT:      0 | struct H1
303*67e74705SXin Li // CHECK-NEXT:  0:0-0 |   unsigned long a
304*67e74705SXin Li // CHECK-NEXT:    4:- |   unsigned char
305*67e74705SXin Li // CHECK-NEXT:    4:- |   unsigned long
306*67e74705SXin Li // CHECK-NEXT:  4:0-0 |   unsigned long c
307*67e74705SXin Li // CHECK-NEXT:        | [sizeof=8, align=1]
308*67e74705SXin Li 
309*67e74705SXin Li typedef struct I1 {
310*67e74705SXin Li 	short : 8;
311*67e74705SXin Li 	__declspec(align(16)) short : 8;
312*67e74705SXin Li } I1;
313*67e74705SXin Li 
314*67e74705SXin Li // CHECK:*** Dumping AST Record Layout
315*67e74705SXin Li // CHECK-NEXT:      0 | struct I1
316*67e74705SXin Li // CHECK-NEXT:  0:0-7 |   short
317*67e74705SXin Li // CHECK-NEXT:  1:0-7 |   short
318*67e74705SXin Li // CHECK-NEXT:        | [sizeof=2, align=1]
319*67e74705SXin Li 
320*67e74705SXin Li #pragma pack(pop)
321*67e74705SXin Li 
322*67e74705SXin Li int x[
323*67e74705SXin Li sizeof(A ) +
324*67e74705SXin Li sizeof(B ) +
325*67e74705SXin Li sizeof(C ) +
326*67e74705SXin Li sizeof(D ) +
327*67e74705SXin Li sizeof(E ) +
328*67e74705SXin Li sizeof(F ) +
329*67e74705SXin Li sizeof(G ) +
330*67e74705SXin Li sizeof(H ) +
331*67e74705SXin Li sizeof(I ) +
332*67e74705SXin Li sizeof(A1) +
333*67e74705SXin Li sizeof(B1) +
334*67e74705SXin Li sizeof(C1) +
335*67e74705SXin Li sizeof(D1) +
336*67e74705SXin Li sizeof(E1) +
337*67e74705SXin Li sizeof(F1) +
338*67e74705SXin Li sizeof(G1) +
339*67e74705SXin Li sizeof(H1) +
340*67e74705SXin Li sizeof(I1) +
341*67e74705SXin Li 0];
342