From bca5d375f782dc9db5b3a64c666fd1590125824b Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 22 Mar 2010 20:06:40 +0000 Subject: [PATCH] More work on thunks; almost there now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99199 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 43 +++++++++++++++++++++++++++++++--------- 1 file 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 &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'; + } } } -- 2.40.0