aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-03-22 20:06:40 +0000
committerAnders Carlsson <andersca@mac.com>2010-03-22 20:06:40 +0000
commitbca5d375f782dc9db5b3a64c666fd1590125824b (patch)
tree52d18afad14767379403a70e33157499d58fb7c3 /lib/CodeGen/CGVtable.cpp
parent01f1bfc3284d5817517d35217885ea9ecb252817 (diff)
More work on thunks; almost there now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99199 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index b78867841c..49dbd29063 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -1384,8 +1384,8 @@ public:
};
void VtableBuilder::AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk) {
- if (isBuildingConstructorVtable())
- return;
+ assert(!isBuildingConstructorVtable() &&
+ "Can't add thunks for construction vtable");
llvm::SmallVector<ThunkInfo, 1> &ThunksVector = MethodThunks[MD];
@@ -1436,6 +1436,10 @@ void VtableBuilder::ComputeThisAdjustments() {
Overriders.getOverrider(BaseSubobject(MD->getParent(),
MethodInfo.BaseOffset), MD);
+ // Check if we need an adjustment at all.
+ if (MethodInfo.BaseOffsetInLayoutClass == Overrider.Offset)
+ continue;
+
ThisAdjustment ThisAdjustment =
ComputeThisAdjustment(MD, MethodInfo.BaseOffsetInLayoutClass, Overrider);
@@ -1463,20 +1467,24 @@ void VtableBuilder::ComputeThisAdjustments() {
I != E; ++I) {
const VtableComponent &Component = Components[I->first];
const ThunkInfo &Thunk = I->second;
+ const CXXMethodDecl *MD;
switch (Component.getKind()) {
default:
llvm_unreachable("Unexpected vtable component kind!");
case VtableComponent::CK_FunctionPointer:
- AddThunk(Component.getFunctionDecl(), Thunk);
+ MD = Component.getFunctionDecl();
break;
case VtableComponent::CK_CompleteDtorPointer:
- AddThunk(Component.getDestructorDecl(), Thunk);
+ MD = Component.getDestructorDecl();
break;
case VtableComponent::CK_DeletingDtorPointer:
// We've already added the thunk when we saw the complete dtor pointer.
- break;
+ continue;
}
+
+ if (MD->getParent() == MostDerivedClass)
+ AddThunk(MD, Thunk);
}
}
@@ -1565,10 +1573,6 @@ 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();
@@ -1825,6 +1829,24 @@ VtableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass,
MethodInfoMap.insert(std::make_pair(MD, MethodInfo));
MethodInfoMap.erase(OverriddenMD);
+
+ // If the overridden method exists in a virtual base class or a direct
+ // or indirect base class of a virtual base class, we need to emit a
+ // thunk if we ever have a class hierarchy where the base class is not
+ // a primary base in the complete object.
+ if (!isBuildingConstructorVtable() && OverriddenMD != MD) {
+ // Compute the this adjustment.
+ ThisAdjustment ThisAdjustment =
+ ComputeThisAdjustment(OverriddenMD, BaseOffsetInLayoutClass,
+ Overrider);
+
+ if (ThisAdjustment.VCallOffsetOffset) {
+ // This is a virtual thunk, add it.
+ AddThunk(Overrider.Method,
+ ThunkInfo(ThisAdjustment, ReturnAdjustment()));
+ }
+ }
+
continue;
}
}
@@ -2360,6 +2382,9 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
Out << '\n';
}
+
+ Out << '\n';
+
}
}
}