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