1 // RUN: %clang_cc1 -fno-rtti -triple i686-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only -Wno-inaccessible-base %s 2>&1 \ 2 // RUN: | FileCheck %s --strict-whitespace 3 // RUN: %clang_cc1 -fno-rtti -triple x86_64-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only -Wno-inaccessible-base %s 2>/dev/null \ 4 // RUN: | FileCheck %s -check-prefix CHECK-X64 --strict-whitespace 5 6 extern "C" int printf(const char *fmt, ...); 7 char buffer[419430400]; 8 9 struct A { 10 char a; AA11 A() { 12 printf("A = %d\n", (int)((char*)this - buffer)); 13 printf("A.a = %d\n", (int)((char*)&a - buffer)); 14 } 15 }; 16 17 struct B { 18 __declspec(align(4)) long long a; BB19 B() { 20 printf("B = %d\n", (int)((char*)this - buffer)); 21 printf("B.a = %d\n", (int)((char*)&a - buffer)); 22 } 23 }; 24 25 #pragma pack(push, 2) 26 struct X { 27 B a; 28 char b; 29 int c; XX30 X() { 31 printf("X = %d\n", (int)((char*)this - buffer)); 32 printf("X.a = %d\n", (int)((char*)&a - buffer)); 33 printf("X.b = %d\n", (int)((char*)&b - buffer)); 34 printf("X.c = %d\n", (int)((char*)&c - buffer)); 35 } 36 }; 37 38 // CHECK-LABEL: 0 | struct X{{$}} 39 // CHECK-NEXT: 0 | struct B a 40 // CHECK-NEXT: 0 | long long a 41 // CHECK-NEXT: 8 | char b 42 // CHECK-NEXT: 10 | int c 43 // CHECK-NEXT: | [sizeof=16, align=4 44 // CHECK-NEXT: | nvsize=14, nvalign=4] 45 // CHECK-X64-LABEL: 0 | struct X{{$}} 46 // CHECK-X64-NEXT: 0 | struct B a 47 // CHECK-X64-NEXT: 0 | long long a 48 // CHECK-X64-NEXT: 8 | char b 49 // CHECK-X64-NEXT: 10 | int c 50 // CHECK-X64-NEXT: | [sizeof=16, align=4 51 // CHECK-X64-NEXT: | nvsize=14, nvalign=4] 52 53 struct Y : A, B { 54 char a; 55 int b; YY56 Y() { 57 printf("Y = %d\n", (int)((char*)this - buffer)); 58 printf("Y.a = %d\n", (int)((char*)&a - buffer)); 59 printf("Y.b = %d\n", (int)((char*)&b - buffer)); 60 } 61 }; 62 63 // CHECK-LABEL: 0 | struct Y{{$}} 64 // CHECK-NEXT: 0 | struct A (base) 65 // CHECK-NEXT: 0 | char a 66 // CHECK-NEXT: 4 | struct B (base) 67 // CHECK-NEXT: 4 | long long a 68 // CHECK-NEXT: 12 | char a 69 // CHECK-NEXT: 14 | int b 70 // CHECK-NEXT: | [sizeof=20, align=4 71 // CHECK-NEXT: | nvsize=18, nvalign=4] 72 // CHECK-X64-LABEL: 0 | struct Y{{$}} 73 // CHECK-X64-NEXT: 0 | struct A (base) 74 // CHECK-X64-NEXT: 0 | char a 75 // CHECK-X64-NEXT: 4 | struct B (base) 76 // CHECK-X64-NEXT: 4 | long long a 77 // CHECK-X64-NEXT: 12 | char a 78 // CHECK-X64-NEXT: 14 | int b 79 // CHECK-X64-NEXT: | [sizeof=20, align=4 80 // CHECK-X64-NEXT: | nvsize=18, nvalign=4] 81 82 struct Z : virtual B { 83 char a; 84 int b; ZZ85 Z() { 86 printf("Z = %d\n", (int)((char*)this - buffer)); 87 printf("Z.a = %d\n", (int)((char*)&a - buffer)); 88 printf("Z.b = %d\n", (int)((char*)&b - buffer)); 89 } 90 }; 91 92 // CHECK-LABEL: 0 | struct Z{{$}} 93 // CHECK-NEXT: 0 | (Z vbtable pointer) 94 // CHECK-NEXT: 4 | char a 95 // CHECK-NEXT: 6 | int b 96 // CHECK-NEXT: 12 | struct B (virtual base) 97 // CHECK-NEXT: 12 | long long a 98 // CHECK-NEXT: | [sizeof=20, align=4 99 // CHECK-NEXT: | nvsize=10, nvalign=4] 100 // CHECK-X64-LABEL: 0 | struct Z{{$}} 101 // CHECK-X64-NEXT: 0 | (Z vbtable pointer) 102 // CHECK-X64-NEXT: 8 | char a 103 // CHECK-X64-NEXT: 10 | int b 104 // CHECK-X64-NEXT: 16 | struct B (virtual base) 105 // CHECK-X64-NEXT: 16 | long long a 106 // CHECK-X64-NEXT: | [sizeof=24, align=4 107 // CHECK-X64-NEXT: | nvsize=14, nvalign=4] 108 109 #pragma pack(pop) 110 111 struct A1 { long long a; }; 112 #pragma pack(push, 1) 113 struct B1 : virtual A1 { char a; }; 114 #pragma pack(pop) 115 struct C1 : B1 {}; 116 117 // CHECK-LABEL: 0 | struct C1{{$}} 118 // CHECK-NEXT: 0 | struct B1 (base) 119 // CHECK-NEXT: 0 | (B1 vbtable pointer) 120 // CHECK-NEXT: 4 | char a 121 // CHECK-NEXT: 8 | struct A1 (virtual base) 122 // CHECK-NEXT: 8 | long long a 123 // CHECK-NEXT: | [sizeof=16, align=8 124 // CHECK-NEXT: | nvsize=5, nvalign=8] 125 // CHECK-X64-LABEL: 0 | struct C1{{$}} 126 // CHECK-X64-NEXT: 0 | struct B1 (base) 127 // CHECK-X64-NEXT: 0 | (B1 vbtable pointer) 128 // CHECK-X64-NEXT: 8 | char a 129 // CHECK-X64-NEXT: 16 | struct A1 (virtual base) 130 // CHECK-X64-NEXT: 16 | long long a 131 // CHECK-X64-NEXT: | [sizeof=24, align=8 132 // CHECK-X64-NEXT: | nvsize=9, nvalign=8] 133 134 struct CA0 { CA0CA0135 CA0() {} 136 }; 137 struct CA1 : virtual CA0 { CA1CA1138 CA1() {} 139 }; 140 #pragma pack(push, 1) 141 struct CA2 : public CA1, public CA0 { CA2MethodCA2142 virtual void CA2Method() {} CA2CA2143 CA2() {} 144 }; 145 #pragma pack(pop) 146 147 // CHECK-LABEL: 0 | struct CA2{{$}} 148 // CHECK-NEXT: 0 | (CA2 vftable pointer) 149 // CHECK-NEXT: 4 | struct CA1 (base) 150 // CHECK-NEXT: 4 | (CA1 vbtable pointer) 151 // CHECK-NEXT: 9 | struct CA0 (base) (empty) 152 // CHECK-NEXT: 9 | struct CA0 (virtual base) (empty) 153 // CHECK-NEXT: | [sizeof=9, align=1 154 // CHECK-NEXT: | nvsize=9, nvalign=1] 155 // CHECK-X64-LABEL: 0 | struct CA2{{$}} 156 // CHECK-X64-NEXT: 0 | (CA2 vftable pointer) 157 // CHECK-X64-NEXT: 8 | struct CA1 (base) 158 // CHECK-X64-NEXT: 8 | (CA1 vbtable pointer) 159 // CHECK-X64-NEXT: 17 | struct CA0 (base) (empty) 160 // CHECK-X64-NEXT: 17 | struct CA0 (virtual base) (empty) 161 // CHECK-X64-NEXT: | [sizeof=17, align=1 162 // CHECK-X64-NEXT: | nvsize=17, nvalign=1] 163 164 #pragma pack(16) 165 struct YA { 166 __declspec(align(32)) char : 1; 167 }; 168 // CHECK-LABEL: 0 | struct YA{{$}} 169 // CHECK-NEXT:0:0-0 | char 170 // CHECK-NEXT: | [sizeof=32, align=32 171 // CHECK-NEXT: | nvsize=32, nvalign=32] 172 // CHECK-X64-LABEL: 0 | struct YA{{$}} 173 // CHECK-X64-NEXT:0:0-0 | char 174 // CHECK-X64-NEXT: | [sizeof=32, align=32 175 // CHECK-X64-NEXT: | nvsize=32, nvalign=32] 176 177 #pragma pack(1) 178 struct YB { 179 char a; 180 YA b; 181 }; 182 // CHECK-LABEL: 0 | struct YB{{$}} 183 // CHECK-NEXT: 0 | char a 184 // CHECK-NEXT: 1 | struct YA b 185 // CHECK-NEXT:1:0-0 | char 186 // CHECK-NEXT: | [sizeof=33, align=1 187 // CHECK-NEXT: | nvsize=33, nvalign=1] 188 // CHECK-X64-LABEL: 0 | struct YB{{$}} 189 // CHECK-X64-NEXT: 0 | char a 190 // CHECK-X64-NEXT: 1 | struct YA b 191 // CHECK-X64-NEXT:1:0-0 | char 192 // CHECK-X64-NEXT: | [sizeof=33, align=1 193 // CHECK-X64-NEXT: | nvsize=33, nvalign=1] 194 195 #pragma pack(8) 196 struct YC { 197 __declspec(align(32)) char : 1; 198 }; 199 // CHECK-LABEL: 0 | struct YC{{$}} 200 // CHECK-NEXT:0:0-0 | char 201 // CHECK-NEXT: | [sizeof=32, align=32 202 // CHECK-NEXT: | nvsize=32, nvalign=32] 203 // CHECK-X64-LABEL: 0 | struct YC{{$}} 204 // CHECK-X64-NEXT: 0:0-0 | char 205 // CHECK-X64-NEXT: | [sizeof=8, align=32 206 // CHECK-X64-NEXT: | nvsize=8, nvalign=32] 207 208 #pragma pack(1) 209 struct YD { 210 char a; 211 YC b; 212 }; 213 // CHECK-LABEL: 0 | struct YD{{$}} 214 // CHECK-NEXT: 0 | char a 215 // CHECK-NEXT: 1 | struct YC b 216 // CHECK-NEXT:1:0-0 | char 217 // CHECK-NEXT: | [sizeof=33, align=1 218 // CHECK-NEXT: | nvsize=33, nvalign=1] 219 // CHECK-X64-LABEL: 0 | struct YD{{$}} 220 // CHECK-X64-NEXT: 0 | char a 221 // CHECK-X64-NEXT: 1 | struct YC b 222 // CHECK-X64-NEXT:1:0-0 | char 223 // CHECK-X64-NEXT: | [sizeof=9, align=1 224 // CHECK-X64-NEXT: | nvsize=9, nvalign=1] 225 226 #pragma pack(4) 227 struct YE { 228 __declspec(align(32)) char : 1; 229 }; 230 // CHECK-LABEL: 0 | struct YE{{$}} 231 // CHECK-NEXT: 0:0-0 | char 232 // CHECK-NEXT: | [sizeof=4, align=32 233 // CHECK-NEXT: | nvsize=4, nvalign=32] 234 // CHECK-X64-LABEL: 0 | struct YE{{$}} 235 // CHECK-X64-NEXT: 0:0-0 | char 236 // CHECK-X64-NEXT: | [sizeof=4, align=32 237 // CHECK-X64-NEXT: | nvsize=4, nvalign=32] 238 239 #pragma pack(1) 240 struct YF { 241 char a; 242 YE b; 243 }; 244 // CHECK-LABEL: 0 | struct YF{{$}} 245 // CHECK-NEXT: 0 | char a 246 // CHECK-NEXT: 1 | struct YE b 247 // CHECK-NEXT:1:0-0 | char 248 // CHECK-NEXT: | [sizeof=5, align=1 249 // CHECK-NEXT: | nvsize=5, nvalign=1] 250 // CHECK-X64-LABEL: 0 | struct YF{{$}} 251 // CHECK-X64-NEXT: 0 | char a 252 // CHECK-X64-NEXT: 1 | struct YE b 253 // CHECK-X64-NEXT:1:0-0 | char 254 // CHECK-X64-NEXT: | [sizeof=5, align=1 255 // CHECK-X64-NEXT: | nvsize=5, nvalign=1] 256 257 #pragma pack(16) 258 struct __declspec(align(16)) D0 { char a; }; 259 #pragma pack(1) 260 struct D1 : public D0 { char a; }; 261 #pragma pack(16) 262 struct D2 : D1 { char a; }; 263 264 // CHECK-LABEL: 0 | struct D2{{$}} 265 // CHECK-NEXT: 0 | struct D1 (base) 266 // CHECK-NEXT: 0 | struct D0 (base) 267 // CHECK-NEXT: 0 | char a 268 // CHECK-NEXT: 1 | char a 269 // CHECK-NEXT: 2 | char a 270 // CHECK-NEXT: | [sizeof=16, align=16 271 // CHECK-NEXT: | nvsize=16, nvalign=16] 272 // CHECK-X64-LABEL: 0 | struct D2{{$}} 273 // CHECK-X64-NEXT: 0 | struct D1 (base) 274 // CHECK-X64-NEXT: 0 | struct D0 (base) 275 // CHECK-X64-NEXT: 0 | char a 276 // CHECK-X64-NEXT: 1 | char a 277 // CHECK-X64-NEXT: 2 | char a 278 // CHECK-X64-NEXT: | [sizeof=16, align=16 279 // CHECK-X64-NEXT: | nvsize=16, nvalign=16] 280 281 #pragma pack() 282 struct JA { char a; }; 283 #pragma pack(1) 284 struct JB { __declspec(align(4)) char a; }; 285 #pragma pack() 286 struct JC : JB, JA { }; 287 288 // CHECK-LABEL: 0 | struct JC{{$}} 289 // CHECK-NEXT: 0 | struct JB (base) 290 // CHECK-NEXT: 0 | char a 291 // CHECK-NEXT: 1 | struct JA (base) 292 // CHECK-NEXT: 1 | char a 293 // CHECK-NEXT: | [sizeof=4, align=4 294 // CHECK-NEXT: | nvsize=4, nvalign=4] 295 // CHECK-X64-LABEL: 0 | struct JC{{$}} 296 // CHECK-X64-NEXT: 0 | struct JB (base) 297 // CHECK-X64-NEXT: 0 | char a 298 // CHECK-X64-NEXT: 1 | struct JA (base) 299 // CHECK-X64-NEXT: 1 | char a 300 // CHECK-X64-NEXT: | [sizeof=4, align=4 301 // CHECK-X64-NEXT: | nvsize=4, nvalign=4] 302 303 #pragma pack() 304 struct KA { char a; }; 305 #pragma pack(1) 306 struct KB : KA { __declspec(align(2)) char a; }; 307 308 // CHECK-LABEL: 0 | struct KB{{$}} 309 // CHECK-NEXT: 0 | struct KA (base) 310 // CHECK-NEXT: 0 | char a 311 // CHECK-NEXT: 2 | char a 312 // CHECK-NEXT: | [sizeof=4, align=2 313 // CHECK-NEXT: | nvsize=3, nvalign=2] 314 // CHECK-X64-LABEL: 0 | struct KB{{$}} 315 // CHECK-X64-NEXT: 0 | struct KA (base) 316 // CHECK-X64-NEXT: 0 | char a 317 // CHECK-X64-NEXT: 2 | char a 318 // CHECK-X64-NEXT: | [sizeof=4, align=2 319 // CHECK-X64-NEXT: | nvsize=3, nvalign=2] 320 321 #pragma pack(1) 322 struct L { funL323 virtual void fun() {} 324 __declspec(align(256)) int Field; 325 }; 326 327 // CHECK-LABEL: 0 | struct L{{$}} 328 // CHECK-NEXT: 0 | (L vftable pointer) 329 // CHECK-NEXT: 256 | int Field 330 // CHECK-NEXT: | [sizeof=512, align=256 331 // CHECK-NEXT: | nvsize=260, nvalign=256] 332 // CHECK-X64-LABEL: 0 | struct L{{$}} 333 // CHECK-X64-NEXT: 0 | (L vftable pointer) 334 // CHECK-X64-NEXT: 256 | int Field 335 // CHECK-X64-NEXT: | [sizeof=512, align=256 336 // CHECK-X64-NEXT: | nvsize=260, nvalign=256] 337 338 #pragma pack() 339 struct MA {}; 340 #pragma pack(1) 341 struct MB : virtual MA { 342 __declspec(align(256)) int Field; 343 }; 344 345 // CHECK-LABEL: 0 | struct MB{{$}} 346 // CHECK-NEXT: 0 | (MB vbtable pointer) 347 // CHECK-NEXT: 256 | int Field 348 // CHECK-NEXT: 260 | struct MA (virtual base) (empty) 349 // CHECK-NEXT: | [sizeof=512, align=256 350 // CHECK-NEXT: | nvsize=260, nvalign=256] 351 // CHECK-X64-LABEL: 0 | struct MB{{$}} 352 // CHECK-X64-NEXT: 0 | (MB vbtable pointer) 353 // CHECK-X64-NEXT: 256 | int Field 354 // CHECK-X64-NEXT: 260 | struct MA (virtual base) (empty) 355 // CHECK-X64-NEXT: | [sizeof=512, align=256 356 // CHECK-X64-NEXT: | nvsize=260, nvalign=256] 357 358 struct RA {}; 359 #pragma pack(1) 360 struct __declspec(align(8)) RB0 { 361 __declspec(align(1024)) int b : 3; 362 }; 363 364 struct __declspec(align(8)) RB1 { 365 __declspec(align(1024)) int b : 3; fRB1366 virtual void f() {} 367 }; 368 369 struct __declspec(align(8)) RB2 : virtual RA { 370 __declspec(align(1024)) int b : 3; 371 }; 372 373 struct __declspec(align(8)) RB3 : virtual RA { 374 __declspec(align(1024)) int b : 3; fRB3375 virtual void f() {} 376 }; 377 378 struct RC { 379 char _; 380 __declspec(align(1024)) int c : 3; 381 }; 382 struct RE { 383 char _; 384 RC c; 385 }; 386 #pragma pack() 387 388 // CHECK-LABEL: 0 | struct RB0{{$}} 389 // CHECK-NEXT:0:0-2 | int b 390 // CHECK-NEXT: | [sizeof=8, align=1024 391 // CHECK-NEXT: | nvsize=4, nvalign=1024] 392 // CHECK-LABEL: 0 | struct RB1{{$}} 393 // CHECK-NEXT: 0 | (RB1 vftable pointer) 394 // CHECK-NEXT: 1024:0-2 | int b 395 // CHECK-NEXT: | [sizeof=1032, align=1024 396 // CHECK-NEXT: | nvsize=1028, nvalign=1024] 397 // CHECK-LABEL: 0 | struct RB2{{$}} 398 // CHECK-NEXT: 0 | (RB2 vbtable pointer) 399 // CHECK-NEXT: 1024:0-2 | int b 400 // CHECK-NEXT: 1028 | struct RA (virtual base) (empty) 401 // CHECK-NEXT: | [sizeof=1032, align=1024 402 // CHECK-NEXT: | nvsize=1028, nvalign=1024] 403 // CHECK-LABEL: 0 | struct RB3{{$}} 404 // CHECK-NEXT: 0 | (RB3 vftable pointer) 405 // CHECK-NEXT: 1024 | (RB3 vbtable pointer) 406 // CHECK-NEXT: 2048:0-2 | int b 407 // CHECK-NEXT: 2052 | struct RA (virtual base) (empty) 408 // CHECK-NEXT: | [sizeof=2056, align=1024 409 // CHECK-NEXT: | nvsize=2052, nvalign=1024] 410 // CHECK-LABEL: 0 | struct RC{{$}} 411 // CHECK-NEXT: 0 | char _ 412 // CHECK-NEXT: 1024:0-2 | int c 413 // CHECK-NEXT: | [sizeof=1028, align=1024 414 // CHECK-NEXT: | nvsize=1028, nvalign=1024] 415 // CHECK-LABEL: 0 | struct RE{{$}} 416 // CHECK-NEXT: 0 | char _ 417 // CHECK-NEXT: 1 | struct RC c 418 // CHECK-NEXT: 1 | char _ 419 // CHECK-NEXT: 1025:0-2 | int c 420 // CHECK-NEXT: | [sizeof=1029, align=1 421 // CHECK-NEXT: | nvsize=1029, nvalign=1] 422 // CHECK-X64-LABEL: 0 | struct RB0{{$}} 423 // CHECK-X64-NEXT: 0:0-2 | int b 424 // CHECK-X64-NEXT: | [sizeof=8, align=1024 425 // CHECK-X64-NEXT: | nvsize=4, nvalign=1024] 426 // CHECK-X64-LABEL: 0 | struct RB1{{$}} 427 // CHECK-X64-NEXT: 0 | (RB1 vftable pointer) 428 // CHECK-X64-NEXT: 1024:0-2 | int b 429 // CHECK-X64-NEXT: | [sizeof=1032, align=1024 430 // CHECK-X64-NEXT: | nvsize=1028, nvalign=1024] 431 // CHECK-X64-LABEL: 0 | struct RB2{{$}} 432 // CHECK-X64-NEXT: 0 | (RB2 vbtable pointer) 433 // CHECK-X64-NEXT: 1024:0-2 | int b 434 // CHECK-X64-NEXT: 1028 | struct RA (virtual base) (empty) 435 // CHECK-X64-NEXT: | [sizeof=1032, align=1024 436 // CHECK-X64-NEXT: | nvsize=1028, nvalign=1024] 437 // CHECK-X64-LABEL: 0 | struct RB3{{$}} 438 // CHECK-X64-NEXT: 0 | (RB3 vftable pointer) 439 // CHECK-X64-NEXT: 1024 | (RB3 vbtable pointer) 440 // CHECK-X64-NEXT: 2048:0-2 | int b 441 // CHECK-X64-NEXT: 2052 | struct RA (virtual base) (empty) 442 // CHECK-X64-NEXT: | [sizeof=2056, align=1024 443 // CHECK-X64-NEXT: | nvsize=2052, nvalign=1024] 444 // CHECK-X64-LABEL: 0 | struct RC{{$}} 445 // CHECK-X64-NEXT: 0 | char _ 446 // CHECK-X64-NEXT: 1024:0-2 | int c 447 // CHECK-X64-NEXT: | [sizeof=1028, align=1024 448 // CHECK-X64-NEXT: | nvsize=1028, nvalign=1024] 449 // CHECK-X64-LABEL: 0 | struct RE{{$}} 450 // CHECK-X64-NEXT: 0 | char _ 451 // CHECK-X64-NEXT: 1 | struct RC c 452 // CHECK-X64-NEXT: 1 | char _ 453 // CHECK-X64-NEXT: 1025:0-2 | int c 454 // CHECK-X64-NEXT: | [sizeof=1029, align=1 455 // CHECK-X64-NEXT: | nvsize=1029, nvalign=1] 456 457 struct NA {}; 458 struct NB {}; 459 #pragma pack(push, 1) 460 struct NC : virtual NA, virtual NB {}; 461 #pragma pack(pop) 462 struct ND : NC {}; 463 464 // CHECK-LABEL: 0 | struct NA (empty){{$}} 465 // CHECK-NEXT: | [sizeof=1, align=1 466 // CHECK-NEXT: | nvsize=0, nvalign=1] 467 // CHECK-LABEL: 0 | struct NB (empty){{$}} 468 // CHECK-NEXT: | [sizeof=1, align=1 469 // CHECK-NEXT: | nvsize=0, nvalign=1] 470 // CHECK-LABEL: 0 | struct NC{{$}} 471 // CHECK-NEXT: 0 | (NC vbtable pointer) 472 // CHECK-NEXT: 4 | struct NA (virtual base) (empty) 473 // CHECK-NEXT: 8 | struct NB (virtual base) (empty) 474 // CHECK-NEXT: | [sizeof=8, align=1 475 // CHECK-NEXT: | nvsize=4, nvalign=1] 476 // CHECK-LABEL: 0 | struct ND{{$}} 477 // CHECK-NEXT: 0 | struct NC (base) 478 // CHECK-NEXT: 0 | (NC vbtable pointer) 479 // CHECK-NEXT: 4 | struct NA (virtual base) (empty) 480 // CHECK-NEXT: 8 | struct NB (virtual base) (empty) 481 // CHECK-NEXT: | [sizeof=8, align=4 482 // CHECK-NEXT: | nvsize=4, nvalign=4] 483 // CHECK-X64-LABEL: 0 | struct NA (empty){{$}} 484 // CHECK-X64-NEXT: | [sizeof=1, align=1 485 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] 486 // CHECK-X64-LABEL: 0 | struct NB (empty){{$}} 487 // CHECK-X64-NEXT: | [sizeof=1, align=1 488 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] 489 // CHECK-X64-LABEL: 0 | struct NC{{$}} 490 // CHECK-X64-NEXT: 0 | (NC vbtable pointer) 491 // CHECK-X64-NEXT: 8 | struct NA (virtual base) (empty) 492 // CHECK-X64-NEXT: 12 | struct NB (virtual base) (empty) 493 // CHECK-X64-NEXT: | [sizeof=12, align=1 494 // CHECK-X64-NEXT: | nvsize=8, nvalign=1] 495 // CHECK-X64-LABEL: 0 | struct ND{{$}} 496 // CHECK-X64-NEXT: 0 | struct NC (base) 497 // CHECK-X64-NEXT: 0 | (NC vbtable pointer) 498 // CHECK-X64-NEXT: 8 | struct NA (virtual base) (empty) 499 // CHECK-X64-NEXT: 12 | struct NB (virtual base) (empty) 500 // CHECK-X64-NEXT: | [sizeof=12, align=4 501 // CHECK-X64-NEXT: | nvsize=8, nvalign=4] 502 503 struct OA {}; 504 struct OB {}; 505 struct OC : virtual OA, virtual OB {}; 506 #pragma pack(push, 1) 507 struct OD : OC {}; 508 #pragma pack(pop) 509 510 // CHECK-LABEL: 0 | struct OA (empty){{$}} 511 // CHECK-NEXT: | [sizeof=1, align=1 512 // CHECK-NEXT: | nvsize=0, nvalign=1] 513 // CHECK-LABEL: 0 | struct OB (empty){{$}} 514 // CHECK-NEXT: | [sizeof=1, align=1 515 // CHECK-NEXT: | nvsize=0, nvalign=1] 516 // CHECK-LABEL: 0 | struct OC{{$}} 517 // CHECK-NEXT: 0 | (OC vbtable pointer) 518 // CHECK-NEXT: 4 | struct OA (virtual base) (empty) 519 // CHECK-NEXT: 8 | struct OB (virtual base) (empty) 520 // CHECK-NEXT: | [sizeof=8, align=4 521 // CHECK-NEXT: | nvsize=4, nvalign=4] 522 // CHECK-LABEL: 0 | struct OD{{$}} 523 // CHECK-NEXT: 0 | struct OC (base) 524 // CHECK-NEXT: 0 | (OC vbtable pointer) 525 // CHECK-NEXT: 4 | struct OA (virtual base) (empty) 526 // CHECK-NEXT: 8 | struct OB (virtual base) (empty) 527 // CHECK-NEXT: | [sizeof=8, align=1 528 // CHECK-NEXT: | nvsize=4, nvalign=1] 529 // CHECK-X64-LABEL: 0 | struct OA (empty){{$}} 530 // CHECK-X64-NEXT: | [sizeof=1, align=1 531 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] 532 // CHECK-X64-LABEL: 0 | struct OB (empty){{$}} 533 // CHECK-X64-NEXT: | [sizeof=1, align=1 534 // CHECK-X64-NEXT: | nvsize=0, nvalign=1] 535 // CHECK-X64-LABEL: 0 | struct OC{{$}} 536 // CHECK-X64-NEXT: 0 | (OC vbtable pointer) 537 // CHECK-X64-NEXT: 8 | struct OA (virtual base) (empty) 538 // CHECK-X64-NEXT: 12 | struct OB (virtual base) (empty) 539 // CHECK-X64-NEXT: | [sizeof=16, align=8 540 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 541 // CHECK-X64-LABEL: 0 | struct OD{{$}} 542 // CHECK-X64-NEXT: 0 | struct OC (base) 543 // CHECK-X64-NEXT: 0 | (OC vbtable pointer) 544 // CHECK-X64-NEXT: 8 | struct OA (virtual base) (empty) 545 // CHECK-X64-NEXT: 12 | struct OB (virtual base) (empty) 546 // CHECK-X64-NEXT: | [sizeof=12, align=1 547 // CHECK-X64-NEXT: | nvsize=8, nvalign=1] 548 549 struct __declspec(align(4)) PA { 550 int c; 551 }; 552 553 typedef __declspec(align(8)) PA PB; 554 555 #pragma pack(push, 1) 556 struct PC { 557 char a; 558 PB x; 559 }; 560 #pragma pack(pop) 561 562 // CHECK: 0 | struct PC 563 // CHECK-NEXT: 0 | char a 564 // CHECK-NEXT: 8 | struct PA x 565 // CHECK-NEXT: 8 | int c 566 // CHECK-NEXT: | [sizeof=16, align=8 567 // CHECK-NEXT: | nvsize=12, nvalign=8] 568 // CHECK-X64: 0 | struct PC 569 // CHECK-X64-NEXT: 0 | char a 570 // CHECK-X64-NEXT: 8 | struct PA x 571 // CHECK-X64-NEXT: 8 | int c 572 // CHECK-X64-NEXT: | [sizeof=16, align=8 573 // CHECK-X64-NEXT: | nvsize=12, nvalign=8] 574 575 typedef PB PD; 576 577 #pragma pack(push, 1) 578 struct PE { 579 char a; 580 PD x; 581 }; 582 #pragma pack(pop) 583 584 // CHECK: 0 | struct PE 585 // CHECK-NEXT: 0 | char a 586 // CHECK-NEXT: 8 | struct PA x 587 // CHECK-NEXT: 8 | int c 588 // CHECK-NEXT: | [sizeof=16, align=8 589 // CHECK-NEXT: | nvsize=12, nvalign=8] 590 // CHECK-X64: 0 | struct PE 591 // CHECK-X64-NEXT: 0 | char a 592 // CHECK-X64-NEXT: 8 | struct PA x 593 // CHECK-X64-NEXT: 8 | int c 594 // CHECK-X64-NEXT: | [sizeof=16, align=8 595 // CHECK-X64-NEXT: | nvsize=12, nvalign=8] 596 597 typedef int __declspec(align(2)) QA; 598 #pragma pack(push, 1) 599 struct QB { 600 char a; 601 QA b; 602 }; 603 #pragma pack(pop) 604 605 // CHECK-LABEL: 0 | struct QB{{$}} 606 // CHECK-NEXT: 0 | char a 607 // CHECK-NEXT: 2 | QA b 608 // CHECK-NEXT: | [sizeof=6, align=2 609 // CHECK-NEXT: | nvsize=6, nvalign=2] 610 // CHECK-X64-LABEL: 0 | struct QB{{$}} 611 // CHECK-X64-NEXT: 0 | char a 612 // CHECK-X64-NEXT: 2 | QA b 613 // CHECK-X64-NEXT: | [sizeof=6, align=2 614 // CHECK-X64-NEXT: | nvsize=6, nvalign=2] 615 616 struct QC { 617 char a; 618 QA b; 619 }; 620 621 // CHECK-LABEL: 0 | struct QC{{$}} 622 // CHECK-NEXT: 0 | char a 623 // CHECK-NEXT: 4 | QA b 624 // CHECK-NEXT: | [sizeof=8, align=4 625 // CHECK-NEXT: | nvsize=8, nvalign=4] 626 // CHECK-X64-LABEL: 0 | struct QC{{$}} 627 // CHECK-X64-NEXT: 0 | char a 628 // CHECK-X64-NEXT: 4 | QA b 629 // CHECK-X64-NEXT: | [sizeof=8, align=4 630 // CHECK-X64-NEXT: | nvsize=8, nvalign=4] 631 632 struct QD { 633 char a; 634 QA b : 3; 635 }; 636 637 // CHECK-LABEL: 0 | struct QD{{$}} 638 // CHECK-NEXT: 0 | char a 639 // CHECK-NEXT:4:0-2 | QA b 640 // CHECK-NEXT: | [sizeof=8, align=4 641 // CHECK-NEXT: | nvsize=8, nvalign=4] 642 // CHECK-X64-LABEL: 0 | struct QD{{$}} 643 // CHECK-X64-NEXT: 0 | char a 644 // CHECK-X64-NEXT:4:0-2 | QA b 645 // CHECK-X64-NEXT: | [sizeof=8, align=4 646 // CHECK-X64-NEXT: | nvsize=8, nvalign=4] 647 648 struct __declspec(align(4)) EmptyAlignedLongLongMemb { 649 long long FlexArrayMemb[0]; 650 }; 651 652 // CHECK-LABEL: 0 | struct EmptyAlignedLongLongMemb{{$}} 653 // CHECK-NEXT: 0 | long long[0] FlexArrayMemb 654 // CHECK-NEXT: | [sizeof=8, align=8 655 // CHECK-NEXT: | nvsize=0, nvalign=8] 656 // CHECK-X64-LABEL: 0 | struct EmptyAlignedLongLongMemb{{$}} 657 // CHECK-X64-NEXT: 0 | long long[0] FlexArrayMemb 658 // CHECK-X64-NEXT: | [sizeof=8, align=8 659 // CHECK-X64-NEXT: | nvsize=0, nvalign=8] 660 661 #pragma pack(1) 662 struct __declspec(align(4)) EmptyPackedAlignedLongLongMemb { 663 long long FlexArrayMemb[0]; 664 }; 665 #pragma pack() 666 667 // CHECK-LABEL: 0 | struct EmptyPackedAlignedLongLongMemb{{$}} 668 // CHECK-NEXT: 0 | long long[0] FlexArrayMemb 669 // CHECK-NEXT: | [sizeof=4, align=4 670 // CHECK-NEXT: | nvsize=0, nvalign=4] 671 // CHECK-X64-LABEL: 0 | struct EmptyPackedAlignedLongLongMemb{{$}} 672 // CHECK-X64-NEXT: 0 | long long[0] FlexArrayMemb 673 // CHECK-X64-NEXT: | [sizeof=4, align=4 674 // CHECK-X64-NEXT: | nvsize=0, nvalign=4] 675 676 int a[ 677 sizeof(X)+ 678 sizeof(Y)+ 679 sizeof(Z)+ 680 sizeof(C1)+ 681 sizeof(CA2)+ 682 sizeof(YA)+ 683 sizeof(YB)+ 684 sizeof(YC)+ 685 sizeof(YD)+ 686 sizeof(YE)+ 687 sizeof(YF)+ 688 sizeof(YF)+ 689 sizeof(D2)+ 690 sizeof(JC)+ 691 sizeof(KB)+ 692 sizeof(L)+ 693 sizeof(MB)+ 694 sizeof(RB0)+ 695 sizeof(RB1)+ 696 sizeof(RB2)+ 697 sizeof(RB3)+ 698 sizeof(RC)+ 699 sizeof(RE)+ 700 sizeof(ND)+ 701 sizeof(OD)+ 702 sizeof(PC)+ 703 sizeof(PE)+ 704 sizeof(QB)+ 705 sizeof(QC)+ 706 sizeof(QD)+ 707 sizeof(EmptyAlignedLongLongMemb)+ 708 sizeof(EmptyPackedAlignedLongLongMemb)+ 709 0]; 710