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. 4 namespace 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 13 namespace 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() 19 struct A { 20 virtual void f(); 21 }; 22 void A::f() { } 23 24 } 25 26 namespace 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 &) 40 struct 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 }; 49 void 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] 61 struct B { 62 virtual void f(); 63 virtual void g() = 0; 64 virtual ~B() = 0; 65 }; 66 void B::f() { } 67 68 } 69 70 namespace 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() 81 struct A { 82 virtual void f(); 83 }; 84 void 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() 93 struct B : A { 94 virtual void f(); 95 virtual void g(); 96 }; 97 void 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() 107 struct C : A { 108 virtual void g(); 109 virtual void h(); 110 }; 111 void 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() 122 struct D : B { 123 virtual void f(); 124 virtual void g(); 125 virtual void h(); 126 }; 127 128 void D::f() { } 129 } 130 131 namespace Test4 { 132 133 // Test non-virtual result adjustments. 134 135 struct R1 { int r1; }; 136 struct R2 { int r2; }; 137 struct R3 : R1, R2 { int r3; }; 138 139 struct 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 152 struct B : A { 153 virtual R3 *f(); 154 }; 155 R3 *B::f() { return 0; } 156 157 // Test virtual result adjustments. 158 struct V1 { int v1; }; 159 struct V2 : virtual V1 { int v1; }; 160 161 struct 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() 173 struct D : C { 174 virtual V2 *f(); 175 }; 176 V2 *D::f() { return 0; }; 177 178 // Virtual result adjustments with an additional non-virtual adjustment. 179 struct 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 190 struct E : A { 191 virtual V3 *f(); 192 }; 193 V3 *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] 205 struct F : A { 206 virtual void g(); 207 virtual R3 *f() = 0; 208 }; 209 void F::g() { } 210 211 } 212 213 namespace Test5 { 214 215 // Simple secondary vtables without 'this' pointer adjustments. 216 struct A { 217 virtual void f(); 218 virtual void g(); 219 int a; 220 }; 221 222 struct B1 : A { 223 virtual void f(); 224 int b1; 225 }; 226 227 struct 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() 247 struct C : B1, B2 { 248 virtual void h(); 249 }; 250 void C::h() { } 251 } 252 253 namespace Test6 { 254 255 // Simple non-virtual 'this' pointer adjustments. 256 struct A1 { 257 virtual void f(); 258 int a; 259 }; 260 261 struct 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] 277 struct C : A1, A2 { 278 virtual void f(); 279 }; 280 void C::f() { } 281 282 } 283 284 namespace 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 289 struct A { 290 virtual void f(); 291 int a; 292 }; 293 294 struct B1 : A { }; 295 struct B2 : A { }; 296 297 struct 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] 318 struct D : C, B1, B2 { 319 virtual void f(); 320 }; 321 void D::f() { } 322 323 } 324 325 namespace 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 330 struct 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() 337 struct B : A { 338 virtual void f(); 339 }; 340 void B::f() { } 341 342 } 343 344 namespace Test9 { 345 346 // Simple test of vbase offsets. 347 348 struct A1 { int a1; }; 349 struct 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() 358 struct B : virtual A1, virtual A2 { 359 int b; 360 361 virtual void f(); 362 }; 363 364 365 void B::f() { } 366 367 } 368 369 namespace Test10 { 370 371 // Test for a bug where we would not emit secondary vtables for bases 372 // of a primary base. 373 struct A1 { virtual void a1(); }; 374 struct 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() 388 struct B : A1, A2 { 389 int b; 390 }; 391 392 struct C : B { 393 virtual void f(); 394 }; 395 void C::f() { } 396 397 } 398 399 namespace Test11 { 400 401 // Very simple test of vtables for virtual bases. 402 struct A1 { int a; }; 403 struct A2 { int b; }; 404 405 struct 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 419 struct C : virtual B { 420 virtual void f(); 421 }; 422 void C::f() { } 423 424 } 425 426 namespace 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() 456 struct A1 { 457 virtual void a1(); 458 int a; 459 }; 460 461 struct A2 { 462 virtual void a2(); 463 int a; 464 }; 465 466 struct A3 { 467 virtual void a3(); 468 int a; 469 }; 470 471 struct A : A1, A2, A3 { 472 virtual void a(); 473 int i; 474 }; 475 476 struct B : virtual A { 477 virtual void f(); 478 479 virtual void a(); 480 }; 481 void B::f() { } 482 483 } 484 485 namespace Test13 { 486 487 // Test that we don't try to emit a vtable for 'A' twice. 488 struct A { 489 virtual void f(); 490 }; 491 492 struct 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() 506 struct C : virtual B, virtual A { 507 virtual void f(); 508 }; 509 void C::f() { } 510 511 } 512 513 namespace Test14 { 514 515 // Verify that we handle A being a non-virtual base of B, which is a virtual base. 516 517 struct A { 518 virtual void f(); 519 }; 520 521 struct B : A { }; 522 523 struct 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() 535 struct D : C, virtual B { 536 virtual void f(); 537 }; 538 void D::f() { } 539 540 } 541 542 namespace Test15 { 543 544 // Test that we don't emit an extra vtable for B since it's a primary base of C. 545 struct A { virtual void a(); }; 546 struct B { virtual void b(); }; 547 548 struct 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() 566 struct D : A, virtual B, virtual C { 567 virtual void f(); 568 }; 569 void D::f() { } 570 571 } 572 573 namespace Test16 { 574 575 // Test that destructors share vcall offsets. 576 577 struct A { virtual ~A(); }; 578 struct B { virtual ~B(); }; 579 580 struct 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] 606 struct D : virtual C { 607 virtual void f(); 608 }; 609 void D::f() { } 610 611 } 612 613 namespace Test17 { 614 615 // Test that we don't mark E::f in the C-in-E vtable as unused. 616 struct A { virtual void f(); }; 617 struct B : virtual A { virtual void f(); }; 618 struct C : virtual A { virtual void f(); }; 619 struct D : virtual B, virtual C { virtual void f(); }; 620 621 // CHECK: Vtable for 'Test17::E' (13 entries). 622 // CHECK-NEXT: 0 | vbase_offset (0) 623 // CHECK-NEXT: 1 | vbase_offset (8) 624 // CHECK-NEXT: 2 | vbase_offset (0) 625 // CHECK-NEXT: 3 | vbase_offset (0) 626 // CHECK-NEXT: 4 | vcall_offset (0) 627 // CHECK-NEXT: 5 | offset_to_top (0) 628 // CHECK-NEXT: 6 | Test17::E RTTI 629 // CHECK-NEXT: -- (Test17::A, 0) vtable address -- 630 // CHECK-NEXT: -- (Test17::B, 0) vtable address -- 631 // CHECK-NEXT: -- (Test17::D, 0) vtable address -- 632 // CHECK-NEXT: -- (Test17::E, 0) vtable address -- 633 // CHECK-NEXT: 7 | void Test17::E::f() 634 // CHECK-NEXT: 8 | vbase_offset (-8) 635 // CHECK-NEXT: 9 | vcall_offset (-8) 636 // CHECK-NEXT: 10 | offset_to_top (-8) 637 // CHECK-NEXT: 11 | Test17::E RTTI 638 // CHECK-NEXT: -- (Test17::C, 8) vtable address -- 639 // CHECK-NEXT: 12 | void Test17::E::f() 640 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 641 class E : virtual D { 642 virtual void f(); 643 }; 644 void E::f() {} 645 646 } 647 648 namespace Test18 { 649 650 // Test that we compute the right 'this' adjustment offsets. 651 652 struct A { 653 virtual void f(); 654 virtual void g(); 655 }; 656 657 struct B : virtual A { 658 virtual void f(); 659 }; 660 661 struct C : A, B { 662 virtual void g(); 663 }; 664 665 // CHECK: Vtable for 'Test18::D' (24 entries). 666 // CHECK-NEXT: 0 | vbase_offset (8) 667 // CHECK-NEXT: 1 | vbase_offset (0) 668 // CHECK-NEXT: 2 | vbase_offset (0) 669 // CHECK-NEXT: 3 | vcall_offset (8) 670 // CHECK-NEXT: 4 | vcall_offset (0) 671 // CHECK-NEXT: 5 | offset_to_top (0) 672 // CHECK-NEXT: 6 | Test18::D RTTI 673 // CHECK-NEXT: -- (Test18::A, 0) vtable address -- 674 // CHECK-NEXT: -- (Test18::B, 0) vtable address -- 675 // CHECK-NEXT: -- (Test18::D, 0) vtable address -- 676 // CHECK-NEXT: 7 | void Test18::D::f() 677 // CHECK-NEXT: 8 | void Test18::C::g() 678 // CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 679 // CHECK-NEXT: 9 | void Test18::D::h() 680 // CHECK-NEXT: 10 | vcall_offset (0) 681 // CHECK-NEXT: 11 | vcall_offset (-8) 682 // CHECK-NEXT: 12 | vbase_offset (-8) 683 // CHECK-NEXT: 13 | offset_to_top (-8) 684 // CHECK-NEXT: 14 | Test18::D RTTI 685 // CHECK-NEXT: -- (Test18::A, 8) vtable address -- 686 // CHECK-NEXT: -- (Test18::C, 8) vtable address -- 687 // CHECK-NEXT: 15 | void Test18::D::f() 688 // CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 689 // CHECK-NEXT: 16 | void Test18::C::g() 690 // CHECK-NEXT: 17 | vbase_offset (-16) 691 // CHECK-NEXT: 18 | vcall_offset (-8) 692 // CHECK-NEXT: 19 | vcall_offset (-16) 693 // CHECK-NEXT: 20 | offset_to_top (-16) 694 // CHECK-NEXT: 21 | Test18::D RTTI 695 // CHECK-NEXT: -- (Test18::B, 16) vtable address -- 696 // CHECK-NEXT: 22 | void Test18::D::f() 697 // CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset] 698 // CHECK-NEXT: 23 | [unused] void Test18::C::g() 699 700 // CHECK: Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries). 701 // CHECK-NEXT: 0 | vbase_offset (0) 702 // CHECK-NEXT: 1 | vcall_offset (0) 703 // CHECK-NEXT: 2 | vcall_offset (0) 704 // CHECK-NEXT: 3 | offset_to_top (0) 705 // CHECK-NEXT: 4 | Test18::B RTTI 706 // CHECK-NEXT: -- (Test18::A, 0) vtable address -- 707 // CHECK-NEXT: -- (Test18::B, 0) vtable address -- 708 // CHECK-NEXT: 5 | void Test18::B::f() 709 // CHECK-NEXT: 6 | void Test18::A::g() 710 711 // CHECK: Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries). 712 // CHECK-NEXT: 0 | vcall_offset (0) 713 // CHECK-NEXT: 1 | vcall_offset (0) 714 // CHECK-NEXT: 2 | vbase_offset (-8) 715 // CHECK-NEXT: 3 | offset_to_top (0) 716 // CHECK-NEXT: 4 | Test18::C RTTI 717 // CHECK-NEXT: -- (Test18::A, 8) vtable address -- 718 // CHECK-NEXT: -- (Test18::C, 8) vtable address -- 719 // CHECK-NEXT: 5 | void Test18::A::f() 720 // CHECK-NEXT: 6 | void Test18::C::g() 721 // CHECK-NEXT: 7 | vbase_offset (-16) 722 // CHECK-NEXT: 8 | vcall_offset (-8) 723 // CHECK-NEXT: 9 | vcall_offset (0) 724 // CHECK-NEXT: 10 | offset_to_top (-8) 725 // CHECK-NEXT: 11 | Test18::C RTTI 726 // CHECK-NEXT: -- (Test18::B, 16) vtable address -- 727 // CHECK-NEXT: 12 | void Test18::B::f() 728 // CHECK-NEXT: 13 | [unused] void Test18::C::g() 729 // CHECK-NEXT: 14 | vcall_offset (8) 730 // CHECK-NEXT: 15 | vcall_offset (16) 731 // CHECK-NEXT: 16 | offset_to_top (8) 732 // CHECK-NEXT: 17 | Test18::C RTTI 733 // CHECK-NEXT: -- (Test18::A, 0) vtable address -- 734 // CHECK-NEXT: 18 | void Test18::B::f() 735 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 736 // CHECK-NEXT: 19 | void Test18::C::g() 737 // CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] 738 739 // CHECK: Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries). 740 // CHECK-NEXT: 0 | vbase_offset (-16) 741 // CHECK-NEXT: 1 | vcall_offset (-16) 742 // CHECK-NEXT: 2 | vcall_offset (0) 743 // CHECK-NEXT: 3 | offset_to_top (0) 744 // CHECK-NEXT: 4 | Test18::B RTTI 745 // CHECK-NEXT: -- (Test18::B, 16) vtable address -- 746 // CHECK-NEXT: 5 | void Test18::B::f() 747 // CHECK-NEXT: 6 | [unused] void Test18::A::g() 748 // CHECK-NEXT: 7 | vcall_offset (0) 749 // CHECK-NEXT: 8 | vcall_offset (16) 750 // CHECK-NEXT: 9 | offset_to_top (16) 751 // CHECK-NEXT: 10 | Test18::B RTTI 752 // CHECK-NEXT: -- (Test18::A, 0) vtable address -- 753 // CHECK-NEXT: 11 | void Test18::B::f() 754 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 755 // CHECK-NEXT: 12 | void Test18::A::g() 756 struct D : virtual B, virtual C, virtual A 757 { 758 virtual void f(); 759 virtual void h(); 760 }; 761 void D::f() {} 762 763 } 764 765 namespace Test19 { 766 767 // Another 'this' adjustment test. 768 769 struct A { 770 int a; 771 772 virtual void f(); 773 }; 774 775 struct B : A { 776 int b; 777 778 virtual void g(); 779 }; 780 781 struct C { 782 virtual void c(); 783 }; 784 785 // CHECK: Vtable for 'Test19::D' (13 entries). 786 // CHECK-NEXT: 0 | vbase_offset (24) 787 // CHECK-NEXT: 1 | offset_to_top (0) 788 // CHECK-NEXT: 2 | Test19::D RTTI 789 // CHECK-NEXT: -- (Test19::C, 0) vtable address -- 790 // CHECK-NEXT: -- (Test19::D, 0) vtable address -- 791 // CHECK-NEXT: 3 | void Test19::C::c() 792 // CHECK-NEXT: 4 | void Test19::D::f() 793 // CHECK-NEXT: 5 | offset_to_top (-8) 794 // CHECK-NEXT: 6 | Test19::D RTTI 795 // CHECK-NEXT: -- (Test19::A, 8) vtable address -- 796 // CHECK-NEXT: -- (Test19::B, 8) vtable address -- 797 // CHECK-NEXT: 7 | void Test19::D::f() 798 // CHECK-NEXT: [this adjustment: -8 non-virtual] 799 // CHECK-NEXT: 8 | void Test19::B::g() 800 // CHECK-NEXT: 9 | vcall_offset (-24) 801 // CHECK-NEXT: 10 | offset_to_top (-24) 802 // CHECK-NEXT: 11 | Test19::D RTTI 803 // CHECK-NEXT: -- (Test19::A, 24) vtable address -- 804 // CHECK-NEXT: 12 | void Test19::D::f() 805 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 806 struct D : C, B, virtual A { 807 virtual void f(); 808 }; 809 void D::f() { } 810 811 } 812 813 namespace Test20 { 814 815 // pure virtual member functions should never have 'this' adjustments. 816 817 struct A { 818 virtual void f() = 0; 819 virtual void g(); 820 }; 821 822 struct B : A { }; 823 824 // CHECK: Vtable for 'Test20::C' (9 entries). 825 // CHECK-NEXT: 0 | offset_to_top (0) 826 // CHECK-NEXT: 1 | Test20::C RTTI 827 // CHECK-NEXT: -- (Test20::A, 0) vtable address -- 828 // CHECK-NEXT: -- (Test20::C, 0) vtable address -- 829 // CHECK-NEXT: 2 | void Test20::C::f() [pure] 830 // CHECK-NEXT: 3 | void Test20::A::g() 831 // CHECK-NEXT: 4 | void Test20::C::h() 832 // CHECK-NEXT: 5 | offset_to_top (-8) 833 // CHECK-NEXT: 6 | Test20::C RTTI 834 // CHECK-NEXT: -- (Test20::A, 8) vtable address -- 835 // CHECK-NEXT: -- (Test20::B, 8) vtable address -- 836 // CHECK-NEXT: 7 | void Test20::C::f() [pure] 837 // CHECK-NEXT: 8 | void Test20::A::g() 838 struct C : A, B { 839 virtual void f() = 0; 840 virtual void h(); 841 }; 842 void C::h() { } 843 844 } 845 846 namespace Test21 { 847 848 // Test that we get vbase offsets right in secondary vtables. 849 struct A { 850 virtual void f(); 851 }; 852 853 struct B : virtual A { }; 854 class C : virtual B { }; 855 class D : virtual C { }; 856 857 class E : virtual C { }; 858 859 // CHECK: Vtable for 'Test21::F' (16 entries). 860 // CHECK-NEXT: 0 | vbase_offset (8) 861 // CHECK-NEXT: 1 | vbase_offset (0) 862 // CHECK-NEXT: 2 | vbase_offset (0) 863 // CHECK-NEXT: 3 | vbase_offset (0) 864 // CHECK-NEXT: 4 | vbase_offset (0) 865 // CHECK-NEXT: 5 | vcall_offset (0) 866 // CHECK-NEXT: 6 | offset_to_top (0) 867 // CHECK-NEXT: 7 | Test21::F RTTI 868 // CHECK-NEXT: -- (Test21::A, 0) vtable address -- 869 // CHECK-NEXT: -- (Test21::B, 0) vtable address -- 870 // CHECK-NEXT: -- (Test21::C, 0) vtable address -- 871 // CHECK-NEXT: -- (Test21::D, 0) vtable address -- 872 // CHECK-NEXT: -- (Test21::F, 0) vtable address -- 873 // CHECK-NEXT: 8 | void Test21::F::f() 874 // CHECK-NEXT: 9 | vbase_offset (-8) 875 // CHECK-NEXT: 10 | vbase_offset (-8) 876 // CHECK-NEXT: 11 | vbase_offset (-8) 877 // CHECK-NEXT: 12 | vcall_offset (-8) 878 // CHECK-NEXT: 13 | offset_to_top (-8) 879 // CHECK-NEXT: 14 | Test21::F RTTI 880 // CHECK-NEXT: -- (Test21::E, 8) vtable address -- 881 // CHECK-NEXT: 15 | [unused] void Test21::F::f() 882 // 883 // CHECK: Virtual base offset offsets for 'Test21::F' (5 entries). 884 // CHECK-NEXT: Test21::A | -32 885 // CHECK-NEXT: Test21::B | -40 886 // CHECK-NEXT: Test21::C | -48 887 // CHECK-NEXT: Test21::D | -56 888 // CHECK-NEXT: Test21::E | -64 889 class F : virtual D, virtual E { 890 virtual void f(); 891 }; 892 void F::f() { } 893 894 } 895 896 namespace Test22 { 897 898 // Very simple construction vtable test. 899 struct V1 { 900 int v1; 901 }; 902 903 struct V2 : virtual V1 { 904 int v2; 905 }; 906 907 // CHECK: Vtable for 'Test22::C' (8 entries). 908 // CHECK-NEXT: 0 | vbase_offset (16) 909 // CHECK-NEXT: 1 | vbase_offset (12) 910 // CHECK-NEXT: 2 | offset_to_top (0) 911 // CHECK-NEXT: 3 | Test22::C RTTI 912 // CHECK-NEXT: -- (Test22::C, 0) vtable address -- 913 // CHECK-NEXT: 4 | void Test22::C::f() 914 // CHECK-NEXT: 5 | vbase_offset (-4) 915 // CHECK-NEXT: 6 | offset_to_top (-16) 916 // CHECK-NEXT: 7 | Test22::C RTTI 917 // CHECK-NEXT: -- (Test22::V2, 16) vtable address -- 918 919 // CHECK: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries). 920 // CHECK-NEXT: 0 | vbase_offset (-4) 921 // CHECK-NEXT: 1 | offset_to_top (0) 922 // CHECK-NEXT: 2 | Test22::V2 RTTI 923 924 struct C : virtual V1, virtual V2 { 925 int c; 926 virtual void f(); 927 }; 928 void C::f() { } 929 930 } 931 932 namespace Test23 { 933 934 struct A { 935 int a; 936 }; 937 938 struct B : virtual A { 939 int b; 940 }; 941 942 struct C : A, virtual B { 943 int c; 944 }; 945 946 // CHECK: Vtable for 'Test23::D' (7 entries). 947 // CHECK-NEXT: 0 | vbase_offset (20) 948 // CHECK-NEXT: 1 | vbase_offset (24) 949 // CHECK-NEXT: 2 | offset_to_top (0) 950 // CHECK-NEXT: 3 | Test23::D RTTI 951 // CHECK-NEXT: -- (Test23::C, 0) vtable address -- 952 // CHECK-NEXT: -- (Test23::D, 0) vtable address -- 953 // CHECK-NEXT: 4 | vbase_offset (-4) 954 // CHECK-NEXT: 5 | offset_to_top (-24) 955 // CHECK-NEXT: 6 | Test23::D RTTI 956 // CHECK-NEXT: -- (Test23::B, 24) vtable address -- 957 958 // CHECK: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries). 959 // CHECK-NEXT: 0 | vbase_offset (20) 960 // CHECK-NEXT: 1 | vbase_offset (24) 961 // CHECK-NEXT: 2 | offset_to_top (0) 962 // CHECK-NEXT: 3 | Test23::C RTTI 963 // CHECK-NEXT: -- (Test23::C, 0) vtable address -- 964 // CHECK-NEXT: 4 | vbase_offset (-4) 965 // CHECK-NEXT: 5 | offset_to_top (-24) 966 // CHECK-NEXT: 6 | Test23::C RTTI 967 // CHECK-NEXT: -- (Test23::B, 24) vtable address -- 968 969 // CHECK: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries). 970 // CHECK-NEXT: 0 | vbase_offset (-4) 971 // CHECK-NEXT: 1 | offset_to_top (0) 972 // CHECK-NEXT: 2 | Test23::B RTTI 973 // CHECK-NEXT: -- (Test23::B, 24) vtable address -- 974 975 struct D : virtual A, virtual B, C { 976 int d; 977 978 void f(); 979 }; 980 void D::f() { } 981 982 } 983 984 namespace Test24 { 985 986 // Another construction vtable test. 987 988 struct A { 989 virtual void f(); 990 }; 991 992 struct B : virtual A { }; 993 struct C : virtual A { }; 994 995 // CHECK: Vtable for 'Test24::D' (10 entries). 996 // CHECK-NEXT: 0 | vbase_offset (0) 997 // CHECK-NEXT: 1 | vcall_offset (0) 998 // CHECK-NEXT: 2 | offset_to_top (0) 999 // CHECK-NEXT: 3 | Test24::D RTTI 1000 // CHECK-NEXT: -- (Test24::A, 0) vtable address -- 1001 // CHECK-NEXT: -- (Test24::B, 0) vtable address -- 1002 // CHECK-NEXT: -- (Test24::D, 0) vtable address -- 1003 // CHECK-NEXT: 4 | void Test24::D::f() 1004 // CHECK-NEXT: 5 | vbase_offset (-8) 1005 // CHECK-NEXT: 6 | vcall_offset (-8) 1006 // CHECK-NEXT: 7 | offset_to_top (-8) 1007 // CHECK-NEXT: 8 | Test24::D RTTI 1008 // CHECK-NEXT: -- (Test24::C, 8) vtable address -- 1009 // CHECK-NEXT: 9 | [unused] void Test24::D::f() 1010 1011 // CHECK: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries). 1012 // CHECK-NEXT: 0 | vbase_offset (0) 1013 // CHECK-NEXT: 1 | vcall_offset (0) 1014 // CHECK-NEXT: 2 | offset_to_top (0) 1015 // CHECK-NEXT: 3 | Test24::B RTTI 1016 // CHECK-NEXT: -- (Test24::A, 0) vtable address -- 1017 // CHECK-NEXT: -- (Test24::B, 0) vtable address -- 1018 // CHECK-NEXT: 4 | void Test24::A::f() 1019 1020 // CHECK: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries). 1021 // CHECK-NEXT: 0 | vbase_offset (-8) 1022 // CHECK-NEXT: 1 | vcall_offset (-8) 1023 // CHECK-NEXT: 2 | offset_to_top (0) 1024 // CHECK-NEXT: 3 | Test24::C RTTI 1025 // CHECK-NEXT: -- (Test24::C, 8) vtable address -- 1026 // CHECK-NEXT: 4 | [unused] void Test24::A::f() 1027 // CHECK-NEXT: 5 | vcall_offset (0) 1028 // CHECK-NEXT: 6 | offset_to_top (8) 1029 // CHECK-NEXT: 7 | Test24::C RTTI 1030 // CHECK-NEXT: -- (Test24::A, 0) vtable address -- 1031 // CHECK-NEXT: 8 | void Test24::A::f() 1032 struct D : B, C { 1033 virtual void f(); 1034 }; 1035 void D::f() { } 1036 1037 } 1038 1039 namespace Test25 { 1040 1041 // This mainly tests that we don't assert on this class hierarchy. 1042 1043 struct V { 1044 virtual void f(); 1045 }; 1046 1047 struct A : virtual V { }; 1048 struct B : virtual V { }; 1049 1050 // CHECK: Vtable for 'Test25::C' (11 entries). 1051 // CHECK-NEXT: 0 | vbase_offset (0) 1052 // CHECK-NEXT: 1 | vcall_offset (0) 1053 // CHECK-NEXT: 2 | offset_to_top (0) 1054 // CHECK-NEXT: 3 | Test25::C RTTI 1055 // CHECK-NEXT: -- (Test25::A, 0) vtable address -- 1056 // CHECK-NEXT: -- (Test25::C, 0) vtable address -- 1057 // CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1058 // CHECK-NEXT: 4 | void Test25::V::f() 1059 // CHECK-NEXT: 5 | void Test25::C::g() 1060 // CHECK-NEXT: 6 | vbase_offset (-8) 1061 // CHECK-NEXT: 7 | vcall_offset (-8) 1062 // CHECK-NEXT: 8 | offset_to_top (-8) 1063 // CHECK-NEXT: 9 | Test25::C RTTI 1064 // CHECK-NEXT: -- (Test25::B, 8) vtable address -- 1065 // CHECK-NEXT: 10 | [unused] void Test25::V::f() 1066 1067 // CHECK: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries). 1068 // CHECK-NEXT: 0 | vbase_offset (0) 1069 // CHECK-NEXT: 1 | vcall_offset (0) 1070 // CHECK-NEXT: 2 | offset_to_top (0) 1071 // CHECK-NEXT: 3 | Test25::A RTTI 1072 // CHECK-NEXT: -- (Test25::A, 0) vtable address -- 1073 // CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1074 // CHECK-NEXT: 4 | void Test25::V::f() 1075 1076 // CHECK: Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries). 1077 // CHECK-NEXT: 0 | vbase_offset (-8) 1078 // CHECK-NEXT: 1 | vcall_offset (-8) 1079 // CHECK-NEXT: 2 | offset_to_top (0) 1080 // CHECK-NEXT: 3 | Test25::B RTTI 1081 // CHECK-NEXT: -- (Test25::B, 8) vtable address -- 1082 // CHECK-NEXT: 4 | [unused] void Test25::V::f() 1083 // CHECK-NEXT: 5 | vcall_offset (0) 1084 // CHECK-NEXT: 6 | offset_to_top (8) 1085 // CHECK-NEXT: 7 | Test25::B RTTI 1086 // CHECK-NEXT: -- (Test25::V, 0) vtable address -- 1087 // CHECK-NEXT: 8 | void Test25::V::f() 1088 struct C : A, virtual V, B { 1089 virtual void g(); 1090 }; 1091 void C::g() { } 1092 1093 } 1094 1095 namespace Test26 { 1096 1097 // Test that we generate the right number of entries in the C-in-D construction vtable, and that 1098 // we don't mark A::a as unused. 1099 1100 struct A { 1101 virtual void a(); 1102 }; 1103 1104 struct B { 1105 virtual void c(); 1106 }; 1107 1108 struct C : virtual A { 1109 virtual void b(); 1110 }; 1111 1112 // CHECK: Vtable for 'Test26::D' (15 entries). 1113 // CHECK-NEXT: 0 | vbase_offset (8) 1114 // CHECK-NEXT: 1 | vbase_offset (8) 1115 // CHECK-NEXT: 2 | vbase_offset (0) 1116 // CHECK-NEXT: 3 | vcall_offset (0) 1117 // CHECK-NEXT: 4 | offset_to_top (0) 1118 // CHECK-NEXT: 5 | Test26::D RTTI 1119 // CHECK-NEXT: -- (Test26::B, 0) vtable address -- 1120 // CHECK-NEXT: -- (Test26::D, 0) vtable address -- 1121 // CHECK-NEXT: 6 | void Test26::B::c() 1122 // CHECK-NEXT: 7 | void Test26::D::d() 1123 // CHECK-NEXT: 8 | vcall_offset (0) 1124 // CHECK-NEXT: 9 | vbase_offset (0) 1125 // CHECK-NEXT: 10 | vcall_offset (0) 1126 // CHECK-NEXT: 11 | offset_to_top (-8) 1127 // CHECK-NEXT: 12 | Test26::D RTTI 1128 // CHECK-NEXT: -- (Test26::A, 8) vtable address -- 1129 // CHECK-NEXT: -- (Test26::C, 8) vtable address -- 1130 // CHECK-NEXT: 13 | void Test26::A::a() 1131 // CHECK-NEXT: 14 | void Test26::C::b() 1132 1133 // CHECK: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries). 1134 // CHECK-NEXT: 0 | vcall_offset (0) 1135 // CHECK-NEXT: 1 | vbase_offset (0) 1136 // CHECK-NEXT: 2 | vcall_offset (0) 1137 // CHECK-NEXT: 3 | offset_to_top (0) 1138 // CHECK-NEXT: 4 | Test26::C RTTI 1139 // CHECK-NEXT: -- (Test26::A, 8) vtable address -- 1140 // CHECK-NEXT: -- (Test26::C, 8) vtable address -- 1141 // CHECK-NEXT: 5 | void Test26::A::a() 1142 // CHECK-NEXT: 6 | void Test26::C::b() 1143 class D : virtual B, virtual C { 1144 virtual void d(); 1145 }; 1146 void D::d() { } 1147 1148 } 1149 1150 namespace Test27 { 1151 1152 // Test that we don't generate a secondary vtable for C in the D-in-E vtable, since 1153 // C doesn't have any virtual bases. 1154 1155 struct A { 1156 virtual void a(); 1157 }; 1158 1159 struct B { 1160 virtual void b(); 1161 }; 1162 1163 struct C { 1164 virtual void c(); 1165 }; 1166 1167 struct D : A, virtual B, C { 1168 virtual void d(); 1169 }; 1170 1171 // CHECK: Vtable for 'Test27::E' (13 entries). 1172 // CHECK-NEXT: 0 | vbase_offset (16) 1173 // CHECK-NEXT: 1 | offset_to_top (0) 1174 // CHECK-NEXT: 2 | Test27::E RTTI 1175 // CHECK-NEXT: -- (Test27::A, 0) vtable address -- 1176 // CHECK-NEXT: -- (Test27::D, 0) vtable address -- 1177 // CHECK-NEXT: -- (Test27::E, 0) vtable address -- 1178 // CHECK-NEXT: 3 | void Test27::A::a() 1179 // CHECK-NEXT: 4 | void Test27::D::d() 1180 // CHECK-NEXT: 5 | void Test27::E::e() 1181 // CHECK-NEXT: 6 | offset_to_top (-8) 1182 // CHECK-NEXT: 7 | Test27::E RTTI 1183 // CHECK-NEXT: -- (Test27::C, 8) vtable address -- 1184 // CHECK-NEXT: 8 | void Test27::C::c() 1185 // CHECK-NEXT: 9 | vcall_offset (0) 1186 // CHECK-NEXT: 10 | offset_to_top (-16) 1187 // CHECK-NEXT: 11 | Test27::E RTTI 1188 // CHECK-NEXT: -- (Test27::B, 16) vtable address -- 1189 // CHECK-NEXT: 12 | void Test27::B::b() 1190 1191 // CHECK: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries). 1192 // CHECK-NEXT: 0 | vbase_offset (16) 1193 // CHECK-NEXT: 1 | offset_to_top (0) 1194 // CHECK-NEXT: 2 | Test27::D RTTI 1195 // CHECK-NEXT: -- (Test27::A, 0) vtable address -- 1196 // CHECK-NEXT: -- (Test27::D, 0) vtable address -- 1197 // CHECK-NEXT: 3 | void Test27::A::a() 1198 // CHECK-NEXT: 4 | void Test27::D::d() 1199 // CHECK-NEXT: 5 | vcall_offset (0) 1200 // CHECK-NEXT: 6 | offset_to_top (-16) 1201 // CHECK-NEXT: 7 | Test27::D RTTI 1202 // CHECK-NEXT: -- (Test27::B, 16) vtable address -- 1203 // CHECK-NEXT: 8 | void Test27::B::b() 1204 struct E : D { 1205 virtual void e(); 1206 }; 1207 void E::e() { } 1208 1209 } 1210 1211 namespace Test28 { 1212 1213 // Check that we do include the vtable for B in the D-in-E construction vtable, since 1214 // B is a base class of a virtual base (C). 1215 1216 struct A { 1217 virtual void a(); 1218 }; 1219 1220 struct B { 1221 virtual void b(); 1222 }; 1223 1224 struct C : A, B { 1225 virtual void c(); 1226 }; 1227 1228 struct D : virtual C { 1229 }; 1230 1231 // CHECK: Vtable for 'Test28::E' (14 entries). 1232 // CHECK-NEXT: 0 | vbase_offset (8) 1233 // CHECK-NEXT: 1 | offset_to_top (0) 1234 // CHECK-NEXT: 2 | Test28::E RTTI 1235 // CHECK-NEXT: -- (Test28::D, 0) vtable address -- 1236 // CHECK-NEXT: -- (Test28::E, 0) vtable address -- 1237 // CHECK-NEXT: 3 | void Test28::E::e() 1238 // CHECK-NEXT: 4 | vcall_offset (8) 1239 // CHECK-NEXT: 5 | vcall_offset (0) 1240 // CHECK-NEXT: 6 | vcall_offset (0) 1241 // CHECK-NEXT: 7 | offset_to_top (-8) 1242 // CHECK-NEXT: 8 | Test28::E RTTI 1243 // CHECK-NEXT: -- (Test28::A, 8) vtable address -- 1244 // CHECK-NEXT: -- (Test28::C, 8) vtable address -- 1245 // CHECK-NEXT: 9 | void Test28::A::a() 1246 // CHECK-NEXT: 10 | void Test28::C::c() 1247 // CHECK-NEXT: 11 | offset_to_top (-16) 1248 // CHECK-NEXT: 12 | Test28::E RTTI 1249 // CHECK-NEXT: -- (Test28::B, 16) vtable address -- 1250 // CHECK-NEXT: 13 | void Test28::B::b() 1251 1252 // CHECK: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries). 1253 // CHECK-NEXT: 0 | vbase_offset (8) 1254 // CHECK-NEXT: 1 | offset_to_top (0) 1255 // CHECK-NEXT: 2 | Test28::D RTTI 1256 // CHECK-NEXT: -- (Test28::D, 0) vtable address -- 1257 // CHECK-NEXT: 3 | vcall_offset (8) 1258 // CHECK-NEXT: 4 | vcall_offset (0) 1259 // CHECK-NEXT: 5 | vcall_offset (0) 1260 // CHECK-NEXT: 6 | offset_to_top (-8) 1261 // CHECK-NEXT: 7 | Test28::D RTTI 1262 // CHECK-NEXT: -- (Test28::A, 8) vtable address -- 1263 // CHECK-NEXT: -- (Test28::C, 8) vtable address -- 1264 // CHECK-NEXT: 8 | void Test28::A::a() 1265 // CHECK-NEXT: 9 | void Test28::C::c() 1266 // CHECK-NEXT: 10 | offset_to_top (-16) 1267 // CHECK-NEXT: 11 | Test28::D RTTI 1268 // CHECK-NEXT: -- (Test28::B, 16) vtable address -- 1269 // CHECK-NEXT: 12 | void Test28::B::b() 1270 struct E : D { 1271 virtual void e(); 1272 }; 1273 void E::e() { } 1274 1275 } 1276 1277 namespace Test29 { 1278 1279 // Test that the covariant return thunk for B::f will have a virtual 'this' adjustment, 1280 // matching gcc. 1281 1282 struct V1 { }; 1283 struct V2 : virtual V1 { }; 1284 1285 struct A { 1286 virtual V1 *f(); 1287 }; 1288 1289 // CHECK: Vtable for 'Test29::B' (6 entries). 1290 // CHECK-NEXT: 0 | vbase_offset (0) 1291 // CHECK-NEXT: 1 | vcall_offset (0) 1292 // CHECK-NEXT: 2 | offset_to_top (0) 1293 // CHECK-NEXT: 3 | Test29::B RTTI 1294 // CHECK-NEXT: -- (Test29::A, 0) vtable address -- 1295 // CHECK-NEXT: -- (Test29::B, 0) vtable address -- 1296 // CHECK-NEXT: 4 | Test29::V2 *Test29::B::f() 1297 // CHECK-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset] 1298 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 1299 // CHECK-NEXT: 5 | Test29::V2 *Test29::B::f() 1300 struct B : virtual A { 1301 virtual V2 *f(); 1302 }; 1303 V2 *B::f() { return 0; } 1304 1305 } 1306 1307 namespace Test30 { 1308 1309 // Test that we don't assert when generating a vtable for F. 1310 struct A { }; 1311 1312 struct B : virtual A { 1313 int i; 1314 }; 1315 1316 struct C { 1317 virtual void f(); 1318 }; 1319 1320 struct D : virtual C, B { }; 1321 struct E : virtual D { }; 1322 1323 struct F : E { 1324 virtual void f(); 1325 }; 1326 void F::f() { } 1327 1328 } 1329 1330 namespace Test31 { 1331 1332 // Test that we don't add D::f twice to the primary vtable. 1333 struct A { 1334 int a; 1335 }; 1336 1337 struct B { 1338 virtual void f(); 1339 }; 1340 1341 struct C : A, virtual B { 1342 virtual void f(); 1343 }; 1344 1345 // CHECK: Vtable for 'Test31::D' (11 entries). 1346 // CHECK-NEXT: 0 | vbase_offset (0) 1347 // CHECK-NEXT: 1 | vbase_offset (8) 1348 // CHECK-NEXT: 2 | vcall_offset (0) 1349 // CHECK-NEXT: 3 | offset_to_top (0) 1350 // CHECK-NEXT: 4 | Test31::D RTTI 1351 // CHECK-NEXT: -- (Test31::B, 0) vtable address -- 1352 // CHECK-NEXT: -- (Test31::D, 0) vtable address -- 1353 // CHECK-NEXT: 5 | void Test31::D::f() 1354 // CHECK-NEXT: 6 | vbase_offset (-8) 1355 // CHECK-NEXT: 7 | vcall_offset (-8) 1356 // CHECK-NEXT: 8 | offset_to_top (-8) 1357 // CHECK-NEXT: 9 | Test31::D RTTI 1358 // CHECK-NEXT: -- (Test31::C, 8) vtable address -- 1359 // CHECK-NEXT: 10 | void Test31::D::f() 1360 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 1361 struct D : virtual C { 1362 virtual void f(); 1363 }; 1364 void D::f() { } 1365 1366 } 1367 1368 namespace Test32 { 1369 1370 // Check that we correctly lay out the virtual bases of 'Test32::D'. 1371 1372 struct A { 1373 virtual void f(); 1374 }; 1375 1376 struct B : virtual A { }; 1377 struct C : A, virtual B { }; 1378 struct D : virtual B { }; 1379 1380 // CHECK: Virtual base offset offsets for 'Test32::E' (3 entries). 1381 // CHECK-NEXT: Test32::A | -32 1382 // CHECK-NEXT: Test32::B | -24 1383 // CHECK-NEXT: Test32::D | -40 1384 struct E : C, virtual D { 1385 virtual void f(); 1386 }; 1387 void E::f() { } 1388 1389 } 1390 1391 namespace Test33 { 1392 1393 // Test that we don't emit too many vcall offsets in 'Test32::F'. 1394 1395 struct A { 1396 virtual void a(); 1397 }; 1398 1399 struct B { 1400 virtual void b(); 1401 }; 1402 1403 struct C : virtual A, virtual B { 1404 virtual void c(); 1405 }; 1406 1407 struct D : virtual C { }; 1408 1409 struct E : A, D { 1410 virtual void e(); 1411 }; 1412 1413 // CHECK: Vtable for 'Test33::F' (30 entries). 1414 // CHECK-NEXT: 0 | vbase_offset (24) 1415 // CHECK-NEXT: 1 | vbase_offset (16) 1416 // CHECK-NEXT: 2 | vbase_offset (16) 1417 // CHECK-NEXT: 3 | vbase_offset (8) 1418 // CHECK-NEXT: 4 | offset_to_top (0) 1419 // CHECK-NEXT: 5 | Test33::F RTTI 1420 // CHECK-NEXT: -- (Test33::A, 0) vtable address -- 1421 // CHECK-NEXT: -- (Test33::F, 0) vtable address -- 1422 // CHECK-NEXT: 6 | void Test33::A::a() 1423 // CHECK-NEXT: 7 | void Test33::F::f() 1424 // CHECK-NEXT: 8 | vcall_offset (0) 1425 // CHECK-NEXT: 9 | vcall_offset (0) 1426 // CHECK-NEXT: 10 | vbase_offset (16) 1427 // CHECK-NEXT: 11 | vbase_offset (8) 1428 // CHECK-NEXT: 12 | vbase_offset (8) 1429 // CHECK-NEXT: 13 | offset_to_top (-8) 1430 // CHECK-NEXT: 14 | Test33::F RTTI 1431 // CHECK-NEXT: -- (Test33::A, 8) vtable address -- 1432 // CHECK-NEXT: -- (Test33::E, 8) vtable address -- 1433 // CHECK-NEXT: 15 | void Test33::A::a() 1434 // CHECK-NEXT: 16 | void Test33::E::e() 1435 // CHECK-NEXT: 17 | vbase_offset (0) 1436 // CHECK-NEXT: 18 | vcall_offset (0) 1437 // CHECK-NEXT: 19 | vbase_offset (8) 1438 // CHECK-NEXT: 20 | vbase_offset (0) 1439 // CHECK-NEXT: 21 | vcall_offset (0) 1440 // CHECK-NEXT: 22 | offset_to_top (-16) 1441 // CHECK-NEXT: 23 | Test33::F RTTI 1442 // CHECK-NEXT: -- (Test33::A, 16) vtable address -- 1443 // CHECK-NEXT: -- (Test33::C, 16) vtable address -- 1444 // CHECK-NEXT: -- (Test33::D, 16) vtable address -- 1445 // CHECK-NEXT: 24 | void Test33::A::a() 1446 // CHECK-NEXT: 25 | void Test33::C::c() 1447 // CHECK-NEXT: 26 | vcall_offset (0) 1448 // CHECK-NEXT: 27 | offset_to_top (-24) 1449 // CHECK-NEXT: 28 | Test33::F RTTI 1450 // CHECK-NEXT: -- (Test33::B, 24) vtable address -- 1451 // CHECK-NEXT: 29 | void Test33::B::b() 1452 struct F : virtual E, A { 1453 virtual void f(); 1454 }; 1455 void F::f() { } 1456 1457 } 1458 1459 namespace Test34 { 1460 1461 // Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly. 1462 1463 struct A { 1464 virtual void a(); 1465 }; 1466 struct B : virtual A { }; 1467 1468 struct C : B, A { 1469 virtual void c(); 1470 }; 1471 1472 struct D : A, C { }; 1473 1474 struct E : virtual D { 1475 virtual void e(); 1476 }; 1477 1478 // CHECK: Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries). 1479 // CHECK-NEXT: 0 | vbase_offset (0) 1480 // CHECK-NEXT: 1 | vbase_offset (8) 1481 // CHECK-NEXT: 2 | vcall_offset (0) 1482 // CHECK-NEXT: 3 | offset_to_top (0) 1483 // CHECK-NEXT: 4 | Test34::E RTTI 1484 // CHECK-NEXT: -- (Test34::A, 0) vtable address -- 1485 // CHECK-NEXT: -- (Test34::E, 0) vtable address -- 1486 // CHECK-NEXT: 5 | void Test34::A::a() 1487 // CHECK-NEXT: 6 | void Test34::E::e() 1488 // CHECK-NEXT: 7 | vcall_offset (8) 1489 // CHECK-NEXT: 8 | vcall_offset (0) 1490 // CHECK-NEXT: 9 | vbase_offset (-8) 1491 // CHECK-NEXT: 10 | offset_to_top (-8) 1492 // CHECK-NEXT: 11 | Test34::E RTTI 1493 // CHECK-NEXT: -- (Test34::A, 8) vtable address -- 1494 // CHECK-NEXT: -- (Test34::D, 8) vtable address -- 1495 // CHECK-NEXT: 12 | void Test34::A::a() 1496 // CHECK-NEXT: 13 | vbase_offset (-16) 1497 // CHECK-NEXT: 14 | vcall_offset (-16) 1498 // CHECK-NEXT: 15 | offset_to_top (-16) 1499 // CHECK-NEXT: 16 | Test34::E RTTI 1500 // CHECK-NEXT: -- (Test34::B, 16) vtable address -- 1501 // CHECK-NEXT: -- (Test34::C, 16) vtable address -- 1502 // CHECK-NEXT: 17 | [unused] void Test34::A::a() 1503 // CHECK-NEXT: 18 | void Test34::C::c() 1504 // CHECK-NEXT: 19 | offset_to_top (-24) 1505 // CHECK-NEXT: 20 | Test34::E RTTI 1506 // CHECK-NEXT: -- (Test34::A, 24) vtable address -- 1507 // CHECK-NEXT: 21 | void Test34::A::a() 1508 struct F : E { 1509 virtual void f(); 1510 }; 1511 void F::f() { } 1512 1513 } 1514 1515 namespace Test35 { 1516 1517 // Test that we lay out the virtual bases of 'Test35::H' in the correct order. 1518 1519 struct A { 1520 virtual void a(); 1521 1522 int i; 1523 }; 1524 1525 struct B : virtual A { 1526 virtual void b(); 1527 }; 1528 1529 struct C { 1530 virtual void c(); 1531 }; 1532 1533 struct D : C, virtual B { 1534 virtual void d(); 1535 }; 1536 1537 struct E : D { 1538 virtual void e(); 1539 1540 bool b; 1541 }; 1542 1543 struct F : virtual D { }; 1544 struct G : virtual E { }; 1545 1546 // CHECK: Vtable for 'Test35::H' (32 entries). 1547 // CHECK-NEXT: 0 | vbase_offset (32) 1548 // CHECK-NEXT: 1 | vbase_offset (0) 1549 // CHECK-NEXT: 2 | vcall_offset (0) 1550 // CHECK-NEXT: 3 | vcall_offset (0) 1551 // CHECK-NEXT: 4 | vbase_offset (16) 1552 // CHECK-NEXT: 5 | vbase_offset (8) 1553 // CHECK-NEXT: 6 | offset_to_top (0) 1554 // CHECK-NEXT: 7 | Test35::H RTTI 1555 // CHECK-NEXT: -- (Test35::C, 0) vtable address -- 1556 // CHECK-NEXT: -- (Test35::D, 0) vtable address -- 1557 // CHECK-NEXT: -- (Test35::F, 0) vtable address -- 1558 // CHECK-NEXT: -- (Test35::H, 0) vtable address -- 1559 // CHECK-NEXT: 8 | void Test35::C::c() 1560 // CHECK-NEXT: 9 | void Test35::D::d() 1561 // CHECK-NEXT: 10 | void Test35::H::h() 1562 // CHECK-NEXT: 11 | vbase_offset (0) 1563 // CHECK-NEXT: 12 | vbase_offset (24) 1564 // CHECK-NEXT: 13 | vcall_offset (0) 1565 // CHECK-NEXT: 14 | vbase_offset (8) 1566 // CHECK-NEXT: 15 | offset_to_top (-8) 1567 // CHECK-NEXT: 16 | Test35::H RTTI 1568 // CHECK-NEXT: -- (Test35::B, 8) vtable address -- 1569 // CHECK-NEXT: -- (Test35::G, 8) vtable address -- 1570 // CHECK-NEXT: 17 | void Test35::B::b() 1571 // CHECK-NEXT: 18 | vcall_offset (0) 1572 // CHECK-NEXT: 19 | offset_to_top (-16) 1573 // CHECK-NEXT: 20 | Test35::H RTTI 1574 // CHECK-NEXT: -- (Test35::A, 16) vtable address -- 1575 // CHECK-NEXT: 21 | void Test35::A::a() 1576 // CHECK-NEXT: 22 | vcall_offset (0) 1577 // CHECK-NEXT: 23 | vcall_offset (0) 1578 // CHECK-NEXT: 24 | vcall_offset (0) 1579 // CHECK-NEXT: 25 | vbase_offset (-16) 1580 // CHECK-NEXT: 26 | vbase_offset (-24) 1581 // CHECK-NEXT: 27 | offset_to_top (-32) 1582 // CHECK-NEXT: 28 | Test35::H RTTI 1583 // CHECK-NEXT: -- (Test35::C, 32) vtable address -- 1584 // CHECK-NEXT: -- (Test35::D, 32) vtable address -- 1585 // CHECK-NEXT: -- (Test35::E, 32) vtable address -- 1586 // CHECK-NEXT: 29 | void Test35::C::c() 1587 // CHECK-NEXT: 30 | void Test35::D::d() 1588 // CHECK-NEXT: 31 | void Test35::E::e() 1589 1590 // CHECK: Virtual base offset offsets for 'Test35::H' (4 entries). 1591 // CHECK-NEXT: Test35::A | -32 1592 // CHECK-NEXT: Test35::B | -24 1593 // CHECK-NEXT: Test35::D | -56 1594 // CHECK-NEXT: Test35::E | -64 1595 struct H : F, G { 1596 virtual void h(); 1597 }; 1598 void H::h() { } 1599 1600 } 1601 1602 namespace Test36 { 1603 1604 // Test that we don't mark B::f as unused in the vtable for D. 1605 1606 struct A { 1607 virtual void f(); 1608 }; 1609 1610 struct B : virtual A { }; 1611 1612 struct C : virtual A { 1613 virtual void f(); 1614 }; 1615 1616 // CHECK: Vtable for 'Test36::D' (12 entries). 1617 // CHECK-NEXT: 0 | vbase_offset (8) 1618 // CHECK-NEXT: 1 | vbase_offset (8) 1619 // CHECK-NEXT: 2 | vcall_offset (0) 1620 // CHECK-NEXT: 3 | offset_to_top (0) 1621 // CHECK-NEXT: 4 | Test36::D RTTI 1622 // CHECK-NEXT: -- (Test36::C, 0) vtable address -- 1623 // CHECK-NEXT: -- (Test36::D, 0) vtable address -- 1624 // CHECK-NEXT: 5 | void Test36::C::f() 1625 // CHECK-NEXT: 6 | void Test36::D::g() 1626 // CHECK-NEXT: 7 | vbase_offset (0) 1627 // CHECK-NEXT: 8 | vcall_offset (-8) 1628 // CHECK-NEXT: 9 | offset_to_top (-8) 1629 // CHECK-NEXT: 10 | Test36::D RTTI 1630 // CHECK-NEXT: -- (Test36::A, 8) vtable address -- 1631 // CHECK-NEXT: -- (Test36::B, 8) vtable address -- 1632 // CHECK-NEXT: 11 | void Test36::C::f() 1633 // CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] 1634 struct D : virtual B, C { 1635 virtual void g(); 1636 }; 1637 void D::g() { } 1638 1639 } 1640