diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-10-27 17:11:51 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-10-27 17:11:51 +0000 |
| commit | 07c915e1d59f981b6fc2e7f7529ca6d4f57018cb (patch) | |
| tree | 8e00e15fe68ab087f2e9d3c4016b4d8ba687d570 /clang/lib/CodeGen | |
| parent | 28c4f18bfecd596645c67eb818634f55653e0300 (diff) | |
| download | bcm5719-llvm-07c915e1d59f981b6fc2e7f7529ca6d4f57018cb.tar.gz bcm5719-llvm-07c915e1d59f981b6fc2e7f7529ca6d4f57018cb.zip | |
[MS ABI] Reuse getVFPtrOffsets instead of using getClassAtVTableLocation
getClassAtVTableLocation hunts through virtual bases without using the
MDC layout which is indicative of a bug.
Instead, reuse the getVFPtrOffsets machinery to calculate which
subobject within the MDC is responsible for the vfptr.
Differential Revision: https://reviews.llvm.org/D25895
llvm-svn: 285315
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 56 |
1 files changed, 16 insertions, 40 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 9f7313c497b..9f6022fce3d 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1762,42 +1762,6 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD, return VTable; } -// Compute the identity of the most derived class whose virtual table is located -// at the given offset into RD. -static const CXXRecordDecl *getClassAtVTableLocation(ASTContext &Ctx, - const CXXRecordDecl *RD, - CharUnits Offset) { - if (Offset.isZero()) - return RD; - - const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); - const CXXRecordDecl *MaxBase = nullptr; - CharUnits MaxBaseOffset; - for (auto &&B : RD->bases()) { - const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl(); - CharUnits BaseOffset = B.isVirtual() ? Layout.getVBaseClassOffset(Base) - : Layout.getBaseClassOffset(Base); - if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) { - MaxBase = Base; - MaxBaseOffset = BaseOffset; - } - } - assert(MaxBase); - return getClassAtVTableLocation(Ctx, MaxBase, Offset - MaxBaseOffset); -} - -// Compute the identity of the most derived class whose virtual table is located -// at the MethodVFTableLocation ML. -static const CXXRecordDecl * -getClassAtVTableLocation(ASTContext &Ctx, GlobalDecl GD, - MicrosoftVTableContext::MethodVFTableLocation &ML) { - const CXXRecordDecl *RD = ML.VBase; - if (!RD) - RD = cast<CXXMethodDecl>(GD.getDecl())->getParent(); - - return getClassAtVTableLocation(Ctx, RD, ML.VFPtrOffset); -} - CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, @@ -1813,18 +1777,30 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl()); llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty, MethodDecl->getParent()); + MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext(); MicrosoftVTableContext::MethodVFTableLocation ML = - CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); + VFTContext.getMethodVFTableLocation(GD); + + // Compute the identity of the most derived class whose virtual table is + // located at the MethodVFTableLocation ML. + auto getObjectWithVPtr = [&] { + return llvm::find_if(VFTContext.getVFPtrOffsets( + ML.VBase ? ML.VBase : MethodDecl->getParent()), + [&](const std::unique_ptr<VPtrInfo> &Info) { + return Info->FullOffsetInMDC == ML.VFPtrOffset; + }) + ->get() + ->ObjectWithVPtr; + }; llvm::Value *VFunc; if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) { VFunc = CGF.EmitVTableTypeCheckedLoad( - getClassAtVTableLocation(getContext(), GD, ML), VTable, + getObjectWithVPtr(), VTable, ML.Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8); } else { if (CGM.getCodeGenOpts().PrepareForLTO) - CGF.EmitTypeMetadataCodeForVCall( - getClassAtVTableLocation(getContext(), GD, ML), VTable, Loc); + CGF.EmitTypeMetadataCodeForVCall(getObjectWithVPtr(), VTable, Loc); llvm::Value *VFuncPtr = Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn"); |

