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