We were mistakenly marking morally virtual bases as being uninteresting. Fix this.

llvm-svn: 98180
This commit is contained in:
Anders Carlsson 2010-03-10 19:39:11 +00:00
parent 2734ebd37f
commit 115b4756b5
2 changed files with 80 additions and 5 deletions

View File

@ -1235,7 +1235,11 @@ private:
/// LayoutSecondaryVtables - Layout the secondary vtables for the given base
/// subobject.
void LayoutSecondaryVtables(BaseSubobject Base, uint64_t OffsetInLayoutClass);
///
/// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
/// or a direct or indirect base of a virtual base.
void LayoutSecondaryVtables(BaseSubobject Base, bool BaseIsMorallyVirtual,
uint64_t OffsetInLayoutClass);
/// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
/// class hierarchy.
@ -1772,11 +1776,16 @@ VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base,
AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
}
bool BaseIsMorallyVirtual = BaseIsVirtual;
if (isBuildingConstructorVtable() && Base.getBase() == MostDerivedClass)
BaseIsMorallyVirtual = false;
// Layout secondary vtables.
LayoutSecondaryVtables(Base, OffsetInLayoutClass);
LayoutSecondaryVtables(Base, BaseIsMorallyVirtual, OffsetInLayoutClass);
}
void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
bool BaseIsMorallyVirtual,
uint64_t OffsetInLayoutClass) {
// Itanium C++ ABI 2.5.2:
// Following the primary virtual table of a derived class are secondary
@ -1806,10 +1815,9 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
// tables, which will therefore not be present in the construction
// virtual table group, even though the subobject virtual tables are
// present in the main virtual table group for the complete object.
if (!BaseDecl->getNumVBases()) {
if (!BaseIsMorallyVirtual && !BaseDecl->getNumVBases())
continue;
}
}
// Get the base offset of this base.
uint64_t RelativeBaseOffset = Layout.getBaseClassOffset(BaseDecl);
@ -1821,7 +1829,7 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
// to emit secondary vtables for other bases of this base.
if (BaseDecl == PrimaryBase) {
LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
BaseOffsetInLayoutClass);
BaseIsMorallyVirtual, BaseOffsetInLayoutClass);
continue;
}

View File

@ -1150,4 +1150,71 @@ struct E : D {
virtual void e();
};
void E::e() { }
}
namespace Test28 {
// Check that we do include the vtable for B in the D-in-E construction vtable, since
// B is a base class of a virtual base (C).
struct A {
virtual void a();
};
struct B {
virtual void b();
};
struct C : A, B {
virtual void c();
};
struct D : virtual C {
};
// CHECK: Vtable for 'Test28::E' (14 entries).
// CHECK-NEXT: 0 | vbase_offset (8)
// CHECK-NEXT: 1 | offset_to_top (0)
// CHECK-NEXT: 2 | Test28::E RTTI
// CHECK-NEXT: -- (Test28::D, 0) vtable address --
// CHECK-NEXT: -- (Test28::E, 0) vtable address --
// CHECK-NEXT: 3 | void Test28::E::e()
// CHECK-NEXT: 4 | vcall_offset (8)
// CHECK-NEXT: 5 | vcall_offset (0)
// CHECK-NEXT: 6 | vcall_offset (0)
// CHECK-NEXT: 7 | offset_to_top (-8)
// CHECK-NEXT: 8 | Test28::E RTTI
// CHECK-NEXT: -- (Test28::A, 8) vtable address --
// CHECK-NEXT: -- (Test28::C, 8) vtable address --
// CHECK-NEXT: 9 | void Test28::A::a()
// CHECK-NEXT: 10 | void Test28::C::c()
// CHECK-NEXT: 11 | offset_to_top (-16)
// CHECK-NEXT: 12 | Test28::E RTTI
// CHECK-NEXT: -- (Test28::B, 16) vtable address --
// CHECK-NEXT: 13 | void Test28::B::b()
// CHECK: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
// CHECK-NEXT: 0 | vbase_offset (8)
// CHECK-NEXT: 1 | offset_to_top (0)
// CHECK-NEXT: 2 | Test28::D RTTI
// CHECK-NEXT: -- (Test28::D, 0) vtable address --
// CHECK-NEXT: 3 | vcall_offset (8)
// CHECK-NEXT: 4 | vcall_offset (0)
// CHECK-NEXT: 5 | vcall_offset (0)
// CHECK-NEXT: 6 | offset_to_top (-8)
// CHECK-NEXT: 7 | Test28::D RTTI
// CHECK-NEXT: -- (Test28::A, 8) vtable address --
// CHECK-NEXT: -- (Test28::C, 8) vtable address --
// CHECK-NEXT: 8 | void Test28::A::a()
// CHECK-NEXT: 9 | void Test28::C::c()
// CHECK-NEXT: 10 | offset_to_top (-16)
// CHECK-NEXT: 11 | Test28::D RTTI
// CHECK-NEXT: -- (Test28::B, 16) vtable address --
// CHECK-NEXT: 12 | void Test28::B::b()
struct E : D {
virtual void e();
};
void E::e() { }
}