Skip to content

Commit

Permalink
More this adjustment simplification.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98333 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Anders Carlsson committed Mar 12, 2010
1 parent 4ea9006 commit 617def3
Showing 1 changed file with 59 additions and 56 deletions.
115 changes: 59 additions & 56 deletions lib/CodeGen/CGVtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,11 +1235,13 @@ class VtableBuilder {
BaseSubobject Derived) const;

/// ComputeThisAdjustment - Compute the 'this' pointer adjustment for the
/// given virtual member function and the 'this' pointer adjustment base
/// offset.
ThisAdjustment ComputeThisAdjustment(const CXXMethodDecl *MD,
BaseOffset Offset);

/// given virtual member function, its offset in the layout class and its
/// final overrider.
ThisAdjustment
ComputeThisAdjustment(const CXXMethodDecl *MD,
uint64_t BaseOffsetInLayoutClass,
FinalOverriders::OverriderInfo Overrider);

/// AddMethod - Add a single virtual member function to the vtable
/// components vector.
void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment);
Expand Down Expand Up @@ -1356,44 +1358,26 @@ void VtableBuilder::ComputeThisAdjustments() {
const CXXMethodDecl *MD = I->first;
const MethodInfo &MethodInfo = I->second;

// Ignore adjustments for unused function pointers.
uint64_t VtableIndex = MethodInfo.VtableIndex;
if (Components[VtableIndex].getKind() ==
VtableComponent::CK_UnusedFunctionPointer)
continue;

// Get the final overrider for this method.
FinalOverriders::OverriderInfo Overrider =
Overriders.getOverrider(BaseSubobject(MD->getParent(),
MethodInfo.BaseOffset), MD);

// Check if we need an adjustment.
if (Overrider.Offset == MethodInfo.BaseOffsetInLayoutClass)
continue;

uint64_t VtableIndex = MethodInfo.VtableIndex;
ThisAdjustment ThisAdjustment =
ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider);

// Ignore adjustments for pure virtual member functions.
if (Overrider.Method->isPure())
if (ThisAdjustment.isEmpty())
continue;

// Ignore adjustments for unused function pointers.
if (Components[VtableIndex].getKind() ==
VtableComponent::CK_UnusedFunctionPointer)
continue;

BaseSubobject OverriddenBaseSubobject(MD->getParent(),
MethodInfo.BaseOffsetInLayoutClass);

BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(),
Overrider.Offset);

// Compute the adjustment offset.
BaseOffset ThisAdjustmentOffset =
ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject,
OverriderBaseSubobject);

// Then compute the adjustment itself.
ThisAdjustment ThisAdjustment = ComputeThisAdjustment(Overrider.Method,
ThisAdjustmentOffset);

// Add it.
Thunks[VtableIndex].This = ThisAdjustment;

if (isa<CXXDestructorDecl>(MD)) {
// Add an adjustment for the deleting destructor as well.
Thunks[VtableIndex + 1].This = ThisAdjustment;
Expand Down Expand Up @@ -1485,38 +1469,57 @@ VtableBuilder::ComputeThisAdjustmentBaseOffset(BaseSubobject Base,
return BaseOffset();
}

VtableBuilder::ThisAdjustment
VtableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD,
uint64_t BaseOffsetInLayoutClass,
FinalOverriders::OverriderInfo Overrider) {
// Check if we need an adjustment at all.
if (BaseOffsetInLayoutClass == Overrider.Offset)
return ThisAdjustment();

// Ignore adjustments for pure virtual member functions.
if (Overrider.Method->isPure())
return ThisAdjustment();

BaseSubobject OverriddenBaseSubobject(MD->getParent(),
BaseOffsetInLayoutClass);

BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(),
Overrider.Offset);

// Compute the adjustment offset.
BaseOffset Offset = ComputeThisAdjustmentBaseOffset(OverriddenBaseSubobject,
OverriderBaseSubobject);
if (Offset.isEmpty())
return ThisAdjustment();

VtableBuilder::ThisAdjustment
VtableBuilder::ComputeThisAdjustment(const CXXMethodDecl *MD,
BaseOffset Offset) {
ThisAdjustment Adjustment;

if (!Offset.isEmpty()) {
if (Offset.VirtualBase) {
// Get the vcall offset map for this virtual base.
VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase];

if (VCallOffsets.empty()) {
// We don't have vcall offsets for this virtual base, go ahead and
// build them.
VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
/*FinalOverriders=*/0,
BaseSubobject(Offset.VirtualBase, 0),
/*BaseIsVirtual=*/true,
/*OffsetInLayoutClass=*/0);
if (Offset.VirtualBase) {
// Get the vcall offset map for this virtual base.
VCallOffsetMap &VCallOffsets = VCallOffsetsForVBases[Offset.VirtualBase];

if (VCallOffsets.empty()) {
// We don't have vcall offsets for this virtual base, go ahead and
// build them.
VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
/*FinalOverriders=*/0,
BaseSubobject(Offset.VirtualBase, 0),
/*BaseIsVirtual=*/true,
/*OffsetInLayoutClass=*/0);

VCallOffsets = Builder.getVCallOffsets();
}

Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD);
VCallOffsets = Builder.getVCallOffsets();
}

Adjustment.NonVirtual = Offset.NonVirtualOffset;
Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD);
}

// Set the non-virtual part of the adjustment.
Adjustment.NonVirtual = Offset.NonVirtualOffset;

return Adjustment;
}

void
VtableBuilder::AddMethod(const CXXMethodDecl *MD,
ReturnAdjustment ReturnAdjustment) {
Expand Down

0 comments on commit 617def3

Please sign in to comment.