vtable-layout.cpp revision a96a2e961a3bce0ad2fc44a115ac949a481d42db
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::A, 8) vtable address -- 639// CHECK-NEXT: -- (Test17::C, 8) vtable address -- 640// CHECK-NEXT: 12 | void Test17::E::f() 641// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 642class E : virtual D { 643 virtual void f(); 644}; 645void E::f() {} 646 647} 648 649namespace Test18 { 650 651// Test that we compute the right 'this' adjustment offsets. 652 653struct A { 654 virtual void f(); 655 virtual void g(); 656}; 657 658struct B : virtual A { 659 virtual void f(); 660}; 661 662struct C : A, B { 663 virtual void g(); 664}; 665 666// CHECK: Vtable for 'Test18::D' (24 entries). 667// CHECK-NEXT: 0 | vbase_offset (8) 668// CHECK-NEXT: 1 | vbase_offset (0) 669// CHECK-NEXT: 2 | vbase_offset (0) 670// CHECK-NEXT: 3 | vcall_offset (8) 671// CHECK-NEXT: 4 | vcall_offset (0) 672// CHECK-NEXT: 5 | offset_to_top (0) 673// CHECK-NEXT: 6 | Test18::D RTTI 674// CHECK-NEXT: -- (Test18::A, 0) vtable address -- 675// CHECK-NEXT: -- (Test18::B, 0) vtable address -- 676// CHECK-NEXT: -- (Test18::D, 0) vtable address -- 677// CHECK-NEXT: 7 | void Test18::D::f() 678// CHECK-NEXT: 8 | void Test18::C::g() 679// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 680// CHECK-NEXT: 9 | void Test18::D::h() 681// CHECK-NEXT: 10 | vcall_offset (0) 682// CHECK-NEXT: 11 | vcall_offset (-8) 683// CHECK-NEXT: 12 | vbase_offset (-8) 684// CHECK-NEXT: 13 | offset_to_top (-8) 685// CHECK-NEXT: 14 | Test18::D RTTI 686// CHECK-NEXT: -- (Test18::A, 8) vtable address -- 687// CHECK-NEXT: -- (Test18::C, 8) vtable address -- 688// CHECK-NEXT: 15 | void Test18::D::f() 689// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 690// CHECK-NEXT: 16 | void Test18::C::g() 691// CHECK-NEXT: 17 | vbase_offset (-16) 692// CHECK-NEXT: 18 | vcall_offset (-8) 693// CHECK-NEXT: 19 | vcall_offset (-16) 694// CHECK-NEXT: 20 | offset_to_top (-16) 695// CHECK-NEXT: 21 | Test18::D RTTI 696// CHECK-NEXT: -- (Test18::A, 16) vtable address -- 697// CHECK-NEXT: -- (Test18::B, 16) vtable address -- 698// CHECK-NEXT: 22 | void Test18::D::f() 699// CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset] 700// CHECK-NEXT: 23 | [unused] void Test18::C::g() 701struct D : virtual B, virtual C, virtual A 702{ 703 virtual void f(); 704 virtual void h(); 705}; 706void D::f() {} 707 708} 709 710namespace Test19 { 711 712// Another 'this' adjustment test. 713 714struct A { 715 int a; 716 717 virtual void f(); 718}; 719 720struct B : A { 721 int b; 722 723 virtual void g(); 724}; 725 726struct C { 727 virtual void c(); 728}; 729 730// CHECK: Vtable for 'Test19::D' (13 entries). 731// CHECK-NEXT: 0 | vbase_offset (24) 732// CHECK-NEXT: 1 | offset_to_top (0) 733// CHECK-NEXT: 2 | Test19::D RTTI 734// CHECK-NEXT: -- (Test19::C, 0) vtable address -- 735// CHECK-NEXT: -- (Test19::D, 0) vtable address -- 736// CHECK-NEXT: 3 | void Test19::C::c() 737// CHECK-NEXT: 4 | void Test19::D::f() 738// CHECK-NEXT: 5 | offset_to_top (-8) 739// CHECK-NEXT: 6 | Test19::D RTTI 740// CHECK-NEXT: -- (Test19::A, 8) vtable address -- 741// CHECK-NEXT: -- (Test19::B, 8) vtable address -- 742// CHECK-NEXT: 7 | void Test19::D::f() 743// CHECK-NEXT: [this adjustment: -8 non-virtual] 744// CHECK-NEXT: 8 | void Test19::B::g() 745// CHECK-NEXT: 9 | vcall_offset (-24) 746// CHECK-NEXT: 10 | offset_to_top (-24) 747// CHECK-NEXT: 11 | Test19::D RTTI 748// CHECK-NEXT: -- (Test19::A, 24) vtable address -- 749// CHECK-NEXT: 12 | void Test19::D::f() 750// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 751struct D : C, B, virtual A { 752 virtual void f(); 753}; 754void D::f() { } 755 756} 757 758namespace Test20 { 759 760// pure virtual member functions should never have 'this' adjustments. 761 762struct A { 763 virtual void f() = 0; 764 virtual void g(); 765}; 766 767struct B : A { }; 768 769// CHECK: Vtable for 'Test20::C' (9 entries). 770// CHECK-NEXT: 0 | offset_to_top (0) 771// CHECK-NEXT: 1 | Test20::C RTTI 772// CHECK-NEXT: -- (Test20::A, 0) vtable address -- 773// CHECK-NEXT: -- (Test20::C, 0) vtable address -- 774// CHECK-NEXT: 2 | void Test20::C::f() [pure] 775// CHECK-NEXT: 3 | void Test20::A::g() 776// CHECK-NEXT: 4 | void Test20::C::h() 777// CHECK-NEXT: 5 | offset_to_top (-8) 778// CHECK-NEXT: 6 | Test20::C RTTI 779// CHECK-NEXT: -- (Test20::A, 8) vtable address -- 780// CHECK-NEXT: -- (Test20::B, 8) vtable address -- 781// CHECK-NEXT: 7 | void Test20::C::f() [pure] 782// CHECK-NEXT: 8 | void Test20::A::g() 783struct C : A, B { 784 virtual void f() = 0; 785 virtual void h(); 786}; 787void C::h() { } 788 789} 790 791namespace Test21 { 792 793// Test that we get vbase offsets right in secondary vtables. 794struct A { 795 virtual void f(); 796}; 797 798struct B : virtual A { }; 799class C : virtual B { }; 800class D : virtual C { }; 801 802class E : virtual C { }; 803 804// CHECK: Vtable for 'Test21::F' (16 entries). 805// CHECK-NEXT: 0 | vbase_offset (8) 806// CHECK-NEXT: 1 | vbase_offset (0) 807// CHECK-NEXT: 2 | vbase_offset (0) 808// CHECK-NEXT: 3 | vbase_offset (0) 809// CHECK-NEXT: 4 | vbase_offset (0) 810// CHECK-NEXT: 5 | vcall_offset (0) 811// CHECK-NEXT: 6 | offset_to_top (0) 812// CHECK-NEXT: 7 | Test21::F RTTI 813// CHECK-NEXT: -- (Test21::A, 0) vtable address -- 814// CHECK-NEXT: -- (Test21::B, 0) vtable address -- 815// CHECK-NEXT: -- (Test21::C, 0) vtable address -- 816// CHECK-NEXT: -- (Test21::D, 0) vtable address -- 817// CHECK-NEXT: -- (Test21::F, 0) vtable address -- 818// CHECK-NEXT: 8 | void Test21::F::f() 819// CHECK-NEXT: 9 | vbase_offset (-8) 820// CHECK-NEXT: 10 | vbase_offset (-8) 821// CHECK-NEXT: 11 | vbase_offset (-8) 822// CHECK-NEXT: 12 | vcall_offset (-8) 823// CHECK-NEXT: 13 | offset_to_top (-8) 824// CHECK-NEXT: 14 | Test21::F RTTI 825// CHECK-NEXT: -- (Test21::A, 8) vtable address -- 826// CHECK-NEXT: -- (Test21::B, 8) vtable address -- 827// CHECK-NEXT: -- (Test21::C, 8) vtable address -- 828// CHECK-NEXT: -- (Test21::E, 8) vtable address -- 829// CHECK-NEXT: 15 | [unused] void Test21::F::f() 830class F : virtual D, virtual E { 831 virtual void f(); 832}; 833void F::f() { } 834 835} 836 837namespace Test22 { 838 839// Very simple construction vtable test. 840struct V1 { 841 int v1; 842}; 843 844struct V2 : virtual V1 { 845 int v2; 846}; 847 848// CHECK: Vtable for 'Test22::C' (8 entries). 849// CHECK-NEXT: 0 | vbase_offset (16) 850// CHECK-NEXT: 1 | vbase_offset (12) 851// CHECK-NEXT: 2 | offset_to_top (0) 852// CHECK-NEXT: 3 | Test22::C RTTI 853// CHECK-NEXT: -- (Test22::C, 0) vtable address -- 854// CHECK-NEXT: 4 | void Test22::C::f() 855// CHECK-NEXT: 5 | vbase_offset (-4) 856// CHECK-NEXT: 6 | offset_to_top (-16) 857// CHECK-NEXT: 7 | Test22::C RTTI 858// CHECK-NEXT: -- (Test22::V2, 16) vtable address -- 859 860// CHECK: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries). 861// CHECK-NEXT: 0 | vbase_offset (-4) 862// CHECK-NEXT: 1 | offset_to_top (0) 863// CHECK-NEXT: 2 | Test22::V2 RTTI 864 865struct C : virtual V1, virtual V2 { 866 int c; 867 virtual void f(); 868}; 869void C::f() { } 870 871} 872 873namespace Test23 { 874 875struct A { 876 int a; 877}; 878 879struct B : virtual A { 880 int b; 881}; 882 883struct C : A, virtual B { 884 int c; 885}; 886 887// CHECK: Vtable for 'Test23::D' (7 entries). 888// CHECK-NEXT: 0 | vbase_offset (20) 889// CHECK-NEXT: 1 | vbase_offset (24) 890// CHECK-NEXT: 2 | offset_to_top (0) 891// CHECK-NEXT: 3 | Test23::D RTTI 892// CHECK-NEXT: -- (Test23::C, 0) vtable address -- 893// CHECK-NEXT: -- (Test23::D, 0) vtable address -- 894// CHECK-NEXT: 4 | vbase_offset (-4) 895// CHECK-NEXT: 5 | offset_to_top (-24) 896// CHECK-NEXT: 6 | Test23::D RTTI 897// CHECK-NEXT: -- (Test23::B, 24) vtable address -- 898 899// CHECK: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries). 900// CHECK-NEXT: 0 | vbase_offset (20) 901// CHECK-NEXT: 1 | vbase_offset (24) 902// CHECK-NEXT: 2 | offset_to_top (0) 903// CHECK-NEXT: 3 | Test23::C RTTI 904// CHECK-NEXT: -- (Test23::C, 0) vtable address -- 905// CHECK-NEXT: 4 | vbase_offset (-4) 906// CHECK-NEXT: 5 | offset_to_top (-24) 907// CHECK-NEXT: 6 | Test23::C RTTI 908// CHECK-NEXT: -- (Test23::B, 24) vtable address -- 909 910// CHECK: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries). 911// CHECK-NEXT: 0 | vbase_offset (-4) 912// CHECK-NEXT: 1 | offset_to_top (0) 913// CHECK-NEXT: 2 | Test23::B RTTI 914// CHECK-NEXT: -- (Test23::B, 24) vtable address -- 915 916struct D : virtual A, virtual B, C { 917 int d; 918 919 void f(); 920}; 921void D::f() { } 922 923} 924 925namespace Test24 { 926 927// Another construction vtable test. 928 929struct A { 930 virtual void f(); 931}; 932 933struct B : virtual A { }; 934struct C : virtual A { }; 935 936// CHECK: Vtable for 'Test24::D' (10 entries). 937// CHECK-NEXT: 0 | vbase_offset (0) 938// CHECK-NEXT: 1 | vcall_offset (0) 939// CHECK-NEXT: 2 | offset_to_top (0) 940// CHECK-NEXT: 3 | Test24::D RTTI 941// CHECK-NEXT: -- (Test24::A, 0) vtable address -- 942// CHECK-NEXT: -- (Test24::B, 0) vtable address -- 943// CHECK-NEXT: -- (Test24::D, 0) vtable address -- 944// CHECK-NEXT: 4 | void Test24::D::f() 945// CHECK-NEXT: 5 | vbase_offset (-8) 946// CHECK-NEXT: 6 | vcall_offset (-8) 947// CHECK-NEXT: 7 | offset_to_top (-8) 948// CHECK-NEXT: 8 | Test24::D RTTI 949// CHECK-NEXT: -- (Test24::A, 8) vtable address -- 950// CHECK-NEXT: -- (Test24::C, 8) vtable address -- 951// CHECK-NEXT: 9 | [unused] void Test24::D::f() 952 953// CHECK: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries). 954// CHECK-NEXT: 0 | vbase_offset (0) 955// CHECK-NEXT: 1 | vcall_offset (0) 956// CHECK-NEXT: 2 | offset_to_top (0) 957// CHECK-NEXT: 3 | Test24::B RTTI 958// CHECK-NEXT: -- (Test24::A, 0) vtable address -- 959// CHECK-NEXT: -- (Test24::B, 0) vtable address -- 960// CHECK-NEXT: 4 | void Test24::A::f() 961 962// CHECK: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries). 963// CHECK-NEXT: 0 | vbase_offset (-8) 964// CHECK-NEXT: 1 | vcall_offset (-8) 965// CHECK-NEXT: 2 | offset_to_top (0) 966// CHECK-NEXT: 3 | Test24::C RTTI 967// CHECK-NEXT: -- (Test24::A, 8) vtable address -- 968// CHECK-NEXT: -- (Test24::C, 8) vtable address -- 969// CHECK-NEXT: 4 | [unused] void Test24::A::f() 970// CHECK-NEXT: 5 | vcall_offset (0) 971// CHECK-NEXT: 6 | offset_to_top (8) 972// CHECK-NEXT: 7 | Test24::C RTTI 973// CHECK-NEXT: -- (Test24::A, 0) vtable address -- 974// CHECK-NEXT: 8 | void Test24::A::f() 975struct D : B, C { 976 virtual void f(); 977}; 978void D::f() { } 979 980} 981 982namespace Test25 { 983 984// This mainly tests that we don't assert on this class hierarchy. 985 986struct V { 987 virtual void f(); 988}; 989 990struct A : virtual V { }; 991struct B : virtual V { }; 992 993// CHECK: Vtable for 'Test25::C' (11 entries). 994// CHECK-NEXT: 0 | vbase_offset (0) 995// CHECK-NEXT: 1 | vcall_offset (0) 996// CHECK-NEXT: 2 | offset_to_top (0) 997// CHECK-NEXT: 3 | Test25::C RTTI 998// CHECK-NEXT: -- (Test25::A, 0) vtable address -- 999// CHECK-NEXT: -- (Test25::C, 0) vtable address -- 1000// CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1001// CHECK-NEXT: 4 | void Test25::V::f() 1002// CHECK-NEXT: 5 | void Test25::C::g() 1003// CHECK-NEXT: 6 | vbase_offset (-8) 1004// CHECK-NEXT: 7 | vcall_offset (-8) 1005// CHECK-NEXT: 8 | offset_to_top (-8) 1006// CHECK-NEXT: 9 | Test25::C RTTI 1007// CHECK-NEXT: -- (Test25::B, 8) vtable address -- 1008// CHECK-NEXT: -- (Test25::V, 8) vtable address -- 1009// CHECK-NEXT: 10 | [unused] void Test25::V::f() 1010 1011// CHECK: Construction vtable for ('Test25::A', 0) in 'Test25::C' (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 | Test25::A RTTI 1016// CHECK-NEXT: -- (Test25::A, 0) vtable address -- 1017// CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1018// CHECK-NEXT: 4 | void Test25::V::f() 1019 1020// CHECK: Construction vtable for ('Test25::B', 8) in 'Test25::C' (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 | Test25::B RTTI 1025// CHECK-NEXT: -- (Test25::B, 8) vtable address -- 1026// CHECK-NEXT: -- (Test25::V, 8) vtable address -- 1027// CHECK-NEXT: 4 | [unused] void Test25::V::f() 1028// CHECK-NEXT: 5 | vcall_offset (0) 1029// CHECK-NEXT: 6 | offset_to_top (8) 1030// CHECK-NEXT: 7 | Test25::B RTTI 1031// CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1032// CHECK-NEXT: 8 | void Test25::V::f() 1033struct C : A, virtual V, B { 1034 virtual void g(); 1035}; 1036void C::g() { } 1037 1038} 1039 1040namespace Test26 { 1041 1042// Test that we generate the right number of entries in the C-in-D construction vtable, and that 1043// we don't mark A::a as unused. 1044 1045struct A { 1046 virtual void a(); 1047}; 1048 1049struct B { 1050 virtual void c(); 1051}; 1052 1053struct C : virtual A { 1054 virtual void b(); 1055}; 1056 1057// CHECK: Vtable for 'Test26::D' (15 entries). 1058// CHECK-NEXT: 0 | vbase_offset (8) 1059// CHECK-NEXT: 1 | vbase_offset (8) 1060// CHECK-NEXT: 2 | vbase_offset (0) 1061// CHECK-NEXT: 3 | vcall_offset (0) 1062// CHECK-NEXT: 4 | offset_to_top (0) 1063// CHECK-NEXT: 5 | Test26::D RTTI 1064// CHECK-NEXT: -- (Test26::B, 0) vtable address -- 1065// CHECK-NEXT: -- (Test26::D, 0) vtable address -- 1066// CHECK-NEXT: 6 | void Test26::B::c() 1067// CHECK-NEXT: 7 | void Test26::D::d() 1068// CHECK-NEXT: 8 | vcall_offset (0) 1069// CHECK-NEXT: 9 | vbase_offset (0) 1070// CHECK-NEXT: 10 | vcall_offset (0) 1071// CHECK-NEXT: 11 | offset_to_top (-8) 1072// CHECK-NEXT: 12 | Test26::D RTTI 1073// CHECK-NEXT: -- (Test26::A, 8) vtable address -- 1074// CHECK-NEXT: -- (Test26::C, 8) vtable address -- 1075// CHECK-NEXT: 13 | void Test26::A::a() 1076// CHECK-NEXT: 14 | void Test26::C::b() 1077 1078// CHECK: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries). 1079// CHECK-NEXT: 0 | vcall_offset (0) 1080// CHECK-NEXT: 1 | vbase_offset (0) 1081// CHECK-NEXT: 2 | vcall_offset (0) 1082// CHECK-NEXT: 3 | offset_to_top (0) 1083// CHECK-NEXT: 4 | Test26::C RTTI 1084// CHECK-NEXT: -- (Test26::A, 8) vtable address -- 1085// CHECK-NEXT: -- (Test26::C, 8) vtable address -- 1086// CHECK-NEXT: 5 | void Test26::A::a() 1087// CHECK-NEXT: 6 | void Test26::C::b() 1088class D : virtual B, virtual C { 1089 virtual void d(); 1090}; 1091void D::d() { } 1092 1093} 1094 1095namespace Test27 { 1096 1097// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since 1098// C doesn't have any virtual bases. 1099 1100struct A { 1101 virtual void a(); 1102}; 1103 1104struct B { 1105 virtual void b(); 1106}; 1107 1108struct C { 1109 virtual void c(); 1110}; 1111 1112struct D : A, virtual B, C { 1113 virtual void d(); 1114}; 1115 1116// CHECK: Vtable for 'Test27::E' (13 entries). 1117// CHECK-NEXT: 0 | vbase_offset (16) 1118// CHECK-NEXT: 1 | offset_to_top (0) 1119// CHECK-NEXT: 2 | Test27::E RTTI 1120// CHECK-NEXT: -- (Test27::A, 0) vtable address -- 1121// CHECK-NEXT: -- (Test27::D, 0) vtable address -- 1122// CHECK-NEXT: -- (Test27::E, 0) vtable address -- 1123// CHECK-NEXT: 3 | void Test27::A::a() 1124// CHECK-NEXT: 4 | void Test27::D::d() 1125// CHECK-NEXT: 5 | void Test27::E::e() 1126// CHECK-NEXT: 6 | offset_to_top (-8) 1127// CHECK-NEXT: 7 | Test27::E RTTI 1128// CHECK-NEXT: -- (Test27::C, 8) vtable address -- 1129// CHECK-NEXT: 8 | void Test27::C::c() 1130// CHECK-NEXT: 9 | vcall_offset (0) 1131// CHECK-NEXT: 10 | offset_to_top (-16) 1132// CHECK-NEXT: 11 | Test27::E RTTI 1133// CHECK-NEXT: -- (Test27::B, 16) vtable address -- 1134// CHECK-NEXT: 12 | void Test27::B::b() 1135 1136// CHECK: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries). 1137// CHECK-NEXT: 0 | vbase_offset (16) 1138// CHECK-NEXT: 1 | offset_to_top (0) 1139// CHECK-NEXT: 2 | Test27::D RTTI 1140// CHECK-NEXT: -- (Test27::A, 0) vtable address -- 1141// CHECK-NEXT: -- (Test27::D, 0) vtable address -- 1142// CHECK-NEXT: 3 | void Test27::A::a() 1143// CHECK-NEXT: 4 | void Test27::D::d() 1144// CHECK-NEXT: 5 | vcall_offset (0) 1145// CHECK-NEXT: 6 | offset_to_top (-16) 1146// CHECK-NEXT: 7 | Test27::D RTTI 1147// CHECK-NEXT: -- (Test27::B, 16) vtable address -- 1148// CHECK-NEXT: 8 | void Test27::B::b() 1149struct E : D { 1150 virtual void e(); 1151}; 1152void E::e() { } 1153 1154} 1155 1156namespace Test28 { 1157 1158// Check that we do include the vtable for B in the D-in-E construction vtable, since 1159// B is a base class of a virtual base (C). 1160 1161struct A { 1162 virtual void a(); 1163}; 1164 1165struct B { 1166 virtual void b(); 1167}; 1168 1169struct C : A, B { 1170 virtual void c(); 1171}; 1172 1173struct D : virtual C { 1174}; 1175 1176// CHECK: Vtable for 'Test28::E' (14 entries). 1177// CHECK-NEXT: 0 | vbase_offset (8) 1178// CHECK-NEXT: 1 | offset_to_top (0) 1179// CHECK-NEXT: 2 | Test28::E RTTI 1180// CHECK-NEXT: -- (Test28::D, 0) vtable address -- 1181// CHECK-NEXT: -- (Test28::E, 0) vtable address -- 1182// CHECK-NEXT: 3 | void Test28::E::e() 1183// CHECK-NEXT: 4 | vcall_offset (8) 1184// CHECK-NEXT: 5 | vcall_offset (0) 1185// CHECK-NEXT: 6 | vcall_offset (0) 1186// CHECK-NEXT: 7 | offset_to_top (-8) 1187// CHECK-NEXT: 8 | Test28::E RTTI 1188// CHECK-NEXT: -- (Test28::A, 8) vtable address -- 1189// CHECK-NEXT: -- (Test28::C, 8) vtable address -- 1190// CHECK-NEXT: 9 | void Test28::A::a() 1191// CHECK-NEXT: 10 | void Test28::C::c() 1192// CHECK-NEXT: 11 | offset_to_top (-16) 1193// CHECK-NEXT: 12 | Test28::E RTTI 1194// CHECK-NEXT: -- (Test28::B, 16) vtable address -- 1195// CHECK-NEXT: 13 | void Test28::B::b() 1196 1197// CHECK: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries). 1198// CHECK-NEXT: 0 | vbase_offset (8) 1199// CHECK-NEXT: 1 | offset_to_top (0) 1200// CHECK-NEXT: 2 | Test28::D RTTI 1201// CHECK-NEXT: -- (Test28::D, 0) vtable address -- 1202// CHECK-NEXT: 3 | vcall_offset (8) 1203// CHECK-NEXT: 4 | vcall_offset (0) 1204// CHECK-NEXT: 5 | vcall_offset (0) 1205// CHECK-NEXT: 6 | offset_to_top (-8) 1206// CHECK-NEXT: 7 | Test28::D RTTI 1207// CHECK-NEXT: -- (Test28::A, 8) vtable address -- 1208// CHECK-NEXT: -- (Test28::C, 8) vtable address -- 1209// CHECK-NEXT: 8 | void Test28::A::a() 1210// CHECK-NEXT: 9 | void Test28::C::c() 1211// CHECK-NEXT: 10 | offset_to_top (-16) 1212// CHECK-NEXT: 11 | Test28::D RTTI 1213// CHECK-NEXT: -- (Test28::B, 16) vtable address -- 1214// CHECK-NEXT: 12 | void Test28::B::b() 1215struct E : D { 1216 virtual void e(); 1217}; 1218void E::e() { } 1219 1220} 1221