summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-02-21 02:27:32 +0000
committerReid Kleckner <reid@kleckner.net>2014-02-21 02:27:32 +0000
commite4a5220d7c463d5f891f23e520f54e7734c24960 (patch)
tree86f025518c82abbafa53943a0a903d88c7358e2f /clang/lib
parentf1939029183cb011f7a174dc12b5a2f5c40b0664 (diff)
downloadbcm5719-llvm-e4a5220d7c463d5f891f23e520f54e7734c24960.tar.gz
bcm5719-llvm-e4a5220d7c463d5f891f23e520f54e7734c24960.zip
MS ABI: Include the vfptr offset in memptrs to virtual methods
Virtual methods expect 'this' to point to the vfptr containing the virtual method, and this extends to virtual member pointer thunks. The relevant vfptr is always at offset zero on entry to the thunk, and no this adjustment is needed. Previously we would not include the vfptr adjustment in the member pointer, and we'd look at the vfptr offset when loading from the vftable in the thunk. Fixes PR18917. llvm-svn: 201835
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp35
1 files changed, 22 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 57ad9fb1ad9..7e3cf4f2000 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -328,8 +328,9 @@ private:
const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD);
/// \brief Generate a thunk for calling a virtual member function MD.
- llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
- StringRef ThunkName);
+ llvm::Function *EmitVirtualMemPtrThunk(
+ const CXXMethodDecl *MD,
+ const MicrosoftVTableContext::MethodVFTableLocation &ML);
public:
virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
@@ -1015,9 +1016,15 @@ MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) {
return VBGlobals;
}
-llvm::Function *
-MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
- StringRef ThunkName) {
+llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
+ const CXXMethodDecl *MD,
+ const MicrosoftVTableContext::MethodVFTableLocation &ML) {
+ // Calculate the mangled name.
+ SmallString<256> ThunkName;
+ llvm::raw_svector_ostream Out(ThunkName);
+ getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
+ Out.flush();
+
// If the thunk has been generated previously, just return it.
if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
return cast<llvm::Function>(GV);
@@ -1041,9 +1048,14 @@ MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
CodeGenFunction CGF(CGM);
CGF.StartThunk(ThunkFn, MD, FnInfo);
- // Get to the Callee.
+ // Load the vfptr and then callee from the vftable. The callee should have
+ // adjusted 'this' so that the vfptr is at offset zero.
llvm::Value *This = CGF.LoadCXXThis();
- llvm::Value *Callee = getVirtualFunctionPointer(CGF, MD, This, ThunkTy);
+ llvm::Value *VTable =
+ CGF.GetVTablePtr(This, ThunkTy->getPointerTo()->getPointerTo());
+ llvm::Value *VFuncPtr =
+ CGF.Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
+ llvm::Value *Callee = CGF.Builder.CreateLoad(VFuncPtr);
// Make the call and return the result.
CGF.EmitCallAndReturnForThunk(MD, Callee, 0);
@@ -1523,13 +1535,10 @@ MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD,
"member function in virtual base class");
FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
} else {
- SmallString<256> ThunkName;
- llvm::raw_svector_ostream Out(ThunkName);
- getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
- Out.flush();
-
- llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ThunkName.str());
+ llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML);
FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy);
+ // Include the vfptr adjustment if the method is in a non-primary vftable.
+ NonVirtualBaseAdjustment += ML.VFPtrOffset;
}
}
OpenPOWER on IntegriCloud