[cfe-commits] r98180 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-layout.cpp
Anders Carlsson
andersca at mac.com
Wed Mar 10 11:39:11 PST 2010
Author: andersca
Date: Wed Mar 10 13:39:11 2010
New Revision: 98180
URL: http://llvm.org/viewvc/llvm-project?rev=98180&view=rev
Log:
We were mistakenly marking morally virtual bases as being uninteresting. Fix this.
Modified:
cfe/trunk/lib/CodeGen/CGVtable.cpp
cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=98180&r1=98179&r2=98180&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Wed Mar 10 13:39:11 2010
@@ -1235,7 +1235,11 @@
/// 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 @@
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,9 +1815,8 @@
// 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.
@@ -1821,7 +1829,7 @@
// to emit secondary vtables for other bases of this base.
if (BaseDecl == PrimaryBase) {
LayoutSecondaryVtables(BaseSubobject(BaseDecl, BaseOffset),
- BaseOffsetInLayoutClass);
+ BaseIsMorallyVirtual, BaseOffsetInLayoutClass);
continue;
}
Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=98180&r1=98179&r2=98180&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Wed Mar 10 13:39:11 2010
@@ -1150,4 +1150,71 @@
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() { }
+
}
More information about the cfe-commits
mailing list