vtable-layout.cpp revision 97913576dbe624971bf18726899983d211d742c0
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s 2 3// For now, just verify this doesn't crash. 4namespace test0 { 5 struct Obj {}; 6 7 struct Base { virtual const Obj *foo() = 0; }; 8 struct Derived : Base { virtual Obj *foo() { return new Obj(); } }; 9 10 void test(Derived *D) { D->foo(); } 11} 12 13namespace Test1 { 14// CHECK: Vtable for 'Test1::A' (3 entries). 15// CHECK-NEXT: 0 | offset_to_top (0) 16// CHECK-NEXT: 1 | Test1::A RTTI 17// CHECK-NEXT: -- (Test1::A, 0) vtable address -- 18// CHECK-NEXT: 2 | void Test1::A::f() 19struct A { 20 virtual void f(); 21}; 22void A::f() { } 23 24} 25 26namespace Test2 { 27 28// This is a smoke test of the vtable dumper. 29// CHECK: Vtable for 'Test2::A' (9 entries). 30// CHECK-NEXT: 0 | offset_to_top (0) 31// CHECK-NEXT: 1 | Test2::A RTTI 32// CHECK-NEXT: -- (Test2::A, 0) vtable address -- 33// CHECK-NEXT: 2 | void Test2::A::f() 34// CHECK-NEXT: 3 | void Test2::A::f() const 35// CHECK-NEXT: 4 | Test2::A *Test2::A::g(int) 36// CHECK-NEXT: 5 | Test2::A::~A() [complete] 37// CHECK-NEXT: 6 | Test2::A::~A() [deleting] 38// CHECK-NEXT: 7 | void Test2::A::h() 39// CHECK-NEXT: 8 | Test2::A &Test2::A::operator=(Test2::A const &) 40struct A { 41 virtual void f(); 42 virtual void f() const; 43 44 virtual A* g(int a); 45 virtual ~A(); 46 virtual void h(); 47 virtual A& operator=(const A&); 48}; 49void A::f() { } 50 51// Another simple vtable dumper test. 52 53// CHECK: Vtable for 'Test2::B' (6 entries). 54// CHECK-NEXT: 0 | offset_to_top (0) 55// CHECK-NEXT: 1 | Test2::B RTTI 56// CHECK-NEXT: -- (Test2::B, 0) vtable address -- 57// CHECK-NEXT: 2 | void Test2::B::f() 58// CHECK-NEXT: 3 | void Test2::B::g() [pure] 59// CHECK-NEXT: 4 | Test2::B::~B() [complete] [pure] 60// CHECK-NEXT: 5 | Test2::B::~B() [deleting] [pure] 61struct B { 62 virtual void f(); 63 virtual void g() = 0; 64 virtual ~B() = 0; 65}; 66void B::f() { } 67 68} 69 70namespace Test3 { 71 72// If a function in a derived class overrides a function in a primary base, 73// then the function should not have an entry in the derived class (unless the return 74// value requires adjusting). 75 76// CHECK: Vtable for 'Test3::A' (3 entries). 77// CHECK-NEXT: 0 | offset_to_top (0) 78// CHECK-NEXT: 1 | Test3::A RTTI 79// CHECK-NEXT: -- (Test3::A, 0) vtable address -- 80// CHECK-NEXT: 2 | void Test3::A::f() 81struct A { 82 virtual void f(); 83}; 84void A::f() { } 85 86// CHECK: Vtable for 'Test3::B' (4 entries). 87// CHECK-NEXT: 0 | offset_to_top (0) 88// CHECK-NEXT: 1 | Test3::B RTTI 89// CHECK-NEXT: -- (Test3::A, 0) vtable address -- 90// CHECK-NEXT: -- (Test3::B, 0) vtable address -- 91// CHECK-NEXT: 2 | void Test3::B::f() 92// CHECK-NEXT: 3 | void Test3::B::g() 93struct B : A { 94 virtual void f(); 95 virtual void g(); 96}; 97void B::f() { } 98 99// CHECK: Vtable for 'Test3::C' (5 entries). 100// CHECK-NEXT: 0 | offset_to_top (0) 101// CHECK-NEXT: 1 | Test3::C RTTI 102// CHECK-NEXT: -- (Test3::A, 0) vtable address -- 103// CHECK-NEXT: -- (Test3::C, 0) vtable address -- 104// CHECK-NEXT: 2 | void Test3::A::f() 105// CHECK-NEXT: 3 | void Test3::C::g() 106// CHECK-NEXT: 4 | void Test3::C::h() 107struct C : A { 108 virtual void g(); 109 virtual void h(); 110}; 111void C::g() { } 112 113// CHECK: Vtable for 'Test3::D' (5 entries). 114// CHECK-NEXT: 0 | offset_to_top (0) 115// CHECK-NEXT: 1 | Test3::D RTTI 116// CHECK-NEXT: -- (Test3::A, 0) vtable address -- 117// CHECK-NEXT: -- (Test3::B, 0) vtable address -- 118// CHECK-NEXT: -- (Test3::D, 0) vtable address -- 119// CHECK-NEXT: 2 | void Test3::D::f() 120// CHECK-NEXT: 3 | void Test3::D::g() 121// CHECK-NEXT: 4 | void Test3::D::h() 122struct D : B { 123 virtual void f(); 124 virtual void g(); 125 virtual void h(); 126}; 127 128void D::f() { } 129} 130 131namespace Test4 { 132 133// Test non-virtual result adjustments. 134 135struct R1 { int r1; }; 136struct R2 { int r2; }; 137struct R3 : R1, R2 { int r3; }; 138 139struct A { 140 virtual R2 *f(); 141}; 142 143// CHECK: Vtable for 'Test4::B' (4 entries). 144// CHECK-NEXT: 0 | offset_to_top (0) 145// CHECK-NEXT: 1 | Test4::B RTTI 146// CHECK-NEXT: -- (Test4::A, 0) vtable address -- 147// CHECK-NEXT: -- (Test4::B, 0) vtable address -- 148// CHECK-NEXT: 2 | Test4::R3 *Test4::B::f() 149// CHECK-NEXT: [return adjustment: 4 non-virtual] 150// CHECK-NEXT: 3 | Test4::R3 *Test4::B::f() 151 152struct B : A { 153 virtual R3 *f(); 154}; 155R3 *B::f() { return 0; } 156 157// Test virtual result adjustments. 158struct V1 { int v1; }; 159struct V2 : virtual V1 { int v1; }; 160 161struct C { 162 virtual V1 *f(); 163}; 164 165// CHECK: Vtable for 'Test4::D' (4 entries). 166// CHECK-NEXT: 0 | offset_to_top (0) 167// CHECK-NEXT: 1 | Test4::D RTTI 168// CHECK-NEXT: -- (Test4::C, 0) vtable address -- 169// CHECK-NEXT: -- (Test4::D, 0) vtable address -- 170// CHECK-NEXT: 2 | Test4::V2 *Test4::D::f() 171// CHECK-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset] 172// CHECK-NEXT: 3 | Test4::V2 *Test4::D::f() 173struct D : C { 174 virtual V2 *f(); 175}; 176V2 *D::f() { return 0; }; 177 178// Virtual result adjustments with an additional non-virtual adjustment. 179struct V3 : virtual R3 { int r3; }; 180 181// CHECK: Vtable for 'Test4::E' (4 entries). 182// CHECK-NEXT: 0 | offset_to_top (0) 183// CHECK-NEXT: 1 | Test4::E RTTI 184// CHECK-NEXT: -- (Test4::A, 0) vtable address -- 185// CHECK-NEXT: -- (Test4::E, 0) vtable address -- 186// CHECK-NEXT: 2 | Test4::V3 *Test4::E::f() 187// CHECK-NEXT: [return adjustment: 4 non-virtual, -24 vbase offset offset] 188// CHECK-NEXT: 3 | Test4::V3 *Test4::E::f() 189 190struct E : A { 191 virtual V3 *f(); 192}; 193V3 *E::f() { return 0;} 194 195// Test that a pure virtual member doesn't get a thunk. 196 197// CHECK: Vtable for 'Test4::F' (5 entries). 198// CHECK-NEXT: 0 | offset_to_top (0) 199// CHECK-NEXT: 1 | Test4::F RTTI 200// CHECK-NEXT: -- (Test4::A, 0) vtable address -- 201// CHECK-NEXT: -- (Test4::F, 0) vtable address -- 202// CHECK-NEXT: 2 | Test4::R3 *Test4::F::f() [pure] 203// CHECK-NEXT: 3 | void Test4::F::g() 204// CHECK-NEXT: 4 | Test4::R3 *Test4::F::f() [pure] 205struct F : A { 206 virtual void g(); 207 virtual R3 *f() = 0; 208}; 209void F::g() { } 210 211} 212 213namespace Test5 { 214 215// Simple secondary vtables without 'this' pointer adjustments. 216struct A { 217 virtual void f(); 218 virtual void g(); 219 int a; 220}; 221 222struct B1 : A { 223 virtual void f(); 224 int b1; 225}; 226 227struct B2 : A { 228 virtual void g(); 229 int b2; 230}; 231 232// CHECK: Vtable for 'Test5::C' (9 entries). 233// CHECK-NEXT: 0 | offset_to_top (0) 234// CHECK-NEXT: 1 | Test5::C RTTI 235// CHECK-NEXT: -- (Test5::A, 0) vtable address -- 236// CHECK-NEXT: -- (Test5::B1, 0) vtable address -- 237// CHECK-NEXT: -- (Test5::C, 0) vtable address -- 238// CHECK-NEXT: 2 | void Test5::B1::f() 239// CHECK-NEXT: 3 | void Test5::A::g() 240// CHECK-NEXT: 4 | void Test5::C::h() 241// CHECK-NEXT: 5 | offset_to_top (-16) 242// CHECK-NEXT: 6 | Test5::C RTTI 243// CHECK-NEXT: -- (Test5::A, 16) vtable address -- 244// CHECK-NEXT: -- (Test5::B2, 16) vtable address -- 245// CHECK-NEXT: 7 | void Test5::A::f() 246// CHECK-NEXT: 8 | void Test5::B2::g() 247struct C : B1, B2 { 248 virtual void h(); 249}; 250void C::h() { } 251} 252 253namespace Test6 { 254 255// Simple non-virtual 'this' pointer adjustments. 256struct A1 { 257 virtual void f(); 258 int a; 259}; 260 261struct A2 { 262 virtual void f(); 263 int a; 264}; 265 266// CHECK: Vtable for 'Test6::C' (6 entries). 267// CHECK-NEXT: 0 | offset_to_top (0) 268// CHECK-NEXT: 1 | Test6::C RTTI 269// CHECK-NEXT: -- (Test6::A1, 0) vtable address -- 270// CHECK-NEXT: -- (Test6::C, 0) vtable address -- 271// CHECK-NEXT: 2 | void Test6::C::f() 272// CHECK-NEXT: 3 | offset_to_top (-16) 273// CHECK-NEXT: 4 | Test6::C RTTI 274// CHECK-NEXT: -- (Test6::A2, 16) vtable address -- 275// CHECK-NEXT: 5 | void Test6::C::f() 276// CHECK-NEXT: [this adjustment: -16 non-virtual] 277struct C : A1, A2 { 278 virtual void f(); 279}; 280void C::f() { } 281 282} 283 284namespace Test7 { 285 286// Test that the D::f overrider for A::f have different 'this' pointer 287// adjustments in the two A base subobjects. 288 289struct A { 290 virtual void f(); 291 int a; 292}; 293 294struct B1 : A { }; 295struct B2 : A { }; 296 297struct C { virtual void c(); }; 298 299// CHECK: Vtable for 'Test7::D' (10 entries). 300// CHECK-NEXT: 0 | offset_to_top (0) 301// CHECK-NEXT: 1 | Test7::D RTTI 302// CHECK-NEXT: -- (Test7::C, 0) vtable address -- 303// CHECK-NEXT: -- (Test7::D, 0) vtable address -- 304// CHECK-NEXT: 2 | void Test7::C::c() 305// CHECK-NEXT: 3 | void Test7::D::f() 306// CHECK-NEXT: 4 | offset_to_top (-8) 307// CHECK-NEXT: 5 | Test7::D RTTI 308// CHECK-NEXT: -- (Test7::A, 8) vtable address -- 309// CHECK-NEXT: -- (Test7::B1, 8) vtable address -- 310// CHECK-NEXT: 6 | void Test7::D::f() 311// CHECK-NEXT: [this adjustment: -8 non-virtual] 312// CHECK-NEXT: 7 | offset_to_top (-24) 313// CHECK-NEXT: 8 | Test7::D RTTI 314// CHECK-NEXT: -- (Test7::A, 24) vtable address -- 315// CHECK-NEXT: -- (Test7::B2, 24) vtable address -- 316// CHECK-NEXT: 9 | void Test7::D::f() 317// CHECK-NEXT: [this adjustment: -24 non-virtual] 318struct D : C, B1, B2 { 319 virtual void f(); 320}; 321void D::f() { } 322 323} 324 325namespace Test8 { 326 327// Test that we don't try to layout vtables for classes that don't have 328// virtual bases or virtual member functions. 329 330struct A { }; 331 332// CHECK: Vtable for 'Test8::B' (3 entries). 333// CHECK-NEXT: 0 | offset_to_top (0) 334// CHECK-NEXT: 1 | Test8::B RTTI 335// CHECK-NEXT: -- (Test8::B, 0) vtable address -- 336// CHECK-NEXT: 2 | void Test8::B::f() 337struct B : A { 338 virtual void f(); 339}; 340void B::f() { } 341 342} 343 344namespace Test9 { 345 346// Simple test of vbase offsets. 347 348struct A1 { int a1; }; 349struct A2 { int a2; }; 350 351// CHECK: Vtable for 'Test9::B' (5 entries). 352// CHECK-NEXT: 0 | vbase_offset (16) 353// CHECK-NEXT: 1 | vbase_offset (12) 354// CHECK-NEXT: 2 | offset_to_top (0) 355// CHECK-NEXT: 3 | Test9::B RTTI 356// CHECK-NEXT: -- (Test9::B, 0) vtable address -- 357// CHECK-NEXT: 4 | void Test9::B::f() 358struct B : virtual A1, virtual A2 { 359 int b; 360 361 virtual void f(); 362}; 363 364 365void B::f() { } 366 367} 368 369namespace Test10 { 370 371// Test for a bug where we would not emit secondary vtables for bases 372// of a primary base. 373struct A1 { virtual void a1(); }; 374struct A2 { virtual void a2(); }; 375 376// CHECK: Vtable for 'Test10::C' (7 entries). 377// CHECK-NEXT: 0 | offset_to_top (0) 378// CHECK-NEXT: 1 | Test10::C RTTI 379// CHECK-NEXT: -- (Test10::A1, 0) vtable address -- 380// CHECK-NEXT: -- (Test10::B, 0) vtable address -- 381// CHECK-NEXT: -- (Test10::C, 0) vtable address -- 382// CHECK-NEXT: 2 | void Test10::A1::a1() 383// CHECK-NEXT: 3 | void Test10::C::f() 384// CHECK-NEXT: 4 | offset_to_top (-8) 385// CHECK-NEXT: 5 | Test10::C RTTI 386// CHECK-NEXT: -- (Test10::A2, 8) vtable address -- 387// CHECK-NEXT: 6 | void Test10::A2::a2() 388struct B : A1, A2 { 389 int b; 390}; 391 392struct C : B { 393 virtual void f(); 394}; 395void C::f() { } 396 397} 398 399namespace Test11 { 400 401// Very simple test of vtables for virtual bases. 402struct A1 { int a; }; 403struct A2 { int b; }; 404 405struct B : A1, virtual A2 { 406 int b; 407}; 408 409// CHECK: Vtable for 'Test11::C' (8 entries). 410// CHECK-NEXT: 0 | vbase_offset (24) 411// CHECK-NEXT: 1 | vbase_offset (8) 412// CHECK-NEXT: 2 | offset_to_top (0) 413// CHECK-NEXT: 3 | Test11::C RTTI 414// CHECK-NEXT: -- (Test11::C, 0) vtable address -- 415// CHECK-NEXT: 4 | void Test11::C::f() 416// CHECK-NEXT: 5 | vbase_offset (16) 417// CHECK-NEXT: 6 | offset_to_top (-8) 418// CHECK-NEXT: 7 | Test11::C RTTI 419struct C : virtual B { 420 virtual void f(); 421}; 422void C::f() { } 423 424} 425 426namespace Test12 { 427 428// Test that the right vcall offsets are generated in the right order. 429 430// CHECK: Vtable for 'Test12::B' (19 entries). 431// CHECK-NEXT: 0 | vbase_offset (8) 432// CHECK-NEXT: 1 | offset_to_top (0) 433// CHECK-NEXT: 2 | Test12::B RTTI 434// CHECK-NEXT: -- (Test12::B, 0) vtable address -- 435// CHECK-NEXT: 3 | void Test12::B::f() 436// CHECK-NEXT: 4 | void Test12::B::a() 437// CHECK-NEXT: 5 | vcall_offset (32) 438// CHECK-NEXT: 6 | vcall_offset (16) 439// CHECK-NEXT: 7 | vcall_offset (-8) 440// CHECK-NEXT: 8 | vcall_offset (0) 441// CHECK-NEXT: 9 | offset_to_top (-8) 442// CHECK-NEXT: 10 | Test12::B RTTI 443// CHECK-NEXT: -- (Test12::A, 8) vtable address -- 444// CHECK-NEXT: -- (Test12::A1, 8) vtable address -- 445// CHECK-NEXT: 11 | void Test12::A1::a1() 446// CHECK-NEXT: 12 | void Test12::B::a() 447// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 448// CHECK-NEXT: 13 | offset_to_top (-24) 449// CHECK-NEXT: 14 | Test12::B RTTI 450// CHECK-NEXT: -- (Test12::A2, 24) vtable address -- 451// CHECK-NEXT: 15 | void Test12::A2::a2() 452// CHECK-NEXT: 16 | offset_to_top (-40) 453// CHECK-NEXT: 17 | Test12::B RTTI 454// CHECK-NEXT: -- (Test12::A3, 40) vtable address -- 455// CHECK-NEXT: 18 | void Test12::A3::a3() 456struct A1 { 457 virtual void a1(); 458 int a; 459}; 460 461struct A2 { 462 virtual void a2(); 463 int a; 464}; 465 466struct A3 { 467 virtual void a3(); 468 int a; 469}; 470 471struct A : A1, A2, A3 { 472 virtual void a(); 473 int i; 474}; 475 476struct B : virtual A { 477 virtual void f(); 478 479 virtual void a(); 480}; 481void B::f() { } 482 483} 484 485namespace Test13 { 486 487// Test that we don't try to emit a vtable for 'A' twice. 488struct A { 489 virtual void f(); 490}; 491 492struct B : virtual A { 493 virtual void f(); 494}; 495 496// CHECK: Vtable for 'Test13::C' (6 entries). 497// CHECK-NEXT: 0 | vbase_offset (0) 498// CHECK-NEXT: 1 | vbase_offset (0) 499// CHECK-NEXT: 2 | vcall_offset (0) 500// CHECK-NEXT: 3 | offset_to_top (0) 501// CHECK-NEXT: 4 | Test13::C RTTI 502// CHECK-NEXT: -- (Test13::A, 0) vtable address -- 503// CHECK-NEXT: -- (Test13::B, 0) vtable address -- 504// CHECK-NEXT: -- (Test13::C, 0) vtable address -- 505// CHECK-NEXT: 5 | void Test13::C::f() 506struct C : virtual B, virtual A { 507 virtual void f(); 508}; 509void C::f() { } 510 511} 512 513namespace Test14 { 514 515// Verify that we handle A being a non-virtual base of B, which is a virtual base. 516 517struct A { 518 virtual void f(); 519}; 520 521struct B : A { }; 522 523struct C : virtual B { }; 524 525// CHECK: Vtable for 'Test14::D' (5 entries). 526// CHECK-NEXT: 0 | vbase_offset (0) 527// CHECK-NEXT: 1 | vcall_offset (0) 528// CHECK-NEXT: 2 | offset_to_top (0) 529// CHECK-NEXT: 3 | Test14::D RTTI 530// CHECK-NEXT: -- (Test14::A, 0) vtable address -- 531// CHECK-NEXT: -- (Test14::B, 0) vtable address -- 532// CHECK-NEXT: -- (Test14::C, 0) vtable address -- 533// CHECK-NEXT: -- (Test14::D, 0) vtable address -- 534// CHECK-NEXT: 4 | void Test14::D::f() 535struct D : C, virtual B { 536 virtual void f(); 537}; 538void D::f() { } 539 540} 541 542namespace Test15 { 543 544// Test that we don't emit an extra vtable for B since it's a primary base of C. 545struct A { virtual void a(); }; 546struct B { virtual void b(); }; 547 548struct C : virtual B { }; 549 550// CHECK: Vtable for 'Test15::D' (11 entries). 551// CHECK-NEXT: 0 | vbase_offset (8) 552// CHECK-NEXT: 1 | vbase_offset (8) 553// CHECK-NEXT: 2 | offset_to_top (0) 554// CHECK-NEXT: 3 | Test15::D RTTI 555// CHECK-NEXT: -- (Test15::A, 0) vtable address -- 556// CHECK-NEXT: -- (Test15::D, 0) vtable address -- 557// CHECK-NEXT: 4 | void Test15::A::a() 558// CHECK-NEXT: 5 | void Test15::D::f() 559// CHECK-NEXT: 6 | vbase_offset (0) 560// CHECK-NEXT: 7 | vcall_offset (0) 561// CHECK-NEXT: 8 | offset_to_top (-8) 562// CHECK-NEXT: 9 | Test15::D RTTI 563// CHECK-NEXT: -- (Test15::B, 8) vtable address -- 564// CHECK-NEXT: -- (Test15::C, 8) vtable address -- 565// CHECK-NEXT: 10 | void Test15::B::b() 566struct D : A, virtual B, virtual C { 567 virtual void f(); 568}; 569void D::f() { } 570 571} 572 573namespace Test16 { 574 575// Test that destructors share vcall offsets. 576 577struct A { virtual ~A(); }; 578struct B { virtual ~B(); }; 579 580struct C : A, B { virtual ~C(); }; 581 582// CHECK: Vtable for 'Test16::D' (15 entries). 583// CHECK-NEXT: 0 | vbase_offset (8) 584// CHECK-NEXT: 1 | offset_to_top (0) 585// CHECK-NEXT: 2 | Test16::D RTTI 586// CHECK-NEXT: -- (Test16::D, 0) vtable address -- 587// CHECK-NEXT: 3 | void Test16::D::f() 588// CHECK-NEXT: 4 | Test16::D::~D() [complete] 589// CHECK-NEXT: 5 | Test16::D::~D() [deleting] 590// CHECK-NEXT: 6 | vcall_offset (-8) 591// CHECK-NEXT: 7 | offset_to_top (-8) 592// CHECK-NEXT: 8 | Test16::D RTTI 593// CHECK-NEXT: -- (Test16::A, 8) vtable address -- 594// CHECK-NEXT: -- (Test16::C, 8) vtable address -- 595// CHECK-NEXT: 9 | Test16::D::~D() [complete] 596// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 597// CHECK-NEXT: 10 | Test16::D::~D() [deleting] 598// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 599// CHECK-NEXT: 11 | offset_to_top (-16) 600// CHECK-NEXT: 12 | Test16::D RTTI 601// CHECK-NEXT: -- (Test16::B, 16) vtable address -- 602// CHECK-NEXT: 13 | Test16::D::~D() [complete] 603// CHECK-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset] 604// CHECK-NEXT: 14 | Test16::D::~D() [deleting] 605// CHECK-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset] 606struct D : virtual C { 607 virtual void f(); 608}; 609void D::f() { } 610 611} 612 613namespace Test17 { 614 615// Test that we don't mark E::f in the C-in-E vtable as unused. 616struct A { virtual void f(); }; 617struct B : virtual A { virtual void f(); }; 618struct C : virtual A { virtual void f(); }; 619struct D : virtual B, virtual C { virtual void f(); }; 620 621// CHECK: Vtable for 'Test17::E' (13 entries). 622// CHECK-NEXT: 0 | vbase_offset (0) 623// CHECK-NEXT: 1 | vbase_offset (8) 624// CHECK-NEXT: 2 | vbase_offset (0) 625// CHECK-NEXT: 3 | vbase_offset (0) 626// CHECK-NEXT: 4 | vcall_offset (0) 627// CHECK-NEXT: 5 | offset_to_top (0) 628// CHECK-NEXT: 6 | Test17::E RTTI 629// CHECK-NEXT: -- (Test17::A, 0) vtable address -- 630// CHECK-NEXT: -- (Test17::B, 0) vtable address -- 631// CHECK-NEXT: -- (Test17::D, 0) vtable address -- 632// CHECK-NEXT: -- (Test17::E, 0) vtable address -- 633// CHECK-NEXT: 7 | void Test17::E::f() 634// CHECK-NEXT: 8 | vbase_offset (-8) 635// CHECK-NEXT: 9 | vcall_offset (-8) 636// CHECK-NEXT: 10 | offset_to_top (-8) 637// CHECK-NEXT: 11 | Test17::E RTTI 638// CHECK-NEXT: -- (Test17::C, 8) vtable address -- 639// CHECK-NEXT: 12 | void Test17::E::f() 640// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 641class E : virtual D { 642 virtual void f(); 643}; 644void E::f() {} 645 646} 647 648namespace Test18 { 649 650// Test that we compute the right 'this' adjustment offsets. 651 652struct A { 653 virtual void f(); 654 virtual void g(); 655}; 656 657struct B : virtual A { 658 virtual void f(); 659}; 660 661struct C : A, B { 662 virtual void g(); 663}; 664 665// CHECK: Vtable for 'Test18::D' (24 entries). 666// CHECK-NEXT: 0 | vbase_offset (8) 667// CHECK-NEXT: 1 | vbase_offset (0) 668// CHECK-NEXT: 2 | vbase_offset (0) 669// CHECK-NEXT: 3 | vcall_offset (8) 670// CHECK-NEXT: 4 | vcall_offset (0) 671// CHECK-NEXT: 5 | offset_to_top (0) 672// CHECK-NEXT: 6 | Test18::D RTTI 673// CHECK-NEXT: -- (Test18::A, 0) vtable address -- 674// CHECK-NEXT: -- (Test18::B, 0) vtable address -- 675// CHECK-NEXT: -- (Test18::D, 0) vtable address -- 676// CHECK-NEXT: 7 | void Test18::D::f() 677// CHECK-NEXT: 8 | void Test18::C::g() 678// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 679// CHECK-NEXT: 9 | void Test18::D::h() 680// CHECK-NEXT: 10 | vcall_offset (0) 681// CHECK-NEXT: 11 | vcall_offset (-8) 682// CHECK-NEXT: 12 | vbase_offset (-8) 683// CHECK-NEXT: 13 | offset_to_top (-8) 684// CHECK-NEXT: 14 | Test18::D RTTI 685// CHECK-NEXT: -- (Test18::A, 8) vtable address -- 686// CHECK-NEXT: -- (Test18::C, 8) vtable address -- 687// CHECK-NEXT: 15 | void Test18::D::f() 688// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 689// CHECK-NEXT: 16 | void Test18::C::g() 690// CHECK-NEXT: 17 | vbase_offset (-16) 691// CHECK-NEXT: 18 | vcall_offset (-8) 692// CHECK-NEXT: 19 | vcall_offset (-16) 693// CHECK-NEXT: 20 | offset_to_top (-16) 694// CHECK-NEXT: 21 | Test18::D RTTI 695// CHECK-NEXT: -- (Test18::B, 16) vtable address -- 696// CHECK-NEXT: 22 | void Test18::D::f() 697// CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset] 698// CHECK-NEXT: 23 | [unused] void Test18::C::g() 699 700// CHECK: Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries). 701// CHECK-NEXT: 0 | vbase_offset (0) 702// CHECK-NEXT: 1 | vcall_offset (0) 703// CHECK-NEXT: 2 | vcall_offset (0) 704// CHECK-NEXT: 3 | offset_to_top (0) 705// CHECK-NEXT: 4 | Test18::B RTTI 706// CHECK-NEXT: -- (Test18::A, 0) vtable address -- 707// CHECK-NEXT: -- (Test18::B, 0) vtable address -- 708// CHECK-NEXT: 5 | void Test18::B::f() 709// CHECK-NEXT: 6 | void Test18::A::g() 710 711// CHECK: Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries). 712// CHECK-NEXT: 0 | vcall_offset (0) 713// CHECK-NEXT: 1 | vcall_offset (0) 714// CHECK-NEXT: 2 | vbase_offset (-8) 715// CHECK-NEXT: 3 | offset_to_top (0) 716// CHECK-NEXT: 4 | Test18::C RTTI 717// CHECK-NEXT: -- (Test18::A, 8) vtable address -- 718// CHECK-NEXT: -- (Test18::C, 8) vtable address -- 719// CHECK-NEXT: 5 | void Test18::A::f() 720// CHECK-NEXT: 6 | void Test18::C::g() 721// CHECK-NEXT: 7 | vbase_offset (-16) 722// CHECK-NEXT: 8 | vcall_offset (-8) 723// CHECK-NEXT: 9 | vcall_offset (0) 724// CHECK-NEXT: 10 | offset_to_top (-8) 725// CHECK-NEXT: 11 | Test18::C RTTI 726// CHECK-NEXT: -- (Test18::B, 16) vtable address -- 727// CHECK-NEXT: 12 | void Test18::B::f() 728// CHECK-NEXT: 13 | [unused] void Test18::C::g() 729// CHECK-NEXT: 14 | vcall_offset (8) 730// CHECK-NEXT: 15 | vcall_offset (16) 731// CHECK-NEXT: 16 | offset_to_top (8) 732// CHECK-NEXT: 17 | Test18::C RTTI 733// CHECK-NEXT: -- (Test18::A, 0) vtable address -- 734// CHECK-NEXT: 18 | void Test18::B::f() 735// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 736// CHECK-NEXT: 19 | void Test18::C::g() 737// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 738 739// CHECK: Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries). 740// CHECK-NEXT: 0 | vbase_offset (-16) 741// CHECK-NEXT: 1 | vcall_offset (-16) 742// CHECK-NEXT: 2 | vcall_offset (0) 743// CHECK-NEXT: 3 | offset_to_top (0) 744// CHECK-NEXT: 4 | Test18::B RTTI 745// CHECK-NEXT: -- (Test18::B, 16) vtable address -- 746// CHECK-NEXT: 5 | void Test18::B::f() 747// CHECK-NEXT: 6 | [unused] void Test18::A::g() 748// CHECK-NEXT: 7 | vcall_offset (0) 749// CHECK-NEXT: 8 | vcall_offset (16) 750// CHECK-NEXT: 9 | offset_to_top (16) 751// CHECK-NEXT: 10 | Test18::B RTTI 752// CHECK-NEXT: -- (Test18::A, 0) vtable address -- 753// CHECK-NEXT: 11 | void Test18::B::f() 754// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 755// CHECK-NEXT: 12 | void Test18::A::g() 756struct D : virtual B, virtual C, virtual A 757{ 758 virtual void f(); 759 virtual void h(); 760}; 761void D::f() {} 762 763} 764 765namespace Test19 { 766 767// Another 'this' adjustment test. 768 769struct A { 770 int a; 771 772 virtual void f(); 773}; 774 775struct B : A { 776 int b; 777 778 virtual void g(); 779}; 780 781struct C { 782 virtual void c(); 783}; 784 785// CHECK: Vtable for 'Test19::D' (13 entries). 786// CHECK-NEXT: 0 | vbase_offset (24) 787// CHECK-NEXT: 1 | offset_to_top (0) 788// CHECK-NEXT: 2 | Test19::D RTTI 789// CHECK-NEXT: -- (Test19::C, 0) vtable address -- 790// CHECK-NEXT: -- (Test19::D, 0) vtable address -- 791// CHECK-NEXT: 3 | void Test19::C::c() 792// CHECK-NEXT: 4 | void Test19::D::f() 793// CHECK-NEXT: 5 | offset_to_top (-8) 794// CHECK-NEXT: 6 | Test19::D RTTI 795// CHECK-NEXT: -- (Test19::A, 8) vtable address -- 796// CHECK-NEXT: -- (Test19::B, 8) vtable address -- 797// CHECK-NEXT: 7 | void Test19::D::f() 798// CHECK-NEXT: [this adjustment: -8 non-virtual] 799// CHECK-NEXT: 8 | void Test19::B::g() 800// CHECK-NEXT: 9 | vcall_offset (-24) 801// CHECK-NEXT: 10 | offset_to_top (-24) 802// CHECK-NEXT: 11 | Test19::D RTTI 803// CHECK-NEXT: -- (Test19::A, 24) vtable address -- 804// CHECK-NEXT: 12 | void Test19::D::f() 805// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 806struct D : C, B, virtual A { 807 virtual void f(); 808}; 809void D::f() { } 810 811} 812 813namespace Test20 { 814 815// pure virtual member functions should never have 'this' adjustments. 816 817struct A { 818 virtual void f() = 0; 819 virtual void g(); 820}; 821 822struct B : A { }; 823 824// CHECK: Vtable for 'Test20::C' (9 entries). 825// CHECK-NEXT: 0 | offset_to_top (0) 826// CHECK-NEXT: 1 | Test20::C RTTI 827// CHECK-NEXT: -- (Test20::A, 0) vtable address -- 828// CHECK-NEXT: -- (Test20::C, 0) vtable address -- 829// CHECK-NEXT: 2 | void Test20::C::f() [pure] 830// CHECK-NEXT: 3 | void Test20::A::g() 831// CHECK-NEXT: 4 | void Test20::C::h() 832// CHECK-NEXT: 5 | offset_to_top (-8) 833// CHECK-NEXT: 6 | Test20::C RTTI 834// CHECK-NEXT: -- (Test20::A, 8) vtable address -- 835// CHECK-NEXT: -- (Test20::B, 8) vtable address -- 836// CHECK-NEXT: 7 | void Test20::C::f() [pure] 837// CHECK-NEXT: 8 | void Test20::A::g() 838struct C : A, B { 839 virtual void f() = 0; 840 virtual void h(); 841}; 842void C::h() { } 843 844} 845 846namespace Test21 { 847 848// Test that we get vbase offsets right in secondary vtables. 849struct A { 850 virtual void f(); 851}; 852 853struct B : virtual A { }; 854class C : virtual B { }; 855class D : virtual C { }; 856 857class E : virtual C { }; 858 859// CHECK: Vtable for 'Test21::F' (16 entries). 860// CHECK-NEXT: 0 | vbase_offset (8) 861// CHECK-NEXT: 1 | vbase_offset (0) 862// CHECK-NEXT: 2 | vbase_offset (0) 863// CHECK-NEXT: 3 | vbase_offset (0) 864// CHECK-NEXT: 4 | vbase_offset (0) 865// CHECK-NEXT: 5 | vcall_offset (0) 866// CHECK-NEXT: 6 | offset_to_top (0) 867// CHECK-NEXT: 7 | Test21::F RTTI 868// CHECK-NEXT: -- (Test21::A, 0) vtable address -- 869// CHECK-NEXT: -- (Test21::B, 0) vtable address -- 870// CHECK-NEXT: -- (Test21::C, 0) vtable address -- 871// CHECK-NEXT: -- (Test21::D, 0) vtable address -- 872// CHECK-NEXT: -- (Test21::F, 0) vtable address -- 873// CHECK-NEXT: 8 | void Test21::F::f() 874// CHECK-NEXT: 9 | vbase_offset (-8) 875// CHECK-NEXT: 10 | vbase_offset (-8) 876// CHECK-NEXT: 11 | vbase_offset (-8) 877// CHECK-NEXT: 12 | vcall_offset (-8) 878// CHECK-NEXT: 13 | offset_to_top (-8) 879// CHECK-NEXT: 14 | Test21::F RTTI 880// CHECK-NEXT: -- (Test21::E, 8) vtable address -- 881// CHECK-NEXT: 15 | [unused] void Test21::F::f() 882// 883// CHECK: Virtual base offset offsets for 'Test21::F' (5 entries). 884// CHECK-NEXT: Test21::A | -32 885// CHECK-NEXT: Test21::B | -40 886// CHECK-NEXT: Test21::C | -48 887// CHECK-NEXT: Test21::D | -56 888// CHECK-NEXT: Test21::E | -64 889class F : virtual D, virtual E { 890 virtual void f(); 891}; 892void F::f() { } 893 894} 895 896namespace Test22 { 897 898// Very simple construction vtable test. 899struct V1 { 900 int v1; 901}; 902 903struct V2 : virtual V1 { 904 int v2; 905}; 906 907// CHECK: Vtable for 'Test22::C' (8 entries). 908// CHECK-NEXT: 0 | vbase_offset (16) 909// CHECK-NEXT: 1 | vbase_offset (12) 910// CHECK-NEXT: 2 | offset_to_top (0) 911// CHECK-NEXT: 3 | Test22::C RTTI 912// CHECK-NEXT: -- (Test22::C, 0) vtable address -- 913// CHECK-NEXT: 4 | void Test22::C::f() 914// CHECK-NEXT: 5 | vbase_offset (-4) 915// CHECK-NEXT: 6 | offset_to_top (-16) 916// CHECK-NEXT: 7 | Test22::C RTTI 917// CHECK-NEXT: -- (Test22::V2, 16) vtable address -- 918 919// CHECK: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries). 920// CHECK-NEXT: 0 | vbase_offset (-4) 921// CHECK-NEXT: 1 | offset_to_top (0) 922// CHECK-NEXT: 2 | Test22::V2 RTTI 923 924struct C : virtual V1, virtual V2 { 925 int c; 926 virtual void f(); 927}; 928void C::f() { } 929 930} 931 932namespace Test23 { 933 934struct A { 935 int a; 936}; 937 938struct B : virtual A { 939 int b; 940}; 941 942struct C : A, virtual B { 943 int c; 944}; 945 946// CHECK: Vtable for 'Test23::D' (7 entries). 947// CHECK-NEXT: 0 | vbase_offset (20) 948// CHECK-NEXT: 1 | vbase_offset (24) 949// CHECK-NEXT: 2 | offset_to_top (0) 950// CHECK-NEXT: 3 | Test23::D RTTI 951// CHECK-NEXT: -- (Test23::C, 0) vtable address -- 952// CHECK-NEXT: -- (Test23::D, 0) vtable address -- 953// CHECK-NEXT: 4 | vbase_offset (-4) 954// CHECK-NEXT: 5 | offset_to_top (-24) 955// CHECK-NEXT: 6 | Test23::D RTTI 956// CHECK-NEXT: -- (Test23::B, 24) vtable address -- 957 958// CHECK: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries). 959// CHECK-NEXT: 0 | vbase_offset (20) 960// CHECK-NEXT: 1 | vbase_offset (24) 961// CHECK-NEXT: 2 | offset_to_top (0) 962// CHECK-NEXT: 3 | Test23::C RTTI 963// CHECK-NEXT: -- (Test23::C, 0) vtable address -- 964// CHECK-NEXT: 4 | vbase_offset (-4) 965// CHECK-NEXT: 5 | offset_to_top (-24) 966// CHECK-NEXT: 6 | Test23::C RTTI 967// CHECK-NEXT: -- (Test23::B, 24) vtable address -- 968 969// CHECK: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries). 970// CHECK-NEXT: 0 | vbase_offset (-4) 971// CHECK-NEXT: 1 | offset_to_top (0) 972// CHECK-NEXT: 2 | Test23::B RTTI 973// CHECK-NEXT: -- (Test23::B, 24) vtable address -- 974 975struct D : virtual A, virtual B, C { 976 int d; 977 978 void f(); 979}; 980void D::f() { } 981 982} 983 984namespace Test24 { 985 986// Another construction vtable test. 987 988struct A { 989 virtual void f(); 990}; 991 992struct B : virtual A { }; 993struct C : virtual A { }; 994 995// CHECK: Vtable for 'Test24::D' (10 entries). 996// CHECK-NEXT: 0 | vbase_offset (0) 997// CHECK-NEXT: 1 | vcall_offset (0) 998// CHECK-NEXT: 2 | offset_to_top (0) 999// CHECK-NEXT: 3 | Test24::D RTTI 1000// CHECK-NEXT: -- (Test24::A, 0) vtable address -- 1001// CHECK-NEXT: -- (Test24::B, 0) vtable address -- 1002// CHECK-NEXT: -- (Test24::D, 0) vtable address -- 1003// CHECK-NEXT: 4 | void Test24::D::f() 1004// CHECK-NEXT: 5 | vbase_offset (-8) 1005// CHECK-NEXT: 6 | vcall_offset (-8) 1006// CHECK-NEXT: 7 | offset_to_top (-8) 1007// CHECK-NEXT: 8 | Test24::D RTTI 1008// CHECK-NEXT: -- (Test24::C, 8) vtable address -- 1009// CHECK-NEXT: 9 | [unused] void Test24::D::f() 1010 1011// CHECK: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries). 1012// CHECK-NEXT: 0 | vbase_offset (0) 1013// CHECK-NEXT: 1 | vcall_offset (0) 1014// CHECK-NEXT: 2 | offset_to_top (0) 1015// CHECK-NEXT: 3 | Test24::B RTTI 1016// CHECK-NEXT: -- (Test24::A, 0) vtable address -- 1017// CHECK-NEXT: -- (Test24::B, 0) vtable address -- 1018// CHECK-NEXT: 4 | void Test24::A::f() 1019 1020// CHECK: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries). 1021// CHECK-NEXT: 0 | vbase_offset (-8) 1022// CHECK-NEXT: 1 | vcall_offset (-8) 1023// CHECK-NEXT: 2 | offset_to_top (0) 1024// CHECK-NEXT: 3 | Test24::C RTTI 1025// CHECK-NEXT: -- (Test24::C, 8) vtable address -- 1026// CHECK-NEXT: 4 | [unused] void Test24::A::f() 1027// CHECK-NEXT: 5 | vcall_offset (0) 1028// CHECK-NEXT: 6 | offset_to_top (8) 1029// CHECK-NEXT: 7 | Test24::C RTTI 1030// CHECK-NEXT: -- (Test24::A, 0) vtable address -- 1031// CHECK-NEXT: 8 | void Test24::A::f() 1032struct D : B, C { 1033 virtual void f(); 1034}; 1035void D::f() { } 1036 1037} 1038 1039namespace Test25 { 1040 1041// This mainly tests that we don't assert on this class hierarchy. 1042 1043struct V { 1044 virtual void f(); 1045}; 1046 1047struct A : virtual V { }; 1048struct B : virtual V { }; 1049 1050// CHECK: Vtable for 'Test25::C' (11 entries). 1051// CHECK-NEXT: 0 | vbase_offset (0) 1052// CHECK-NEXT: 1 | vcall_offset (0) 1053// CHECK-NEXT: 2 | offset_to_top (0) 1054// CHECK-NEXT: 3 | Test25::C RTTI 1055// CHECK-NEXT: -- (Test25::A, 0) vtable address -- 1056// CHECK-NEXT: -- (Test25::C, 0) vtable address -- 1057// CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1058// CHECK-NEXT: 4 | void Test25::V::f() 1059// CHECK-NEXT: 5 | void Test25::C::g() 1060// CHECK-NEXT: 6 | vbase_offset (-8) 1061// CHECK-NEXT: 7 | vcall_offset (-8) 1062// CHECK-NEXT: 8 | offset_to_top (-8) 1063// CHECK-NEXT: 9 | Test25::C RTTI 1064// CHECK-NEXT: -- (Test25::B, 8) vtable address -- 1065// CHECK-NEXT: 10 | [unused] void Test25::V::f() 1066 1067// CHECK: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries). 1068// CHECK-NEXT: 0 | vbase_offset (0) 1069// CHECK-NEXT: 1 | vcall_offset (0) 1070// CHECK-NEXT: 2 | offset_to_top (0) 1071// CHECK-NEXT: 3 | Test25::A RTTI 1072// CHECK-NEXT: -- (Test25::A, 0) vtable address -- 1073// CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1074// CHECK-NEXT: 4 | void Test25::V::f() 1075 1076// CHECK: Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries). 1077// CHECK-NEXT: 0 | vbase_offset (-8) 1078// CHECK-NEXT: 1 | vcall_offset (-8) 1079// CHECK-NEXT: 2 | offset_to_top (0) 1080// CHECK-NEXT: 3 | Test25::B RTTI 1081// CHECK-NEXT: -- (Test25::B, 8) vtable address -- 1082// CHECK-NEXT: 4 | [unused] void Test25::V::f() 1083// CHECK-NEXT: 5 | vcall_offset (0) 1084// CHECK-NEXT: 6 | offset_to_top (8) 1085// CHECK-NEXT: 7 | Test25::B RTTI 1086// CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1087// CHECK-NEXT: 8 | void Test25::V::f() 1088struct C : A, virtual V, B { 1089 virtual void g(); 1090}; 1091void C::g() { } 1092 1093} 1094 1095namespace Test26 { 1096 1097// Test that we generate the right number of entries in the C-in-D construction vtable, and that 1098// we don't mark A::a as unused. 1099 1100struct A { 1101 virtual void a(); 1102}; 1103 1104struct B { 1105 virtual void c(); 1106}; 1107 1108struct C : virtual A { 1109 virtual void b(); 1110}; 1111 1112// CHECK: Vtable for 'Test26::D' (15 entries). 1113// CHECK-NEXT: 0 | vbase_offset (8) 1114// CHECK-NEXT: 1 | vbase_offset (8) 1115// CHECK-NEXT: 2 | vbase_offset (0) 1116// CHECK-NEXT: 3 | vcall_offset (0) 1117// CHECK-NEXT: 4 | offset_to_top (0) 1118// CHECK-NEXT: 5 | Test26::D RTTI 1119// CHECK-NEXT: -- (Test26::B, 0) vtable address -- 1120// CHECK-NEXT: -- (Test26::D, 0) vtable address -- 1121// CHECK-NEXT: 6 | void Test26::B::c() 1122// CHECK-NEXT: 7 | void Test26::D::d() 1123// CHECK-NEXT: 8 | vcall_offset (0) 1124// CHECK-NEXT: 9 | vbase_offset (0) 1125// CHECK-NEXT: 10 | vcall_offset (0) 1126// CHECK-NEXT: 11 | offset_to_top (-8) 1127// CHECK-NEXT: 12 | Test26::D RTTI 1128// CHECK-NEXT: -- (Test26::A, 8) vtable address -- 1129// CHECK-NEXT: -- (Test26::C, 8) vtable address -- 1130// CHECK-NEXT: 13 | void Test26::A::a() 1131// CHECK-NEXT: 14 | void Test26::C::b() 1132 1133// CHECK: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries). 1134// CHECK-NEXT: 0 | vcall_offset (0) 1135// CHECK-NEXT: 1 | vbase_offset (0) 1136// CHECK-NEXT: 2 | vcall_offset (0) 1137// CHECK-NEXT: 3 | offset_to_top (0) 1138// CHECK-NEXT: 4 | Test26::C RTTI 1139// CHECK-NEXT: -- (Test26::A, 8) vtable address -- 1140// CHECK-NEXT: -- (Test26::C, 8) vtable address -- 1141// CHECK-NEXT: 5 | void Test26::A::a() 1142// CHECK-NEXT: 6 | void Test26::C::b() 1143class D : virtual B, virtual C { 1144 virtual void d(); 1145}; 1146void D::d() { } 1147 1148} 1149 1150namespace Test27 { 1151 1152// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since 1153// C doesn't have any virtual bases. 1154 1155struct A { 1156 virtual void a(); 1157}; 1158 1159struct B { 1160 virtual void b(); 1161}; 1162 1163struct C { 1164 virtual void c(); 1165}; 1166 1167struct D : A, virtual B, C { 1168 virtual void d(); 1169}; 1170 1171// CHECK: Vtable for 'Test27::E' (13 entries). 1172// CHECK-NEXT: 0 | vbase_offset (16) 1173// CHECK-NEXT: 1 | offset_to_top (0) 1174// CHECK-NEXT: 2 | Test27::E RTTI 1175// CHECK-NEXT: -- (Test27::A, 0) vtable address -- 1176// CHECK-NEXT: -- (Test27::D, 0) vtable address -- 1177// CHECK-NEXT: -- (Test27::E, 0) vtable address -- 1178// CHECK-NEXT: 3 | void Test27::A::a() 1179// CHECK-NEXT: 4 | void Test27::D::d() 1180// CHECK-NEXT: 5 | void Test27::E::e() 1181// CHECK-NEXT: 6 | offset_to_top (-8) 1182// CHECK-NEXT: 7 | Test27::E RTTI 1183// CHECK-NEXT: -- (Test27::C, 8) vtable address -- 1184// CHECK-NEXT: 8 | void Test27::C::c() 1185// CHECK-NEXT: 9 | vcall_offset (0) 1186// CHECK-NEXT: 10 | offset_to_top (-16) 1187// CHECK-NEXT: 11 | Test27::E RTTI 1188// CHECK-NEXT: -- (Test27::B, 16) vtable address -- 1189// CHECK-NEXT: 12 | void Test27::B::b() 1190 1191// CHECK: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries). 1192// CHECK-NEXT: 0 | vbase_offset (16) 1193// CHECK-NEXT: 1 | offset_to_top (0) 1194// CHECK-NEXT: 2 | Test27::D RTTI 1195// CHECK-NEXT: -- (Test27::A, 0) vtable address -- 1196// CHECK-NEXT: -- (Test27::D, 0) vtable address -- 1197// CHECK-NEXT: 3 | void Test27::A::a() 1198// CHECK-NEXT: 4 | void Test27::D::d() 1199// CHECK-NEXT: 5 | vcall_offset (0) 1200// CHECK-NEXT: 6 | offset_to_top (-16) 1201// CHECK-NEXT: 7 | Test27::D RTTI 1202// CHECK-NEXT: -- (Test27::B, 16) vtable address -- 1203// CHECK-NEXT: 8 | void Test27::B::b() 1204struct E : D { 1205 virtual void e(); 1206}; 1207void E::e() { } 1208 1209} 1210 1211namespace Test28 { 1212 1213// Check that we do include the vtable for B in the D-in-E construction vtable, since 1214// B is a base class of a virtual base (C). 1215 1216struct A { 1217 virtual void a(); 1218}; 1219 1220struct B { 1221 virtual void b(); 1222}; 1223 1224struct C : A, B { 1225 virtual void c(); 1226}; 1227 1228struct D : virtual C { 1229}; 1230 1231// CHECK: Vtable for 'Test28::E' (14 entries). 1232// CHECK-NEXT: 0 | vbase_offset (8) 1233// CHECK-NEXT: 1 | offset_to_top (0) 1234// CHECK-NEXT: 2 | Test28::E RTTI 1235// CHECK-NEXT: -- (Test28::D, 0) vtable address -- 1236// CHECK-NEXT: -- (Test28::E, 0) vtable address -- 1237// CHECK-NEXT: 3 | void Test28::E::e() 1238// CHECK-NEXT: 4 | vcall_offset (8) 1239// CHECK-NEXT: 5 | vcall_offset (0) 1240// CHECK-NEXT: 6 | vcall_offset (0) 1241// CHECK-NEXT: 7 | offset_to_top (-8) 1242// CHECK-NEXT: 8 | Test28::E RTTI 1243// CHECK-NEXT: -- (Test28::A, 8) vtable address -- 1244// CHECK-NEXT: -- (Test28::C, 8) vtable address -- 1245// CHECK-NEXT: 9 | void Test28::A::a() 1246// CHECK-NEXT: 10 | void Test28::C::c() 1247// CHECK-NEXT: 11 | offset_to_top (-16) 1248// CHECK-NEXT: 12 | Test28::E RTTI 1249// CHECK-NEXT: -- (Test28::B, 16) vtable address -- 1250// CHECK-NEXT: 13 | void Test28::B::b() 1251 1252// CHECK: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries). 1253// CHECK-NEXT: 0 | vbase_offset (8) 1254// CHECK-NEXT: 1 | offset_to_top (0) 1255// CHECK-NEXT: 2 | Test28::D RTTI 1256// CHECK-NEXT: -- (Test28::D, 0) vtable address -- 1257// CHECK-NEXT: 3 | vcall_offset (8) 1258// CHECK-NEXT: 4 | vcall_offset (0) 1259// CHECK-NEXT: 5 | vcall_offset (0) 1260// CHECK-NEXT: 6 | offset_to_top (-8) 1261// CHECK-NEXT: 7 | Test28::D RTTI 1262// CHECK-NEXT: -- (Test28::A, 8) vtable address -- 1263// CHECK-NEXT: -- (Test28::C, 8) vtable address -- 1264// CHECK-NEXT: 8 | void Test28::A::a() 1265// CHECK-NEXT: 9 | void Test28::C::c() 1266// CHECK-NEXT: 10 | offset_to_top (-16) 1267// CHECK-NEXT: 11 | Test28::D RTTI 1268// CHECK-NEXT: -- (Test28::B, 16) vtable address -- 1269// CHECK-NEXT: 12 | void Test28::B::b() 1270struct E : D { 1271 virtual void e(); 1272}; 1273void E::e() { } 1274 1275} 1276 1277namespace Test29 { 1278 1279// Test that the covariant return thunk for B::f will have a virtual 'this' adjustment, 1280// matching gcc. 1281 1282struct V1 { }; 1283struct V2 : virtual V1 { }; 1284 1285struct A { 1286 virtual V1 *f(); 1287}; 1288 1289// CHECK: Vtable for 'Test29::B' (6 entries). 1290// CHECK-NEXT: 0 | vbase_offset (0) 1291// CHECK-NEXT: 1 | vcall_offset (0) 1292// CHECK-NEXT: 2 | offset_to_top (0) 1293// CHECK-NEXT: 3 | Test29::B RTTI 1294// CHECK-NEXT: -- (Test29::A, 0) vtable address -- 1295// CHECK-NEXT: -- (Test29::B, 0) vtable address -- 1296// CHECK-NEXT: 4 | Test29::V2 *Test29::B::f() 1297// CHECK-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset] 1298// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 1299// CHECK-NEXT: 5 | Test29::V2 *Test29::B::f() 1300struct B : virtual A { 1301 virtual V2 *f(); 1302}; 1303V2 *B::f() { return 0; } 1304 1305} 1306 1307namespace Test30 { 1308 1309// Test that we don't assert when generating a vtable for F. 1310struct A { }; 1311 1312struct B : virtual A { 1313 int i; 1314}; 1315 1316struct C { 1317 virtual void f(); 1318}; 1319 1320struct D : virtual C, B { }; 1321struct E : virtual D { }; 1322 1323struct F : E { 1324 virtual void f(); 1325}; 1326void F::f() { } 1327 1328} 1329 1330namespace Test31 { 1331 1332// Test that we don't add D::f twice to the primary vtable. 1333struct A { 1334 int a; 1335}; 1336 1337struct B { 1338 virtual void f(); 1339}; 1340 1341struct C : A, virtual B { 1342 virtual void f(); 1343}; 1344 1345// CHECK: Vtable for 'Test31::D' (11 entries). 1346// CHECK-NEXT: 0 | vbase_offset (0) 1347// CHECK-NEXT: 1 | vbase_offset (8) 1348// CHECK-NEXT: 2 | vcall_offset (0) 1349// CHECK-NEXT: 3 | offset_to_top (0) 1350// CHECK-NEXT: 4 | Test31::D RTTI 1351// CHECK-NEXT: -- (Test31::B, 0) vtable address -- 1352// CHECK-NEXT: -- (Test31::D, 0) vtable address -- 1353// CHECK-NEXT: 5 | void Test31::D::f() 1354// CHECK-NEXT: 6 | vbase_offset (-8) 1355// CHECK-NEXT: 7 | vcall_offset (-8) 1356// CHECK-NEXT: 8 | offset_to_top (-8) 1357// CHECK-NEXT: 9 | Test31::D RTTI 1358// CHECK-NEXT: -- (Test31::C, 8) vtable address -- 1359// CHECK-NEXT: 10 | void Test31::D::f() 1360// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 1361struct D : virtual C { 1362 virtual void f(); 1363}; 1364void D::f() { } 1365 1366} 1367 1368namespace Test32 { 1369 1370// Check that we correctly lay out the virtual bases of 'Test32::D'. 1371 1372struct A { 1373 virtual void f(); 1374}; 1375 1376struct B : virtual A { }; 1377struct C : A, virtual B { }; 1378struct D : virtual B { }; 1379 1380// CHECK: Virtual base offset offsets for 'Test32::E' (3 entries). 1381// CHECK-NEXT: Test32::A | -32 1382// CHECK-NEXT: Test32::B | -24 1383// CHECK-NEXT: Test32::D | -40 1384struct E : C, virtual D { 1385 virtual void f(); 1386}; 1387void E::f() { } 1388 1389} 1390 1391namespace Test33 { 1392 1393// Test that we don't emit too many vcall offsets in 'Test32::F'. 1394 1395struct A { 1396 virtual void a(); 1397}; 1398 1399struct B { 1400 virtual void b(); 1401}; 1402 1403struct C : virtual A, virtual B { 1404 virtual void c(); 1405}; 1406 1407struct D : virtual C { }; 1408 1409struct E : A, D { 1410 virtual void e(); 1411}; 1412 1413// CHECK: Vtable for 'Test33::F' (30 entries). 1414// CHECK-NEXT: 0 | vbase_offset (24) 1415// CHECK-NEXT: 1 | vbase_offset (16) 1416// CHECK-NEXT: 2 | vbase_offset (16) 1417// CHECK-NEXT: 3 | vbase_offset (8) 1418// CHECK-NEXT: 4 | offset_to_top (0) 1419// CHECK-NEXT: 5 | Test33::F RTTI 1420// CHECK-NEXT: -- (Test33::A, 0) vtable address -- 1421// CHECK-NEXT: -- (Test33::F, 0) vtable address -- 1422// CHECK-NEXT: 6 | void Test33::A::a() 1423// CHECK-NEXT: 7 | void Test33::F::f() 1424// CHECK-NEXT: 8 | vcall_offset (0) 1425// CHECK-NEXT: 9 | vcall_offset (0) 1426// CHECK-NEXT: 10 | vbase_offset (16) 1427// CHECK-NEXT: 11 | vbase_offset (8) 1428// CHECK-NEXT: 12 | vbase_offset (8) 1429// CHECK-NEXT: 13 | offset_to_top (-8) 1430// CHECK-NEXT: 14 | Test33::F RTTI 1431// CHECK-NEXT: -- (Test33::A, 8) vtable address -- 1432// CHECK-NEXT: -- (Test33::E, 8) vtable address -- 1433// CHECK-NEXT: 15 | void Test33::A::a() 1434// CHECK-NEXT: 16 | void Test33::E::e() 1435// CHECK-NEXT: 17 | vbase_offset (0) 1436// CHECK-NEXT: 18 | vcall_offset (0) 1437// CHECK-NEXT: 19 | vbase_offset (8) 1438// CHECK-NEXT: 20 | vbase_offset (0) 1439// CHECK-NEXT: 21 | vcall_offset (0) 1440// CHECK-NEXT: 22 | offset_to_top (-16) 1441// CHECK-NEXT: 23 | Test33::F RTTI 1442// CHECK-NEXT: -- (Test33::A, 16) vtable address -- 1443// CHECK-NEXT: -- (Test33::C, 16) vtable address -- 1444// CHECK-NEXT: -- (Test33::D, 16) vtable address -- 1445// CHECK-NEXT: 24 | void Test33::A::a() 1446// CHECK-NEXT: 25 | void Test33::C::c() 1447// CHECK-NEXT: 26 | vcall_offset (0) 1448// CHECK-NEXT: 27 | offset_to_top (-24) 1449// CHECK-NEXT: 28 | Test33::F RTTI 1450// CHECK-NEXT: -- (Test33::B, 24) vtable address -- 1451// CHECK-NEXT: 29 | void Test33::B::b() 1452struct F : virtual E, A { 1453 virtual void f(); 1454}; 1455void F::f() { } 1456 1457} 1458 1459namespace Test34 { 1460 1461// Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly. 1462 1463struct A { 1464 virtual void a(); 1465}; 1466struct B : virtual A { }; 1467 1468struct C : B, A { 1469 virtual void c(); 1470}; 1471 1472struct D : A, C { }; 1473 1474struct E : virtual D { 1475 virtual void e(); 1476}; 1477 1478// CHECK: Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries). 1479// CHECK-NEXT: 0 | vbase_offset (0) 1480// CHECK-NEXT: 1 | vbase_offset (8) 1481// CHECK-NEXT: 2 | vcall_offset (0) 1482// CHECK-NEXT: 3 | offset_to_top (0) 1483// CHECK-NEXT: 4 | Test34::E RTTI 1484// CHECK-NEXT: -- (Test34::A, 0) vtable address -- 1485// CHECK-NEXT: -- (Test34::E, 0) vtable address -- 1486// CHECK-NEXT: 5 | void Test34::A::a() 1487// CHECK-NEXT: 6 | void Test34::E::e() 1488// CHECK-NEXT: 7 | vcall_offset (8) 1489// CHECK-NEXT: 8 | vcall_offset (0) 1490// CHECK-NEXT: 9 | vbase_offset (-8) 1491// CHECK-NEXT: 10 | offset_to_top (-8) 1492// CHECK-NEXT: 11 | Test34::E RTTI 1493// CHECK-NEXT: -- (Test34::A, 8) vtable address -- 1494// CHECK-NEXT: -- (Test34::D, 8) vtable address -- 1495// CHECK-NEXT: 12 | void Test34::A::a() 1496// CHECK-NEXT: 13 | vbase_offset (-16) 1497// CHECK-NEXT: 14 | vcall_offset (-16) 1498// CHECK-NEXT: 15 | offset_to_top (-16) 1499// CHECK-NEXT: 16 | Test34::E RTTI 1500// CHECK-NEXT: -- (Test34::B, 16) vtable address -- 1501// CHECK-NEXT: -- (Test34::C, 16) vtable address -- 1502// CHECK-NEXT: 17 | [unused] void Test34::A::a() 1503// CHECK-NEXT: 18 | void Test34::C::c() 1504// CHECK-NEXT: 19 | offset_to_top (-24) 1505// CHECK-NEXT: 20 | Test34::E RTTI 1506// CHECK-NEXT: -- (Test34::A, 24) vtable address -- 1507// CHECK-NEXT: 21 | void Test34::A::a() 1508struct F : E { 1509 virtual void f(); 1510}; 1511void F::f() { } 1512 1513} 1514 1515namespace Test35 { 1516 1517// Test that we lay out the virtual bases of 'Test35::H' in the correct order. 1518 1519struct A { 1520 virtual void a(); 1521 1522 int i; 1523}; 1524 1525struct B : virtual A { 1526 virtual void b(); 1527}; 1528 1529struct C { 1530 virtual void c(); 1531}; 1532 1533struct D : C, virtual B { 1534 virtual void d(); 1535}; 1536 1537struct E : D { 1538 virtual void e(); 1539 1540 bool b; 1541}; 1542 1543struct F : virtual D { }; 1544struct G : virtual E { }; 1545 1546// CHECK: Vtable for 'Test35::H' (32 entries). 1547// CHECK-NEXT: 0 | vbase_offset (32) 1548// CHECK-NEXT: 1 | vbase_offset (0) 1549// CHECK-NEXT: 2 | vcall_offset (0) 1550// CHECK-NEXT: 3 | vcall_offset (0) 1551// CHECK-NEXT: 4 | vbase_offset (16) 1552// CHECK-NEXT: 5 | vbase_offset (8) 1553// CHECK-NEXT: 6 | offset_to_top (0) 1554// CHECK-NEXT: 7 | Test35::H RTTI 1555// CHECK-NEXT: -- (Test35::C, 0) vtable address -- 1556// CHECK-NEXT: -- (Test35::D, 0) vtable address -- 1557// CHECK-NEXT: -- (Test35::F, 0) vtable address -- 1558// CHECK-NEXT: -- (Test35::H, 0) vtable address -- 1559// CHECK-NEXT: 8 | void Test35::C::c() 1560// CHECK-NEXT: 9 | void Test35::D::d() 1561// CHECK-NEXT: 10 | void Test35::H::h() 1562// CHECK-NEXT: 11 | vbase_offset (0) 1563// CHECK-NEXT: 12 | vbase_offset (24) 1564// CHECK-NEXT: 13 | vcall_offset (0) 1565// CHECK-NEXT: 14 | vbase_offset (8) 1566// CHECK-NEXT: 15 | offset_to_top (-8) 1567// CHECK-NEXT: 16 | Test35::H RTTI 1568// CHECK-NEXT: -- (Test35::B, 8) vtable address -- 1569// CHECK-NEXT: -- (Test35::G, 8) vtable address -- 1570// CHECK-NEXT: 17 | void Test35::B::b() 1571// CHECK-NEXT: 18 | vcall_offset (0) 1572// CHECK-NEXT: 19 | offset_to_top (-16) 1573// CHECK-NEXT: 20 | Test35::H RTTI 1574// CHECK-NEXT: -- (Test35::A, 16) vtable address -- 1575// CHECK-NEXT: 21 | void Test35::A::a() 1576// CHECK-NEXT: 22 | vcall_offset (0) 1577// CHECK-NEXT: 23 | vcall_offset (0) 1578// CHECK-NEXT: 24 | vcall_offset (0) 1579// CHECK-NEXT: 25 | vbase_offset (-16) 1580// CHECK-NEXT: 26 | vbase_offset (-24) 1581// CHECK-NEXT: 27 | offset_to_top (-32) 1582// CHECK-NEXT: 28 | Test35::H RTTI 1583// CHECK-NEXT: -- (Test35::C, 32) vtable address -- 1584// CHECK-NEXT: -- (Test35::D, 32) vtable address -- 1585// CHECK-NEXT: -- (Test35::E, 32) vtable address -- 1586// CHECK-NEXT: 29 | void Test35::C::c() 1587// CHECK-NEXT: 30 | void Test35::D::d() 1588// CHECK-NEXT: 31 | void Test35::E::e() 1589 1590// CHECK: Virtual base offset offsets for 'Test35::H' (4 entries). 1591// CHECK-NEXT: Test35::A | -32 1592// CHECK-NEXT: Test35::B | -24 1593// CHECK-NEXT: Test35::D | -56 1594// CHECK-NEXT: Test35::E | -64 1595struct H : F, G { 1596 virtual void h(); 1597}; 1598void H::h() { } 1599 1600} 1601