vtable-layout-abi-examples.cpp revision 014a358058fab46a84718b1424e40ad5a8068827
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s 2 3/// Examples from the Itanium C++ ABI specification. 4/// http://www.codesourcery.com/public/cxx-abi/ 5 6namespace Test1 { 7 8// This is from http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html 9 10// CHECK: Vtable for 'Test1::A' (5 entries). 11// CHECK-NEXT: 0 | offset_to_top (0) 12// CHECK-NEXT: 1 | Test1::A RTTI 13// CHECK-NEXT: -- (Test1::A, 0) vtable address -- 14// CHECK-NEXT: 2 | void Test1::A::f() 15// CHECK-NEXT: 3 | void Test1::A::g() 16// CHECK-NEXT: 4 | void Test1::A::h() 17struct A { 18 virtual void f (); 19 virtual void g (); 20 virtual void h (); 21 int ia; 22}; 23void A::f() {} 24 25// CHECK: Vtable for 'Test1::B' (13 entries). 26// CHECK-NEXT: 0 | vbase_offset (16) 27// CHECK-NEXT: 1 | offset_to_top (0) 28// CHECK-NEXT: 2 | Test1::B RTTI 29// CHECK-NEXT: -- (Test1::B, 0) vtable address -- 30// CHECK-NEXT: 3 | void Test1::B::f() 31// CHECK-NEXT: 4 | void Test1::B::h() 32// CHECK-NEXT: 5 | vcall_offset (-16) 33// CHECK-NEXT: 6 | vcall_offset (0) 34// CHECK-NEXT: 7 | vcall_offset (-16) 35// CHECK-NEXT: 8 | offset_to_top (-16) 36// CHECK-NEXT: 9 | Test1::B RTTI 37// CHECK-NEXT: -- (Test1::A, 16) vtable address -- 38// CHECK-NEXT: 10 | void Test1::B::f() 39// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 40// CHECK-NEXT: 11 | void Test1::A::g() 41// CHECK-NEXT: 12 | void Test1::B::h() 42// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] 43struct B: public virtual A { 44 void f (); 45 void h (); 46 int ib; 47}; 48void B::f() {} 49 50// CHECK: Vtable for 'Test1::C' (13 entries). 51// CHECK-NEXT: 0 | vbase_offset (16) 52// CHECK-NEXT: 1 | offset_to_top (0) 53// CHECK-NEXT: 2 | Test1::C RTTI 54// CHECK-NEXT: -- (Test1::C, 0) vtable address -- 55// CHECK-NEXT: 3 | void Test1::C::g() 56// CHECK-NEXT: 4 | void Test1::C::h() 57// CHECK-NEXT: 5 | vcall_offset (-16) 58// CHECK-NEXT: 6 | vcall_offset (-16) 59// CHECK-NEXT: 7 | vcall_offset (0) 60// CHECK-NEXT: 8 | offset_to_top (-16) 61// CHECK-NEXT: 9 | Test1::C RTTI 62// CHECK-NEXT: -- (Test1::A, 16) vtable address -- 63// CHECK-NEXT: 10 | void Test1::A::f() 64// CHECK-NEXT: 11 | void Test1::C::g() 65// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 66// CHECK-NEXT: 12 | void Test1::C::h() 67// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] 68struct C: public virtual A { 69 void g (); 70 void h (); 71 int ic; 72}; 73void C::g() {} 74 75// CHECK: Vtable for 'Test1::D' (18 entries). 76// CHECK-NEXT: 0 | vbase_offset (32) 77// CHECK-NEXT: 1 | offset_to_top (0) 78// CHECK-NEXT: 2 | Test1::D RTTI 79// CHECK-NEXT: -- (Test1::B, 0) vtable address -- 80// CHECK-NEXT: -- (Test1::D, 0) vtable address -- 81// CHECK-NEXT: 3 | void Test1::B::f() 82// CHECK-NEXT: 4 | void Test1::D::h() 83// CHECK-NEXT: 5 | vbase_offset (16) 84// CHECK-NEXT: 6 | offset_to_top (-16) 85// CHECK-NEXT: 7 | Test1::D RTTI 86// CHECK-NEXT: -- (Test1::C, 16) vtable address -- 87// CHECK-NEXT: 8 | void Test1::C::g() 88// CHECK-NEXT: 9 | void Test1::D::h() 89// CHECK-NEXT: [this adjustment: -16 non-virtual] 90// CHECK-NEXT: 10 | vcall_offset (-32) 91// CHECK-NEXT: 11 | vcall_offset (-16) 92// CHECK-NEXT: 12 | vcall_offset (-32) 93// CHECK-NEXT: 13 | offset_to_top (-32) 94// CHECK-NEXT: 14 | Test1::D RTTI 95// CHECK-NEXT: -- (Test1::A, 32) vtable address -- 96// CHECK-NEXT: 15 | void Test1::B::f() 97// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 98// CHECK-NEXT: 16 | void Test1::C::g() 99// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 100// CHECK-NEXT: 17 | void Test1::D::h() 101// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] 102struct D: public B, public C { 103 void h (); 104 int id; 105}; 106void D::h() { } 107 108struct X { 109 int ix; 110 virtual void x(); 111}; 112 113// CHECK: Vtable for 'Test1::E' (24 entries). 114// CHECK-NEXT: 0 | vbase_offset (56) 115// CHECK-NEXT: 1 | offset_to_top (0) 116// CHECK-NEXT: 2 | Test1::E RTTI 117// CHECK-NEXT: -- (Test1::E, 0) vtable address -- 118// CHECK-NEXT: -- (Test1::X, 0) vtable address -- 119// CHECK-NEXT: 3 | void Test1::X::x() 120// CHECK-NEXT: 4 | void Test1::E::f() 121// CHECK-NEXT: 5 | void Test1::E::h() 122// CHECK-NEXT: 6 | vbase_offset (40) 123// CHECK-NEXT: 7 | offset_to_top (-16) 124// CHECK-NEXT: 8 | Test1::E RTTI 125// CHECK-NEXT: -- (Test1::B, 16) vtable address -- 126// CHECK-NEXT: -- (Test1::D, 16) vtable address -- 127// CHECK-NEXT: 9 | void Test1::E::f() 128// CHECK-NEXT: [this adjustment: -16 non-virtual] 129// CHECK-NEXT: 10 | void Test1::E::h() 130// CHECK-NEXT: [this adjustment: -16 non-virtual] 131// CHECK-NEXT: 11 | vbase_offset (24) 132// CHECK-NEXT: 12 | offset_to_top (-32) 133// CHECK-NEXT: 13 | Test1::E RTTI 134// CHECK-NEXT: -- (Test1::C, 32) vtable address -- 135// CHECK-NEXT: 14 | void Test1::C::g() 136// CHECK-NEXT: 15 | void Test1::E::h() 137// CHECK-NEXT: [this adjustment: -32 non-virtual] 138// CHECK-NEXT: 16 | vcall_offset (-56) 139// CHECK-NEXT: 17 | vcall_offset (-24) 140// CHECK-NEXT: 18 | vcall_offset (-56) 141// CHECK-NEXT: 19 | offset_to_top (-56) 142// CHECK-NEXT: 20 | Test1::E RTTI 143// CHECK-NEXT: -- (Test1::A, 56) vtable address -- 144// CHECK-NEXT: 21 | void Test1::E::f() 145// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 146// CHECK-NEXT: 22 | void Test1::C::g() 147// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 148// CHECK-NEXT: 23 | void Test1::E::h() 149// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] 150struct E : X, D { 151 int ie; 152 void f(); 153 void h (); 154}; 155void E::f() { } 156 157} 158 159namespace Test2 { 160 161// From http://www.codesourcery.com/public/cxx-abi/abi.html#class-types. 162 163struct A { virtual void f(); }; 164struct B : virtual public A { int i; }; 165struct C : virtual public A { int j; }; 166 167// CHECK: Vtable for 'Test2::D' (11 entries). 168// CHECK-NEXT: 0 | vbase_offset (0) 169// CHECK-NEXT: 1 | vcall_offset (0) 170// CHECK-NEXT: 2 | offset_to_top (0) 171// CHECK-NEXT: 3 | Test2::D RTTI 172// CHECK-NEXT: -- (Test2::A, 0) vtable address -- 173// CHECK-NEXT: -- (Test2::B, 0) vtable address -- 174// CHECK-NEXT: -- (Test2::D, 0) vtable address -- 175// CHECK-NEXT: 4 | void Test2::A::f() 176// CHECK-NEXT: 5 | void Test2::D::d() 177// CHECK-NEXT: 6 | vbase_offset (-16) 178// CHECK-NEXT: 7 | vcall_offset (-16) 179// CHECK-NEXT: 8 | offset_to_top (-16) 180// CHECK-NEXT: 9 | Test2::D RTTI 181// CHECK-NEXT: -- (Test2::C, 16) vtable address -- 182// CHECK-NEXT: 10 | [unused] void Test2::A::f() 183struct D : public B, public C { 184 virtual void d(); 185}; 186void D::d() { } 187 188} 189 190namespace Test3 { 191 192// From http://www.codesourcery.com/public/cxx-abi/abi-examples.html#vtable-ctor 193 194struct V1 { 195 int v1; 196 virtual void f(); 197}; 198 199struct V2 : virtual V1 { 200 int v2; 201 virtual void f(); 202}; 203 204// CHECK: Vtable for 'Test3::C' (14 entries). 205// CHECK-NEXT: 0 | vbase_offset (32) 206// CHECK-NEXT: 1 | vbase_offset (16) 207// CHECK-NEXT: 2 | offset_to_top (0) 208// CHECK-NEXT: 3 | Test3::C RTTI 209// CHECK-NEXT: -- (Test3::C, 0) vtable address -- 210// CHECK-NEXT: 4 | void Test3::C::f() 211// CHECK-NEXT: 5 | vcall_offset (-16) 212// CHECK-NEXT: 6 | offset_to_top (-16) 213// CHECK-NEXT: 7 | Test3::C RTTI 214// CHECK-NEXT: -- (Test3::V1, 16) vtable address -- 215// CHECK-NEXT: 8 | void Test3::C::f() 216// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 217// CHECK-NEXT: 9 | vcall_offset (-32) 218// CHECK-NEXT: 10 | vbase_offset (-16) 219// CHECK-NEXT: 11 | offset_to_top (-32) 220// CHECK-NEXT: 12 | Test3::C RTTI 221// CHECK-NEXT: -- (Test3::V2, 32) vtable address -- 222// CHECK-NEXT: 13 | void Test3::C::f() 223// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 224 225// CHECK: Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries). 226// CHECK-NEXT: 0 | vcall_offset (0) 227// CHECK-NEXT: 1 | vbase_offset (-16) 228// CHECK-NEXT: 2 | offset_to_top (0) 229// CHECK-NEXT: 3 | Test3::V2 RTTI 230// CHECK-NEXT: -- (Test3::V2, 32) vtable address -- 231// CHECK-NEXT: 4 | void Test3::V2::f() 232// CHECK-NEXT: 5 | vcall_offset (16) 233// CHECK-NEXT: 6 | offset_to_top (16) 234// CHECK-NEXT: 7 | Test3::V2 RTTI 235// CHECK-NEXT: -- (Test3::V1, 16) vtable address -- 236// CHECK-NEXT: 8 | void Test3::V2::f() 237// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 238struct C : virtual V1, virtual V2 { 239 int c; 240 virtual void f(); 241}; 242void C::f() { } 243 244struct B { 245 int b; 246}; 247 248// CHECK: Vtable for 'Test3::D' (15 entries). 249// CHECK-NEXT: 0 | vbase_offset (40) 250// CHECK-NEXT: 1 | vbase_offset (24) 251// CHECK-NEXT: 2 | offset_to_top (0) 252// CHECK-NEXT: 3 | Test3::D RTTI 253// CHECK-NEXT: -- (Test3::C, 0) vtable address -- 254// CHECK-NEXT: -- (Test3::D, 0) vtable address -- 255// CHECK-NEXT: 4 | void Test3::C::f() 256// CHECK-NEXT: 5 | void Test3::D::g() 257// CHECK-NEXT: 6 | vcall_offset (-24) 258// CHECK-NEXT: 7 | offset_to_top (-24) 259// CHECK-NEXT: 8 | Test3::D RTTI 260// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- 261// CHECK-NEXT: 9 | void Test3::C::f() 262// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 263// CHECK-NEXT: 10 | vcall_offset (-40) 264// CHECK-NEXT: 11 | vbase_offset (-16) 265// CHECK-NEXT: 12 | offset_to_top (-40) 266// CHECK-NEXT: 13 | Test3::D RTTI 267// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- 268// CHECK-NEXT: 14 | void Test3::C::f() 269// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 270 271// CHECK: Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries). 272// CHECK-NEXT: 0 | vbase_offset (40) 273// CHECK-NEXT: 1 | vbase_offset (24) 274// CHECK-NEXT: 2 | offset_to_top (0) 275// CHECK-NEXT: 3 | Test3::C RTTI 276// CHECK-NEXT: -- (Test3::C, 0) vtable address -- 277// CHECK-NEXT: 4 | void Test3::C::f() 278// CHECK-NEXT: 5 | vcall_offset (-24) 279// CHECK-NEXT: 6 | offset_to_top (-24) 280// CHECK-NEXT: 7 | Test3::C RTTI 281// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- 282// CHECK-NEXT: 8 | void Test3::C::f() 283// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 284// CHECK-NEXT: 9 | vcall_offset (-40) 285// CHECK-NEXT: 10 | vbase_offset (-16) 286// CHECK-NEXT: 11 | offset_to_top (-40) 287// CHECK-NEXT: 12 | Test3::C RTTI 288// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- 289// CHECK-NEXT: 13 | void Test3::C::f() 290// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 291 292// CHECK: Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries). 293// CHECK-NEXT: 0 | vcall_offset (0) 294// CHECK-NEXT: 1 | vbase_offset (-16) 295// CHECK-NEXT: 2 | offset_to_top (0) 296// CHECK-NEXT: 3 | Test3::V2 RTTI 297// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- 298// CHECK-NEXT: 4 | void Test3::V2::f() 299// CHECK-NEXT: 5 | vcall_offset (16) 300// CHECK-NEXT: 6 | offset_to_top (16) 301// CHECK-NEXT: 7 | Test3::V2 RTTI 302// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- 303// CHECK-NEXT: 8 | void Test3::V2::f() 304// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 305struct D : B, C { 306 int d; 307 virtual void g(); 308}; 309void D::g() { } 310 311} 312