diff options
| author | Anders Carlsson <andersca@mac.com> | 2010-03-22 20:06:40 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2010-03-22 20:06:40 +0000 |
| commit | 290c6ed7c78cf36c3cfedb10d34ec074fc226251 (patch) | |
| tree | a67082f93d2343d1caa92a890f1b41b78e7e7b58 /clang | |
| parent | a9effb55f335c12d6bfa1e7d9a07fe3819b7cf49 (diff) | |
| download | bcm5719-llvm-290c6ed7c78cf36c3cfedb10d34ec074fc226251.tar.gz bcm5719-llvm-290c6ed7c78cf36c3cfedb10d34ec074fc226251.zip | |
More work on thunks; almost there now.
llvm-svn: 99199
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index b78867841cc..49dbd290637 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/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'; + } } } |

