2007 lines · cpp
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t2// RUN: FileCheck --check-prefix=CHECK-1 %s < %t3// RUN: FileCheck --check-prefix=CHECK-2 %s < %t4// RUN: FileCheck --check-prefix=CHECK-3 %s < %t5// RUN: FileCheck --check-prefix=CHECK-4 %s < %t6// RUN: FileCheck --check-prefix=CHECK-5 %s < %t7// RUN: FileCheck --check-prefix=CHECK-6 %s < %t8// RUN: FileCheck --check-prefix=CHECK-7 %s < %t9// RUN: FileCheck --check-prefix=CHECK-8 %s < %t10// RUN: FileCheck --check-prefix=CHECK-9 %s < %t11// RUN: FileCheck --check-prefix=CHECK-10 %s < %t12// RUN: FileCheck --check-prefix=CHECK-11 %s < %t13// RUN: FileCheck --check-prefix=CHECK-12 %s < %t14// RUN: FileCheck --check-prefix=CHECK-13 %s < %t15// RUN: FileCheck --check-prefix=CHECK-14 %s < %t16// RUN: FileCheck --check-prefix=CHECK-15 %s < %t17// RUN: FileCheck --check-prefix=CHECK-16 %s < %t18// RUN: FileCheck --check-prefix=CHECK-17 %s < %t19// RUN: FileCheck --check-prefix=CHECK-18 %s < %t20// RUN: FileCheck --check-prefix=CHECK-19 %s < %t21// RUN: FileCheck --check-prefix=CHECK-20 %s < %t22// RUN: FileCheck --check-prefix=CHECK-21 %s < %t23// RUN: FileCheck --check-prefix=CHECK-22 %s < %t24// RUN: FileCheck --check-prefix=CHECK-23 %s < %t25// RUN: FileCheck --check-prefix=CHECK-24 %s < %t26// RUN: FileCheck --check-prefix=CHECK-25 %s < %t27// RUN: FileCheck --check-prefix=CHECK-26 %s < %t28// RUN: FileCheck --check-prefix=CHECK-27 %s < %t29// RUN: FileCheck --check-prefix=CHECK-28 %s < %t30// RUN: FileCheck --check-prefix=CHECK-29 %s < %t31// RUN: FileCheck --check-prefix=CHECK-30 %s < %t32// RUN: FileCheck --check-prefix=CHECK-31 %s < %t33// RUN: FileCheck --check-prefix=CHECK-32 %s < %t34// RUN: FileCheck --check-prefix=CHECK-33 %s < %t35// RUN: FileCheck --check-prefix=CHECK-34 %s < %t36// RUN: FileCheck --check-prefix=CHECK-35 %s < %t37// RUN: FileCheck --check-prefix=CHECK-36 %s < %t38// RUN: FileCheck --check-prefix=CHECK-37 %s < %t39// RUN: FileCheck --check-prefix=CHECK-38 %s < %t40// RUN: FileCheck --check-prefix=CHECK-39 %s < %t41// RUN: FileCheck --check-prefix=CHECK-40 %s < %t42// RUN: FileCheck --check-prefix=CHECK-41 %s < %t43// RUN: FileCheck --check-prefix=CHECK-42 %s < %t44// RUN: FileCheck --check-prefix=CHECK-43 %s < %t45// RUN: FileCheck --check-prefix=CHECK-44 %s < %t46// RUN: FileCheck --check-prefix=CHECK-45 %s < %t47// RUN: FileCheck --check-prefix=CHECK-46 %s < %t48// RUN: FileCheck --check-prefix=CHECK-47 %s < %t49// RUN: FileCheck --check-prefix=CHECK-48 %s < %t50 51// For now, just verify this doesn't crash.52namespace test0 {53 struct Obj {};54 55 struct Base { virtual const Obj *foo() = 0; };56 struct Derived : Base { virtual Obj *foo() { return new Obj(); } };57 58 void test(Derived *D) { D->foo(); }59}60 61namespace Test1 {62// CHECK-1: Vtable for 'Test1::A' (3 entries).63// CHECK-1-NEXT: 0 | offset_to_top (0)64// CHECK-1-NEXT: 1 | Test1::A RTTI65// CHECK-1-NEXT: -- (Test1::A, 0) vtable address --66// CHECK-1-NEXT: 2 | void Test1::A::f()67//68// CHECK-1: VTable indices for 'Test1::A' (1 entries).69// CHECK-1-NEXT: 0 | void Test1::A::f()70struct A {71 virtual void f();72};73void A::f() { }74 75}76 77namespace Test2 {78 79// This is a smoke test of the vtable dumper.80// CHECK-2: Vtable for 'Test2::A' (9 entries).81// CHECK-2-NEXT: 0 | offset_to_top (0)82// CHECK-2-NEXT: 1 | Test2::A RTTI83// CHECK-2-NEXT: -- (Test2::A, 0) vtable address --84// CHECK-2-NEXT: 2 | void Test2::A::f()85// CHECK-2-NEXT: 3 | void Test2::A::f() const86// CHECK-2-NEXT: 4 | A *Test2::A::g(int)87// CHECK-2-NEXT: 5 | Test2::A::~A() [complete]88// CHECK-2-NEXT: 6 | Test2::A::~A() [deleting]89// CHECK-2-NEXT: 7 | void Test2::A::h()90// CHECK-2-NEXT: 8 | A &Test2::A::operator=(const A &)91//92// CHECK-2: VTable indices for 'Test2::A' (7 entries).93// CHECK-2-NEXT: 0 | void Test2::A::f()94// CHECK-2-NEXT: 1 | void Test2::A::f() const95// CHECK-2-NEXT: 2 | A *Test2::A::g(int)96// CHECK-2-NEXT: 3 | Test2::A::~A() [complete]97// CHECK-2-NEXT: 4 | Test2::A::~A() [deleting]98// CHECK-2-NEXT: 5 | void Test2::A::h()99// CHECK-2-NEXT: 6 | A &Test2::A::operator=(const A &)100struct A {101 virtual void f();102 virtual void f() const;103 104 virtual A* g(int a);105 virtual ~A();106 virtual void h();107 virtual A& operator=(const A&);108};109void A::f() { }110 111// Another simple vtable dumper test.112 113// CHECK-3: Vtable for 'Test2::B' (6 entries).114// CHECK-3-NEXT: 0 | offset_to_top (0)115// CHECK-3-NEXT: 1 | Test2::B RTTI116// CHECK-3-NEXT: -- (Test2::B, 0) vtable address --117// CHECK-3-NEXT: 2 | void Test2::B::f()118// CHECK-3-NEXT: 3 | void Test2::B::g() [pure]119// CHECK-3-NEXT: 4 | Test2::B::~B() [complete] [pure]120// CHECK-3-NEXT: 5 | Test2::B::~B() [deleting] [pure]121//122// CHECK-3: VTable indices for 'Test2::B' (4 entries).123// CHECK-3-NEXT: 0 | void Test2::B::f()124// CHECK-3-NEXT: 1 | void Test2::B::g()125// CHECK-3-NEXT: 2 | Test2::B::~B() [complete]126// CHECK-3-NEXT: 3 | Test2::B::~B() [deleting]127struct B {128 virtual void f();129 virtual void g() = 0;130 virtual ~B() = 0;131};132void B::f() { }133 134}135 136namespace Test3 {137 138// If a function in a derived class overrides a function in a primary base,139// then the function should not have an entry in the derived class (unless the return140// value requires adjusting).141 142// CHECK-4: Vtable for 'Test3::A' (3 entries).143// CHECK-4-NEXT: 0 | offset_to_top (0)144// CHECK-4-NEXT: 1 | Test3::A RTTI145// CHECK-4-NEXT: -- (Test3::A, 0) vtable address --146// CHECK-4-NEXT: 2 | void Test3::A::f()147//148// CHECK-4: VTable indices for 'Test3::A' (1 entries).149// CHECK-4-NEXT: 0 | void Test3::A::f()150struct A {151 virtual void f();152};153void A::f() { }154 155// CHECK-5: Vtable for 'Test3::B' (4 entries).156// CHECK-5-NEXT: 0 | offset_to_top (0)157// CHECK-5-NEXT: 1 | Test3::B RTTI158// CHECK-5-NEXT: -- (Test3::A, 0) vtable address --159// CHECK-5-NEXT: -- (Test3::B, 0) vtable address --160// CHECK-5-NEXT: 2 | void Test3::B::f()161// CHECK-5-NEXT: 3 | void Test3::B::g()162//163// CHECK-5: VTable indices for 'Test3::B' (2 entries).164// CHECK-5-NEXT: 0 | void Test3::B::f()165// CHECK-5-NEXT: 1 | void Test3::B::g()166struct B : A {167 virtual void f();168 virtual void g();169};170void B::f() { }171 172// CHECK-6: Vtable for 'Test3::C' (5 entries).173// CHECK-6-NEXT: 0 | offset_to_top (0)174// CHECK-6-NEXT: 1 | Test3::C RTTI175// CHECK-6-NEXT: -- (Test3::A, 0) vtable address --176// CHECK-6-NEXT: -- (Test3::C, 0) vtable address --177// CHECK-6-NEXT: 2 | void Test3::A::f()178// CHECK-6-NEXT: 3 | void Test3::C::g()179// CHECK-6-NEXT: 4 | void Test3::C::h()180//181// CHECK-6: VTable indices for 'Test3::C' (2 entries).182// CHECK-6-NEXT: 1 | void Test3::C::g()183// CHECK-6-NEXT: 2 | void Test3::C::h()184struct C : A {185 virtual void g();186 virtual void h();187};188void C::g() { }189 190// CHECK-7: Vtable for 'Test3::D' (5 entries).191// CHECK-7-NEXT: 0 | offset_to_top (0)192// CHECK-7-NEXT: 1 | Test3::D RTTI193// CHECK-7-NEXT: -- (Test3::A, 0) vtable address --194// CHECK-7-NEXT: -- (Test3::B, 0) vtable address --195// CHECK-7-NEXT: -- (Test3::D, 0) vtable address --196// CHECK-7-NEXT: 2 | void Test3::D::f()197// CHECK-7-NEXT: 3 | void Test3::D::g()198// CHECK-7-NEXT: 4 | void Test3::D::h()199//200// CHECK-7: VTable indices for 'Test3::D' (3 entries).201// CHECK-7-NEXT: 0 | void Test3::D::f()202// CHECK-7-NEXT: 1 | void Test3::D::g()203// CHECK-7-NEXT: 2 | void Test3::D::h()204struct D : B {205 virtual void f();206 virtual void g();207 virtual void h();208};209 210void D::f() { }211}212 213namespace Test4 {214 215// Test non-virtual result adjustments.216 217struct R1 { int r1; };218struct R2 { int r2; };219struct R3 : R1, R2 { int r3; };220 221struct A {222 virtual R2 *f();223};224 225// CHECK-8: Vtable for 'Test4::B' (4 entries).226// CHECK-8-NEXT: 0 | offset_to_top (0)227// CHECK-8-NEXT: 1 | Test4::B RTTI228// CHECK-8-NEXT: -- (Test4::A, 0) vtable address --229// CHECK-8-NEXT: -- (Test4::B, 0) vtable address --230// CHECK-8-NEXT: 2 | R3 *Test4::B::f()231// CHECK-8-NEXT: [return adjustment: 4 non-virtual]232// CHECK-8-NEXT: 3 | R3 *Test4::B::f()233//234// CHECK-8: VTable indices for 'Test4::B' (1 entries).235// CHECK-8-NEXT: 1 | R3 *Test4::B::f()236struct B : A {237 virtual R3 *f();238};239R3 *B::f() { return 0; }240 241// Test virtual result adjustments.242struct V1 { int v1; };243struct V2 : virtual V1 { int v1; };244 245struct C {246 virtual V1 *f();247};248 249// CHECK-9: Vtable for 'Test4::D' (4 entries).250// CHECK-9-NEXT: 0 | offset_to_top (0)251// CHECK-9-NEXT: 1 | Test4::D RTTI252// CHECK-9-NEXT: -- (Test4::C, 0) vtable address --253// CHECK-9-NEXT: -- (Test4::D, 0) vtable address --254// CHECK-9-NEXT: 2 | V2 *Test4::D::f()255// CHECK-9-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]256// CHECK-9-NEXT: 3 | V2 *Test4::D::f()257//258// CHECK-9: VTable indices for 'Test4::D' (1 entries).259// CHECK-9-NEXT: 1 | V2 *Test4::D::f()260struct D : C {261 virtual V2 *f();262};263V2 *D::f() { return 0; };264 265// Virtual result adjustments with an additional non-virtual adjustment.266struct V3 : virtual R3 { int r3; };267 268// CHECK-10: Vtable for 'Test4::E' (4 entries).269// CHECK-10-NEXT: 0 | offset_to_top (0)270// CHECK-10-NEXT: 1 | Test4::E RTTI271// CHECK-10-NEXT: -- (Test4::A, 0) vtable address --272// CHECK-10-NEXT: -- (Test4::E, 0) vtable address --273// CHECK-10-NEXT: 2 | V3 *Test4::E::f()274// CHECK-10-NEXT: [return adjustment: 4 non-virtual, -24 vbase offset offset]275// CHECK-10-NEXT: 3 | V3 *Test4::E::f()276//277// CHECK-10: VTable indices for 'Test4::E' (1 entries).278// CHECK-10-NEXT: 1 | V3 *Test4::E::f()279struct E : A {280 virtual V3 *f();281};282V3 *E::f() { return 0;}283 284// Test that a pure virtual member doesn't get a thunk.285 286// CHECK-11: Vtable for 'Test4::F' (5 entries).287// CHECK-11-NEXT: 0 | offset_to_top (0)288// CHECK-11-NEXT: 1 | Test4::F RTTI289// CHECK-11-NEXT: -- (Test4::A, 0) vtable address --290// CHECK-11-NEXT: -- (Test4::F, 0) vtable address --291// CHECK-11-NEXT: 2 | R3 *Test4::F::f() [pure]292// CHECK-11-NEXT: 3 | void Test4::F::g()293// CHECK-11-NEXT: 4 | R3 *Test4::F::f() [pure]294//295// CHECK-11: VTable indices for 'Test4::F' (2 entries).296// CHECK-11-NEXT: 1 | void Test4::F::g()297// CHECK-11-NEXT: 2 | R3 *Test4::F::f()298struct F : A {299 virtual void g();300 virtual R3 *f() = 0;301};302void F::g() { }303 304}305 306namespace Test5 {307 308// Simple secondary vtables without 'this' pointer adjustments.309struct A {310 virtual void f();311 virtual void g();312 int a;313};314 315struct B1 : A {316 virtual void f();317 int b1;318};319 320struct B2 : A {321 virtual void g();322 int b2;323};324 325// CHECK-12: Vtable for 'Test5::C' (9 entries).326// CHECK-12-NEXT: 0 | offset_to_top (0)327// CHECK-12-NEXT: 1 | Test5::C RTTI328// CHECK-12-NEXT: -- (Test5::A, 0) vtable address --329// CHECK-12-NEXT: -- (Test5::B1, 0) vtable address --330// CHECK-12-NEXT: -- (Test5::C, 0) vtable address --331// CHECK-12-NEXT: 2 | void Test5::B1::f()332// CHECK-12-NEXT: 3 | void Test5::A::g()333// CHECK-12-NEXT: 4 | void Test5::C::h()334// CHECK-12-NEXT: 5 | offset_to_top (-16)335// CHECK-12-NEXT: 6 | Test5::C RTTI336// CHECK-12-NEXT: -- (Test5::A, 16) vtable address --337// CHECK-12-NEXT: -- (Test5::B2, 16) vtable address --338// CHECK-12-NEXT: 7 | void Test5::A::f()339// CHECK-12-NEXT: 8 | void Test5::B2::g()340//341// CHECK-12: VTable indices for 'Test5::C' (1 entries).342// CHECK-12-NEXT: 2 | void Test5::C::h()343struct C : B1, B2 {344 virtual void h();345};346void C::h() { }347}348 349namespace Test6 {350 351// Simple non-virtual 'this' pointer adjustments.352struct A1 {353 virtual void f();354 int a;355};356 357struct A2 {358 virtual void f();359 int a;360};361 362// CHECK-13: Vtable for 'Test6::C' (6 entries).363// CHECK-13-NEXT: 0 | offset_to_top (0)364// CHECK-13-NEXT: 1 | Test6::C RTTI365// CHECK-13-NEXT: -- (Test6::A1, 0) vtable address --366// CHECK-13-NEXT: -- (Test6::C, 0) vtable address --367// CHECK-13-NEXT: 2 | void Test6::C::f()368// CHECK-13-NEXT: 3 | offset_to_top (-16)369// CHECK-13-NEXT: 4 | Test6::C RTTI370// CHECK-13-NEXT: -- (Test6::A2, 16) vtable address --371// CHECK-13-NEXT: 5 | void Test6::C::f()372// CHECK-13-NEXT: [this adjustment: -16 non-virtual]373//374// CHECK-13: VTable indices for 'Test6::C' (1 entries).375// CHECK-13-NEXT: 0 | void Test6::C::f()376struct C : A1, A2 {377 virtual void f();378};379void C::f() { }380 381}382 383namespace Test7 {384 385// Test that the D::f overrider for A::f have different 'this' pointer386// adjustments in the two A base subobjects.387 388struct A {389 virtual void f();390 int a;391};392 393struct B1 : A { };394struct B2 : A { };395 396struct C { virtual void c(); };397 398// CHECK-14: Vtable for 'Test7::D' (10 entries).399// CHECK-14-NEXT: 0 | offset_to_top (0)400// CHECK-14-NEXT: 1 | Test7::D RTTI401// CHECK-14-NEXT: -- (Test7::C, 0) vtable address --402// CHECK-14-NEXT: -- (Test7::D, 0) vtable address --403// CHECK-14-NEXT: 2 | void Test7::C::c()404// CHECK-14-NEXT: 3 | void Test7::D::f()405// CHECK-14-NEXT: 4 | offset_to_top (-8)406// CHECK-14-NEXT: 5 | Test7::D RTTI407// CHECK-14-NEXT: -- (Test7::A, 8) vtable address --408// CHECK-14-NEXT: -- (Test7::B1, 8) vtable address --409// CHECK-14-NEXT: 6 | void Test7::D::f()410// CHECK-14-NEXT: [this adjustment: -8 non-virtual]411// CHECK-14-NEXT: 7 | offset_to_top (-24)412// CHECK-14-NEXT: 8 | Test7::D RTTI413// CHECK-14-NEXT: -- (Test7::A, 24) vtable address --414// CHECK-14-NEXT: -- (Test7::B2, 24) vtable address --415// CHECK-14-NEXT: 9 | void Test7::D::f()416// CHECK-14-NEXT: [this adjustment: -24 non-virtual]417//418// CHECK-14: VTable indices for 'Test7::D' (1 entries).419// CHECK-14-NEXT: 1 | void Test7::D::f()420struct D : C, B1, B2 {421 virtual void f();422};423void D::f() { }424 425}426 427namespace Test8 {428 429// Test that we don't try to layout vtables for classes that don't have430// virtual bases or virtual member functions.431 432struct A { };433 434// CHECK-15: Vtable for 'Test8::B' (3 entries).435// CHECK-15-NEXT: 0 | offset_to_top (0)436// CHECK-15-NEXT: 1 | Test8::B RTTI437// CHECK-15-NEXT: -- (Test8::B, 0) vtable address --438// CHECK-15-NEXT: 2 | void Test8::B::f()439//440// CHECK-15: VTable indices for 'Test8::B' (1 entries).441// CHECK-15-NEXT: 0 | void Test8::B::f()442struct B : A {443 virtual void f();444};445void B::f() { }446 447}448 449namespace Test9 {450 451// Simple test of vbase offsets.452 453struct A1 { int a1; };454struct A2 { int a2; };455 456// CHECK-16: Vtable for 'Test9::B' (5 entries).457// CHECK-16-NEXT: 0 | vbase_offset (16)458// CHECK-16-NEXT: 1 | vbase_offset (12)459// CHECK-16-NEXT: 2 | offset_to_top (0)460// CHECK-16-NEXT: 3 | Test9::B RTTI461// CHECK-16-NEXT: -- (Test9::B, 0) vtable address --462// CHECK-16-NEXT: 4 | void Test9::B::f()463//464// CHECK-16: VTable indices for 'Test9::B' (1 entries).465// CHECK-16-NEXT: 0 | void Test9::B::f()466struct B : virtual A1, virtual A2 {467 int b;468 469 virtual void f();470};471 472 473void B::f() { }474 475}476 477namespace Test10 {478 479// Test for a bug where we would not emit secondary vtables for bases480// of a primary base.481struct A1 { virtual void a1(); };482struct A2 { virtual void a2(); };483 484// CHECK-17: Vtable for 'Test10::C' (7 entries).485// CHECK-17-NEXT: 0 | offset_to_top (0)486// CHECK-17-NEXT: 1 | Test10::C RTTI487// CHECK-17-NEXT: -- (Test10::A1, 0) vtable address --488// CHECK-17-NEXT: -- (Test10::B, 0) vtable address --489// CHECK-17-NEXT: -- (Test10::C, 0) vtable address --490// CHECK-17-NEXT: 2 | void Test10::A1::a1()491// CHECK-17-NEXT: 3 | void Test10::C::f()492// CHECK-17-NEXT: 4 | offset_to_top (-8)493// CHECK-17-NEXT: 5 | Test10::C RTTI494// CHECK-17-NEXT: -- (Test10::A2, 8) vtable address --495// CHECK-17-NEXT: 6 | void Test10::A2::a2()496//497// CHECK-17: VTable indices for 'Test10::C' (1 entries).498// CHECK-17-NEXT: 1 | void Test10::C::f()499struct B : A1, A2 {500 int b;501};502 503struct C : B {504 virtual void f();505};506void C::f() { }507 508}509 510namespace Test11 {511 512// Very simple test of vtables for virtual bases.513struct A1 { int a; };514struct A2 { int b; };515 516struct B : A1, virtual A2 {517 int b;518};519 520// CHECK-18: Vtable for 'Test11::C' (8 entries).521// CHECK-18-NEXT: 0 | vbase_offset (24)522// CHECK-18-NEXT: 1 | vbase_offset (8)523// CHECK-18-NEXT: 2 | offset_to_top (0)524// CHECK-18-NEXT: 3 | Test11::C RTTI525// CHECK-18-NEXT: -- (Test11::C, 0) vtable address --526// CHECK-18-NEXT: 4 | void Test11::C::f()527// CHECK-18-NEXT: 5 | vbase_offset (16)528// CHECK-18-NEXT: 6 | offset_to_top (-8)529// CHECK-18-NEXT: 7 | Test11::C RTTI530//531// CHECK-18: VTable indices for 'Test11::C' (1 entries).532// CHECK-18-NEXT: 0 | void Test11::C::f()533struct C : virtual B {534 virtual void f();535};536void C::f() { }537 538}539 540namespace Test12 {541 542// Test that the right vcall offsets are generated in the right order.543 544// CHECK-19: Vtable for 'Test12::B' (19 entries).545// CHECK-19-NEXT: 0 | vbase_offset (8)546// CHECK-19-NEXT: 1 | offset_to_top (0)547// CHECK-19-NEXT: 2 | Test12::B RTTI548// CHECK-19-NEXT: -- (Test12::B, 0) vtable address --549// CHECK-19-NEXT: 3 | void Test12::B::f()550// CHECK-19-NEXT: 4 | void Test12::B::a()551// CHECK-19-NEXT: 5 | vcall_offset (32)552// CHECK-19-NEXT: 6 | vcall_offset (16)553// CHECK-19-NEXT: 7 | vcall_offset (-8)554// CHECK-19-NEXT: 8 | vcall_offset (0)555// CHECK-19-NEXT: 9 | offset_to_top (-8)556// CHECK-19-NEXT: 10 | Test12::B RTTI557// CHECK-19-NEXT: -- (Test12::A, 8) vtable address --558// CHECK-19-NEXT: -- (Test12::A1, 8) vtable address --559// CHECK-19-NEXT: 11 | void Test12::A1::a1()560// CHECK-19-NEXT: 12 | void Test12::B::a()561// CHECK-19-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]562// CHECK-19-NEXT: 13 | offset_to_top (-24)563// CHECK-19-NEXT: 14 | Test12::B RTTI564// CHECK-19-NEXT: -- (Test12::A2, 24) vtable address --565// CHECK-19-NEXT: 15 | void Test12::A2::a2()566// CHECK-19-NEXT: 16 | offset_to_top (-40)567// CHECK-19-NEXT: 17 | Test12::B RTTI568// CHECK-19-NEXT: -- (Test12::A3, 40) vtable address --569// CHECK-19-NEXT: 18 | void Test12::A3::a3()570//571// CHECK-19: VTable indices for 'Test12::B' (2 entries).572// CHECK-19-NEXT: 0 | void Test12::B::f()573// CHECK-19-NEXT: 1 | void Test12::B::a()574struct A1 {575 virtual void a1();576 int a;577};578 579struct A2 {580 virtual void a2();581 int a;582};583 584struct A3 {585 virtual void a3();586 int a;587};588 589struct A : A1, A2, A3 {590 virtual void a();591 int i;592};593 594struct B : virtual A {595 virtual void f();596 597 virtual void a();598};599void B::f() { }600 601}602 603namespace Test13 {604 605// Test that we don't try to emit a vtable for 'A' twice.606struct A {607 virtual void f();608};609 610struct B : virtual A {611 virtual void f();612};613 614// CHECK-20: Vtable for 'Test13::C' (6 entries).615// CHECK-20-NEXT: 0 | vbase_offset (0)616// CHECK-20-NEXT: 1 | vbase_offset (0)617// CHECK-20-NEXT: 2 | vcall_offset (0)618// CHECK-20-NEXT: 3 | offset_to_top (0)619// CHECK-20-NEXT: 4 | Test13::C RTTI620// CHECK-20-NEXT: -- (Test13::A, 0) vtable address --621// CHECK-20-NEXT: -- (Test13::B, 0) vtable address --622// CHECK-20-NEXT: -- (Test13::C, 0) vtable address --623// CHECK-20-NEXT: 5 | void Test13::C::f()624//625// CHECK-20: VTable indices for 'Test13::C' (1 entries).626// CHECK-20-NEXT: 0 | void Test13::C::f()627struct C : virtual B, virtual A {628 virtual void f();629};630void C::f() { }631 632}633 634namespace Test14 {635 636// Verify that we handle A being a non-virtual base of B, which is a virtual base.637 638struct A {639 virtual void f();640};641 642struct B : A { };643 644struct C : virtual B { };645 646// CHECK-21: Vtable for 'Test14::D' (5 entries).647// CHECK-21-NEXT: 0 | vbase_offset (0)648// CHECK-21-NEXT: 1 | vcall_offset (0)649// CHECK-21-NEXT: 2 | offset_to_top (0)650// CHECK-21-NEXT: 3 | Test14::D RTTI651// CHECK-21-NEXT: -- (Test14::A, 0) vtable address --652// CHECK-21-NEXT: -- (Test14::B, 0) vtable address --653// CHECK-21-NEXT: -- (Test14::C, 0) vtable address --654// CHECK-21-NEXT: -- (Test14::D, 0) vtable address --655// CHECK-21-NEXT: 4 | void Test14::D::f()656//657// CHECK-21: VTable indices for 'Test14::D' (1 entries).658// CHECK-21-NEXT: 0 | void Test14::D::f()659struct D : C, virtual B {660 virtual void f();661};662void D::f() { }663 664}665 666namespace Test15 {667 668// Test that we don't emit an extra vtable for B since it's a primary base of C.669struct A { virtual void a(); };670struct B { virtual void b(); };671 672struct C : virtual B { };673 674// CHECK-22: Vtable for 'Test15::D' (11 entries).675// CHECK-22-NEXT: 0 | vbase_offset (8)676// CHECK-22-NEXT: 1 | vbase_offset (8)677// CHECK-22-NEXT: 2 | offset_to_top (0)678// CHECK-22-NEXT: 3 | Test15::D RTTI679// CHECK-22-NEXT: -- (Test15::A, 0) vtable address --680// CHECK-22-NEXT: -- (Test15::D, 0) vtable address --681// CHECK-22-NEXT: 4 | void Test15::A::a()682// CHECK-22-NEXT: 5 | void Test15::D::f()683// CHECK-22-NEXT: 6 | vbase_offset (0)684// CHECK-22-NEXT: 7 | vcall_offset (0)685// CHECK-22-NEXT: 8 | offset_to_top (-8)686// CHECK-22-NEXT: 9 | Test15::D RTTI687// CHECK-22-NEXT: -- (Test15::B, 8) vtable address --688// CHECK-22-NEXT: -- (Test15::C, 8) vtable address --689// CHECK-22-NEXT: 10 | void Test15::B::b()690//691// CHECK-22: VTable indices for 'Test15::D' (1 entries).692// CHECK-22-NEXT: 1 | void Test15::D::f()693struct D : A, virtual B, virtual C {694 virtual void f();695};696void D::f() { }697 698}699 700namespace Test16 {701 702// Test that destructors share vcall offsets.703 704struct A { virtual ~A(); };705struct B { virtual ~B(); };706 707struct C : A, B { virtual ~C(); };708 709// CHECK-23: Vtable for 'Test16::D' (15 entries).710// CHECK-23-NEXT: 0 | vbase_offset (8)711// CHECK-23-NEXT: 1 | offset_to_top (0)712// CHECK-23-NEXT: 2 | Test16::D RTTI713// CHECK-23-NEXT: -- (Test16::D, 0) vtable address --714// CHECK-23-NEXT: 3 | void Test16::D::f()715// CHECK-23-NEXT: 4 | Test16::D::~D() [complete]716// CHECK-23-NEXT: 5 | Test16::D::~D() [deleting]717// CHECK-23-NEXT: 6 | vcall_offset (-8)718// CHECK-23-NEXT: 7 | offset_to_top (-8)719// CHECK-23-NEXT: 8 | Test16::D RTTI720// CHECK-23-NEXT: -- (Test16::A, 8) vtable address --721// CHECK-23-NEXT: -- (Test16::C, 8) vtable address --722// CHECK-23-NEXT: 9 | Test16::D::~D() [complete]723// CHECK-23-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]724// CHECK-23-NEXT: 10 | Test16::D::~D() [deleting]725// CHECK-23-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]726// CHECK-23-NEXT: 11 | offset_to_top (-16)727// CHECK-23-NEXT: 12 | Test16::D RTTI728// CHECK-23-NEXT: -- (Test16::B, 16) vtable address --729// CHECK-23-NEXT: 13 | Test16::D::~D() [complete]730// CHECK-23-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]731// CHECK-23-NEXT: 14 | Test16::D::~D() [deleting]732// CHECK-23-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]733//734// CHECK-23: VTable indices for 'Test16::D' (3 entries).735// CHECK-23-NEXT: 0 | void Test16::D::f()736// CHECK-23-NEXT: 1 | Test16::D::~D() [complete]737// CHECK-23-NEXT: 2 | Test16::D::~D() [deleting]738struct D : virtual C {739 virtual void f();740};741void D::f() { }742 743}744 745namespace Test17 {746 747// Test that we don't mark E::f in the C-in-E vtable as unused.748struct A { virtual void f(); };749struct B : virtual A { virtual void f(); };750struct C : virtual A { virtual void f(); };751struct D : virtual B, virtual C { virtual void f(); };752 753// CHECK-24: Vtable for 'Test17::E' (13 entries).754// CHECK-24-NEXT: 0 | vbase_offset (0)755// CHECK-24-NEXT: 1 | vbase_offset (8)756// CHECK-24-NEXT: 2 | vbase_offset (0)757// CHECK-24-NEXT: 3 | vbase_offset (0)758// CHECK-24-NEXT: 4 | vcall_offset (0)759// CHECK-24-NEXT: 5 | offset_to_top (0)760// CHECK-24-NEXT: 6 | Test17::E RTTI761// CHECK-24-NEXT: -- (Test17::A, 0) vtable address --762// CHECK-24-NEXT: -- (Test17::B, 0) vtable address --763// CHECK-24-NEXT: -- (Test17::D, 0) vtable address --764// CHECK-24-NEXT: -- (Test17::E, 0) vtable address --765// CHECK-24-NEXT: 7 | void Test17::E::f()766// CHECK-24-NEXT: 8 | vbase_offset (-8)767// CHECK-24-NEXT: 9 | vcall_offset (-8)768// CHECK-24-NEXT: 10 | offset_to_top (-8)769// CHECK-24-NEXT: 11 | Test17::E RTTI770// CHECK-24-NEXT: -- (Test17::C, 8) vtable address --771// CHECK-24-NEXT: 12 | void Test17::E::f()772// CHECK-24-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]773//774// CHECK-24: VTable indices for 'Test17::E' (1 entries).775// CHECK-24-NEXT: 0 | void Test17::E::f()776class E : virtual D {777 virtual void f();778};779void E::f() {}780 781}782 783namespace Test18 {784 785// Test that we compute the right 'this' adjustment offsets.786 787struct A {788 virtual void f();789 virtual void g();790};791 792struct B : virtual A {793 virtual void f();794};795 796struct C : A, B {797 virtual void g();798};799 800// CHECK-25: Vtable for 'Test18::D' (24 entries).801// CHECK-25-NEXT: 0 | vbase_offset (8)802// CHECK-25-NEXT: 1 | vbase_offset (0)803// CHECK-25-NEXT: 2 | vbase_offset (0)804// CHECK-25-NEXT: 3 | vcall_offset (8)805// CHECK-25-NEXT: 4 | vcall_offset (0)806// CHECK-25-NEXT: 5 | offset_to_top (0)807// CHECK-25-NEXT: 6 | Test18::D RTTI808// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --809// CHECK-25-NEXT: -- (Test18::B, 0) vtable address --810// CHECK-25-NEXT: -- (Test18::D, 0) vtable address --811// CHECK-25-NEXT: 7 | void Test18::D::f()812// CHECK-25-NEXT: 8 | void Test18::C::g()813// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]814// CHECK-25-NEXT: 9 | void Test18::D::h()815// CHECK-25-NEXT: 10 | vcall_offset (0)816// CHECK-25-NEXT: 11 | vcall_offset (-8)817// CHECK-25-NEXT: 12 | vbase_offset (-8)818// CHECK-25-NEXT: 13 | offset_to_top (-8)819// CHECK-25-NEXT: 14 | Test18::D RTTI820// CHECK-25-NEXT: -- (Test18::A, 8) vtable address --821// CHECK-25-NEXT: -- (Test18::C, 8) vtable address --822// CHECK-25-NEXT: 15 | void Test18::D::f()823// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]824// CHECK-25-NEXT: 16 | void Test18::C::g()825// CHECK-25-NEXT: 17 | vbase_offset (-16)826// CHECK-25-NEXT: 18 | vcall_offset (-8)827// CHECK-25-NEXT: 19 | vcall_offset (-16)828// CHECK-25-NEXT: 20 | offset_to_top (-16)829// CHECK-25-NEXT: 21 | Test18::D RTTI830// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --831// CHECK-25-NEXT: 22 | void Test18::D::f()832// CHECK-25-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset]833// CHECK-25-NEXT: 23 | [unused] void Test18::C::g()834//835// CHECK-25: VTable indices for 'Test18::D' (2 entries).836// CHECK-25-NEXT: 0 | void Test18::D::f()837// CHECK-25-NEXT: 2 | void Test18::D::h()838 839// CHECK-25: Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries).840// CHECK-25-NEXT: 0 | vbase_offset (0)841// CHECK-25-NEXT: 1 | vcall_offset (0)842// CHECK-25-NEXT: 2 | vcall_offset (0)843// CHECK-25-NEXT: 3 | offset_to_top (0)844// CHECK-25-NEXT: 4 | Test18::B RTTI845// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --846// CHECK-25-NEXT: -- (Test18::B, 0) vtable address --847// CHECK-25-NEXT: 5 | void Test18::B::f()848// CHECK-25-NEXT: 6 | void Test18::A::g()849 850// CHECK-25: Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries).851// CHECK-25-NEXT: 0 | vcall_offset (0)852// CHECK-25-NEXT: 1 | vcall_offset (0)853// CHECK-25-NEXT: 2 | vbase_offset (-8)854// CHECK-25-NEXT: 3 | offset_to_top (0)855// CHECK-25-NEXT: 4 | Test18::C RTTI856// CHECK-25-NEXT: -- (Test18::A, 8) vtable address --857// CHECK-25-NEXT: -- (Test18::C, 8) vtable address --858// CHECK-25-NEXT: 5 | void Test18::A::f()859// CHECK-25-NEXT: 6 | void Test18::C::g()860// CHECK-25-NEXT: 7 | vbase_offset (-16)861// CHECK-25-NEXT: 8 | vcall_offset (-8)862// CHECK-25-NEXT: 9 | vcall_offset (0)863// CHECK-25-NEXT: 10 | offset_to_top (-8)864// CHECK-25-NEXT: 11 | Test18::C RTTI865// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --866// CHECK-25-NEXT: 12 | void Test18::B::f()867// CHECK-25-NEXT: 13 | [unused] void Test18::C::g()868// CHECK-25-NEXT: 14 | vcall_offset (8)869// CHECK-25-NEXT: 15 | vcall_offset (16)870// CHECK-25-NEXT: 16 | offset_to_top (8)871// CHECK-25-NEXT: 17 | Test18::C RTTI872// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --873// CHECK-25-NEXT: 18 | void Test18::B::f()874// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]875// CHECK-25-NEXT: 19 | void Test18::C::g()876// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]877 878// CHECK-25: Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries).879// CHECK-25-NEXT: 0 | vbase_offset (-16)880// CHECK-25-NEXT: 1 | vcall_offset (-16)881// CHECK-25-NEXT: 2 | vcall_offset (0)882// CHECK-25-NEXT: 3 | offset_to_top (0)883// CHECK-25-NEXT: 4 | Test18::B RTTI884// CHECK-25-NEXT: -- (Test18::B, 16) vtable address --885// CHECK-25-NEXT: 5 | void Test18::B::f()886// CHECK-25-NEXT: 6 | [unused] void Test18::A::g()887// CHECK-25-NEXT: 7 | vcall_offset (0)888// CHECK-25-NEXT: 8 | vcall_offset (16)889// CHECK-25-NEXT: 9 | offset_to_top (16)890// CHECK-25-NEXT: 10 | Test18::B RTTI891// CHECK-25-NEXT: -- (Test18::A, 0) vtable address --892// CHECK-25-NEXT: 11 | void Test18::B::f()893// CHECK-25-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]894// CHECK-25-NEXT: 12 | void Test18::A::g()895struct D : virtual B, virtual C, virtual A896{897 virtual void f();898 virtual void h();899};900void D::f() {}901 902}903 904namespace Test19 {905 906// Another 'this' adjustment test.907 908struct A {909 int a;910 911 virtual void f();912};913 914struct B : A {915 int b;916 917 virtual void g();918};919 920struct C {921 virtual void c();922};923 924// CHECK-26: Vtable for 'Test19::D' (13 entries).925// CHECK-26-NEXT: 0 | vbase_offset (24)926// CHECK-26-NEXT: 1 | offset_to_top (0)927// CHECK-26-NEXT: 2 | Test19::D RTTI928// CHECK-26-NEXT: -- (Test19::C, 0) vtable address --929// CHECK-26-NEXT: -- (Test19::D, 0) vtable address --930// CHECK-26-NEXT: 3 | void Test19::C::c()931// CHECK-26-NEXT: 4 | void Test19::D::f()932// CHECK-26-NEXT: 5 | offset_to_top (-8)933// CHECK-26-NEXT: 6 | Test19::D RTTI934// CHECK-26-NEXT: -- (Test19::A, 8) vtable address --935// CHECK-26-NEXT: -- (Test19::B, 8) vtable address --936// CHECK-26-NEXT: 7 | void Test19::D::f()937// CHECK-26-NEXT: [this adjustment: -8 non-virtual]938// CHECK-26-NEXT: 8 | void Test19::B::g()939// CHECK-26-NEXT: 9 | vcall_offset (-24)940// CHECK-26-NEXT: 10 | offset_to_top (-24)941// CHECK-26-NEXT: 11 | Test19::D RTTI942// CHECK-26-NEXT: -- (Test19::A, 24) vtable address --943// CHECK-26-NEXT: 12 | void Test19::D::f()944// CHECK-26-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]945//946// CHECK-26: VTable indices for 'Test19::D' (1 entries).947// CHECK-26-NEXT: 1 | void Test19::D::f()948struct D : C, B, virtual A {949 virtual void f();950};951void D::f() { }952 953}954 955namespace Test20 {956 957// pure virtual member functions should never have 'this' adjustments.958 959struct A {960 virtual void f() = 0;961 virtual void g();962};963 964struct B : A { };965 966// CHECK-27: Vtable for 'Test20::C' (9 entries).967// CHECK-27-NEXT: 0 | offset_to_top (0)968// CHECK-27-NEXT: 1 | Test20::C RTTI969// CHECK-27-NEXT: -- (Test20::A, 0) vtable address --970// CHECK-27-NEXT: -- (Test20::C, 0) vtable address --971// CHECK-27-NEXT: 2 | void Test20::C::f() [pure]972// CHECK-27-NEXT: 3 | void Test20::A::g()973// CHECK-27-NEXT: 4 | void Test20::C::h()974// CHECK-27-NEXT: 5 | offset_to_top (-8)975// CHECK-27-NEXT: 6 | Test20::C RTTI976// CHECK-27-NEXT: -- (Test20::A, 8) vtable address --977// CHECK-27-NEXT: -- (Test20::B, 8) vtable address --978// CHECK-27-NEXT: 7 | void Test20::C::f() [pure]979// CHECK-27-NEXT: 8 | void Test20::A::g()980//981// CHECK-27: VTable indices for 'Test20::C' (2 entries).982// CHECK-27-NEXT: 0 | void Test20::C::f()983// CHECK-27-NEXT: 2 | void Test20::C::h()984struct C : A, B {985 virtual void f() = 0;986 virtual void h();987};988void C::h() { }989 990}991 992namespace Test21 {993 994// Test that we get vbase offsets right in secondary vtables.995struct A {996 virtual void f();997};998 999struct B : virtual A { };1000class C : virtual B { };1001class D : virtual C { };1002 1003class E : virtual C { };1004 1005// CHECK-28: Vtable for 'Test21::F' (16 entries).1006// CHECK-28-NEXT: 0 | vbase_offset (8)1007// CHECK-28-NEXT: 1 | vbase_offset (0)1008// CHECK-28-NEXT: 2 | vbase_offset (0)1009// CHECK-28-NEXT: 3 | vbase_offset (0)1010// CHECK-28-NEXT: 4 | vbase_offset (0)1011// CHECK-28-NEXT: 5 | vcall_offset (0)1012// CHECK-28-NEXT: 6 | offset_to_top (0)1013// CHECK-28-NEXT: 7 | Test21::F RTTI1014// CHECK-28-NEXT: -- (Test21::A, 0) vtable address --1015// CHECK-28-NEXT: -- (Test21::B, 0) vtable address --1016// CHECK-28-NEXT: -- (Test21::C, 0) vtable address --1017// CHECK-28-NEXT: -- (Test21::D, 0) vtable address --1018// CHECK-28-NEXT: -- (Test21::F, 0) vtable address --1019// CHECK-28-NEXT: 8 | void Test21::F::f()1020// CHECK-28-NEXT: 9 | vbase_offset (-8)1021// CHECK-28-NEXT: 10 | vbase_offset (-8)1022// CHECK-28-NEXT: 11 | vbase_offset (-8)1023// CHECK-28-NEXT: 12 | vcall_offset (-8)1024// CHECK-28-NEXT: 13 | offset_to_top (-8)1025// CHECK-28-NEXT: 14 | Test21::F RTTI1026// CHECK-28-NEXT: -- (Test21::E, 8) vtable address --1027// CHECK-28-NEXT: 15 | [unused] void Test21::F::f()1028//1029// CHECK-28: Virtual base offset offsets for 'Test21::F' (5 entries).1030// CHECK-28-NEXT: Test21::A | -321031// CHECK-28-NEXT: Test21::B | -401032// CHECK-28-NEXT: Test21::C | -481033// CHECK-28-NEXT: Test21::D | -561034// CHECK-28-NEXT: Test21::E | -641035//1036// CHECK-28: VTable indices for 'Test21::F' (1 entries).1037// CHECK-28-NEXT: 0 | void Test21::F::f()1038class F : virtual D, virtual E {1039 virtual void f();1040};1041void F::f() { }1042 1043}1044 1045namespace Test22 {1046 1047// Very simple construction vtable test.1048struct V1 {1049 int v1;1050};1051 1052struct V2 : virtual V1 {1053 int v2;1054};1055 1056// CHECK-29: Vtable for 'Test22::C' (8 entries).1057// CHECK-29-NEXT: 0 | vbase_offset (16)1058// CHECK-29-NEXT: 1 | vbase_offset (12)1059// CHECK-29-NEXT: 2 | offset_to_top (0)1060// CHECK-29-NEXT: 3 | Test22::C RTTI1061// CHECK-29-NEXT: -- (Test22::C, 0) vtable address --1062// CHECK-29-NEXT: 4 | void Test22::C::f()1063// CHECK-29-NEXT: 5 | vbase_offset (-4)1064// CHECK-29-NEXT: 6 | offset_to_top (-16)1065// CHECK-29-NEXT: 7 | Test22::C RTTI1066// CHECK-29-NEXT: -- (Test22::V2, 16) vtable address --1067//1068// CHECK-29: VTable indices for 'Test22::C' (1 entries).1069// CHECK-29-NEXT: 0 | void Test22::C::f()1070 1071// CHECK-29: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).1072// CHECK-29-NEXT: 0 | vbase_offset (-4)1073// CHECK-29-NEXT: 1 | offset_to_top (0)1074// CHECK-29-NEXT: 2 | Test22::V2 RTTI1075 1076struct C : virtual V1, virtual V2 {1077 int c;1078 virtual void f();1079};1080void C::f() { }1081 1082}1083 1084namespace Test23 {1085 1086struct A {1087 int a;1088};1089 1090struct B : virtual A {1091 int b;1092};1093 1094struct C : A, virtual B {1095 int c;1096};1097 1098// CHECK-30: Vtable for 'Test23::D' (7 entries).1099// CHECK-30-NEXT: 0 | vbase_offset (20)1100// CHECK-30-NEXT: 1 | vbase_offset (24)1101// CHECK-30-NEXT: 2 | offset_to_top (0)1102// CHECK-30-NEXT: 3 | Test23::D RTTI1103// CHECK-30-NEXT: -- (Test23::C, 0) vtable address --1104// CHECK-30-NEXT: -- (Test23::D, 0) vtable address --1105// CHECK-30-NEXT: 4 | vbase_offset (-4)1106// CHECK-30-NEXT: 5 | offset_to_top (-24)1107// CHECK-30-NEXT: 6 | Test23::D RTTI1108// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --1109 1110// CHECK-30: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).1111// CHECK-30-NEXT: 0 | vbase_offset (20)1112// CHECK-30-NEXT: 1 | vbase_offset (24)1113// CHECK-30-NEXT: 2 | offset_to_top (0)1114// CHECK-30-NEXT: 3 | Test23::C RTTI1115// CHECK-30-NEXT: -- (Test23::C, 0) vtable address --1116// CHECK-30-NEXT: 4 | vbase_offset (-4)1117// CHECK-30-NEXT: 5 | offset_to_top (-24)1118// CHECK-30-NEXT: 6 | Test23::C RTTI1119// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --1120 1121// CHECK-30: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).1122// CHECK-30-NEXT: 0 | vbase_offset (-4)1123// CHECK-30-NEXT: 1 | offset_to_top (0)1124// CHECK-30-NEXT: 2 | Test23::B RTTI1125// CHECK-30-NEXT: -- (Test23::B, 24) vtable address --1126 1127struct D : virtual A, virtual B, C {1128 int d;1129 1130 void f();1131};1132void D::f() { }1133 D d;1134}1135 1136namespace Test24 {1137 1138// Another construction vtable test.1139 1140struct A {1141 virtual void f();1142};1143 1144struct B : virtual A { };1145struct C : virtual A { };1146 1147// CHECK-31: Vtable for 'Test24::D' (10 entries).1148// CHECK-31-NEXT: 0 | vbase_offset (0)1149// CHECK-31-NEXT: 1 | vcall_offset (0)1150// CHECK-31-NEXT: 2 | offset_to_top (0)1151// CHECK-31-NEXT: 3 | Test24::D RTTI1152// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --1153// CHECK-31-NEXT: -- (Test24::B, 0) vtable address --1154// CHECK-31-NEXT: -- (Test24::D, 0) vtable address --1155// CHECK-31-NEXT: 4 | void Test24::D::f()1156// CHECK-31-NEXT: 5 | vbase_offset (-8)1157// CHECK-31-NEXT: 6 | vcall_offset (-8)1158// CHECK-31-NEXT: 7 | offset_to_top (-8)1159// CHECK-31-NEXT: 8 | Test24::D RTTI1160// CHECK-31-NEXT: -- (Test24::C, 8) vtable address --1161// CHECK-31-NEXT: 9 | [unused] void Test24::D::f()1162//1163// CHECK-31: VTable indices for 'Test24::D' (1 entries).1164// CHECK-31-NEXT: 0 | void Test24::D::f()1165 1166// CHECK-31: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries).1167// CHECK-31-NEXT: 0 | vbase_offset (0)1168// CHECK-31-NEXT: 1 | vcall_offset (0)1169// CHECK-31-NEXT: 2 | offset_to_top (0)1170// CHECK-31-NEXT: 3 | Test24::B RTTI1171// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --1172// CHECK-31-NEXT: -- (Test24::B, 0) vtable address --1173// CHECK-31-NEXT: 4 | void Test24::A::f()1174 1175// CHECK-31: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries).1176// CHECK-31-NEXT: 0 | vbase_offset (-8)1177// CHECK-31-NEXT: 1 | vcall_offset (-8)1178// CHECK-31-NEXT: 2 | offset_to_top (0)1179// CHECK-31-NEXT: 3 | Test24::C RTTI1180// CHECK-31-NEXT: -- (Test24::C, 8) vtable address --1181// CHECK-31-NEXT: 4 | [unused] void Test24::A::f()1182// CHECK-31-NEXT: 5 | vcall_offset (0)1183// CHECK-31-NEXT: 6 | offset_to_top (8)1184// CHECK-31-NEXT: 7 | Test24::C RTTI1185// CHECK-31-NEXT: -- (Test24::A, 0) vtable address --1186// CHECK-31-NEXT: 8 | void Test24::A::f()1187struct D : B, C {1188 virtual void f();1189};1190void D::f() { }1191 1192}1193 1194namespace Test25 {1195 1196// This mainly tests that we don't assert on this class hierarchy.1197 1198struct V {1199 virtual void f();1200};1201 1202struct A : virtual V { };1203struct B : virtual V { };1204 1205// CHECK-32: Vtable for 'Test25::C' (11 entries).1206// CHECK-32-NEXT: 0 | vbase_offset (0)1207// CHECK-32-NEXT: 1 | vcall_offset (0)1208// CHECK-32-NEXT: 2 | offset_to_top (0)1209// CHECK-32-NEXT: 3 | Test25::C RTTI1210// CHECK-32-NEXT: -- (Test25::A, 0) vtable address --1211// CHECK-32-NEXT: -- (Test25::C, 0) vtable address --1212// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --1213// CHECK-32-NEXT: 4 | void Test25::V::f()1214// CHECK-32-NEXT: 5 | void Test25::C::g()1215// CHECK-32-NEXT: 6 | vbase_offset (-8)1216// CHECK-32-NEXT: 7 | vcall_offset (-8)1217// CHECK-32-NEXT: 8 | offset_to_top (-8)1218// CHECK-32-NEXT: 9 | Test25::C RTTI1219// CHECK-32-NEXT: -- (Test25::B, 8) vtable address --1220// CHECK-32-NEXT: 10 | [unused] void Test25::V::f()1221//1222// CHECK-32: VTable indices for 'Test25::C' (1 entries).1223// CHECK-32-NEXT: 1 | void Test25::C::g()1224 1225// CHECK-32: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).1226// CHECK-32-NEXT: 0 | vbase_offset (0)1227// CHECK-32-NEXT: 1 | vcall_offset (0)1228// CHECK-32-NEXT: 2 | offset_to_top (0)1229// CHECK-32-NEXT: 3 | Test25::A RTTI1230// CHECK-32-NEXT: -- (Test25::A, 0) vtable address --1231// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --1232// CHECK-32-NEXT: 4 | void Test25::V::f()1233 1234// CHECK-32: Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries).1235// CHECK-32-NEXT: 0 | vbase_offset (-8)1236// CHECK-32-NEXT: 1 | vcall_offset (-8)1237// CHECK-32-NEXT: 2 | offset_to_top (0)1238// CHECK-32-NEXT: 3 | Test25::B RTTI1239// CHECK-32-NEXT: -- (Test25::B, 8) vtable address --1240// CHECK-32-NEXT: 4 | [unused] void Test25::V::f()1241// CHECK-32-NEXT: 5 | vcall_offset (0)1242// CHECK-32-NEXT: 6 | offset_to_top (8)1243// CHECK-32-NEXT: 7 | Test25::B RTTI1244// CHECK-32-NEXT: -- (Test25::V, 0) vtable address --1245// CHECK-32-NEXT: 8 | void Test25::V::f()1246struct C : A, virtual V, B {1247 virtual void g();1248};1249void C::g() { }1250 1251}1252 1253namespace Test26 {1254 1255// Test that we generate the right number of entries in the C-in-D construction vtable, and that1256// we don't mark A::a as unused.1257 1258struct A {1259 virtual void a();1260};1261 1262struct B {1263 virtual void c();1264};1265 1266struct C : virtual A {1267 virtual void b();1268};1269 1270// CHECK-33: Vtable for 'Test26::D' (15 entries).1271// CHECK-33-NEXT: 0 | vbase_offset (8)1272// CHECK-33-NEXT: 1 | vbase_offset (8)1273// CHECK-33-NEXT: 2 | vbase_offset (0)1274// CHECK-33-NEXT: 3 | vcall_offset (0)1275// CHECK-33-NEXT: 4 | offset_to_top (0)1276// CHECK-33-NEXT: 5 | Test26::D RTTI1277// CHECK-33-NEXT: -- (Test26::B, 0) vtable address --1278// CHECK-33-NEXT: -- (Test26::D, 0) vtable address --1279// CHECK-33-NEXT: 6 | void Test26::B::c()1280// CHECK-33-NEXT: 7 | void Test26::D::d()1281// CHECK-33-NEXT: 8 | vcall_offset (0)1282// CHECK-33-NEXT: 9 | vbase_offset (0)1283// CHECK-33-NEXT: 10 | vcall_offset (0)1284// CHECK-33-NEXT: 11 | offset_to_top (-8)1285// CHECK-33-NEXT: 12 | Test26::D RTTI1286// CHECK-33-NEXT: -- (Test26::A, 8) vtable address --1287// CHECK-33-NEXT: -- (Test26::C, 8) vtable address --1288// CHECK-33-NEXT: 13 | void Test26::A::a()1289// CHECK-33-NEXT: 14 | void Test26::C::b()1290//1291// CHECK-33: VTable indices for 'Test26::D' (1 entries).1292// CHECK-33-NEXT: 1 | void Test26::D::d()1293 1294// CHECK-33: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries).1295// CHECK-33-NEXT: 0 | vcall_offset (0)1296// CHECK-33-NEXT: 1 | vbase_offset (0)1297// CHECK-33-NEXT: 2 | vcall_offset (0)1298// CHECK-33-NEXT: 3 | offset_to_top (0)1299// CHECK-33-NEXT: 4 | Test26::C RTTI1300// CHECK-33-NEXT: -- (Test26::A, 8) vtable address --1301// CHECK-33-NEXT: -- (Test26::C, 8) vtable address --1302// CHECK-33-NEXT: 5 | void Test26::A::a()1303// CHECK-33-NEXT: 6 | void Test26::C::b()1304class D : virtual B, virtual C {1305 virtual void d();1306};1307void D::d() { }1308 1309}1310 1311namespace Test27 {1312 1313// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since1314// C doesn't have any virtual bases.1315 1316struct A {1317 virtual void a();1318};1319 1320struct B {1321 virtual void b();1322};1323 1324struct C {1325 virtual void c();1326};1327 1328struct D : A, virtual B, C {1329 virtual void d();1330};1331 1332// CHECK-34: Vtable for 'Test27::E' (13 entries).1333// CHECK-34-NEXT: 0 | vbase_offset (16)1334// CHECK-34-NEXT: 1 | offset_to_top (0)1335// CHECK-34-NEXT: 2 | Test27::E RTTI1336// CHECK-34-NEXT: -- (Test27::A, 0) vtable address --1337// CHECK-34-NEXT: -- (Test27::D, 0) vtable address --1338// CHECK-34-NEXT: -- (Test27::E, 0) vtable address --1339// CHECK-34-NEXT: 3 | void Test27::A::a()1340// CHECK-34-NEXT: 4 | void Test27::D::d()1341// CHECK-34-NEXT: 5 | void Test27::E::e()1342// CHECK-34-NEXT: 6 | offset_to_top (-8)1343// CHECK-34-NEXT: 7 | Test27::E RTTI1344// CHECK-34-NEXT: -- (Test27::C, 8) vtable address --1345// CHECK-34-NEXT: 8 | void Test27::C::c()1346// CHECK-34-NEXT: 9 | vcall_offset (0)1347// CHECK-34-NEXT: 10 | offset_to_top (-16)1348// CHECK-34-NEXT: 11 | Test27::E RTTI1349// CHECK-34-NEXT: -- (Test27::B, 16) vtable address --1350// CHECK-34-NEXT: 12 | void Test27::B::b()1351//1352// CHECK-34: VTable indices for 'Test27::E' (1 entries).1353// CHECK-34-NEXT: 2 | void Test27::E::e()1354 1355// CHECK-34: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries).1356// CHECK-34-NEXT: 0 | vbase_offset (16)1357// CHECK-34-NEXT: 1 | offset_to_top (0)1358// CHECK-34-NEXT: 2 | Test27::D RTTI1359// CHECK-34-NEXT: -- (Test27::A, 0) vtable address --1360// CHECK-34-NEXT: -- (Test27::D, 0) vtable address --1361// CHECK-34-NEXT: 3 | void Test27::A::a()1362// CHECK-34-NEXT: 4 | void Test27::D::d()1363// CHECK-34-NEXT: 5 | vcall_offset (0)1364// CHECK-34-NEXT: 6 | offset_to_top (-16)1365// CHECK-34-NEXT: 7 | Test27::D RTTI1366// CHECK-34-NEXT: -- (Test27::B, 16) vtable address --1367// CHECK-34-NEXT: 8 | void Test27::B::b()1368struct E : D {1369 virtual void e();1370};1371void E::e() { }1372 1373}1374 1375namespace Test28 {1376 1377// Check that we do include the vtable for B in the D-in-E construction vtable, since1378// B is a base class of a virtual base (C).1379 1380struct A {1381 virtual void a();1382};1383 1384struct B {1385 virtual void b();1386};1387 1388struct C : A, B {1389 virtual void c();1390};1391 1392struct D : virtual C {1393};1394 1395// CHECK-35: Vtable for 'Test28::E' (14 entries).1396// CHECK-35-NEXT: 0 | vbase_offset (8)1397// CHECK-35-NEXT: 1 | offset_to_top (0)1398// CHECK-35-NEXT: 2 | Test28::E RTTI1399// CHECK-35-NEXT: -- (Test28::D, 0) vtable address --1400// CHECK-35-NEXT: -- (Test28::E, 0) vtable address --1401// CHECK-35-NEXT: 3 | void Test28::E::e()1402// CHECK-35-NEXT: 4 | vcall_offset (8)1403// CHECK-35-NEXT: 5 | vcall_offset (0)1404// CHECK-35-NEXT: 6 | vcall_offset (0)1405// CHECK-35-NEXT: 7 | offset_to_top (-8)1406// CHECK-35-NEXT: 8 | Test28::E RTTI1407// CHECK-35-NEXT: -- (Test28::A, 8) vtable address --1408// CHECK-35-NEXT: -- (Test28::C, 8) vtable address --1409// CHECK-35-NEXT: 9 | void Test28::A::a()1410// CHECK-35-NEXT: 10 | void Test28::C::c()1411// CHECK-35-NEXT: 11 | offset_to_top (-16)1412// CHECK-35-NEXT: 12 | Test28::E RTTI1413// CHECK-35-NEXT: -- (Test28::B, 16) vtable address --1414// CHECK-35-NEXT: 13 | void Test28::B::b()1415//1416// CHECK-35: VTable indices for 'Test28::E' (1 entries).1417// CHECK-35-NEXT: 0 | void Test28::E::e()1418 1419// CHECK-35: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).1420// CHECK-35-NEXT: 0 | vbase_offset (8)1421// CHECK-35-NEXT: 1 | offset_to_top (0)1422// CHECK-35-NEXT: 2 | Test28::D RTTI1423// CHECK-35-NEXT: -- (Test28::D, 0) vtable address --1424// CHECK-35-NEXT: 3 | vcall_offset (8)1425// CHECK-35-NEXT: 4 | vcall_offset (0)1426// CHECK-35-NEXT: 5 | vcall_offset (0)1427// CHECK-35-NEXT: 6 | offset_to_top (-8)1428// CHECK-35-NEXT: 7 | Test28::D RTTI1429// CHECK-35-NEXT: -- (Test28::A, 8) vtable address --1430// CHECK-35-NEXT: -- (Test28::C, 8) vtable address --1431// CHECK-35-NEXT: 8 | void Test28::A::a()1432// CHECK-35-NEXT: 9 | void Test28::C::c()1433// CHECK-35-NEXT: 10 | offset_to_top (-16)1434// CHECK-35-NEXT: 11 | Test28::D RTTI1435// CHECK-35-NEXT: -- (Test28::B, 16) vtable address --1436// CHECK-35-NEXT: 12 | void Test28::B::b()1437struct E : D {1438 virtual void e();1439};1440void E::e() { }1441 1442}1443 1444namespace Test29 {1445 1446// Test that the covariant return thunk for B::f will have a virtual 'this' adjustment,1447// matching gcc.1448 1449struct V1 { };1450struct V2 : virtual V1 { };1451 1452struct A {1453 virtual V1 *f();1454};1455 1456// CHECK-36: Vtable for 'Test29::B' (6 entries).1457// CHECK-36-NEXT: 0 | vbase_offset (0)1458// CHECK-36-NEXT: 1 | vcall_offset (0)1459// CHECK-36-NEXT: 2 | offset_to_top (0)1460// CHECK-36-NEXT: 3 | Test29::B RTTI1461// CHECK-36-NEXT: -- (Test29::A, 0) vtable address --1462// CHECK-36-NEXT: -- (Test29::B, 0) vtable address --1463// CHECK-36-NEXT: 4 | V2 *Test29::B::f()1464// CHECK-36-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]1465// CHECK-36-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]1466// CHECK-36-NEXT: 5 | V2 *Test29::B::f()1467//1468// CHECK-36: VTable indices for 'Test29::B' (1 entries).1469// CHECK-36-NEXT: 1 | V2 *Test29::B::f()1470struct B : virtual A {1471 virtual V2 *f();1472};1473V2 *B::f() { return 0; }1474 1475}1476 1477namespace Test30 {1478 1479// Test that we don't assert when generating a vtable for F.1480struct A { };1481 1482struct B : virtual A {1483 int i;1484};1485 1486struct C {1487 virtual void f();1488};1489 1490struct D : virtual C, B { };1491struct E : virtual D { };1492 1493struct F : E {1494 virtual void f();1495};1496void F::f() { }1497 1498}1499 1500namespace Test31 {1501 1502// Test that we don't add D::f twice to the primary vtable.1503struct A {1504 int a;1505};1506 1507struct B {1508 virtual void f();1509};1510 1511struct C : A, virtual B {1512 virtual void f();1513};1514 1515// CHECK-37: Vtable for 'Test31::D' (11 entries).1516// CHECK-37-NEXT: 0 | vbase_offset (0)1517// CHECK-37-NEXT: 1 | vbase_offset (8)1518// CHECK-37-NEXT: 2 | vcall_offset (0)1519// CHECK-37-NEXT: 3 | offset_to_top (0)1520// CHECK-37-NEXT: 4 | Test31::D RTTI1521// CHECK-37-NEXT: -- (Test31::B, 0) vtable address --1522// CHECK-37-NEXT: -- (Test31::D, 0) vtable address --1523// CHECK-37-NEXT: 5 | void Test31::D::f()1524// CHECK-37-NEXT: 6 | vbase_offset (-8)1525// CHECK-37-NEXT: 7 | vcall_offset (-8)1526// CHECK-37-NEXT: 8 | offset_to_top (-8)1527// CHECK-37-NEXT: 9 | Test31::D RTTI1528// CHECK-37-NEXT: -- (Test31::C, 8) vtable address --1529// CHECK-37-NEXT: 10 | void Test31::D::f()1530// CHECK-37-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]1531//1532// CHECK-37: VTable indices for 'Test31::D' (1 entries).1533// CHECK-37-NEXT: 0 | void Test31::D::f()1534struct D : virtual C {1535 virtual void f();1536};1537void D::f() { }1538 1539}1540 1541namespace Test32 {1542 1543// Check that we correctly lay out the virtual bases of 'Test32::D'.1544 1545struct A {1546 virtual void f();1547};1548 1549struct B : virtual A { };1550struct C : A, virtual B { };1551struct D : virtual B { };1552 1553// CHECK-38: Virtual base offset offsets for 'Test32::E' (3 entries).1554// CHECK-38-NEXT: Test32::A | -321555// CHECK-38-NEXT: Test32::B | -241556// CHECK-38-NEXT: Test32::D | -401557struct E : C, virtual D {1558 virtual void f();1559};1560void E::f() { }1561 1562}1563 1564namespace Test33 {1565 1566// Test that we don't emit too many vcall offsets in 'Test32::F'.1567 1568struct A {1569 virtual void a();1570};1571 1572struct B {1573 virtual void b();1574};1575 1576struct C : virtual A, virtual B {1577 virtual void c();1578};1579 1580struct D : virtual C { };1581 1582struct E : A, D {1583 virtual void e();1584};1585 1586// CHECK-39: Vtable for 'Test33::F' (30 entries).1587// CHECK-39-NEXT: 0 | vbase_offset (24)1588// CHECK-39-NEXT: 1 | vbase_offset (16)1589// CHECK-39-NEXT: 2 | vbase_offset (16)1590// CHECK-39-NEXT: 3 | vbase_offset (8)1591// CHECK-39-NEXT: 4 | offset_to_top (0)1592// CHECK-39-NEXT: 5 | Test33::F RTTI1593// CHECK-39-NEXT: -- (Test33::A, 0) vtable address --1594// CHECK-39-NEXT: -- (Test33::F, 0) vtable address --1595// CHECK-39-NEXT: 6 | void Test33::A::a()1596// CHECK-39-NEXT: 7 | void Test33::F::f()1597// CHECK-39-NEXT: 8 | vcall_offset (0)1598// CHECK-39-NEXT: 9 | vcall_offset (0)1599// CHECK-39-NEXT: 10 | vbase_offset (16)1600// CHECK-39-NEXT: 11 | vbase_offset (8)1601// CHECK-39-NEXT: 12 | vbase_offset (8)1602// CHECK-39-NEXT: 13 | offset_to_top (-8)1603// CHECK-39-NEXT: 14 | Test33::F RTTI1604// CHECK-39-NEXT: -- (Test33::A, 8) vtable address --1605// CHECK-39-NEXT: -- (Test33::E, 8) vtable address --1606// CHECK-39-NEXT: 15 | void Test33::A::a()1607// CHECK-39-NEXT: 16 | void Test33::E::e()1608// CHECK-39-NEXT: 17 | vbase_offset (0)1609// CHECK-39-NEXT: 18 | vcall_offset (0)1610// CHECK-39-NEXT: 19 | vbase_offset (8)1611// CHECK-39-NEXT: 20 | vbase_offset (0)1612// CHECK-39-NEXT: 21 | vcall_offset (0)1613// CHECK-39-NEXT: 22 | offset_to_top (-16)1614// CHECK-39-NEXT: 23 | Test33::F RTTI1615// CHECK-39-NEXT: -- (Test33::A, 16) vtable address --1616// CHECK-39-NEXT: -- (Test33::C, 16) vtable address --1617// CHECK-39-NEXT: -- (Test33::D, 16) vtable address --1618// CHECK-39-NEXT: 24 | void Test33::A::a()1619// CHECK-39-NEXT: 25 | void Test33::C::c()1620// CHECK-39-NEXT: 26 | vcall_offset (0)1621// CHECK-39-NEXT: 27 | offset_to_top (-24)1622// CHECK-39-NEXT: 28 | Test33::F RTTI1623// CHECK-39-NEXT: -- (Test33::B, 24) vtable address --1624// CHECK-39-NEXT: 29 | void Test33::B::b()1625//1626// CHECK-39: VTable indices for 'Test33::F' (1 entries).1627// CHECK-39-NEXT: 1 | void Test33::F::f()1628struct F : virtual E, A {1629 virtual void f();1630};1631void F::f() { }1632 1633}1634 1635namespace Test34 {1636 1637// Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly.1638 1639struct A {1640 virtual void a();1641};1642struct B : virtual A { };1643 1644struct C : B, A {1645 virtual void c();1646};1647 1648struct D : A, C { };1649 1650struct E : virtual D {1651 virtual void e();1652};1653 1654// CHECK-40: Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries).1655// CHECK-40-NEXT: 0 | vbase_offset (0)1656// CHECK-40-NEXT: 1 | vbase_offset (8)1657// CHECK-40-NEXT: 2 | vcall_offset (0)1658// CHECK-40-NEXT: 3 | offset_to_top (0)1659// CHECK-40-NEXT: 4 | Test34::E RTTI1660// CHECK-40-NEXT: -- (Test34::A, 0) vtable address --1661// CHECK-40-NEXT: -- (Test34::E, 0) vtable address --1662// CHECK-40-NEXT: 5 | void Test34::A::a()1663// CHECK-40-NEXT: 6 | void Test34::E::e()1664// CHECK-40-NEXT: 7 | vcall_offset (8)1665// CHECK-40-NEXT: 8 | vcall_offset (0)1666// CHECK-40-NEXT: 9 | vbase_offset (-8)1667// CHECK-40-NEXT: 10 | offset_to_top (-8)1668// CHECK-40-NEXT: 11 | Test34::E RTTI1669// CHECK-40-NEXT: -- (Test34::A, 8) vtable address --1670// CHECK-40-NEXT: -- (Test34::D, 8) vtable address --1671// CHECK-40-NEXT: 12 | void Test34::A::a()1672// CHECK-40-NEXT: 13 | vbase_offset (-16)1673// CHECK-40-NEXT: 14 | vcall_offset (-16)1674// CHECK-40-NEXT: 15 | offset_to_top (-16)1675// CHECK-40-NEXT: 16 | Test34::E RTTI1676// CHECK-40-NEXT: -- (Test34::B, 16) vtable address --1677// CHECK-40-NEXT: -- (Test34::C, 16) vtable address --1678// CHECK-40-NEXT: 17 | [unused] void Test34::A::a()1679// CHECK-40-NEXT: 18 | void Test34::C::c()1680// CHECK-40-NEXT: 19 | offset_to_top (-24)1681// CHECK-40-NEXT: 20 | Test34::E RTTI1682// CHECK-40-NEXT: -- (Test34::A, 24) vtable address --1683// CHECK-40-NEXT: 21 | void Test34::A::a()1684struct F : E {1685 virtual void f();1686};1687void F::f() { }1688 1689}1690 1691namespace Test35 {1692 1693// Test that we lay out the virtual bases of 'Test35::H' in the correct order.1694 1695struct A {1696 virtual void a();1697 1698 int i;1699};1700 1701struct B : virtual A {1702 virtual void b();1703};1704 1705struct C {1706 virtual void c();1707};1708 1709struct D : C, virtual B {1710 virtual void d();1711};1712 1713struct E : D {1714 virtual void e();1715 1716 bool b;1717};1718 1719struct F : virtual D { };1720struct G : virtual E { };1721 1722// CHECK-41: Vtable for 'Test35::H' (32 entries).1723// CHECK-41-NEXT: 0 | vbase_offset (32)1724// CHECK-41-NEXT: 1 | vbase_offset (0)1725// CHECK-41-NEXT: 2 | vcall_offset (0)1726// CHECK-41-NEXT: 3 | vcall_offset (0)1727// CHECK-41-NEXT: 4 | vbase_offset (16)1728// CHECK-41-NEXT: 5 | vbase_offset (8)1729// CHECK-41-NEXT: 6 | offset_to_top (0)1730// CHECK-41-NEXT: 7 | Test35::H RTTI1731// CHECK-41-NEXT: -- (Test35::C, 0) vtable address --1732// CHECK-41-NEXT: -- (Test35::D, 0) vtable address --1733// CHECK-41-NEXT: -- (Test35::F, 0) vtable address --1734// CHECK-41-NEXT: -- (Test35::H, 0) vtable address --1735// CHECK-41-NEXT: 8 | void Test35::C::c()1736// CHECK-41-NEXT: 9 | void Test35::D::d()1737// CHECK-41-NEXT: 10 | void Test35::H::h()1738// CHECK-41-NEXT: 11 | vbase_offset (0)1739// CHECK-41-NEXT: 12 | vbase_offset (24)1740// CHECK-41-NEXT: 13 | vcall_offset (0)1741// CHECK-41-NEXT: 14 | vbase_offset (8)1742// CHECK-41-NEXT: 15 | offset_to_top (-8)1743// CHECK-41-NEXT: 16 | Test35::H RTTI1744// CHECK-41-NEXT: -- (Test35::B, 8) vtable address --1745// CHECK-41-NEXT: -- (Test35::G, 8) vtable address --1746// CHECK-41-NEXT: 17 | void Test35::B::b()1747// CHECK-41-NEXT: 18 | vcall_offset (0)1748// CHECK-41-NEXT: 19 | offset_to_top (-16)1749// CHECK-41-NEXT: 20 | Test35::H RTTI1750// CHECK-41-NEXT: -- (Test35::A, 16) vtable address --1751// CHECK-41-NEXT: 21 | void Test35::A::a()1752// CHECK-41-NEXT: 22 | vcall_offset (0)1753// CHECK-41-NEXT: 23 | vcall_offset (0)1754// CHECK-41-NEXT: 24 | vcall_offset (0)1755// CHECK-41-NEXT: 25 | vbase_offset (-16)1756// CHECK-41-NEXT: 26 | vbase_offset (-24)1757// CHECK-41-NEXT: 27 | offset_to_top (-32)1758// CHECK-41-NEXT: 28 | Test35::H RTTI1759// CHECK-41-NEXT: -- (Test35::C, 32) vtable address --1760// CHECK-41-NEXT: -- (Test35::D, 32) vtable address --1761// CHECK-41-NEXT: -- (Test35::E, 32) vtable address --1762// CHECK-41-NEXT: 29 | void Test35::C::c()1763// CHECK-41-NEXT: 30 | void Test35::D::d()1764// CHECK-41-NEXT: 31 | void Test35::E::e()1765//1766// CHECK-41: Virtual base offset offsets for 'Test35::H' (4 entries).1767// CHECK-41-NEXT: Test35::A | -321768// CHECK-41-NEXT: Test35::B | -241769// CHECK-41-NEXT: Test35::D | -561770// CHECK-41-NEXT: Test35::E | -641771//1772// CHECK-41: VTable indices for 'Test35::H' (1 entries).1773// CHECK-41-NEXT: 2 | void Test35::H::h()1774struct H : F, G {1775 virtual void h();1776};1777void H::h() { }1778 1779}1780 1781namespace Test36 {1782 1783// Test that we don't mark B::f as unused in the vtable for D.1784 1785struct A {1786 virtual void f();1787};1788 1789struct B : virtual A { };1790 1791struct C : virtual A {1792 virtual void f();1793};1794 1795// CHECK-42: Vtable for 'Test36::D' (12 entries).1796// CHECK-42-NEXT: 0 | vbase_offset (8)1797// CHECK-42-NEXT: 1 | vbase_offset (8)1798// CHECK-42-NEXT: 2 | vcall_offset (0)1799// CHECK-42-NEXT: 3 | offset_to_top (0)1800// CHECK-42-NEXT: 4 | Test36::D RTTI1801// CHECK-42-NEXT: -- (Test36::C, 0) vtable address --1802// CHECK-42-NEXT: -- (Test36::D, 0) vtable address --1803// CHECK-42-NEXT: 5 | void Test36::C::f()1804// CHECK-42-NEXT: 6 | void Test36::D::g()1805// CHECK-42-NEXT: 7 | vbase_offset (0)1806// CHECK-42-NEXT: 8 | vcall_offset (-8)1807// CHECK-42-NEXT: 9 | offset_to_top (-8)1808// CHECK-42-NEXT: 10 | Test36::D RTTI1809// CHECK-42-NEXT: -- (Test36::A, 8) vtable address --1810// CHECK-42-NEXT: -- (Test36::B, 8) vtable address --1811// CHECK-42-NEXT: 11 | void Test36::C::f()1812// CHECK-42-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]1813//1814// CHECK-42: VTable indices for 'Test36::D' (1 entries).1815// CHECK-42-NEXT: 1 | void Test36::D::g()1816struct D : virtual B, C {1817 virtual void g();1818};1819void D::g() { }1820 1821}1822 1823namespace Test37 {1824 1825// Test that we give C::f the right vtable index. (PR9660).1826struct A {1827 virtual A* f() = 0;1828};1829 1830struct B : virtual A {1831 virtual B* f();1832};1833 1834// CHECK-43: VTable indices for 'Test37::C' (1 entries).1835// CHECK-43-NEXT: 1 | C *Test37::C::f()1836struct C : B {1837 virtual C* f();1838};1839 1840C* C::f() { return 0; }1841 1842}1843 1844namespace Test38 {1845 struct A {1846 virtual void *foo();1847 virtual const void *foo() const;1848 };1849 1850 // CHECK-44: Vtable for 'Test38::B' (7 entries).1851 // CHECK-44-NEXT: 0 | vbase_offset (0)1852 // CHECK-44-NEXT: 1 | vcall_offset (0)1853 // CHECK-44-NEXT: 2 | vcall_offset (0)1854 // CHECK-44-NEXT: 3 | offset_to_top (0)1855 // CHECK-44-NEXT: 4 | Test38::B RTTI1856 // CHECK-44-NEXT: -- (Test38::A, 0) vtable address --1857 // CHECK-44-NEXT: -- (Test38::B, 0) vtable address --1858 // CHECK-44-NEXT: 5 | void *Test38::B::foo()1859 // CHECK-44-NEXT: 6 | const void *Test38::B::foo() const1860 //1861 // CHECK-44: VTable indices for 'Test38::B' (2 entries).1862 // CHECK-44-NEXT: 0 | void *Test38::B::foo()1863 // CHECK-44-NEXT: 1 | const void *Test38::B::foo() const1864 class B : virtual public A {1865 void *foo();1866 const void *foo() const;1867 };1868 1869 void *B::foo() { return 0; }1870}1871 1872namespace Test39 {1873 struct A {1874 virtual void foo() = delete;1875 };1876 1877 // CHECK-45: Vtable for 'Test39::B' (4 entries).1878 // CHECK-45-NEXT: 0 | offset_to_top (0)1879 // CHECK-45-NEXT: 1 | Test39::B RTTI1880 // CHECK-45-NEXT: -- (Test39::A, 0) vtable address --1881 // CHECK-45-NEXT: -- (Test39::B, 0) vtable address --1882 // CHECK-45-NEXT: 2 | void Test39::A::foo() [deleted]1883 // CHECK-45-NEXT: 3 | void Test39::B::foo2()1884 //1885 // CHECK-45: VTable indices for 'Test39::B' (1 entries).1886 // CHECK-45-NEXT: 1 | void Test39::B::foo2()1887 struct B: A {1888 virtual void foo2();1889 };1890 1891 void B::foo2() {1892 }1893}1894 1895namespace Test40 {1896 struct A {1897 virtual void foo() = 0;1898 };1899 1900 struct B : public A {1901 virtual void foo();1902 };1903 1904 struct C: public B {1905 // CHECK-46: VTable indices for 'Test40::C' (8 entries).1906 // CHECK-46-NEXT: 1 | int Test40::C::f(int)1907 // CHECK-46-NEXT: 2 | int Test40::C::f()1908 // CHECK-46-NEXT: 3 | int Test40::C::g(int)1909 // CHECK-46-NEXT: 4 | int Test40::C::g()1910 // CHECK-46-NEXT: 5 | int Test40::C::h(int)1911 // CHECK-46-NEXT: 6 | int Test40::C::h()1912 // CHECK-46-NEXT: 7 | int Test40::C::i(int)1913 // CHECK-46-NEXT: 8 | int Test40::C::i()1914 virtual int f(int);1915 virtual int f();1916 virtual int g(int);1917 virtual int g();1918 virtual int h(int);1919 virtual int h();1920 virtual int i(int);1921 virtual int i();1922 };1923 // Force C's vtable to be generated.1924 int C::f() { return 1; }1925 1926 class D : C {};1927 1928 D d;1929}1930 1931namespace Test41 {1932 struct A {1933 virtual ~A();1934 };1935 struct B;1936 struct B : A {};1937// CHECK-47-LABEL: Vtable for 'Test41::C' (4 entries).1938// CHECK-47-NEXT: 0 | offset_to_top (0)1939// CHECK-47-NEXT: 1 | Test41::C RTTI1940// CHECK-47-NEXT: -- (Test41::A, 0) vtable address --1941// CHECK-47-NEXT: -- (Test41::B, 0) vtable address --1942// CHECK-47-NEXT: -- (Test41::C, 0) vtable address --1943// CHECK-47-NEXT: 2 | Test41::C::~C() [complete]1944// CHECK-47-NEXT: 3 | Test41::C::~C() [deleting]1945 1946// CHECK-47-LABEL: VTable indices for 'Test41::C' (2 entries).1947// CHECK-47-NEXT: 0 | Test41::C::~C() [complete]1948// CHECK-47-NEXT: 1 | Test41::C::~C() [deleting]1949 struct C : B {};1950 C c;1951}1952 1953namespace Test42 {1954// CHECK-48-LABEL: Vtable for 'Test42::C' (3 entries).1955// CHECK-48-NEXT: 0 | offset_to_top (0)1956// CHECK-48-NEXT: 1 | Test42::C RTTI1957// CHECK-48-NEXT: -- (Test42::A, 0) vtable address --1958// CHECK-48-NEXT: -- (Test42::B, 0) vtable address --1959// CHECK-48-NEXT: -- (Test42::C, 0) vtable address --1960// CHECK-48-NEXT: 2 | void Test42::A::f()1961 1962// CHECK-48-LABEL: Vtable for 'Test42::B' (3 entries).1963// CHECK-48-NEXT: 0 | offset_to_top (0)1964// CHECK-48-NEXT: 1 | Test42::B RTTI1965// CHECK-48-NEXT: -- (Test42::A, 0) vtable address --1966// CHECK-48-NEXT: -- (Test42::B, 0) vtable address --1967// CHECK-48-NEXT: 2 | void Test42::A::f()1968 1969// CHECK-48-LABEL: Vtable for 'Test42::A' (3 entries).1970// CHECK-48-NEXT: 0 | offset_to_top (0)1971// CHECK-48-NEXT: 1 | Test42::A RTTI1972// CHECK-48-NEXT: -- (Test42::A, 0) vtable address --1973// CHECK-48-NEXT: 2 | void Test42::A::f()1974// CHECK-48-LABEL: VTable indices for 'Test42::A' (1 entries).1975// CHECK-48-NEXT: 0 | void Test42::A::f()1976 struct A {1977 virtual void f();1978 };1979 struct B;1980 struct B : A {};1981 struct C : B {};1982 void test() { C c; }1983}1984 1985namespace Test43 {1986 struct A {1987 virtual ~A();1988 };1989 template <class T> struct B : T {};1990 struct C;1991 struct C : A {};1992// CHECK-49-LABEL: Vtable for 'Test43::D' (4 entries).1993// CHECK-49-NEXT: 0 | offset_to_top (0)1994// CHECK-49-NEXT: 1 | Test43::D RTTI1995// CHECK-49-NEXT: -- (Test43::A, 0) vtable address --1996// CHECK-49-NEXT: -- (Test43::B, 0) vtable address --1997// CHECK-49-NEXT: -- (Test43::C, 0) vtable address --1998// CHECK-49-NEXT: -- (Test43::D, 0) vtable address --1999// CHECK-49-NEXT: 2 | Test43::D::~D() [complete]2000// CHECK-49-NEXT: 3 | Test43::D::~D() [deleting]2001// CHECK-49-LABEL: VTable indices for 'D' (2 entries).2002// CHECK-49-NEXT: 0 | Test43::D::~D() [complete]2003// CHECK-49-NEXT: 1 | Test43::D::~D() [deleting]2004 struct D : B<C> {};2005 D d;2006}2007