1 // RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fdump-record-layouts \
2 // RUN:     -fsyntax-only  %s | \
3 // RUN:   FileCheck %s
4 
5 // RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fdump-record-layouts \
6 // RUN:     -fsyntax-only %s | \
7 // RUN:   FileCheck %s
8 
9 namespace test1 {
10 // Test the class layout when having a double which is/is not the first struct
11 // member.
12 struct D {
13   double d1;
14   int i1;
15 };
16 
17 struct DoubleFirst {
18   struct D d2;
19   int i2;
20 };
21 
22 struct IntFirst {
23   int i3;
24   struct D d3;
25 };
26 
27 int a = sizeof(DoubleFirst);
28 int b = sizeof(IntFirst);
29 
30 // CHECK:     *** Dumping AST Record Layout
31 // CHECK-NEXT:         0 | struct test1::D
32 // CHECK-NEXT:         0 |   double d1
33 // CHECK-NEXT:         8 |   int i1
34 // CHECK-NEXT:           | [sizeof=16, dsize=16, align=4, preferredalign=8,
35 // CHECK-NEXT:           |  nvsize=16, nvalign=4, preferrednvalign=8]
36 
37 // CHECK:     *** Dumping AST Record Layout
38 // CHECK-NEXT:         0 | struct test1::DoubleFirst
39 // CHECK-NEXT:         0 |   struct test1::D d2
40 // CHECK-NEXT:         0 |     double d1
41 // CHECK-NEXT:         8 |     int i1
42 // CHECK-NEXT:        16 |   int i2
43 // CHECK-NEXT:           | [sizeof=24, dsize=24, align=4, preferredalign=8,
44 // CHECK-NEXT:           |  nvsize=24, nvalign=4, preferrednvalign=8]
45 
46 // CHECK:     *** Dumping AST Record Layout
47 // CHECK-NEXT:         0 | struct test1::IntFirst
48 // CHECK-NEXT:         0 |   int i3
49 // CHECK-NEXT:         4 |   struct test1::D d3
50 // CHECK-NEXT:         4 |     double d1
51 // CHECK-NEXT:        12 |     int i1
52 // CHECK-NEXT:           | [sizeof=20, dsize=20, align=4, preferredalign=4,
53 // CHECK-NEXT:           |  nvsize=20, nvalign=4, preferrednvalign=4]
54 } // namespace test1
55 
56 namespace test2 {
57 // Test the class layout when having a zero-sized bitfield followed by double.
58 struct Double {
59   int : 0;
60   double d;
61 };
62 
63 int a = sizeof(Double);
64 
65 // CHECK:     *** Dumping AST Record Layout
66 // CHECK-NEXT:         0 | struct test2::Double
67 // CHECK-NEXT:       0:- |   int
68 // CHECK-NEXT:         0 |   double d
69 // CHECK-NEXT:           | [sizeof=8, dsize=8, align=4, preferredalign=4,
70 // CHECK-NEXT:           |  nvsize=8, nvalign=4, preferrednvalign=4]
71 } // namespace test2
72 
73 namespace test3 {
74 // Test the class layout when having a double member in union.
75 union A {
76   int b;
77   double d;
78 };
79 
80 struct UnionStruct {
81   union A a;
82   int i;
83 };
84 
85 int a = sizeof(UnionStruct);
86 
87 // CHECK:      *** Dumping AST Record Layout
88 // CHECK-NEXT:          0 | union test3::A
89 // CHECK-NEXT:          0 |   int b
90 // CHECK-NEXT:          0 |   double d
91 // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, preferredalign=8,
92 // CHECK-NEXT:            |  nvsize=8, nvalign=4, preferrednvalign=8]
93 
94 // CHECK:      *** Dumping AST Record Layout
95 // CHECK-NEXT:          0 | struct test3::UnionStruct
96 // CHECK-NEXT:          0 |   union test3::A a
97 // CHECK-NEXT:          0 |     int b
98 // CHECK-NEXT:          0 |     double d
99 // CHECK-NEXT:          8 |   int i
100 // CHECK-NEXT:            | [sizeof=16, dsize=16, align=4, preferredalign=8,
101 // CHECK-NEXT:            |  nvsize=16, nvalign=4, preferrednvalign=8]
102 
103 } // namespace test3
104 
105 namespace test4 {
106 // Test the class layout when having multiple base classes.
107 struct A {
108   int a;
109 };
110 
111 struct B {
112   double d;
113 };
114 
115 class S : A, B {
116 };
117 
118 int a = sizeof(S);
119 
120 // CHECK:      *** Dumping AST Record Layout
121 // CHECK-NEXT:          0 | struct test4::A
122 // CHECK-NEXT:          0 |   int a
123 // CHECK-NEXT:            | [sizeof=4, dsize=4, align=4, preferredalign=4,
124 // CHECK-NEXT:            |  nvsize=4, nvalign=4, preferrednvalign=4]
125 
126 // CHECK:      *** Dumping AST Record Layout
127 // CHECK-NEXT:          0 | struct test4::B
128 // CHECK-NEXT:          0 |   double d
129 // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, preferredalign=8,
130 // CHECK-NEXT:            |  nvsize=8, nvalign=4, preferrednvalign=8]
131 
132 // CHECK:      *** Dumping AST Record Layout
133 // CHECK-NEXT:          0 | class test4::S
134 // CHECK-NEXT:          0 |   struct test4::A (base)
135 // CHECK-NEXT:          0 |     int a
136 // CHECK-NEXT:          4 |   struct test4::B (base)
137 // CHECK-NEXT:          4 |     double d
138 // CHECK-NEXT:            | [sizeof=12, dsize=12, align=4, preferredalign=4,
139 // CHECK-NEXT:            |  nvsize=12, nvalign=4, preferrednvalign=4]
140 } // namespace test4
141 
142 namespace test5 {
143 struct Empty {
144 };
145 
146 struct EmptyDer : Empty {
147   double d;
148 };
149 
150 struct NonEmpty {
151   int i;
152 };
153 
154 struct NonEmptyDer : NonEmpty {
155   double d;
156 };
157 
158 int a = sizeof(EmptyDer);
159 int b = sizeof(NonEmptyDer);
160 
161 // CHECK:      *** Dumping AST Record Layout
162 // CHECK-NEXT:          0 | struct test5::Empty (empty)
163 // CHECK-NEXT:            | [sizeof=1, dsize=1, align=1, preferredalign=1,
164 // CHECK-NEXT:            |  nvsize=1, nvalign=1, preferrednvalign=1]
165 
166 // CHECK:      *** Dumping AST Record Layout
167 // CHECK-NEXT:          0 | struct test5::EmptyDer
168 // CHECK-NEXT:          0 |   struct test5::Empty (base) (empty)
169 // CHECK-NEXT:          0 |   double d
170 // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, preferredalign=8,
171 // CHECK-NEXT:            |  nvsize=8, nvalign=4, preferrednvalign=8]
172 
173 // CHECK:      *** Dumping AST Record Layout
174 // CHECK-NEXT:          0 | struct test5::NonEmpty
175 // CHECK-NEXT:          0 |   int i
176 // CHECK-NEXT:            | [sizeof=4, dsize=4, align=4, preferredalign=4,
177 // CHECK-NEXT:            |  nvsize=4, nvalign=4, preferrednvalign=4]
178 
179 // CHECK:      *** Dumping AST Record Layout
180 // CHECK-NEXT:          0 | struct test5::NonEmptyDer
181 // CHECK-NEXT:          0 |   struct test5::NonEmpty (base)
182 // CHECK-NEXT:          0 |     int i
183 // CHECK-NEXT:          4 |   double d
184 // CHECK-NEXT:            | [sizeof=12, dsize=12, align=4, preferredalign=4,
185 // CHECK-NEXT:            |  nvsize=12, nvalign=4, preferrednvalign=4]
186 } // namespace test5
187 
188 namespace test6 {
189 struct A {
190   struct B {
191     double d[3];
192   } b;
193 };
194 
195 int a = sizeof(A);
196 
197 // CHECK:      *** Dumping AST Record Layout
198 // CHECK-NEXT:          0 | struct test6::A::B
199 // CHECK-NEXT:          0 |   double [3] d
200 // CHECK-NEXT:            | [sizeof=24, dsize=24, align=4, preferredalign=8,
201 // CHECK-NEXT:            |  nvsize=24, nvalign=4, preferrednvalign=8]
202 
203 // CHECK:      *** Dumping AST Record Layout
204 // CHECK-NEXT:          0 | struct test6::A
205 // CHECK-NEXT:          0 |   struct test6::A::B b
206 // CHECK-NEXT:          0 |     double [3] d
207 // CHECK-NEXT:            | [sizeof=24, dsize=24, align=4, preferredalign=8,
208 // CHECK-NEXT:            |  nvsize=24, nvalign=4, preferrednvalign=8]
209 
210 } // namespace test6
211 
212 namespace test7 {
213 struct A {
214   struct B {
215     long double _Complex d[3];
216   } b;
217 };
218 
219 int a = sizeof(A);
220 
221 // CHECK:      *** Dumping AST Record Layout
222 // CHECK-NEXT:          0 | struct test7::A::B
223 // CHECK-NEXT:          0 |   _Complex long double [3] d
224 // CHECK-NEXT:            | [sizeof=48, dsize=48, align=4, preferredalign=8,
225 // CHECK-NEXT:            |  nvsize=48, nvalign=4, preferrednvalign=8]
226 
227 // CHECK:      *** Dumping AST Record Layout
228 // CHECK-NEXT:          0 | struct test7::A
229 // CHECK-NEXT:          0 |   struct test7::A::B b
230 // CHECK-NEXT:          0 |     _Complex long double [3] d
231 // CHECK-NEXT:            | [sizeof=48, dsize=48, align=4, preferredalign=8,
232 // CHECK-NEXT:            |  nvsize=48, nvalign=4, preferrednvalign=8]
233 
234 } // namespace test7
235 
236 namespace test8 {
237 struct Emp {};
238 
239 struct Y : Emp {
240   double d;
241 };
242 
243 struct Z : Emp {
244   Y y;
245 };
246 
247 int a = sizeof(Z);
248 
249 // CHECK:      *** Dumping AST Record Layout
250 // CHECK-NEXT:          0 | struct test8::Emp (empty)
251 // CHECK-NEXT:            | [sizeof=1, dsize=1, align=1, preferredalign=1,
252 // CHECK-NEXT:            |  nvsize=1, nvalign=1, preferrednvalign=1]
253 
254 // CHECK:      *** Dumping AST Record Layout
255 // CHECK-NEXT:          0 | struct test8::Y
256 // CHECK-NEXT:          0 |   struct test8::Emp (base) (empty)
257 // CHECK-NEXT:          0 |   double d
258 // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, preferredalign=8,
259 // CHECK-NEXT:            |  nvsize=8, nvalign=4, preferrednvalign=8]
260 
261 // CHECK:      *** Dumping AST Record Layout
262 // CHECK-NEXT:          0 | struct test8::Z
263 // CHECK-NEXT:          0 |   struct test8::Emp (base) (empty)
264 // CHECK-NEXT:          8 |   struct test8::Y y
265 // CHECK-NEXT:          8 |     struct test8::Emp (base) (empty)
266 // CHECK-NEXT:          8 |     double d
267 // CHECK-NEXT:            | [sizeof=16, dsize=16, align=4, preferredalign=8,
268 // CHECK-NEXT:            |  nvsize=16, nvalign=4, preferrednvalign=8]
269 
270 } // namespace test8
271 
272 namespace test9 {
273 // Test the class layout when having a zero-extent array in a base class, which
274 // renders the base class not empty.
275 struct A { char zea[0]; };
276 
277 struct B : A { double d; };
278 
279 struct C { double d; };
280 struct D : A, C { char x; };
281 
282 int a = sizeof(B);
283 int b = sizeof(D);
284 
285 // CHECK:               0 | struct test9::B
286 // CHECK-NEXT:          0 |   struct test9::A (base)
287 // CHECK-NEXT:          0 |     char [0] zea
288 // CHECK-NEXT:          0 |   double d
289 // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, preferredalign=4,
290 // CHECK-NEXT:            |  nvsize=8, nvalign=4, preferrednvalign=4]
291 
292 // CHECK:               0 | struct test9::D
293 // CHECK-NEXT:          0 |   struct test9::A (base)
294 // CHECK-NEXT:          0 |     char [0] zea
295 // CHECK-NEXT:          0 |   struct test9::C (base)
296 // CHECK-NEXT:          0 |     double d
297 // CHECK-NEXT:          8 |   char x
298 // CHECK-NEXT:            | [sizeof=12, dsize=9, align=4, preferredalign=4,
299 // CHECK-NEXT:            |  nvsize=9, nvalign=4, preferrednvalign=4]
300 
301 } // namespace test9
302 
303 namespace test10 {
304 struct A { double x; };
305 struct B : A {};
306 
307 int a = sizeof(B);
308 
309 // CHECK:               0 | struct test10::B
310 // CHECK-NEXT:          0 |   struct test10::A (base)
311 // CHECK-NEXT:          0 |     double x
312 // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, preferredalign=8,
313 // CHECK-NEXT:            |  nvsize=8, nvalign=4, preferrednvalign=8]
314 
315 } // namespace test10
316 
317 namespace test11 {
318 // Test how #pragma pack and align attribute interacts with AIX `power`
319 // alignment rules.
320 struct A {
321   char a;
322   double __attribute__((aligned(16))) d;
323   int i;
324 };
325 
326 struct B {
327   double __attribute__((aligned(4))) d1;
328   char a;
329   double d2;
330 };
331 
332 #pragma pack(2)
333 struct C {
334   int i;
335   short j;
336   double k;
337 };
338 
339 #pragma pack(2)
340 struct D {
341   double d;
342   short j;
343   int i;
344 };
345 
346 #pragma pack(8)
347 struct E {
348   double __attribute__((aligned(4))) d;
349   short s;
350 };
351 
352 #pragma pack(4)
353 struct F : public D {
354   double d;
355 };
356 
357 #pragma pack(2)
358 struct G : public E {
359   int i;
360 };
361 
362 int a = sizeof(A);
363 int b = sizeof(B);
364 int c = sizeof(C);
365 int d = sizeof(D);
366 int e = sizeof(E);
367 int f = sizeof(F);
368 int g = sizeof(G);
369 
370 // CHECK:      *** Dumping AST Record Layout
371 // CHECK-NEXT:          0 | struct test11::A
372 // CHECK-NEXT:          0 |   char a
373 // CHECK-NEXT:         16 |   double d
374 // CHECK-NEXT:         24 |   int i
375 // CHECK-NEXT:            | [sizeof=32, dsize=32, align=16, preferredalign=16,
376 // CHECK-NEXT:            |  nvsize=32, nvalign=16, preferrednvalign=16]
377 
378 // CHECK:      *** Dumping AST Record Layout
379 // CHECK-NEXT:          0 | struct test11::B
380 // CHECK-NEXT:          0 |   double d1
381 // CHECK-NEXT:          8 |   char a
382 // CHECK-NEXT:         12 |   double d2
383 // CHECK-NEXT:            | [sizeof=24, dsize=24, align=4, preferredalign=8,
384 // CHECK-NEXT:            |  nvsize=24, nvalign=4, preferrednvalign=8]
385 
386 // CHECK:      *** Dumping AST Record Layout
387 // CHECK-NEXT:          0 | struct test11::C
388 // CHECK-NEXT:          0 |   int i
389 // CHECK-NEXT:          4 |   short j
390 // CHECK-NEXT:          6 |   double k
391 // CHECK-NEXT:            | [sizeof=14, dsize=14, align=2, preferredalign=2,
392 // CHECK-NEXT:            |  nvsize=14, nvalign=2, preferrednvalign=2]
393 
394 // CHECK:      *** Dumping AST Record Layout
395 // CHECK-NEXT:          0 | struct test11::D
396 // CHECK-NEXT:          0 |   double d
397 // CHECK-NEXT:          8 |   short j
398 // CHECK-NEXT:         10 |   int i
399 // CHECK-NEXT:            | [sizeof=14, dsize=14, align=2, preferredalign=2,
400 // CHECK-NEXT:            |  nvsize=14, nvalign=2, preferrednvalign=2]
401 
402 // CHECK:      *** Dumping AST Record Layout
403 // CHECK-NEXT:          0 | struct test11::E
404 // CHECK-NEXT:          0 |   double d
405 // CHECK-NEXT:          8 |   short s
406 // CHECK-NEXT:            | [sizeof=16, dsize=16, align=4, preferredalign=8,
407 // CHECK-NEXT:            |  nvsize=16, nvalign=4, preferrednvalign=8]
408 
409 // CHECK:      *** Dumping AST Record Layout
410 // CHECK-NEXT:          0 | struct test11::F
411 // CHECK-NEXT:          0 |   struct test11::D (base)
412 // CHECK-NEXT:          0 |     double d
413 // CHECK-NEXT:          8 |     short j
414 // CHECK-NEXT:         10 |     int i
415 // CHECK-NEXT:         16 |   double d
416 // CHECK-NEXT:            | [sizeof=24, dsize=24, align=4, preferredalign=4,
417 // CHECK-NEXT:            |  nvsize=24, nvalign=4, preferrednvalign=4]
418 
419 // CHECK:      *** Dumping AST Record Layout
420 // CHECK-NEXT:          0 | struct test11::G
421 // CHECK-NEXT:          0 |   struct test11::E (base)
422 // CHECK-NEXT:          0 |     double d
423 // CHECK-NEXT:          8 |     short s
424 // CHECK-NEXT:         16 |   int i
425 // CHECK-NEXT:            | [sizeof=20, dsize=20, align=2, preferredalign=2,
426 // CHECK-NEXT:            |  nvsize=20, nvalign=2, preferrednvalign=2]
427 
428 } // namespace test11
429