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