1 // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \ 2 // RUN: | FileCheck %s --strict-whitespace 3 4 #pragma pack(push, 8) 5 6 class B { 7 public: 8 virtual void b(){} 9 int b_field; 10 protected: 11 private: 12 }; 13 14 class A : public B { 15 public: 16 int a_field; 17 virtual void a(){} 18 char one; 19 protected: 20 private: 21 }; 22 23 class D { 24 public: 25 virtual void b(){} 26 double a; 27 }; 28 29 class C : public virtual A, 30 public D, public B { 31 public: 32 double c1_field; 33 int c2_field; 34 double c3_field; 35 int c4_field; 36 virtual void foo(){} 37 virtual void bar(){} 38 protected: 39 private: 40 }; 41 42 struct BaseStruct 43 { 44 BaseStruct(){} 45 double v0; 46 float v1; 47 C fg; 48 }; 49 50 struct DerivedStruct : public BaseStruct { 51 int x; 52 }; 53 54 struct G 55 { 56 int g_field; 57 }; 58 59 struct H : public G, 60 public virtual D 61 { 62 }; 63 64 struct I : public virtual D 65 { 66 virtual ~I(){} 67 double q; 68 }; 69 70 struct K 71 { 72 int k; 73 }; 74 75 struct L 76 { 77 int l; 78 }; 79 80 struct M : public virtual K 81 { 82 int m; 83 }; 84 85 struct N : public L, public M 86 { 87 virtual void f(){} 88 }; 89 90 struct O : public H, public G { 91 virtual void fo(){} 92 }; 93 94 struct P : public M, public virtual L { 95 int p; 96 }; 97 98 struct R {}; 99 100 class IA { 101 public: 102 virtual ~IA(){} 103 virtual void ia() = 0; 104 }; 105 106 class ICh : public virtual IA { 107 public: 108 virtual ~ICh(){} 109 virtual void ia(){} 110 virtual void iCh(){} 111 }; 112 113 struct f { 114 virtual int asd() {return -90;} 115 }; 116 117 struct s : public virtual f { 118 virtual ~s(){} 119 int r; 120 virtual int asd() {return -9;} 121 }; 122 123 struct sd : virtual s, virtual ICh { 124 virtual ~sd(){} 125 int q; 126 char y; 127 virtual int asd() {return -1;} 128 }; 129 struct AV { 130 virtual void foo(); 131 }; 132 struct BV : AV { 133 }; 134 struct CV : virtual BV { 135 CV(); 136 virtual void foo(); 137 }; 138 struct DV : BV { 139 }; 140 struct EV : CV, DV { 141 }; 142 #pragma pack(pop) 143 144 // This needs only for building layouts. 145 // Without this clang doesn`t dump record layouts. 146 int main() { 147 // This avoid "Can't yet mangle constructors!" for MS ABI. 148 C* c; 149 c->foo(); 150 DerivedStruct* v; 151 H* g; 152 BaseStruct* u; 153 I* i; 154 N* n; 155 O* o; 156 P* p; 157 R* r; 158 sd *h; 159 EV *j; 160 return 0; 161 } 162 163 // CHECK-LABEL: 0 | class B{{$}} 164 // CHECK-NEXT: 0 | (B vftable pointer) 165 // CHECK-NEXT: 4 | int b_field 166 167 // CHECK-NEXT: sizeof=8, align=4 168 // CHECK-NEXT: nvsize=8, nvalign=4 169 170 // CHECK-LABEL: 0 | class A{{$}} 171 // CHECK-NEXT: 0 | class B (primary base) 172 // CHECK-NEXT: 0 | (B vftable pointer) 173 // CHECK-NEXT: 4 | int b_field 174 // CHECK-NEXT: 8 | int a_field 175 // CHECK-NEXT: 12 | char one 176 177 // CHECK-NEXT: sizeof=16, align=4 178 // CHECK-NEXT: nvsize=16, nvalign=4 179 180 // CHECK-LABEL: 0 | class D{{$}} 181 // CHECK-NEXT: 0 | (D vftable pointer) 182 // CHECK-NEXT: 8 | double a 183 184 // CHECK-NEXT: sizeof=16, align=8 185 // CHECK-NEXT: nvsize=16, nvalign=8 186 187 // CHECK-LABEL: 0 | class C{{$}} 188 // CHECK-NEXT: 0 | class D (primary base) 189 // CHECK-NEXT: 0 | (D vftable pointer) 190 // CHECK-NEXT: 8 | double a 191 // CHECK-NEXT: 16 | class B (base) 192 // CHECK-NEXT: 16 | (B vftable pointer) 193 // CHECK-NEXT: 20 | int b_field 194 // CHECK-NEXT: 24 | (C vbtable pointer) 195 // CHECK-NEXT: 32 | double c1_field 196 // CHECK-NEXT: 40 | int c2_field 197 // CHECK-NEXT: 48 | double c3_field 198 // CHECK-NEXT: 56 | int c4_field 199 // CHECK-NEXT: 64 | class A (virtual base) 200 // CHECK-NEXT: 64 | class B (primary base) 201 // CHECK-NEXT: 64 | (B vftable pointer) 202 // CHECK-NEXT: 68 | int b_field 203 // CHECK-NEXT: 72 | int a_field 204 // CHECK-NEXT: 76 | char one 205 206 // CHECK-NEXT: sizeof=80, align=8 207 // CHECK-NEXT: nvsize=64, nvalign=8 208 209 // CHECK: %class.D = type { i32 (...)**, double } 210 211 // CHECK: %class.B = type { i32 (...)**, i32 } 212 213 // CHECK: %class.A = type { %class.B, i32, i8 } 214 215 // CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A } 216 // CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 } 217 218 // CHECK-LABEL: 0 | struct BaseStruct{{$}} 219 // CHECK-NEXT: 0 | double v0 220 // CHECK-NEXT: 8 | float v1 221 // CHECK-NEXT: 16 | class C fg 222 // CHECK-NEXT: 16 | class D (primary base) 223 // CHECK-NEXT: 16 | (D vftable pointer) 224 // CHECK-NEXT: 24 | double a 225 // CHECK-NEXT: 32 | class B (base) 226 // CHECK-NEXT: 32 | (B vftable pointer) 227 // CHECK-NEXT: 36 | int b_field 228 // CHECK-NEXT: 40 | (C vbtable pointer) 229 // CHECK-NEXT: 48 | double c1_field 230 // CHECK-NEXT: 56 | int c2_field 231 // CHECK-NEXT: 64 | double c3_field 232 // CHECK-NEXT: 72 | int c4_field 233 // CHECK-NEXT: 80 | class A (virtual base) 234 // CHECK-NEXT: 80 | class B (primary base) 235 // CHECK-NEXT: 80 | (B vftable pointer) 236 // CHECK-NEXT: 84 | int b_field 237 // CHECK-NEXT: 88 | int a_field 238 // CHECK-NEXT: 92 | char one 239 // CHECK-NEXT: sizeof=96, align=8 240 // CHECK-NEXT: nvsize=96, nvalign=8 241 242 // CHECK: %struct.BaseStruct = type { double, float, %class.C } 243 244 // CHECK-LABEL: 0 | struct DerivedStruct{{$}} 245 // CHECK-NEXT: 0 | struct BaseStruct (base) 246 // CHECK-NEXT: 0 | double v0 247 // CHECK-NEXT: 8 | float v1 248 // CHECK-NEXT: 16 | class C fg 249 // CHECK-NEXT: 16 | class D (primary base) 250 // CHECK-NEXT: 16 | (D vftable pointer) 251 // CHECK-NEXT: 24 | double a 252 // CHECK-NEXT: 32 | class B (base) 253 // CHECK-NEXT: 32 | (B vftable pointer) 254 // CHECK-NEXT: 36 | int b_field 255 // CHECK-NEXT: 40 | (C vbtable pointer) 256 // CHECK-NEXT: 48 | double c1_field 257 // CHECK-NEXT: 56 | int c2_field 258 // CHECK-NEXT: 64 | double c3_field 259 // CHECK-NEXT: 72 | int c4_field 260 // CHECK-NEXT: 80 | class A (virtual base) 261 // CHECK-NEXT: 80 | class B (primary base) 262 // CHECK-NEXT: 80 | (B vftable pointer) 263 // CHECK-NEXT: 84 | int b_field 264 // CHECK-NEXT: 88 | int a_field 265 // CHECK-NEXT: 92 | char one 266 // CHECK-NEXT: 96 | int x 267 // CHECK-NEXT: sizeof=104, align=8 268 // CHECK-NEXT: nvsize=104, nvalign=8 269 270 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 } 271 272 // CHECK-LABEL:0 | struct G 273 // CHECK-NEXT: 0 | int g_field 274 // CHECK-NEXT: sizeof=4, align=4 275 // CHECK-NEXT: nvsize=4, nvalign=4 276 277 // CHECK-LABEL: 0 | struct H{{$}} 278 // CHECK-NEXT: 0 | struct G (base) 279 // CHECK-NEXT: 0 | int g_field 280 // CHECK-NEXT: 4 | (H vbtable pointer) 281 // CHECK-NEXT: 8 | class D (virtual base) 282 // CHECK-NEXT: 8 | (D vftable pointer) 283 // CHECK-NEXT: 16 | double a 284 // CHECK-NEXT: sizeof=24, align=8 285 // CHECK-NEXT: nvsize=8, nvalign=8 286 287 // CHECK: %struct.H = type { %struct.G, i32*, %class.D } 288 289 // CHECK-LABEL: 0 | struct I{{$}} 290 // CHECK-NEXT: 0 | (I vftable pointer) 291 // CHECK-NEXT: 8 | (I vbtable pointer) 292 // CHECK-NEXT: 16 | double q 293 // CHECK-NEXT: 24 | class D (virtual base) 294 // CHECK-NEXT: 24 | (D vftable pointer) 295 // CHECK-NEXT: 32 | double a 296 // CHECK-NEXT: sizeof=40, align=8 297 // CHECK-NEXT: nvsize=24, nvalign=8 298 299 // CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D } 300 // CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double } 301 302 // CHECK-LABEL: 0 | struct L{{$}} 303 // CHECK-NEXT: 0 | int l 304 // CHECK-NEXT: sizeof=4, align=4 305 // CHECK-NEXT: nvsize=4, nvalign=4 306 307 // CHECK-LABEL: 0 | struct K{{$}} 308 // CHECK-NEXT: 0 | int k 309 // CHECK-NEXT: sizeof=4, align=4 310 // CHECK-NEXT: nvsize=4, nvalign=4 311 312 // CHECK-LABEL: 0 | struct M{{$}} 313 // CHECK-NEXT: 0 | (M vbtable pointer) 314 // CHECK-NEXT: 4 | int m 315 // CHECK-NEXT: 8 | struct K (virtual base) 316 // CHECK-NEXT: 8 | int k 317 // CHECK-NEXT: sizeof=12, align=4 318 319 //CHECK: %struct.M = type { i32*, i32, %struct.K } 320 //CHECK: %struct.M.base = type { i32*, i32 } 321 322 // CHECK-LABEL: 0 | struct N{{$}} 323 // CHECK-NEXT: 0 | (N vftable pointer) 324 // CHECK-NEXT: 4 | struct L (base) 325 // CHECK-NEXT: 4 | int l 326 // CHECK-NEXT: 8 | struct M (base) 327 // CHECK-NEXT: 8 | (M vbtable pointer) 328 // CHECK-NEXT: 12 | int m 329 // CHECK-NEXT: 16 | struct K (virtual base) 330 // CHECK-NEXT: 16 | int k 331 // CHECK-NEXT: sizeof=20, align=4 332 // CHECK-NEXT: nvsize=16, nvalign=4 333 334 //CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K } 335 336 // CHECK-LABEL: 0 | struct O{{$}} 337 // CHECK-NEXT: 0 | (O vftable pointer) 338 // CHECK-NEXT: 8 | struct H (base) 339 // CHECK-NEXT: 8 | struct G (base) 340 // CHECK-NEXT: 8 | int g_field 341 // CHECK-NEXT: 12 | (H vbtable pointer) 342 // CHECK-NEXT: 16 | struct G (base) 343 // CHECK-NEXT: 16 | int g_field 344 // CHECK-NEXT: 24 | class D (virtual base) 345 // CHECK-NEXT: 24 | (D vftable pointer) 346 // CHECK-NEXT: 32 | double a 347 // CHECK-NEXT: | [sizeof=40, align=8 348 // CHECK-NEXT: | nvsize=24, nvalign=8] 349 350 // CHECK: struct.O = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, %class.D } 351 // CHECK: struct.O.base = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, [4 x i8] } 352 353 // CHECK-LABEL: 0 | struct P{{$}} 354 // CHECK-NEXT: 0 | struct M (base) 355 // CHECK-NEXT: 0 | (M vbtable pointer) 356 // CHECK-NEXT: 4 | int m 357 // CHECK-NEXT: 8 | int p 358 // CHECK-NEXT: 12 | struct K (virtual base) 359 // CHECK-NEXT: 12 | int k 360 // CHECK-NEXT: 16 | struct L (virtual base) 361 // CHECK-NEXT: 16 | int l 362 // CHECK-NEXT: sizeof=20, align=4 363 // CHECK-NEXT: nvsize=12, nvalign=4 364 365 //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L } 366 367 // CHECK-LABEL: 0 | struct R (empty){{$}} 368 // CHECK-NEXT: sizeof=1, align=1 369 // CHECK-NEXT: nvsize=0, nvalign=1 370 371 //CHECK: %struct.R = type { i8 } 372 373 // CHECK-LABEL: 0 | struct f{{$}} 374 // CHECK-NEXT: 0 | (f vftable pointer) 375 // CHECK-NEXT: sizeof=4, align=4 376 // CHECK-NEXT: nvsize=4, nvalign=4 377 378 // CHECK-LABEL: 0 | struct s{{$}} 379 // CHECK-NEXT: 0 | (s vftable pointer) 380 // CHECK-NEXT: 4 | (s vbtable pointer) 381 // CHECK-NEXT: 8 | int r 382 // CHECK-NEXT: 12 | (vtordisp for vbase f) 383 // CHECK-NEXT: 16 | struct f (virtual base) 384 // CHECK-NEXT: 16 | (f vftable pointer) 385 // CHECK-NEXT: sizeof=20, align=4 386 // CHECK-NEXT: nvsize=12, nvalign=4 387 388 // CHECK-LABEL: 0 | class IA{{$}} 389 // CHECK-NEXT: 0 | (IA vftable pointer) 390 // CHECK-NEXT: sizeof=4, align=4 391 // CHECK-NEXT: nvsize=4, nvalign=4 392 393 // CHECK-LABEL: 0 | class ICh{{$}} 394 // CHECK-NEXT: 0 | (ICh vftable pointer) 395 // CHECK-NEXT: 4 | (ICh vbtable pointer) 396 // CHECK-NEXT: 8 | (vtordisp for vbase IA) 397 // CHECK-NEXT: 12 | class IA (virtual base) 398 // CHECK-NEXT: 12 | (IA vftable pointer) 399 // CHECK-NEXT: sizeof=16, align=4 400 // CHECK-NEXT: nvsize=8, nvalign=4 401 402 // CHECK-LABEL: 0 | struct sd{{$}} 403 // CHECK-NEXT: 0 | (sd vbtable pointer) 404 // CHECK-NEXT: 4 | int q 405 // CHECK-NEXT: 8 | char y 406 // CHECK-NEXT: 12 | (vtordisp for vbase f) 407 // CHECK-NEXT: 16 | struct f (virtual base) 408 // CHECK-NEXT: 16 | (f vftable pointer) 409 // CHECK-NEXT: 20 | struct s (virtual base) 410 // CHECK-NEXT: 20 | (s vftable pointer) 411 // CHECK-NEXT: 24 | (s vbtable pointer) 412 // CHECK-NEXT: 28 | int r 413 // CHECK-NEXT: 32 | (vtordisp for vbase IA) 414 // CHECK-NEXT: 36 | class IA (virtual base) 415 // CHECK-NEXT: 36 | (IA vftable pointer) 416 // CHECK-NEXT: 40 | class ICh (virtual base) 417 // CHECK-NEXT: 40 | (ICh vftable pointer) 418 // CHECK-NEXT: 44 | (ICh vbtable pointer) 419 // CHECK-NEXT: sizeof=48, align=4 420 // CHECK-NEXT: nvsize=12, nvalign=4 421 422 // CHECK: %struct.f = type { i32 (...)** } 423 // CHECK: %struct.s = type { i32 (...)**, i32*, i32, i32, %struct.f } 424 // CHECK: %class.IA = type { i32 (...)** } 425 // CHECK: %class.ICh = type { i32 (...)**, i32*, i32, %class.IA } 426 // CHECK: %struct.sd = type { i32*, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base } 427 428 // CHECK-LABEL: 0 | struct AV{{$}} 429 // CHECK-NEXT: 0 | (AV vftable pointer) 430 // CHECK-NEXT: sizeof=4, align=4 431 // CHECK-NEXT: nvsize=4, nvalign=4 432 433 // CHECK-LABEL: 0 | struct BV{{$}} 434 // CHECK-NEXT: 0 | struct AV (primary base) 435 // CHECK-NEXT: 0 | (AV vftable pointer) 436 // CHECK-NEXT: sizeof=4, align=4 437 // CHECK-NEXT: nvsize=4, nvalign=4 438 439 // CHECK-LABEL: 0 | struct CV{{$}} 440 // CHECK-NEXT: 0 | (CV vbtable pointer) 441 // CHECK-NEXT: 4 | (vtordisp for vbase BV) 442 // CHECK-NEXT: 8 | struct BV (virtual base) 443 // CHECK-NEXT: 8 | struct AV (primary base) 444 // CHECK-NEXT: 8 | (AV vftable pointer) 445 // CHECK-NEXT: sizeof=12, align=4 446 // CHECK-NEXT: nvsize=4, nvalign=4 447 448 // CHECK: %struct.AV = type { i32 (...)** } 449 // CHECK: %struct.BV = type { %struct.AV } 450 // CHECK: %struct.CV = type { i32*, i32, %struct.BV } 451 // CHECK: %struct.CV.base = type { i32* } 452 453 // CHECK-LABEL: 0 | struct DV{{$}} 454 // CHECK-NEXT: 0 | struct BV (primary base) 455 // CHECK-NEXT: 0 | struct AV (primary base) 456 // CHECK-NEXT: 0 | (AV vftable pointer) 457 // CHECK-NEXT: sizeof=4, align=4 458 // CHECK-NEXT: nvsize=4, nvalign=4 459 460 // CHECK: %struct.DV = type { %struct.BV } 461 462 // CHECK-LABEL: 0 | struct EV{{$}} 463 // CHECK-NEXT: 0 | struct DV (primary base) 464 // CHECK-NEXT: 0 | struct BV (primary base) 465 // CHECK-NEXT: 0 | struct AV (primary base) 466 // CHECK-NEXT: 0 | (AV vftable pointer) 467 // CHECK-NEXT: 4 | struct CV (base) 468 // CHECK-NEXT: 4 | (CV vbtable pointer) 469 // CHECK-NEXT: 8 | (vtordisp for vbase BV) 470 // CHECK-NEXT: 12 | struct BV (virtual base) 471 // CHECK-NEXT: 12 | struct AV (primary base) 472 // CHECK-NEXT: 12 | (AV vftable pointer) 473 // CHECK-NEXT: sizeof=16, align=4 474 // CHECK-NEXT: nvsize=8, nvalign=4 475 476 // CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, i32, %struct.BV } 477 // CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base } 478 479 // Overriding a method means that all the vbases containing that 480 // method need a vtordisp. Note: this code will cause an error in cl.exe. 481 namespace test1 { 482 struct A { virtual void foo(); }; 483 struct B : A {}; 484 struct C : virtual A, virtual B { C(); virtual void foo(); }; 485 void test() { C *c; } 486 487 // CHECK-LABEL: 0 | struct test1::C{{$}} 488 // CHECK-NEXT: 0 | (C vbtable pointer) 489 // CHECK-NEXT: 4 | (vtordisp for vbase A) 490 // CHECK-NEXT: 8 | struct test1::A (virtual base) 491 // CHECK-NEXT: 8 | (A vftable pointer) 492 // CHECK-NEXT: 12 | (vtordisp for vbase B) 493 // CHECK-NEXT: 16 | struct test1::B (virtual base) 494 // CHECK-NEXT: 16 | struct test1::A (primary base) 495 // CHECK-NEXT: 16 | (A vftable pointer) 496 // CHECK-NEXT: sizeof=20, align=4 497 // CHECK-NEXT: nvsize=4, nvalign=4 498 } 499