diff options
Diffstat (limited to 'lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r-- | lib/CodeGen/ItaniumCXXABI.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 920b833b25..13768006f4 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -66,6 +66,11 @@ public: llvm::Value *MemFnPtr, const MemberPointerType *MPT); + llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, + llvm::Value *Base, + llvm::Value *MemPtr, + const MemberPointerType *MPT); + llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src); @@ -261,6 +266,31 @@ ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, return Callee; } +/// Compute an l-value by applying the given pointer-to-member to a +/// base object. +llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, + llvm::Value *Base, + llvm::Value *MemPtr, + const MemberPointerType *MPT) { + assert(MemPtr->getType() == getPtrDiffTy()); + + CGBuilderTy &Builder = CGF.Builder; + + unsigned AS = cast<llvm::PointerType>(Base->getType())->getAddressSpace(); + + // Cast to char*. + Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS)); + + // Apply the offset, which we assume is non-null. + llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset"); + + // Cast the address to the appropriate pointer type, adopting the + // address space of the base pointer. + const llvm::Type *PType + = CGF.ConvertType(MPT->getPointeeType())->getPointerTo(AS); + return Builder.CreateBitCast(Addr, PType); +} + /// Perform a derived-to-base or base-to-derived member pointer conversion. /// /// Obligatory offset/adjustment diagram: |