1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \ 2 // RUN: | FileCheck %s 3 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -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 { int a; B0() : a(0xf00000B0) {} }; 9 struct B1 { char a; B1() : a(0xB1) {} }; 10 struct B2 : virtual B1 { int a; B2() : a(0xf00000B2) {} }; 11 struct B3 { __declspec(align(16)) int a; B3() : a(0xf00000B3) {} }; 12 struct B4 : virtual B3 { int a; B4() : a(0xf00000B4) {} }; 13 struct B5 { __declspec(align(32)) int a; B5() : a(0xf00000B5) {} }; 14 struct B6 { int a; B6() : a(0xf00000B6) {} virtual void f() { printf("B6"); } }; 15 16 struct A : B0, virtual B1 { __declspec(align(16)) int a; A() : a(0xf000000A) {} virtual void f() { printf("A"); } }; 17 18 // CHECK: *** Dumping AST Record Layout 19 // CHECK: *** Dumping AST Record Layout 20 // CHECK: *** Dumping AST Record Layout 21 // CHECK-NEXT: 0 | struct A 22 // CHECK-NEXT: 0 | (A vftable pointer) 23 // CHECK-NEXT: 16 | struct B0 (base) 24 // CHECK-NEXT: 16 | int a 25 // CHECK-NEXT: 20 | (A vbtable pointer) 26 // CHECK-NEXT: 48 | int a 27 // CHECK-NEXT: 64 | struct B1 (virtual base) 28 // CHECK-NEXT: 64 | char a 29 // CHECK-NEXT: | [sizeof=80, align=16 30 // CHECK-NEXT: | nvsize=64, nvalign=16] 31 // CHECK-X64: *** Dumping AST Record Layout 32 // CHECK-X64: *** Dumping AST Record Layout 33 // CHECK-X64: *** Dumping AST Record Layout 34 // CHECK-X64-NEXT: 0 | struct A 35 // CHECK-X64-NEXT: 0 | (A vftable pointer) 36 // CHECK-X64-NEXT: 16 | struct B0 (base) 37 // CHECK-X64-NEXT: 16 | int a 38 // CHECK-X64-NEXT: 24 | (A vbtable pointer) 39 // CHECK-X64-NEXT: 48 | int a 40 // CHECK-X64-NEXT: 64 | struct B1 (virtual base) 41 // CHECK-X64-NEXT: 64 | char a 42 // CHECK-X64-NEXT: | [sizeof=80, align=16 43 // CHECK-X64-NEXT: | nvsize=64, nvalign=16] 44 45 struct B : A, B2 { int a; B() : a(0xf000000B) {} virtual void f() { printf("B"); } }; 46 47 // CHECK: *** Dumping AST Record Layout 48 // CHECK: *** Dumping AST Record Layout 49 // CHECK-NEXT: 0 | struct B 50 // CHECK-NEXT: 0 | struct A (primary base) 51 // CHECK-NEXT: 0 | (A vftable pointer) 52 // CHECK-NEXT: 16 | struct B0 (base) 53 // CHECK-NEXT: 16 | int a 54 // CHECK-NEXT: 20 | (A vbtable pointer) 55 // CHECK-NEXT: 48 | int a 56 // CHECK-NEXT: 64 | struct B2 (base) 57 // CHECK-NEXT: 64 | (B2 vbtable pointer) 58 // CHECK-NEXT: 68 | int a 59 // CHECK-NEXT: 72 | int a 60 // CHECK-NEXT: 80 | struct B1 (virtual base) 61 // CHECK-NEXT: 80 | char a 62 // CHECK-NEXT: | [sizeof=96, align=16 63 // CHECK-NEXT: | nvsize=80, nvalign=16] 64 // CHECK-X64: *** Dumping AST Record Layout 65 // CHECK-X64: *** Dumping AST Record Layout 66 // CHECK-X64-NEXT: 0 | struct B 67 // CHECK-X64-NEXT: 0 | struct A (primary base) 68 // CHECK-X64-NEXT: 0 | (A vftable pointer) 69 // CHECK-X64-NEXT: 16 | struct B0 (base) 70 // CHECK-X64-NEXT: 16 | int a 71 // CHECK-X64-NEXT: 24 | (A vbtable pointer) 72 // CHECK-X64-NEXT: 48 | int a 73 // CHECK-X64-NEXT: 64 | struct B2 (base) 74 // CHECK-X64-NEXT: 64 | (B2 vbtable pointer) 75 // CHECK-X64-NEXT: 72 | int a 76 // CHECK-X64-NEXT: 80 | int a 77 // CHECK-X64-NEXT: 96 | struct B1 (virtual base) 78 // CHECK-X64-NEXT: 96 | char a 79 // CHECK-X64-NEXT: | [sizeof=112, align=16 80 // CHECK-X64-NEXT: | nvsize=96, nvalign=16] 81 82 struct C : B4 { int a; C() : a(0xf000000C) {} virtual void f() { printf("C"); } }; 83 84 // CHECK: *** Dumping AST Record Layout 85 // CHECK: *** Dumping AST Record Layout 86 // CHECK: *** Dumping AST Record Layout 87 // CHECK-NEXT: 0 | struct C 88 // CHECK-NEXT: 0 | (C vftable pointer) 89 // CHECK-NEXT: 16 | struct B4 (base) 90 // CHECK-NEXT: 16 | (B4 vbtable pointer) 91 // CHECK-NEXT: 20 | int a 92 // CHECK-NEXT: 24 | int a 93 // CHECK-NEXT: 32 | struct B3 (virtual base) 94 // CHECK-NEXT: 32 | int a 95 // CHECK-NEXT: | [sizeof=48, align=16 96 // CHECK-NEXT: | nvsize=32, nvalign=16] 97 // CHECK-X64: *** Dumping AST Record Layout 98 // CHECK-X64: *** Dumping AST Record Layout 99 // CHECK-X64: *** Dumping AST Record Layout 100 // CHECK-X64-NEXT: 0 | struct C 101 // CHECK-X64-NEXT: 0 | (C vftable pointer) 102 // CHECK-X64-NEXT: 16 | struct B4 (base) 103 // CHECK-X64-NEXT: 16 | (B4 vbtable pointer) 104 // CHECK-X64-NEXT: 24 | int a 105 // CHECK-X64-NEXT: 32 | int a 106 // CHECK-X64-NEXT: 48 | struct B3 (virtual base) 107 // CHECK-X64-NEXT: 48 | int a 108 // CHECK-X64-NEXT: | [sizeof=64, align=16 109 // CHECK-X64-NEXT: | nvsize=48, nvalign=16] 110 111 struct D : C { int a; D() : a(0xf000000D) {} virtual void f() { printf("D"); } }; 112 113 // CHECK: *** Dumping AST Record Layout 114 // CHECK-NEXT: 0 | struct D 115 // CHECK-NEXT: 0 | struct C (primary base) 116 // CHECK-NEXT: 0 | (C vftable pointer) 117 // CHECK-NEXT: 16 | struct B4 (base) 118 // CHECK-NEXT: 16 | (B4 vbtable pointer) 119 // CHECK-NEXT: 20 | int a 120 // CHECK-NEXT: 24 | int a 121 // CHECK-NEXT: 32 | int a 122 // CHECK-NEXT: 48 | struct B3 (virtual base) 123 // CHECK-NEXT: 48 | int a 124 // CHECK-NEXT: | [sizeof=64, align=16 125 // CHECK-NEXT: | nvsize=48, nvalign=16] 126 // CHECK-X64: *** Dumping AST Record Layout 127 // CHECK-X64-NEXT: 0 | struct D 128 // CHECK-X64-NEXT: 0 | struct C (primary base) 129 // CHECK-X64-NEXT: 0 | (C vftable pointer) 130 // CHECK-X64-NEXT: 16 | struct B4 (base) 131 // CHECK-X64-NEXT: 16 | (B4 vbtable pointer) 132 // CHECK-X64-NEXT: 24 | int a 133 // CHECK-X64-NEXT: 32 | int a 134 // CHECK-X64-NEXT: 48 | int a 135 // CHECK-X64-NEXT: 64 | struct B3 (virtual base) 136 // CHECK-X64-NEXT: 64 | int a 137 // CHECK-X64-NEXT: | [sizeof=80, align=16 138 // CHECK-X64-NEXT: | nvsize=64, nvalign=16] 139 140 struct E : virtual C { int a; E() : a(0xf000000E) {} virtual void f() { printf("E"); } }; 141 142 // CHECK: *** Dumping AST Record Layout 143 // CHECK-NEXT: 0 | struct E 144 // CHECK-NEXT: 0 | (E vbtable pointer) 145 // CHECK-NEXT: 4 | int a 146 // CHECK-NEXT: 16 | struct B3 (virtual base) 147 // CHECK-NEXT: 16 | int a 148 // CHECK-NEXT: 44 | (vtordisp for vbase C) 149 // CHECK-NEXT: 48 | struct C (virtual base) 150 // CHECK-NEXT: 48 | (C vftable pointer) 151 // CHECK-NEXT: 64 | struct B4 (base) 152 // CHECK-NEXT: 64 | (B4 vbtable pointer) 153 // CHECK-NEXT: 68 | int a 154 // CHECK-NEXT: 72 | int a 155 // CHECK-NEXT: | [sizeof=80, align=16 156 // CHECK-NEXT: | nvsize=8, nvalign=16] 157 // CHECK-X64: *** Dumping AST Record Layout 158 // CHECK-X64-NEXT: 0 | struct E 159 // CHECK-X64-NEXT: 0 | (E vbtable pointer) 160 // CHECK-X64-NEXT: 8 | int a 161 // CHECK-X64-NEXT: 16 | struct B3 (virtual base) 162 // CHECK-X64-NEXT: 16 | int a 163 // CHECK-X64-NEXT: 44 | (vtordisp for vbase C) 164 // CHECK-X64-NEXT: 48 | struct C (virtual base) 165 // CHECK-X64-NEXT: 48 | (C vftable pointer) 166 // CHECK-X64-NEXT: 64 | struct B4 (base) 167 // CHECK-X64-NEXT: 64 | (B4 vbtable pointer) 168 // CHECK-X64-NEXT: 72 | int a 169 // CHECK-X64-NEXT: 80 | int a 170 // CHECK-X64-NEXT: | [sizeof=96, align=16 171 // CHECK-X64-NEXT: | nvsize=16, nvalign=16] 172 173 struct F : B3, virtual B0 { int a; F() : a(0xf000000F) {} virtual void f() { printf("F"); } }; 174 175 // CHECK: *** Dumping AST Record Layout 176 // CHECK-NEXT: 0 | struct F 177 // CHECK-NEXT: 0 | (F vftable pointer) 178 // CHECK-NEXT: 16 | struct B3 (base) 179 // CHECK-NEXT: 16 | int a 180 // CHECK-NEXT: 32 | (F vbtable pointer) 181 // CHECK-NEXT: 48 | int a 182 // CHECK-NEXT: 64 | struct B0 (virtual base) 183 // CHECK-NEXT: 64 | int a 184 // CHECK-NEXT: | [sizeof=80, align=16 185 // CHECK-NEXT: | nvsize=64, nvalign=16] 186 // CHECK-X64: *** Dumping AST Record Layout 187 // CHECK-X64-NEXT: 0 | struct F 188 // CHECK-X64-NEXT: 0 | (F vftable pointer) 189 // CHECK-X64-NEXT: 16 | struct B3 (base) 190 // CHECK-X64-NEXT: 16 | int a 191 // CHECK-X64-NEXT: 32 | (F vbtable pointer) 192 // CHECK-X64-NEXT: 48 | int a 193 // CHECK-X64-NEXT: 64 | struct B0 (virtual base) 194 // CHECK-X64-NEXT: 64 | int a 195 // CHECK-X64-NEXT: | [sizeof=80, align=16 196 // CHECK-X64-NEXT: | nvsize=64, nvalign=16] 197 198 struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} }; 199 200 // CHECK: *** Dumping AST Record Layout 201 // CHECK: *** Dumping AST Record Layout 202 // CHECK-NEXT: 0 | struct G 203 // CHECK-NEXT: 0 | struct B6 (primary base) 204 // CHECK-NEXT: 0 | (B6 vftable pointer) 205 // CHECK-NEXT: 4 | int a 206 // CHECK-NEXT: 8 | struct B2 (base) 207 // CHECK-NEXT: 8 | (B2 vbtable pointer) 208 // CHECK-NEXT: 12 | int a 209 // CHECK-NEXT: 16 | int a 210 // CHECK-NEXT: 20 | struct B1 (virtual base) 211 // CHECK-NEXT: 20 | char a 212 // CHECK-NEXT: | [sizeof=21, align=4 213 // CHECK-NEXT: | nvsize=20, nvalign=4] 214 // CHECK-X64: *** Dumping AST Record Layout 215 // CHECK-X64: *** Dumping AST Record Layout 216 // CHECK-X64-NEXT: 0 | struct G 217 // CHECK-X64-NEXT: 0 | struct B6 (primary base) 218 // CHECK-X64-NEXT: 0 | (B6 vftable pointer) 219 // CHECK-X64-NEXT: 8 | int a 220 // CHECK-X64-NEXT: 16 | struct B2 (base) 221 // CHECK-X64-NEXT: 16 | (B2 vbtable pointer) 222 // CHECK-X64-NEXT: 24 | int a 223 // CHECK-X64-NEXT: 32 | int a 224 // CHECK-X64-NEXT: 40 | struct B1 (virtual base) 225 // CHECK-X64-NEXT: 40 | char a 226 // CHECK-X64-NEXT: | [sizeof=48, align=8 227 // CHECK-X64-NEXT: | nvsize=40, nvalign=8] 228 229 struct H : B6, B2, virtual B1 { int a; H() : a(0xf0000011) {} }; 230 231 // CHECK: *** Dumping AST Record Layout 232 // CHECK-NEXT: 0 | struct H 233 // CHECK-NEXT: 0 | struct B6 (primary base) 234 // CHECK-NEXT: 0 | (B6 vftable pointer) 235 // CHECK-NEXT: 4 | int a 236 // CHECK-NEXT: 8 | struct B2 (base) 237 // CHECK-NEXT: 8 | (B2 vbtable pointer) 238 // CHECK-NEXT: 12 | int a 239 // CHECK-NEXT: 16 | int a 240 // CHECK-NEXT: 20 | struct B1 (virtual base) 241 // CHECK-NEXT: 20 | char a 242 // CHECK-NEXT: | [sizeof=21, align=4 243 // CHECK-NEXT: | nvsize=20, nvalign=4] 244 // CHECK-X64: *** Dumping AST Record Layout 245 // CHECK-X64-NEXT: 0 | struct H 246 // CHECK-X64-NEXT: 0 | struct B6 (primary base) 247 // CHECK-X64-NEXT: 0 | (B6 vftable pointer) 248 // CHECK-X64-NEXT: 8 | int a 249 // CHECK-X64-NEXT: 16 | struct B2 (base) 250 // CHECK-X64-NEXT: 16 | (B2 vbtable pointer) 251 // CHECK-X64-NEXT: 24 | int a 252 // CHECK-X64-NEXT: 32 | int a 253 // CHECK-X64-NEXT: 40 | struct B1 (virtual base) 254 // CHECK-X64-NEXT: 40 | char a 255 // CHECK-X64-NEXT: | [sizeof=48, align=8 256 // CHECK-X64-NEXT: | nvsize=40, nvalign=8] 257 258 struct I : B0, virtual B1 { int a; int a1; __declspec(align(16)) int a2; I() : a(0xf0000011), a1(0xf0000011), a2(0xf0000011) {} }; 259 260 // CHECK: *** Dumping AST Record Layout 261 // CHECK-NEXT: 0 | struct I 262 // CHECK-NEXT: 0 | struct B0 (base) 263 // CHECK-NEXT: 0 | int a 264 // CHECK-NEXT: 4 | (I vbtable pointer) 265 // CHECK-NEXT: 20 | int a 266 // CHECK-NEXT: 24 | int a1 267 // CHECK-NEXT: 32 | int a2 268 // CHECK-NEXT: 48 | struct B1 (virtual base) 269 // CHECK-NEXT: 48 | char a 270 // CHECK-NEXT: | [sizeof=64, align=16 271 // CHECK-NEXT: | nvsize=48, nvalign=16] 272 // CHECK-X64: *** Dumping AST Record Layout 273 // CHECK-X64-NEXT: 0 | struct I 274 // CHECK-X64-NEXT: 0 | struct B0 (base) 275 // CHECK-X64-NEXT: 0 | int a 276 // CHECK-X64-NEXT: 8 | (I vbtable pointer) 277 // CHECK-X64-NEXT: 20 | int a 278 // CHECK-X64-NEXT: 24 | int a1 279 // CHECK-X64-NEXT: 32 | int a2 280 // CHECK-X64-NEXT: 48 | struct B1 (virtual base) 281 // CHECK-X64-NEXT: 48 | char a 282 // CHECK-X64-NEXT: | [sizeof=64, align=16 283 // CHECK-X64-NEXT: | nvsize=48, nvalign=16] 284 285 struct J : B0, B3, virtual B1 { int a; int a1; J() : a(0xf0000012), a1(0xf0000012) {} }; 286 287 // CHECK: *** Dumping AST Record Layout 288 // CHECK-NEXT: 0 | struct J 289 // CHECK-NEXT: 0 | struct B0 (base) 290 // CHECK-NEXT: 0 | int a 291 // CHECK-NEXT: 16 | struct B3 (base) 292 // CHECK-NEXT: 16 | int a 293 // CHECK-NEXT: 32 | (J vbtable pointer) 294 // CHECK-NEXT: 48 | int a 295 // CHECK-NEXT: 52 | int a1 296 // CHECK-NEXT: 64 | struct B1 (virtual base) 297 // CHECK-NEXT: 64 | char a 298 // CHECK-NEXT: | [sizeof=80, align=16 299 // CHECK-NEXT: | nvsize=64, nvalign=16] 300 // CHECK-X64: *** Dumping AST Record Layout 301 // CHECK-X64-NEXT: 0 | struct J 302 // CHECK-X64-NEXT: 0 | struct B0 (base) 303 // CHECK-X64-NEXT: 0 | int a 304 // CHECK-X64-NEXT: 16 | struct B3 (base) 305 // CHECK-X64-NEXT: 16 | int a 306 // CHECK-X64-NEXT: 32 | (J vbtable pointer) 307 // CHECK-X64-NEXT: 48 | int a 308 // CHECK-X64-NEXT: 52 | int a1 309 // CHECK-X64-NEXT: 64 | struct B1 (virtual base) 310 // CHECK-X64-NEXT: 64 | char a 311 // CHECK-X64-NEXT: | [sizeof=80, align=16 312 // CHECK-X64-NEXT: | nvsize=64, nvalign=16] 313 314 struct K { int a; K() : a(0xf0000013) {} virtual void f() { printf("K"); } }; 315 316 // CHECK: *** Dumping AST Record Layout 317 // CHECK-NEXT: 0 | struct K 318 // CHECK-NEXT: 0 | (K vftable pointer) 319 // CHECK-NEXT: 4 | int a 320 // CHECK-NEXT: | [sizeof=8, align=4 321 // CHECK-NEXT: | nvsize=8, nvalign=4] 322 // CHECK-X64: *** Dumping AST Record Layout 323 // CHECK-X64-NEXT: 0 | struct K 324 // CHECK-X64-NEXT: 0 | (K vftable pointer) 325 // CHECK-X64-NEXT: 8 | int a 326 // CHECK-X64-NEXT: | [sizeof=16, align=8 327 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 328 329 struct L : virtual K { int a; L() : a(0xf0000014) {} virtual void g() { printf("L"); } }; 330 331 // CHECK: *** Dumping AST Record Layout 332 // CHECK-NEXT: 0 | struct L 333 // CHECK-NEXT: 0 | (L vftable pointer) 334 // CHECK-NEXT: 4 | (L vbtable pointer) 335 // CHECK-NEXT: 8 | int a 336 // CHECK-NEXT: 12 | struct K (virtual base) 337 // CHECK-NEXT: 12 | (K vftable pointer) 338 // CHECK-NEXT: 16 | int a 339 // CHECK-NEXT: | [sizeof=20, align=4 340 // CHECK-NEXT: | nvsize=12, nvalign=4] 341 // CHECK-X64: *** Dumping AST Record Layout 342 // CHECK-X64-NEXT: 0 | struct L 343 // CHECK-X64-NEXT: 0 | (L vftable pointer) 344 // CHECK-X64-NEXT: 8 | (L vbtable pointer) 345 // CHECK-X64-NEXT: 16 | int a 346 // CHECK-X64-NEXT: 24 | struct K (virtual base) 347 // CHECK-X64-NEXT: 24 | (K vftable pointer) 348 // CHECK-X64-NEXT: 32 | int a 349 // CHECK-X64-NEXT: | [sizeof=40, align=8 350 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 351 352 struct M : virtual K { int a; M() : a(0xf0000015) {} virtual void f() { printf("M"); } }; 353 354 // CHECK: *** Dumping AST Record Layout 355 // CHECK-NEXT: 0 | struct M 356 // CHECK-NEXT: 0 | (M vbtable pointer) 357 // CHECK-NEXT: 4 | int a 358 // CHECK-NEXT: 8 | (vtordisp for vbase K) 359 // CHECK-NEXT: 12 | struct K (virtual base) 360 // CHECK-NEXT: 12 | (K vftable pointer) 361 // CHECK-NEXT: 16 | int a 362 // CHECK-NEXT: | [sizeof=20, align=4 363 // CHECK-NEXT: | nvsize=8, nvalign=4] 364 // CHECK-X64: *** Dumping AST Record Layout 365 // CHECK-X64-NEXT: 0 | struct M 366 // CHECK-X64-NEXT: 0 | (M vbtable pointer) 367 // CHECK-X64-NEXT: 8 | int a 368 // CHECK-X64-NEXT: 20 | (vtordisp for vbase K) 369 // CHECK-X64-NEXT: 24 | struct K (virtual base) 370 // CHECK-X64-NEXT: 24 | (K vftable pointer) 371 // CHECK-X64-NEXT: 32 | int a 372 // CHECK-X64-NEXT: | [sizeof=40, align=8 373 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 374 375 int a[ 376 sizeof(A)+ 377 sizeof(B)+ 378 sizeof(C)+ 379 sizeof(D)+ 380 sizeof(E)+ 381 sizeof(F)+ 382 sizeof(G)+ 383 sizeof(H)+ 384 sizeof(I)+ 385 sizeof(J)+ 386 sizeof(K)+ 387 sizeof(L)+ 388 sizeof(M)]; 389