[cfe-commits] r96329 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-layout.cpp
Anders Carlsson
andersca at mac.com
Mon Feb 15 20:59:55 PST 2010
Author: andersca
Date: Mon Feb 15 22:59:55 2010
New Revision: 96329
URL: http://llvm.org/viewvc/llvm-project?rev=96329&view=rev
Log:
Emit vbase offsets.
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=96329&r1=96328&r2=96329&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Mon Feb 15 22:59:55 2010
@@ -912,6 +912,27 @@
void VtableBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
int64_t OffsetToTop,
VisitedVirtualBasesSetTy &VBases) {
+ const ASTRecordLayout &MostDerivedClassLayout =
+ Context.getASTRecordLayout(MostDerivedClass);
+
+ // Add vbase offsets.
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ // Check if this is a virtual base that we haven't visited before.
+ if (I->isVirtual() && VBases.insert(BaseDecl)) {
+ // FIXME: We shouldn't use / 8 here.
+ uint64_t Offset =
+ OffsetToTop + MostDerivedClassLayout.getVBaseClassOffset(BaseDecl) / 8;
+
+ VCallAndVBaseOffsets.push_back(VtableComponent::MakeVBaseOffset(Offset));
+ }
+
+ // Check the base class looking for more vbase offsets.
+ AddVBaseOffsets(BaseDecl, OffsetToTop, VBases);
+ }
}
void
@@ -1008,13 +1029,22 @@
void VtableBuilder::LayoutVtable(BaseSubobject Base) {
const CXXRecordDecl *RD = Base.getBase();
-
assert(RD->isDynamicClass() && "class does not have a vtable!");
- // First, add the offset to top.
+ int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8;
+
+ // Add vcall and vbase offsets for this vtable.
+ VisitedVirtualBasesSetTy VBases;
+ AddVCallAndVBaseOffsets(RD, OffsetToTop, VBases);
+
+ // Reverse them and add them to the vtable components.
+ std::reverse(VCallAndVBaseOffsets.begin(), VCallAndVBaseOffsets.end());
+ Components.append(VCallAndVBaseOffsets.begin(), VCallAndVBaseOffsets.end());
+ VCallAndVBaseOffsets.clear();
+
+ // Add the offset to top.
// FIXME: This is not going to be right for construction vtables.
// FIXME: We should not use / 8 here.
- int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8;
Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop));
// Next, add the RTTI.
@@ -1137,7 +1167,11 @@
default:
assert(false && "Unhandled component kind!");
break;
-
+
+ case VtableComponent::CK_VBaseOffset:
+ Out << "vbase_offset (" << Component.getVBaseOffset() << ")";
+ break;
+
case VtableComponent::CK_OffsetToTop:
Out << "offset_to_top (" << Component.getOffsetToTop() << ")";
break;
Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=96329&r1=96328&r2=96329&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Mon Feb 15 22:59:55 2010
@@ -340,3 +340,28 @@
void B::f() { }
}
+
+namespace Test9 {
+
+// Simple test of vbase offsets.
+
+struct A1 { int a1; };
+struct A2 { int a2; };
+
+// CHECK: Vtable for 'Test9::B' (5 entries).
+// CHECK-NEXT: 0 | vbase_offset (16)
+// CHECK-NEXT: 1 | vbase_offset (12)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test9::B RTTI
+// CHECK-NEXT: -- (Test9::B, 0) vtable address --
+// CHECK-NEXT: 4 | void Test9::B::f()
+struct B : virtual A1, virtual A2 {
+ int b;
+
+ virtual void f();
+};
+
+
+void B::f() { }
+
+}
More information about the cfe-commits
mailing list