1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts -fsyntax-only %s 2>/dev/null \ 2 // RUN: | FileCheck %s 3 // 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 // RUN: | FileCheck %s -check-prefix CHECK-X64 5 6 extern "C" int printf(const char *fmt, ...); 7 8 struct B0 { B0() { printf("B0 = %p\n", this); } }; 9 struct B1 { B1() { printf("B1 = %p\n", this); } }; 10 struct B2 { B2() { printf("B2 = %p\n", this); } }; 11 struct B3 { B3() { printf("B3 = %p\n", this); } }; 12 struct B4 { B4() { printf("B4 = %p\n", this); } }; 13 struct B5 { B5() { printf("B5 = %p\n", this); } }; 14 struct __declspec(align(2)) B6 { B6() { printf("B6 = %p\n", this); } }; 15 struct __declspec(align(16)) B7 { B7() { printf("B7 = %p\n", this); } }; 16 struct B8 { char c[5]; B8() { printf("B8 = %p\n", this); } }; 17 struct B9 { char c[6]; B9() { printf("B9 = %p\n", this); } }; 18 struct B10 { char c[7]; B10() { printf("B10 = %p\n", this); } }; 19 struct B11 { char c[8]; B11() { printf("B11 = %p\n", this); } }; 20 struct B0X { B0X() { printf("B0 = %p\n", this); } }; 21 struct B1X { B1X() { printf("B1 = %p\n", this); } }; 22 struct __declspec(align(16)) B2X { B2X() { printf("B2 = %p\n", this); } }; 23 struct __declspec(align(2)) B3X { B3X() { printf("B3 = %p\n", this); } }; 24 struct B4X { B4X() { printf("B4 = %p\n", this); } }; 25 struct B5X { B5X() { printf("B5 = %p\n", this); } }; 26 struct B6X { B6X() { printf("B6 = %p\n", this); } }; 27 struct B8X { short a; B8X() : a(0x000000B8) { printf("B8 = %p\n", this); } }; 28 29 struct AA : B8, B1, virtual B0 { 30 int a; 31 AA() : a(0x000000AA) { printf("AA = %p\n", this); } 32 }; 33 34 // CHECK: *** Dumping AST Record Layout 35 // CHECK: *** Dumping AST Record Layout 36 // CHECK: *** Dumping AST Record Layout 37 // CHECK: *** Dumping AST Record Layout 38 // CHECK-NEXT: 0 | struct AA 39 // CHECK-NEXT: 0 | struct B8 (base) 40 // CHECK-NEXT: 0 | char [5] c 41 // CHECK-NEXT: 13 | struct B1 (base) (empty) 42 // CHECK-NEXT: 8 | (AA vbtable pointer) 43 // CHECK-NEXT: 16 | int a 44 // CHECK-NEXT: 20 | struct B0 (virtual base) (empty) 45 // CHECK-NEXT: | [sizeof=20, align=4 46 // CHECK-NEXT: | nvsize=20, nvalign=4] 47 // CHECK-X64: *** Dumping AST Record Layout 48 // CHECK-X64: *** Dumping AST Record Layout 49 // CHECK-X64: *** Dumping AST Record Layout 50 // CHECK-X64: *** Dumping AST Record Layout 51 // CHECK-X64-NEXT: 0 | struct AA 52 // CHECK-X64-NEXT: 0 | struct B8 (base) 53 // CHECK-X64-NEXT: 0 | char [5] c 54 // CHECK-X64-NEXT: 17 | struct B1 (base) (empty) 55 // CHECK-X64-NEXT: 8 | (AA vbtable pointer) 56 // CHECK-X64-NEXT: 20 | int a 57 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 58 // CHECK-X64-NEXT: | [sizeof=24, align=8 59 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 60 61 struct AB : B8, B1, virtual B0 { 62 short a; 63 AB() : a(0x000000AB) { printf("AB = %p\n", this); } 64 }; 65 66 // CHECK: *** Dumping AST Record Layout 67 // CHECK-NEXT: 0 | struct AB 68 // CHECK-NEXT: 0 | struct B8 (base) 69 // CHECK-NEXT: 0 | char [5] c 70 // CHECK-NEXT: 13 | struct B1 (base) (empty) 71 // CHECK-NEXT: 8 | (AB vbtable pointer) 72 // CHECK-NEXT: 14 | short a 73 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 74 // CHECK-NEXT: | [sizeof=16, align=4 75 // CHECK-NEXT: | nvsize=16, nvalign=4] 76 // CHECK-X64: *** Dumping AST Record Layout 77 // CHECK-X64-NEXT: 0 | struct AB 78 // CHECK-X64-NEXT: 0 | struct B8 (base) 79 // CHECK-X64-NEXT: 0 | char [5] c 80 // CHECK-X64-NEXT: 17 | struct B1 (base) (empty) 81 // CHECK-X64-NEXT: 8 | (AB vbtable pointer) 82 // CHECK-X64-NEXT: 18 | short a 83 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 84 // CHECK-X64-NEXT: | [sizeof=24, align=8 85 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 86 87 struct AC : B8, B1, virtual B0 { 88 char a; 89 AC() : a(0x000000AC) { printf("AC = %p\n", this); } 90 }; 91 92 // CHECK: *** Dumping AST Record Layout 93 // CHECK-NEXT: 0 | struct AC 94 // CHECK-NEXT: 0 | struct B8 (base) 95 // CHECK-NEXT: 0 | char [5] c 96 // CHECK-NEXT: 12 | struct B1 (base) (empty) 97 // CHECK-NEXT: 8 | (AC vbtable pointer) 98 // CHECK-NEXT: 12 | char a 99 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 100 // CHECK-NEXT: | [sizeof=16, align=4 101 // CHECK-NEXT: | nvsize=16, nvalign=4] 102 // CHECK-X64: *** Dumping AST Record Layout 103 // CHECK-X64-NEXT: 0 | struct AC 104 // CHECK-X64-NEXT: 0 | struct B8 (base) 105 // CHECK-X64-NEXT: 0 | char [5] c 106 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 107 // CHECK-X64-NEXT: 8 | (AC vbtable pointer) 108 // CHECK-X64-NEXT: 16 | char a 109 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 110 // CHECK-X64-NEXT: | [sizeof=24, align=8 111 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 112 113 struct AD : B8, B1, virtual B0 { 114 AD() { printf("AD = %p\n", this); } 115 }; 116 117 // CHECK: *** Dumping AST Record Layout 118 // CHECK-NEXT: 0 | struct AD 119 // CHECK-NEXT: 0 | struct B8 (base) 120 // CHECK-NEXT: 0 | char [5] c 121 // CHECK-NEXT: 12 | struct B1 (base) (empty) 122 // CHECK-NEXT: 8 | (AD vbtable pointer) 123 // CHECK-NEXT: 12 | struct B0 (virtual base) (empty) 124 // CHECK-NEXT: | [sizeof=12, align=4 125 // CHECK-NEXT: | nvsize=12, nvalign=4] 126 // CHECK-X64: *** Dumping AST Record Layout 127 // CHECK-X64-NEXT: 0 | struct AD 128 // CHECK-X64-NEXT: 0 | struct B8 (base) 129 // CHECK-X64-NEXT: 0 | char [5] c 130 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 131 // CHECK-X64-NEXT: 8 | (AD vbtable pointer) 132 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) (empty) 133 // CHECK-X64-NEXT: | [sizeof=16, align=8 134 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 135 136 struct AA1 : B9, B1, virtual B0 { 137 int a; 138 AA1() : a(0x00000AA1) { printf("AA1 = %p\n", this); } 139 }; 140 141 // CHECK: *** Dumping AST Record Layout 142 // CHECK: *** Dumping AST Record Layout 143 // CHECK-NEXT: 0 | struct AA1 144 // CHECK-NEXT: 0 | struct B9 (base) 145 // CHECK-NEXT: 0 | char [6] c 146 // CHECK-NEXT: 14 | struct B1 (base) (empty) 147 // CHECK-NEXT: 8 | (AA1 vbtable pointer) 148 // CHECK-NEXT: 16 | int a 149 // CHECK-NEXT: 20 | struct B0 (virtual base) (empty) 150 // CHECK-NEXT: | [sizeof=20, align=4 151 // CHECK-NEXT: | nvsize=20, nvalign=4] 152 // CHECK-X64: *** Dumping AST Record Layout 153 // CHECK-X64: *** Dumping AST Record Layout 154 // CHECK-X64-NEXT: 0 | struct AA1 155 // CHECK-X64-NEXT: 0 | struct B9 (base) 156 // CHECK-X64-NEXT: 0 | char [6] c 157 // CHECK-X64-NEXT: 18 | struct B1 (base) (empty) 158 // CHECK-X64-NEXT: 8 | (AA1 vbtable pointer) 159 // CHECK-X64-NEXT: 20 | int a 160 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 161 // CHECK-X64-NEXT: | [sizeof=24, align=8 162 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 163 164 struct AB1 : B9, B1, virtual B0 { 165 short a; 166 AB1() : a(0x00000AB1) { printf("AB1 = %p\n", this); } 167 }; 168 169 // CHECK: *** Dumping AST Record Layout 170 // CHECK-NEXT: 0 | struct AB1 171 // CHECK-NEXT: 0 | struct B9 (base) 172 // CHECK-NEXT: 0 | char [6] c 173 // CHECK-NEXT: 12 | struct B1 (base) (empty) 174 // CHECK-NEXT: 8 | (AB1 vbtable pointer) 175 // CHECK-NEXT: 12 | short a 176 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 177 // CHECK-NEXT: | [sizeof=16, align=4 178 // CHECK-NEXT: | nvsize=16, nvalign=4] 179 // CHECK-X64: *** Dumping AST Record Layout 180 // CHECK-X64-NEXT: 0 | struct AB1 181 // CHECK-X64-NEXT: 0 | struct B9 (base) 182 // CHECK-X64-NEXT: 0 | char [6] c 183 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 184 // CHECK-X64-NEXT: 8 | (AB1 vbtable pointer) 185 // CHECK-X64-NEXT: 16 | short a 186 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 187 // CHECK-X64-NEXT: | [sizeof=24, align=8 188 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 189 190 struct AC1 : B9, B1, virtual B0 { 191 char a; 192 AC1() : a(0x000000C1) { printf("AC1 = %p\n", this); } 193 }; 194 195 // CHECK: *** Dumping AST Record Layout 196 // CHECK-NEXT: 0 | struct AC1 197 // CHECK-NEXT: 0 | struct B9 (base) 198 // CHECK-NEXT: 0 | char [6] c 199 // CHECK-NEXT: 12 | struct B1 (base) (empty) 200 // CHECK-NEXT: 8 | (AC1 vbtable pointer) 201 // CHECK-NEXT: 12 | char a 202 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 203 // CHECK-NEXT: | [sizeof=16, align=4 204 // CHECK-NEXT: | nvsize=16, nvalign=4] 205 // CHECK-X64: *** Dumping AST Record Layout 206 // CHECK-X64-NEXT: 0 | struct AC1 207 // CHECK-X64-NEXT: 0 | struct B9 (base) 208 // CHECK-X64-NEXT: 0 | char [6] c 209 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 210 // CHECK-X64-NEXT: 8 | (AC1 vbtable pointer) 211 // CHECK-X64-NEXT: 16 | char a 212 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 213 // CHECK-X64-NEXT: | [sizeof=24, align=8 214 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 215 216 struct AD1 : B9, B1, virtual B0 { 217 AD1() { printf("AD1 = %p\n", this); } 218 }; 219 220 // CHECK: *** Dumping AST Record Layout 221 // CHECK-NEXT: 0 | struct AD1 222 // CHECK-NEXT: 0 | struct B9 (base) 223 // CHECK-NEXT: 0 | char [6] c 224 // CHECK-NEXT: 12 | struct B1 (base) (empty) 225 // CHECK-NEXT: 8 | (AD1 vbtable pointer) 226 // CHECK-NEXT: 12 | struct B0 (virtual base) (empty) 227 // CHECK-NEXT: | [sizeof=12, align=4 228 // CHECK-NEXT: | nvsize=12, nvalign=4] 229 // CHECK-X64: *** Dumping AST Record Layout 230 // CHECK-X64-NEXT: 0 | struct AD1 231 // CHECK-X64-NEXT: 0 | struct B9 (base) 232 // CHECK-X64-NEXT: 0 | char [6] c 233 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 234 // CHECK-X64-NEXT: 8 | (AD1 vbtable pointer) 235 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) (empty) 236 // CHECK-X64-NEXT: | [sizeof=16, align=8 237 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 238 239 struct AA2 : B10, B1, virtual B0 { 240 int a; 241 AA2() : a(0x00000AA2) { printf("AA2 = %p\n", this); } 242 }; 243 244 // CHECK: *** Dumping AST Record Layout 245 // CHECK: *** Dumping AST Record Layout 246 // CHECK-NEXT: 0 | struct AA2 247 // CHECK-NEXT: 0 | struct B10 (base) 248 // CHECK-NEXT: 0 | char [7] c 249 // CHECK-NEXT: 15 | struct B1 (base) (empty) 250 // CHECK-NEXT: 8 | (AA2 vbtable pointer) 251 // CHECK-NEXT: 16 | int a 252 // CHECK-NEXT: 20 | struct B0 (virtual base) (empty) 253 // CHECK-NEXT: | [sizeof=20, align=4 254 // CHECK-NEXT: | nvsize=20, nvalign=4] 255 // CHECK-X64: *** Dumping AST Record Layout 256 // CHECK-X64: *** Dumping AST Record Layout 257 // CHECK-X64-NEXT: 0 | struct AA2 258 // CHECK-X64-NEXT: 0 | struct B10 (base) 259 // CHECK-X64-NEXT: 0 | char [7] c 260 // CHECK-X64-NEXT: 19 | struct B1 (base) (empty) 261 // CHECK-X64-NEXT: 8 | (AA2 vbtable pointer) 262 // CHECK-X64-NEXT: 20 | int a 263 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 264 // CHECK-X64-NEXT: | [sizeof=24, align=8 265 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 266 267 struct AB2 : B10, B1, virtual B0 { 268 short a; 269 AB2() : a(0x00000AB2) { printf("AB2 = %p\n", this); } 270 }; 271 272 // CHECK: *** Dumping AST Record Layout 273 // CHECK-NEXT: 0 | struct AB2 274 // CHECK-NEXT: 0 | struct B10 (base) 275 // CHECK-NEXT: 0 | char [7] c 276 // CHECK-NEXT: 13 | struct B1 (base) (empty) 277 // CHECK-NEXT: 8 | (AB2 vbtable pointer) 278 // CHECK-NEXT: 14 | short a 279 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 280 // CHECK-NEXT: | [sizeof=16, align=4 281 // CHECK-NEXT: | nvsize=16, nvalign=4] 282 // CHECK-X64: *** Dumping AST Record Layout 283 // CHECK-X64-NEXT: 0 | struct AB2 284 // CHECK-X64-NEXT: 0 | struct B10 (base) 285 // CHECK-X64-NEXT: 0 | char [7] c 286 // CHECK-X64-NEXT: 17 | struct B1 (base) (empty) 287 // CHECK-X64-NEXT: 8 | (AB2 vbtable pointer) 288 // CHECK-X64-NEXT: 18 | short a 289 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 290 // CHECK-X64-NEXT: | [sizeof=24, align=8 291 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 292 293 struct AC2 : B10, B1, virtual B0 { 294 char a; 295 AC2() : a(0x000000C2) { printf("AC2 = %p\n", this); } 296 }; 297 298 // CHECK: *** Dumping AST Record Layout 299 // CHECK-NEXT: 0 | struct AC2 300 // CHECK-NEXT: 0 | struct B10 (base) 301 // CHECK-NEXT: 0 | char [7] c 302 // CHECK-NEXT: 12 | struct B1 (base) (empty) 303 // CHECK-NEXT: 8 | (AC2 vbtable pointer) 304 // CHECK-NEXT: 12 | char a 305 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 306 // CHECK-NEXT: | [sizeof=16, align=4 307 // CHECK-NEXT: | nvsize=16, nvalign=4] 308 // CHECK-X64: *** Dumping AST Record Layout 309 // CHECK-X64-NEXT: 0 | struct AC2 310 // CHECK-X64-NEXT: 0 | struct B10 (base) 311 // CHECK-X64-NEXT: 0 | char [7] c 312 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 313 // CHECK-X64-NEXT: 8 | (AC2 vbtable pointer) 314 // CHECK-X64-NEXT: 16 | char a 315 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 316 // CHECK-X64-NEXT: | [sizeof=24, align=8 317 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 318 319 struct AD2 : B10, B1, virtual B0 { 320 AD2() { printf("AD2 = %p\n", this); } 321 }; 322 323 // CHECK: *** Dumping AST Record Layout 324 // CHECK-NEXT: 0 | struct AD2 325 // CHECK-NEXT: 0 | struct B10 (base) 326 // CHECK-NEXT: 0 | char [7] c 327 // CHECK-NEXT: 12 | struct B1 (base) (empty) 328 // CHECK-NEXT: 8 | (AD2 vbtable pointer) 329 // CHECK-NEXT: 12 | struct B0 (virtual base) (empty) 330 // CHECK-NEXT: | [sizeof=12, align=4 331 // CHECK-NEXT: | nvsize=12, nvalign=4] 332 // CHECK-X64: *** Dumping AST Record Layout 333 // CHECK-X64-NEXT: 0 | struct AD2 334 // CHECK-X64-NEXT: 0 | struct B10 (base) 335 // CHECK-X64-NEXT: 0 | char [7] c 336 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 337 // CHECK-X64-NEXT: 8 | (AD2 vbtable pointer) 338 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) (empty) 339 // CHECK-X64-NEXT: | [sizeof=16, align=8 340 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 341 342 struct AA3 : B11, B1, virtual B0 { 343 int a; 344 AA3() : a(0x00000AA3) { printf("AA3 = %p\n", this); } 345 }; 346 347 // CHECK: *** Dumping AST Record Layout 348 // CHECK: *** Dumping AST Record Layout 349 // CHECK-NEXT: 0 | struct AA3 350 // CHECK-NEXT: 0 | struct B11 (base) 351 // CHECK-NEXT: 0 | char [8] c 352 // CHECK-NEXT: 12 | struct B1 (base) (empty) 353 // CHECK-NEXT: 8 | (AA3 vbtable pointer) 354 // CHECK-NEXT: 12 | int a 355 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 356 // CHECK-NEXT: | [sizeof=16, align=4 357 // CHECK-NEXT: | nvsize=16, nvalign=4] 358 // CHECK-X64: *** Dumping AST Record Layout 359 // CHECK-X64: *** Dumping AST Record Layout 360 // CHECK-X64-NEXT: 0 | struct AA3 361 // CHECK-X64-NEXT: 0 | struct B11 (base) 362 // CHECK-X64-NEXT: 0 | char [8] c 363 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 364 // CHECK-X64-NEXT: 8 | (AA3 vbtable pointer) 365 // CHECK-X64-NEXT: 16 | int a 366 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 367 // CHECK-X64-NEXT: | [sizeof=24, align=8 368 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 369 370 struct AB3 : B11, B1, virtual B0 { 371 short a; 372 AB3() : a(0x00000AB3) { printf("AB3 = %p\n", this); } 373 }; 374 375 // CHECK: *** Dumping AST Record Layout 376 // CHECK-NEXT: 0 | struct AB3 377 // CHECK-NEXT: 0 | struct B11 (base) 378 // CHECK-NEXT: 0 | char [8] c 379 // CHECK-NEXT: 12 | struct B1 (base) (empty) 380 // CHECK-NEXT: 8 | (AB3 vbtable pointer) 381 // CHECK-NEXT: 12 | short a 382 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 383 // CHECK-NEXT: | [sizeof=16, align=4 384 // CHECK-NEXT: | nvsize=16, nvalign=4] 385 // CHECK-X64: *** Dumping AST Record Layout 386 // CHECK-X64-NEXT: 0 | struct AB3 387 // CHECK-X64-NEXT: 0 | struct B11 (base) 388 // CHECK-X64-NEXT: 0 | char [8] c 389 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 390 // CHECK-X64-NEXT: 8 | (AB3 vbtable pointer) 391 // CHECK-X64-NEXT: 16 | short a 392 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 393 // CHECK-X64-NEXT: | [sizeof=24, align=8 394 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 395 396 struct AC3 : B11, B1, virtual B0 { 397 char a; 398 AC3() : a(0x000000C3) { printf("AC3 = %p\n", this); } 399 }; 400 401 // CHECK: *** Dumping AST Record Layout 402 // CHECK-NEXT: 0 | struct AC3 403 // CHECK-NEXT: 0 | struct B11 (base) 404 // CHECK-NEXT: 0 | char [8] c 405 // CHECK-NEXT: 12 | struct B1 (base) (empty) 406 // CHECK-NEXT: 8 | (AC3 vbtable pointer) 407 // CHECK-NEXT: 12 | char a 408 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 409 // CHECK-NEXT: | [sizeof=16, align=4 410 // CHECK-NEXT: | nvsize=16, nvalign=4] 411 // CHECK-X64: *** Dumping AST Record Layout 412 // CHECK-X64-NEXT: 0 | struct AC3 413 // CHECK-X64-NEXT: 0 | struct B11 (base) 414 // CHECK-X64-NEXT: 0 | char [8] c 415 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 416 // CHECK-X64-NEXT: 8 | (AC3 vbtable pointer) 417 // CHECK-X64-NEXT: 16 | char a 418 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 419 // CHECK-X64-NEXT: | [sizeof=24, align=8 420 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 421 422 struct AD3 : B11, B1, virtual B0 { 423 AD3() { printf("AD3 = %p\n", this); } 424 }; 425 426 // CHECK: *** Dumping AST Record Layout 427 // CHECK-NEXT: 0 | struct AD3 428 // CHECK-NEXT: 0 | struct B11 (base) 429 // CHECK-NEXT: 0 | char [8] c 430 // CHECK-NEXT: 12 | struct B1 (base) (empty) 431 // CHECK-NEXT: 8 | (AD3 vbtable pointer) 432 // CHECK-NEXT: 12 | struct B0 (virtual base) (empty) 433 // CHECK-NEXT: | [sizeof=12, align=4 434 // CHECK-NEXT: | nvsize=12, nvalign=4] 435 // CHECK-X64: *** Dumping AST Record Layout 436 // CHECK-X64-NEXT: 0 | struct AD3 437 // CHECK-X64-NEXT: 0 | struct B11 (base) 438 // CHECK-X64-NEXT: 0 | char [8] c 439 // CHECK-X64-NEXT: 16 | struct B1 (base) (empty) 440 // CHECK-X64-NEXT: 8 | (AD3 vbtable pointer) 441 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) (empty) 442 // CHECK-X64-NEXT: | [sizeof=16, align=8 443 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 444 445 struct B : B1, B2, virtual B0 { 446 B() { printf("B = %p\n", this); } 447 }; 448 449 // CHECK: *** Dumping AST Record Layout 450 // CHECK: *** Dumping AST Record Layout 451 // CHECK-NEXT: 0 | struct B 452 // CHECK-NEXT: 0 | struct B1 (base) (empty) 453 // CHECK-NEXT: 8 | struct B2 (base) (empty) 454 // CHECK-NEXT: 4 | (B vbtable pointer) 455 // CHECK-NEXT: 8 | struct B0 (virtual base) (empty) 456 // CHECK-NEXT: | [sizeof=8, align=4 457 // CHECK-NEXT: | nvsize=8, nvalign=4] 458 // CHECK-X64: *** Dumping AST Record Layout 459 // CHECK-X64: *** Dumping AST Record Layout 460 // CHECK-X64-NEXT: 0 | struct B 461 // CHECK-X64-NEXT: 0 | struct B1 (base) (empty) 462 // CHECK-X64-NEXT: 16 | struct B2 (base) (empty) 463 // CHECK-X64-NEXT: 8 | (B vbtable pointer) 464 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) (empty) 465 // CHECK-X64-NEXT: | [sizeof=16, align=8 466 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 467 468 struct C : B1, B2, B3, virtual B0 { 469 char a; 470 C() : a(0x0000000C) { printf("C = %p\n", this); } 471 }; 472 473 // CHECK: *** Dumping AST Record Layout 474 // CHECK: *** Dumping AST Record Layout 475 // CHECK-NEXT: 0 | struct C 476 // CHECK-NEXT: 0 | struct B1 (base) (empty) 477 // CHECK-NEXT: 1 | struct B2 (base) (empty) 478 // CHECK-NEXT: 8 | struct B3 (base) (empty) 479 // CHECK-NEXT: 4 | (C vbtable pointer) 480 // CHECK-NEXT: 8 | char a 481 // CHECK-NEXT: 12 | struct B0 (virtual base) (empty) 482 // CHECK-NEXT: | [sizeof=12, align=4 483 // CHECK-NEXT: | nvsize=12, nvalign=4] 484 // CHECK-X64: *** Dumping AST Record Layout 485 // CHECK-X64: *** Dumping AST Record Layout 486 // CHECK-X64-NEXT: 0 | struct C 487 // CHECK-X64-NEXT: 0 | struct B1 (base) (empty) 488 // CHECK-X64-NEXT: 1 | struct B2 (base) (empty) 489 // CHECK-X64-NEXT: 16 | struct B3 (base) (empty) 490 // CHECK-X64-NEXT: 8 | (C vbtable pointer) 491 // CHECK-X64-NEXT: 16 | char a 492 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 493 // CHECK-X64-NEXT: | [sizeof=24, align=8 494 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 495 496 struct D : B1, B2, B3, B4, B5, virtual B0 { 497 int a; 498 D() : a(0x0000000D) { printf("D = %p\n", this); } 499 }; 500 501 // CHECK: *** Dumping AST Record Layout 502 // CHECK: *** Dumping AST Record Layout 503 // CHECK: *** Dumping AST Record Layout 504 // CHECK-NEXT: 0 | struct D 505 // CHECK-NEXT: 0 | struct B1 (base) (empty) 506 // CHECK-NEXT: 1 | struct B2 (base) (empty) 507 // CHECK-NEXT: 2 | struct B3 (base) (empty) 508 // CHECK-NEXT: 3 | struct B4 (base) (empty) 509 // CHECK-NEXT: 8 | struct B5 (base) (empty) 510 // CHECK-NEXT: 4 | (D vbtable pointer) 511 // CHECK-NEXT: 8 | int a 512 // CHECK-NEXT: 12 | struct B0 (virtual base) (empty) 513 // CHECK-NEXT: | [sizeof=12, align=4 514 // CHECK-NEXT: | nvsize=12, nvalign=4] 515 // CHECK-X64: *** Dumping AST Record Layout 516 // CHECK-X64: *** Dumping AST Record Layout 517 // CHECK-X64: *** Dumping AST Record Layout 518 // CHECK-X64-NEXT: 0 | struct D 519 // CHECK-X64-NEXT: 0 | struct B1 (base) (empty) 520 // CHECK-X64-NEXT: 1 | struct B2 (base) (empty) 521 // CHECK-X64-NEXT: 2 | struct B3 (base) (empty) 522 // CHECK-X64-NEXT: 3 | struct B4 (base) (empty) 523 // CHECK-X64-NEXT: 16 | struct B5 (base) (empty) 524 // CHECK-X64-NEXT: 8 | (D vbtable pointer) 525 // CHECK-X64-NEXT: 16 | int a 526 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 527 // CHECK-X64-NEXT: | [sizeof=24, align=8 528 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 529 530 struct E : B1, B6, B3, B4, B5, virtual B0 { 531 int a; 532 E() : a(0x0000000E) { printf("E = %p\n", this); } 533 }; 534 535 // CHECK: *** Dumping AST Record Layout 536 // CHECK: *** Dumping AST Record Layout 537 // CHECK-NEXT: 0 | struct E 538 // CHECK-NEXT: 0 | struct B1 (base) (empty) 539 // CHECK-NEXT: 2 | struct B6 (base) (empty) 540 // CHECK-NEXT: 3 | struct B3 (base) (empty) 541 // CHECK-NEXT: 4 | struct B4 (base) (empty) 542 // CHECK-NEXT: 13 | struct B5 (base) (empty) 543 // CHECK-NEXT: 8 | (E vbtable pointer) 544 // CHECK-NEXT: 16 | int a 545 // CHECK-NEXT: 20 | struct B0 (virtual base) (empty) 546 // CHECK-NEXT: | [sizeof=20, align=4 547 // CHECK-NEXT: | nvsize=20, nvalign=4] 548 // CHECK-X64: *** Dumping AST Record Layout 549 // CHECK-X64: *** Dumping AST Record Layout 550 // CHECK-X64-NEXT: 0 | struct E 551 // CHECK-X64-NEXT: 0 | struct B1 (base) (empty) 552 // CHECK-X64-NEXT: 2 | struct B6 (base) (empty) 553 // CHECK-X64-NEXT: 3 | struct B3 (base) (empty) 554 // CHECK-X64-NEXT: 4 | struct B4 (base) (empty) 555 // CHECK-X64-NEXT: 17 | struct B5 (base) (empty) 556 // CHECK-X64-NEXT: 8 | (E vbtable pointer) 557 // CHECK-X64-NEXT: 20 | int a 558 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 559 // CHECK-X64-NEXT: | [sizeof=24, align=8 560 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 561 562 struct F : B1, B6, B4, B8, B5, virtual B0 { 563 int a; 564 F() : a(0x0000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); } 565 }; 566 567 // CHECK: *** Dumping AST Record Layout 568 // CHECK-NEXT: 0 | struct F 569 // CHECK-NEXT: 0 | struct B1 (base) (empty) 570 // CHECK-NEXT: 2 | struct B6 (base) (empty) 571 // CHECK-NEXT: 3 | struct B4 (base) (empty) 572 // CHECK-NEXT: 3 | struct B8 (base) 573 // CHECK-NEXT: 3 | char [5] c 574 // CHECK-NEXT: 12 | struct B5 (base) (empty) 575 // CHECK-NEXT: 8 | (F vbtable pointer) 576 // CHECK-NEXT: 12 | int a 577 // CHECK-NEXT: 16 | struct B0 (virtual base) (empty) 578 // CHECK-NEXT: | [sizeof=16, align=4 579 // CHECK-NEXT: | nvsize=16, nvalign=4] 580 // CHECK-X64: *** Dumping AST Record Layout 581 // CHECK-X64-NEXT: 0 | struct F 582 // CHECK-X64-NEXT: 0 | struct B1 (base) (empty) 583 // CHECK-X64-NEXT: 2 | struct B6 (base) (empty) 584 // CHECK-X64-NEXT: 3 | struct B4 (base) (empty) 585 // CHECK-X64-NEXT: 3 | struct B8 (base) 586 // CHECK-X64-NEXT: 3 | char [5] c 587 // CHECK-X64-NEXT: 16 | struct B5 (base) (empty) 588 // CHECK-X64-NEXT: 8 | (F vbtable pointer) 589 // CHECK-X64-NEXT: 16 | int a 590 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) (empty) 591 // CHECK-X64-NEXT: | [sizeof=24, align=8 592 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 593 594 struct G : B8, B1, virtual B0 { 595 int a; 596 __declspec(align(16)) int a1; 597 G() : a(0x00000010), a1(0xf0000010) { printf("G = %p\n", this); } 598 }; 599 600 // CHECK: *** Dumping AST Record Layout 601 // CHECK-NEXT: 0 | struct G 602 // CHECK-NEXT: 0 | struct B8 (base) 603 // CHECK-NEXT: 0 | char [5] c 604 // CHECK-NEXT: 21 | struct B1 (base) (empty) 605 // CHECK-NEXT: 8 | (G vbtable pointer) 606 // CHECK-NEXT: 24 | int a 607 // CHECK-NEXT: 32 | int a1 608 // CHECK-NEXT: 48 | struct B0 (virtual base) (empty) 609 // CHECK-NEXT: | [sizeof=48, align=16 610 // CHECK-NEXT: | nvsize=48, nvalign=16] 611 // CHECK-X64: *** Dumping AST Record Layout 612 // CHECK-X64-NEXT: 0 | struct G 613 // CHECK-X64-NEXT: 0 | struct B8 (base) 614 // CHECK-X64-NEXT: 0 | char [5] c 615 // CHECK-X64-NEXT: 21 | struct B1 (base) (empty) 616 // CHECK-X64-NEXT: 8 | (G vbtable pointer) 617 // CHECK-X64-NEXT: 24 | int a 618 // CHECK-X64-NEXT: 32 | int a1 619 // CHECK-X64-NEXT: 48 | struct B0 (virtual base) (empty) 620 // CHECK-X64-NEXT: | [sizeof=48, align=16 621 // CHECK-X64-NEXT: | nvsize=48, nvalign=16] 622 623 struct AX : B1X, B2X, B3X, B4X, virtual B0X { 624 int a; 625 AX() : a(0x0000000A) { printf(" A = %p\n", this); } 626 }; 627 628 // CHECK: *** Dumping AST Record Layout 629 // CHECK: *** Dumping AST Record Layout 630 // CHECK: *** Dumping AST Record Layout 631 // CHECK: *** Dumping AST Record Layout 632 // CHECK: *** Dumping AST Record Layout 633 // CHECK: *** Dumping AST Record Layout 634 // CHECK-NEXT: 0 | struct AX 635 // CHECK-NEXT: 0 | struct B1X (base) (empty) 636 // CHECK-NEXT: 16 | struct B2X (base) (empty) 637 // CHECK-NEXT: 18 | struct B3X (base) (empty) 638 // CHECK-NEXT: 35 | struct B4X (base) (empty) 639 // CHECK-NEXT: 20 | (AX vbtable pointer) 640 // CHECK-NEXT: 36 | int a 641 // CHECK-NEXT: 48 | struct B0X (virtual base) (empty) 642 // CHECK-NEXT: | [sizeof=48, align=16 643 // CHECK-NEXT: | nvsize=48, nvalign=16] 644 // CHECK-X64: *** Dumping AST Record Layout 645 // CHECK-X64: *** Dumping AST Record Layout 646 // CHECK-X64: *** Dumping AST Record Layout 647 // CHECK-X64: *** Dumping AST Record Layout 648 // CHECK-X64: *** Dumping AST Record Layout 649 // CHECK-X64: *** Dumping AST Record Layout 650 // CHECK-X64-NEXT: 0 | struct AX 651 // CHECK-X64-NEXT: 0 | struct B1X (base) (empty) 652 // CHECK-X64-NEXT: 16 | struct B2X (base) (empty) 653 // CHECK-X64-NEXT: 18 | struct B3X (base) (empty) 654 // CHECK-X64-NEXT: 35 | struct B4X (base) (empty) 655 // CHECK-X64-NEXT: 24 | (AX vbtable pointer) 656 // CHECK-X64-NEXT: 36 | int a 657 // CHECK-X64-NEXT: 48 | struct B0X (virtual base) (empty) 658 // CHECK-X64-NEXT: | [sizeof=48, align=16 659 // CHECK-X64-NEXT: | nvsize=48, nvalign=16] 660 661 struct BX : B2X, B1X, B3X, B4X, virtual B0X { 662 int a; 663 BX() : a(0x0000000B) { printf(" B = %p\n", this); } 664 }; 665 666 // CHECK: *** Dumping AST Record Layout 667 // CHECK-NEXT: 0 | struct BX 668 // CHECK-NEXT: 0 | struct B2X (base) (empty) 669 // CHECK-NEXT: 1 | struct B1X (base) (empty) 670 // CHECK-NEXT: 2 | struct B3X (base) (empty) 671 // CHECK-NEXT: 19 | struct B4X (base) (empty) 672 // CHECK-NEXT: 4 | (BX vbtable pointer) 673 // CHECK-NEXT: 20 | int a 674 // CHECK-NEXT: 32 | struct B0X (virtual base) (empty) 675 // CHECK-NEXT: | [sizeof=32, align=16 676 // CHECK-NEXT: | nvsize=32, nvalign=16] 677 // CHECK-X64: *** Dumping AST Record Layout 678 // CHECK-X64-NEXT: 0 | struct BX 679 // CHECK-X64-NEXT: 0 | struct B2X (base) (empty) 680 // CHECK-X64-NEXT: 1 | struct B1X (base) (empty) 681 // CHECK-X64-NEXT: 2 | struct B3X (base) (empty) 682 // CHECK-X64-NEXT: 19 | struct B4X (base) (empty) 683 // CHECK-X64-NEXT: 8 | (BX vbtable pointer) 684 // CHECK-X64-NEXT: 20 | int a 685 // CHECK-X64-NEXT: 32 | struct B0X (virtual base) (empty) 686 // CHECK-X64-NEXT: | [sizeof=32, align=16 687 // CHECK-X64-NEXT: | nvsize=32, nvalign=16] 688 689 struct CX : B1X, B3X, B2X, virtual B0X { 690 int a; 691 CX() : a(0x0000000C) { printf(" C = %p\n", this); } 692 }; 693 694 // CHECK: *** Dumping AST Record Layout 695 // CHECK-NEXT: 0 | struct CX 696 // CHECK-NEXT: 0 | struct B1X (base) (empty) 697 // CHECK-NEXT: 2 | struct B3X (base) (empty) 698 // CHECK-NEXT: 32 | struct B2X (base) (empty) 699 // CHECK-NEXT: 16 | (CX vbtable pointer) 700 // CHECK-NEXT: 32 | int a 701 // CHECK-NEXT: 48 | struct B0X (virtual base) (empty) 702 // CHECK-NEXT: | [sizeof=48, align=16 703 // CHECK-NEXT: | nvsize=48, nvalign=16] 704 // CHECK-X64: *** Dumping AST Record Layout 705 // CHECK-X64-NEXT: 0 | struct CX 706 // CHECK-X64-NEXT: 0 | struct B1X (base) (empty) 707 // CHECK-X64-NEXT: 2 | struct B3X (base) (empty) 708 // CHECK-X64-NEXT: 32 | struct B2X (base) (empty) 709 // CHECK-X64-NEXT: 16 | (CX vbtable pointer) 710 // CHECK-X64-NEXT: 32 | int a 711 // CHECK-X64-NEXT: 48 | struct B0X (virtual base) (empty) 712 // CHECK-X64-NEXT: | [sizeof=48, align=16 713 // CHECK-X64-NEXT: | nvsize=48, nvalign=16] 714 715 struct DX : B8X, B1X, virtual B0X { 716 int a; 717 DX() : a(0x0000000D) { printf(" D = %p\n", this); } 718 }; 719 720 // CHECK: *** Dumping AST Record Layout 721 // CHECK: *** Dumping AST Record Layout 722 // CHECK-NEXT: 0 | struct DX 723 // CHECK-NEXT: 0 | struct B8X (base) 724 // CHECK-NEXT: 0 | short a 725 // CHECK-NEXT: 10 | struct B1X (base) (empty) 726 // CHECK-NEXT: 4 | (DX vbtable pointer) 727 // CHECK-NEXT: 12 | int a 728 // CHECK-NEXT: 16 | struct B0X (virtual base) (empty) 729 // CHECK-NEXT: | [sizeof=16, align=4 730 // CHECK-NEXT: | nvsize=16, nvalign=4] 731 // CHECK-X64: *** Dumping AST Record Layout 732 // CHECK-X64: *** Dumping AST Record Layout 733 // CHECK-X64-NEXT: 0 | struct DX 734 // CHECK-X64-NEXT: 0 | struct B8X (base) 735 // CHECK-X64-NEXT: 0 | short a 736 // CHECK-X64-NEXT: 18 | struct B1X (base) (empty) 737 // CHECK-X64-NEXT: 8 | (DX vbtable pointer) 738 // CHECK-X64-NEXT: 20 | int a 739 // CHECK-X64-NEXT: 24 | struct B0X (virtual base) (empty) 740 // CHECK-X64-NEXT: | [sizeof=24, align=8 741 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 742 743 744 struct C0 {}; 745 struct C1 : public C0 { int C1F0; }; 746 struct C2 : public C1, public C0 {}; 747 748 // CHECK: *** Dumping AST Record Layout 749 // CHECK: *** Dumping AST Record Layout 750 // CHECK: *** Dumping AST Record Layout 751 // CHECK-NEXT: 0 | struct C2 752 // CHECK-NEXT: 0 | struct C1 (base) 753 // CHECK-NEXT: 0 | struct C0 (base) (empty) 754 // CHECK-NEXT: 0 | int C1F0 755 // CHECK-NEXT: 5 | struct C0 (base) (empty) 756 // CHECK-NEXT: | [sizeof=8, align=4 757 // CHECK-NEXT: | nvsize=8, nvalign=4] 758 // CHECK-X64: *** Dumping AST Record Layout 759 // CHECK-X64: *** Dumping AST Record Layout 760 // CHECK-X64: *** Dumping AST Record Layout 761 // CHECK-X64-NEXT: 0 | struct C2 762 // CHECK-X64-NEXT: 0 | struct C1 (base) 763 // CHECK-X64-NEXT: 0 | struct C0 (base) (empty) 764 // CHECK-X64-NEXT: 0 | int C1F0 765 // CHECK-X64-NEXT: 5 | struct C0 (base) (empty) 766 // CHECK-X64-NEXT: | [sizeof=8, align=4 767 // CHECK-X64-NEXT: | nvsize=8, nvalign=4] 768 769 struct JA { char a; }; 770 struct JB { 771 char a; 772 virtual void f() {} 773 }; 774 struct JC { char a; }; 775 struct JD : JA, JB, virtual JC {}; 776 777 // CHECK: *** Dumping AST Record Layout 778 // CHECK: *** Dumping AST Record Layout 779 // CHECK: *** Dumping AST Record Layout 780 // CHECK: *** Dumping AST Record Layout 781 // CHECK-NEXT: 0 | struct JD 782 // CHECK-NEXT: 0 | struct JB (primary base) 783 // CHECK-NEXT: 0 | (JB vftable pointer) 784 // CHECK-NEXT: 4 | char a 785 // CHECK-NEXT: 12 | struct JA (base) 786 // CHECK-NEXT: 12 | char a 787 // CHECK-NEXT: 8 | (JD vbtable pointer) 788 // CHECK-NEXT: 16 | struct JC (virtual base) 789 // CHECK-NEXT: 16 | char a 790 // CHECK-NEXT: | [sizeof=17, align=4 791 // CHECK-NEXT: | nvsize=16, nvalign=4] 792 // CHECK-X64: *** Dumping AST Record Layout 793 // CHECK-X64: *** Dumping AST Record Layout 794 // CHECK-X64: *** Dumping AST Record Layout 795 // CHECK-X64: *** Dumping AST Record Layout 796 // CHECK-X64-NEXT: 0 | struct JD 797 // CHECK-X64-NEXT: 0 | struct JB (primary base) 798 // CHECK-X64-NEXT: 0 | (JB vftable pointer) 799 // CHECK-X64-NEXT: 8 | char a 800 // CHECK-X64-NEXT: 24 | struct JA (base) 801 // CHECK-X64-NEXT: 24 | char a 802 // CHECK-X64-NEXT: 16 | (JD vbtable pointer) 803 // CHECK-X64-NEXT: 32 | struct JC (virtual base) 804 // CHECK-X64-NEXT: 32 | char a 805 // CHECK-X64-NEXT: | [sizeof=40, align=8 806 // CHECK-X64-NEXT: | nvsize=32, nvalign=8] 807 808 int a[ 809 sizeof(AA)+ 810 sizeof(AB)+ 811 sizeof(AC)+ 812 sizeof(AD)+ 813 sizeof(AA1)+ 814 sizeof(AB1)+ 815 sizeof(AC1)+ 816 sizeof(AD1)+ 817 sizeof(AA2)+ 818 sizeof(AB2)+ 819 sizeof(AC2)+ 820 sizeof(AD2)+ 821 sizeof(AA3)+ 822 sizeof(AB3)+ 823 sizeof(AC3)+ 824 sizeof(AD3)+ 825 sizeof(B)+ 826 sizeof(C)+ 827 sizeof(D)+ 828 sizeof(E)+ 829 sizeof(F)+ 830 sizeof(G)+ 831 sizeof(AX)+ 832 sizeof(BX)+ 833 sizeof(CX)+ 834 sizeof(DX)+ 835 sizeof(C2)+ 836 sizeof(JD)+ 837 0]; 838