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