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