forked from OSchip/llvm-project
parent
dc2dba306c
commit
77904f1d5b
|
@ -912,6 +912,27 @@ VtableBuilder::AddVCallAndVBaseOffsets(const CXXRecordDecl *RD,
|
||||||
void VtableBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
|
void VtableBuilder::AddVBaseOffsets(const CXXRecordDecl *RD,
|
||||||
int64_t OffsetToTop,
|
int64_t OffsetToTop,
|
||||||
VisitedVirtualBasesSetTy &VBases) {
|
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
|
void
|
||||||
|
@ -1008,13 +1029,22 @@ VtableBuilder::AddMethods(BaseSubobject Base, PrimaryBasesSetTy &PrimaryBases) {
|
||||||
|
|
||||||
void VtableBuilder::LayoutVtable(BaseSubobject Base) {
|
void VtableBuilder::LayoutVtable(BaseSubobject Base) {
|
||||||
const CXXRecordDecl *RD = Base.getBase();
|
const CXXRecordDecl *RD = Base.getBase();
|
||||||
|
|
||||||
assert(RD->isDynamicClass() && "class does not have a vtable!");
|
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: This is not going to be right for construction vtables.
|
||||||
// FIXME: We should not use / 8 here.
|
// FIXME: We should not use / 8 here.
|
||||||
int64_t OffsetToTop = -(int64_t)Base.getBaseOffset() / 8;
|
|
||||||
Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop));
|
Components.push_back(VtableComponent::MakeOffsetToTop(OffsetToTop));
|
||||||
|
|
||||||
// Next, add the RTTI.
|
// Next, add the RTTI.
|
||||||
|
@ -1137,7 +1167,11 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
|
||||||
default:
|
default:
|
||||||
assert(false && "Unhandled component kind!");
|
assert(false && "Unhandled component kind!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VtableComponent::CK_VBaseOffset:
|
||||||
|
Out << "vbase_offset (" << Component.getVBaseOffset() << ")";
|
||||||
|
break;
|
||||||
|
|
||||||
case VtableComponent::CK_OffsetToTop:
|
case VtableComponent::CK_OffsetToTop:
|
||||||
Out << "offset_to_top (" << Component.getOffsetToTop() << ")";
|
Out << "offset_to_top (" << Component.getOffsetToTop() << ")";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -340,3 +340,28 @@ struct B : A {
|
||||||
void B::f() { }
|
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() { }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue