MicrosoftCXXABI.cpp revision b0f533e716ae5a21ca5682ea235a68082fd5ed28
1c3926645d70842eae22641df1bf69da457a0ff11Charles Davis//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===// 2c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 3c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// The LLVM Compiler Infrastructure 4c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 5c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// This file is distributed under the University of Illinois Open Source 6c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// License. See LICENSE.TXT for details. 7c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 8c3926645d70842eae22641df1bf69da457a0ff11Charles Davis//===----------------------------------------------------------------------===// 9c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides C++ code generation targeting the Microsoft Visual C++ ABI. 11c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// The class in this file generates structures that follow the Microsoft 12c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// Visual C++ ABI, which is actually not very well documented at all outside 13c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// of Microsoft. 14c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 15c3926645d70842eae22641df1bf69da457a0ff11Charles Davis//===----------------------------------------------------------------------===// 16c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 17c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "CGCXXABI.h" 18c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "CodeGenModule.h" 19c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "clang/AST/Decl.h" 20c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "clang/AST/DeclCXX.h" 21c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 22c3926645d70842eae22641df1bf69da457a0ff11Charles Davisusing namespace clang; 23c3926645d70842eae22641df1bf69da457a0ff11Charles Davisusing namespace CodeGen; 24c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 25c3926645d70842eae22641df1bf69da457a0ff11Charles Davisnamespace { 26c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 27071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CGCXXABI { 28c3926645d70842eae22641df1bf69da457a0ff11Charles Davispublic: 2914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {} 304c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 31ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov bool isReturnTypeIndirect(const CXXRecordDecl *RD) const { 32ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov // Structures that are not C++03 PODs are always indirect. 33ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return !RD->isPOD(); 34ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov } 35ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov 36ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const { 37ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov if (RD->hasNonTrivialCopyConstructor()) 38ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return RAA_DirectInMemory; 39ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return RAA_Default; 40ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov } 41ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov 42285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos StringRef GetPureVirtualCallName() { return "_purecall"; } 432eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie // No known support for deleted functions in MSVC yet, so this choice is 442eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie // arbitrary. 452eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie StringRef GetDeletedVirtualCallName() { return "_purecall"; } 46285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos 47ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, 48ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *ptr, 49ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall QualType type); 50ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 51b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, 52b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *This, 53b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *ClassDecl, 54b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *BaseClassDecl); 55b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 564c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildConstructorSignature(const CXXConstructorDecl *Ctor, 574c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CXXCtorType Type, 584c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CanQualType &ResTy, 59bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall SmallVectorImpl<CanQualType> &ArgTys); 604c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 611d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF); 621d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 634c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildDestructorSignature(const CXXDestructorDecl *Ctor, 644c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CXXDtorType Type, 654c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CanQualType &ResTy, 6659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov SmallVectorImpl<CanQualType> &ArgTys); 674c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 684c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildInstanceFunctionParams(CodeGenFunction &CGF, 694c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall QualType &ResTy, 70bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall FunctionArgList &Params); 714c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 72bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall void EmitInstanceFunctionProlog(CodeGenFunction &CGF); 73fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall 7463fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, 751d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXConstructorDecl *D, 761d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXCtorType Type, bool ForVirtualBase, 771d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool Delegating, 781d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *This, 791d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgBeg, 801d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgEnd); 811d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 820f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, 830f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CXXDestructorDecl *Dtor, 840f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov CXXDtorType DtorType, 850f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov SourceLocation CallLoc, 860f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ReturnValueSlot ReturnValue, 870f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *This); 880f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 8920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 9020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::GlobalVariable *DeclPtr, 9120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall bool PerformInit); 9220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 93fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // ==== Notes on array cookies ========= 94fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // 95fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // MSVC seems to only use cookies when the class has a destructor; a 96fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // two-argument usual array deallocation function isn't sufficient. 97fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // 98fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // For example, this code prints "100" and "1": 99fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // struct A { 100fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // char x; 101fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // void *operator new[](size_t sz) { 102fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // printf("%u\n", sz); 103fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // return malloc(sz); 104fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 105fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // void operator delete[](void *p, size_t sz) { 106fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // printf("%u\n", sz); 107fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // free(p); 108fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 109fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // }; 110fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // int main() { 111fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // A *p = new A[100]; 112fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // delete[] p; 113fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 114fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // Whereas it prints "104" and "104" if you give A a destructor. 115e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 116e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType); 117e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall bool requiresArrayCookie(const CXXNewExpr *expr); 118e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits getArrayCookieSizeImpl(QualType type); 119e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 120e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *NewPtr, 121e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *NumElements, 122e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall const CXXNewExpr *expr, 123e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType ElementType); 124e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 125e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *allocPtr, 126e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize); 127bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall static bool needThisReturn(GlobalDecl GD); 128a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 129a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerprivate: 130a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Constant *getZeroInt() { 131a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::ConstantInt::get(CGM.IntTy, 0); 132a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 133a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 134a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Constant *getAllOnesInt() { 135a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::Constant::getAllOnesValue(CGM.IntTy); 136a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 137a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 138f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *getConstantOrZeroInt(llvm::Constant *C) { 139f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return C ? C : getZeroInt(); 140f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 141f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 142f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *getValueOrZeroInt(llvm::Value *C) { 143f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return C ? C : getZeroInt(); 144f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 145f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 146a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner void 147a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner GetNullMemberPointerFields(const MemberPointerType *MPT, 148a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVectorImpl<llvm::Constant *> &fields); 149a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 150b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// \brief Finds the offset from the base of RD to the vbptr it uses, even if 151b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// it is reusing a vbptr from a non-virtual base. RD must have morally 152b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// virtual bases. 153b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD); 154b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 155b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// \brief Shared code for virtual base adjustment. Returns the offset from 156b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// the vbptr to the virtual base. Optionally returns the address of the 157b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// vbptr itself. 158b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 159b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *Base, 160b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrOffset, 161b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset, 162b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value **VBPtr = 0); 163b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 164b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// \brief Performs a full virtual base adjustment. Used to dereference 165b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// pointers to members of virtual bases. 166a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD, 167a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Base, 168a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset, 169a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset /* optional */); 170a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 17179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner /// \brief Emits a full member pointer with the fields common to data and 17279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner /// function member pointers. 17379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField, 17479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner bool IsMemberFunction, 175f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXRecordDecl *RD, 176f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment); 177f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 178f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *BuildMemberPointer(const CXXRecordDecl *RD, 179f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXMethodDecl *MD, 180f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment); 181f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 182f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool MemberPointerConstantIsNull(const MemberPointerType *MPT, 183f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *MP); 18479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 185a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerpublic: 186a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT); 187a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 188a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner virtual bool isZeroInitializable(const MemberPointerType *MPT); 189a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 190a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); 191a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 192a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 193a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CharUnits offset); 19479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); 19579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); 196a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 1973d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner virtual llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, 1983d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *L, 1993d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *R, 2003d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner const MemberPointerType *MPT, 2013d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner bool Inequality); 2023d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 203a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 204a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 205a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT); 206a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 207a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, 208a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *Base, 209a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 210a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT); 211a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 212f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, 213f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CastExpr *E, 214f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *Src); 215f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 216f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, 217f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Src); 218f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 219a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner virtual llvm::Value * 220a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 221a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *&This, 222a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *MemPtr, 223a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const MemberPointerType *MPT); 224a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 225c3926645d70842eae22641df1bf69da457a0ff11Charles Davis}; 226c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 227c3926645d70842eae22641df1bf69da457a0ff11Charles Davis} 228c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 229ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCallllvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, 230ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *ptr, 231ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall QualType type) { 232ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall // FIXME: implement 233ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall return ptr; 234ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall} 235ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 236b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerCharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) { 237b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner assert(RD->getNumVBases()); 238b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits Total = CharUnits::Zero(); 239b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner while (RD) { 240b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const ASTRecordLayout &RDLayout = getContext().getASTRecordLayout(RD); 241b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits VBPtrOffset = RDLayout.getVBPtrOffset(); 242b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // -1 is the sentinel for no vbptr. 243b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (VBPtrOffset != CharUnits::fromQuantity(-1)) { 244b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Total += VBPtrOffset; 245b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner break; 246b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 247b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 248b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // RD is reusing the vbptr of a non-virtual base. Find it and continue. 249b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *FirstNVBaseWithVBases = 0; 250b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 251b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner E = RD->bases_end(); I != E; ++I) { 252b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); 253b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (!I->isVirtual() && Base->getNumVBases() > 0) { 254b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner FirstNVBaseWithVBases = Base; 255b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner break; 256b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 257b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 258b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner assert(FirstNVBaseWithVBases); 259b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Total += RDLayout.getBaseClassOffset(FirstNVBaseWithVBases); 260b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner RD = FirstNVBaseWithVBases; 261b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 262b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return Total; 263b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 264b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 265b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Klecknerllvm::Value * 266b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerMicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, 267b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *This, 268b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *ClassDecl, 269b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *BaseClassDecl) { 270b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity(); 271b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars); 272b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 273b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // The vbtable is an array of i32 offsets. The first entry is a self entry, 274b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // and the rest are offsets from the vbptr to virtual bases. The bases are 275b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // ordered the same way our vbases are ordered: as they appear in a 276b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // left-to-right depth-first search of the hierarchy. 277b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner unsigned VBTableIndex = 1; // Start with one to skip the self entry. 278b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner for (CXXRecordDecl::base_class_const_iterator I = ClassDecl->vbases_begin(), 279b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner E = ClassDecl->vbases_end(); I != E; ++I) { 280b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (I->getType()->getAsCXXRecordDecl() == BaseClassDecl) 281b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner break; 282b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBTableIndex++; 283b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 284b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner assert(VBTableIndex != 1 + ClassDecl->getNumVBases() && 285b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner "BaseClassDecl must be a vbase of ClassDecl"); 286b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy); 287b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits VBTableChars = IntSize * VBTableIndex; 288b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset = 289b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity()); 290b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 291b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrToNewBase = 292b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner GetVBaseOffsetFromVBPtr(CGF, This, VBTableOffset, VBPtrOffset); 293b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBPtrToNewBase = 294b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGF.Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy); 295b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return CGF.Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase); 296b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 297b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 298bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallbool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) { 299bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 300bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall return isa<CXXConstructorDecl>(MD); 301bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 302bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 303bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, 304bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CXXCtorType Type, 305bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CanQualType &ResTy, 306bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall SmallVectorImpl<CanQualType> &ArgTys) { 307bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall // 'this' is already in place 3081d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 309bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall // Ctor returns this ptr 310bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall ResTy = ArgTys[0]; 3111d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3121d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXRecordDecl *Class = Ctor->getParent(); 3131d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (Class->getNumVBases()) { 3141d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Constructors of classes with virtual bases take an implicit parameter. 3151d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ArgTys.push_back(CGM.getContext().IntTy); 3161d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 3171d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 3181d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3191d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanovllvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler( 3201d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CodeGenFunction &CGF) { 3211d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF); 3221d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(IsMostDerivedClass && 3231d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "ctor for a class with virtual bases must have an implicit parameter"); 3241d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *IsCompleteObject 3251d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object"); 3261d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3271d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases"); 3281d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases"); 3291d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.Builder.CreateCondBr(IsCompleteObject, 3301d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallVbaseCtorsBB, SkipVbaseCtorsBB); 3311d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3321d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.EmitBlock(CallVbaseCtorsBB); 3331d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // FIXME: emit vbtables somewhere around here. 3341d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3351d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // CGF will put the base ctor calls in this basic block for us later. 3361d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3371d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov return SkipVbaseCtorsBB; 338bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 339bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 34059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanovvoid MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, 34159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CXXDtorType Type, 34259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CanQualType &ResTy, 34359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov SmallVectorImpl<CanQualType> &ArgTys) { 34459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // 'this' is already in place 34559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // TODO: 'for base' flag 34659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 34759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (Type == Dtor_Deleting) { 34859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // The scalar deleting destructor takes an implicit bool parameter. 34959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ArgTys.push_back(CGM.getContext().BoolTy); 35059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 35159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov} 35259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 35359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanovstatic bool IsDeletingDtor(GlobalDecl GD) { 35459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 35559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (isa<CXXDestructorDecl>(MD)) { 35659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov return GD.getDtorType() == Dtor_Deleting; 35759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 35859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov return false; 35959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov} 36059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 361bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, 362bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall QualType &ResTy, 363bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall FunctionArgList &Params) { 364bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall BuildThisParam(CGF, Params); 365bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall if (needThisReturn(CGF.CurGD)) { 366bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall ResTy = Params[0]->getType(); 367bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall } 36859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 3691d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ASTContext &Context = getContext(); 3701d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 3711d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 3721d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParamDecl *IsMostDerived 3731d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = ImplicitParamDecl::Create(Context, 0, 3741d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.CurGD.getDecl()->getLocation(), 3751d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov &Context.Idents.get("is_most_derived"), 3761d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Context.IntTy); 3771d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Params.push_back(IsMostDerived); 3781d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov getStructorImplicitParamDecl(CGF) = IsMostDerived; 3791d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } else if (IsDeletingDtor(CGF.CurGD)) { 38059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ImplicitParamDecl *ShouldDelete 38159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = ImplicitParamDecl::Create(Context, 0, 38259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.CurGD.getDecl()->getLocation(), 38359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov &Context.Idents.get("should_call_delete"), 38459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov Context.BoolTy); 38559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov Params.push_back(ShouldDelete); 38659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov getStructorImplicitParamDecl(CGF) = ShouldDelete; 38759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 388bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 389bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 390bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 391bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall EmitThisParam(CGF); 392bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall if (needThisReturn(CGF.CurGD)) { 393bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 394bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall } 3951d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3961d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 3971d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 3981d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(getStructorImplicitParamDecl(CGF) && 3991d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "no implicit parameter for a constructor with virtual bases?"); 4001d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov getStructorImplicitParamValue(CGF) 4011d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = CGF.Builder.CreateLoad( 4021d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 4031d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "is_most_derived"); 4041d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 4051d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 40659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (IsDeletingDtor(CGF.CurGD)) { 40759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov assert(getStructorImplicitParamDecl(CGF) && 40859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov "no implicit parameter for a deleting destructor?"); 40959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov getStructorImplicitParamValue(CGF) 41059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = CGF.Builder.CreateLoad( 41159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 41259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov "should_call_delete"); 41359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 414bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 415bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 41663fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Renllvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, 4171d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXConstructorDecl *D, 4181d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXCtorType Type, bool ForVirtualBase, 4191d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool Delegating, 4201d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *This, 4211d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgBeg, 4221d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgEnd) { 4231d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(Type == Ctor_Complete || Type == Ctor_Base); 4241d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete); 4251d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 4261d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *ImplicitParam = 0; 4271d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov QualType ImplicitParamTy; 4281d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (D->getParent()->getNumVBases()) { 4291d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); 4301d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParamTy = getContext().IntTy; 4311d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 4321d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 4331d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // FIXME: Provide a source location here. 4341d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, 4351d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParam, ImplicitParamTy, 4361d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ArgBeg, ArgEnd); 43763fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren return Callee; 4381d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 4391d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 4400f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur IskhodzhanovRValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, 4410f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CXXDestructorDecl *Dtor, 4420f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov CXXDtorType DtorType, 4430f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov SourceLocation CallLoc, 4440f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ReturnValueSlot ReturnValue, 4450f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *This) { 4460f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 4470f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 4480f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov // We have only one destructor in the vftable but can get both behaviors 4490f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov // by passing an implicit bool parameter. 4500f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CGFunctionInfo *FInfo 4510f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); 4520f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 4530f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty); 4540f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 4550f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ASTContext &Context = CGF.getContext(); 4560f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *ImplicitParam 4570f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()), 4580f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov DtorType == Dtor_Deleting); 4590f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 4600f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This, 4610f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ImplicitParam, Context.BoolTy, 0, 0); 4620f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov} 4630f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 464e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallbool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 465e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType elementType) { 466e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Microsoft seems to completely ignore the possibility of a 467e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // two-argument usual deallocation function. 468e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return elementType.isDestructedType(); 469e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 470e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 471e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallbool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 472e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Microsoft seems to completely ignore the possibility of a 473e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // two-argument usual deallocation function. 474e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return expr->getAllocatedType().isDestructedType(); 475e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 476e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 477e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallCharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) { 478e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The array cookie is always a size_t; we then pad that out to the 479e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // alignment of the element type. 480e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall ASTContext &Ctx = getContext(); 481e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), 482e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall Ctx.getTypeAlignInChars(type)); 483e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 484e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 485e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 486e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *allocPtr, 487e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize) { 488956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 489e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElementsPtr = 490e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS)); 491e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateLoad(numElementsPtr); 492e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 493e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 494e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 495e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *newPtr, 496e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElements, 497e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall const CXXNewExpr *expr, 498e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType elementType) { 499e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall assert(requiresArrayCookie(expr)); 500e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 501e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The size of the cookie. 502e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize = getArrayCookieSizeImpl(elementType); 503e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 504e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Compute an offset to the cookie. 505e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *cookiePtr = newPtr; 506e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 507e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Write the number of elements into the appropriate slot. 508956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AS = newPtr->getType()->getPointerAddressSpace(); 509e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElementsPtr 510e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS)); 511e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGF.Builder.CreateStore(numElements, numElementsPtr); 512e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 513e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Finally, compute a pointer to the actual data buffer by skipping 514e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // over the cookie completely. 515e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr, 516e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall cookieSize.getQuantity()); 517e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 518e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 51920bb175cb8ae5844034828db094fb948c0e3454aJohn McCallvoid MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 52020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::GlobalVariable *DeclPtr, 52120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall bool PerformInit) { 52220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // FIXME: this code was only tested for global initialization. 52320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Not sure whether we want thread-safe static local variables as VS 52420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // doesn't make them thread-safe. 52520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 52604e517650569598e847c2ab609672e6df93effe5Richard Smith if (D.getTLSKind()) 52704e517650569598e847c2ab609672e6df93effe5Richard Smith CGM.ErrorUnsupported(&D, "dynamic TLS initialization"); 52804e517650569598e847c2ab609672e6df93effe5Richard Smith 52920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Emit the initializer and add a global destructor if appropriate. 53020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit); 53120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall} 53220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 533a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Member pointer helpers. 534a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) { 535a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Inheritance == MSIM_Unspecified; 536a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 537a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 538f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerstatic bool hasOnlyOneField(bool IsMemberFunction, 539f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel Inheritance) { 540f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Inheritance <= MSIM_SinglePolymorphic || 541f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner (!IsMemberFunction && Inheritance <= MSIM_MultiplePolymorphic); 5423d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner} 5433d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 544a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Only member pointers to functions need a this adjustment, since it can be 545a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// combined with the field offset for data pointers. 54679e0291be71adb4c38431e27a683faa40bbedc61Reid Klecknerstatic bool hasNonVirtualBaseAdjustmentField(bool IsMemberFunction, 547a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance) { 54879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner return (IsMemberFunction && Inheritance >= MSIM_Multiple); 549a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 550a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 551a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) { 552a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Inheritance >= MSIM_Virtual; 553a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 554a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 555a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Use zero for the field offset of a null data member pointer if we can 556a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// guarantee that zero is not a valid field offset, or if the member pointer has 557a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// multiple fields. Polymorphic classes have a vfptr at offset zero, so we can 558a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// use zero for null. If there are multiple fields, we can use zero even if it 559a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// is a valid field offset because null-ness testing will check the other 560a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// fields. 561a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) { 562a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single; 563a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 564a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 565a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerbool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 566a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Null-ness for function memptrs only depends on the first field, which is 567a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // the function pointer. The rest don't matter, so we can zero initialize. 568a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 569a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return true; 570a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 571a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // The virtual base adjustment field is always -1 for null, so if we have one 572a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // we can't zero initialize. The field offset is sometimes also -1 if 0 is a 573a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // valid field offset. 574a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 575a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 576a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return (!hasVirtualBaseAdjustmentField(Inheritance) && 577a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner nullFieldOffsetIsZero(Inheritance)); 578a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 579a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 580a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerllvm::Type * 581a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerMicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 582a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 583a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 584a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Type *, 4> fields; 585a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 586a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk 587a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner else 588a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); // FieldOffset 589a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 59079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 59179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Inheritance)) 592a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); 59379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasVBPtrOffsetField(Inheritance)) 594a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); 595a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 596a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset 597a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 598a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (fields.size() == 1) 599a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return fields[0]; 600a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::StructType::get(CGM.getLLVMContext(), fields); 601a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 602a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 603a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknervoid MicrosoftCXXABI:: 604a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerGetNullMemberPointerFields(const MemberPointerType *MPT, 605a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVectorImpl<llvm::Constant *> &fields) { 606a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(fields.empty()); 607a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 608a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 609a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) { 610a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // FunctionPointerOrVirtualThunk 611a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 612a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } else { 613a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (nullFieldOffsetIsZero(Inheritance)) 614a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); // FieldOffset 615a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner else 616a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getAllOnesInt()); // FieldOffset 617a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 618a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 61979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 62079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Inheritance)) 621a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); 62279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasVBPtrOffsetField(Inheritance)) 623a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); 624a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 625a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getAllOnesInt()); 626a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 627a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 628a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Constant * 629a8a0f769ff4113a7f98c232fb0fc773a65371559Reid KlecknerMicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 630a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Constant *, 4> fields; 631a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner GetNullMemberPointerFields(MPT, fields); 632a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (fields.size() == 1) 633a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return fields[0]; 634a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields); 635a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(Res->getType() == ConvertMemberPointerType(MPT)); 636a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Res; 637a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 638a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 639a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Constant * 64079e0291be71adb4c38431e27a683faa40bbedc61Reid KlecknerMicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, 64179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner bool IsMemberFunction, 642f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXRecordDecl *RD, 643f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment) 64479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner{ 645a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 64679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 64779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // Single inheritance class member pointer are represented as scalars instead 64879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // of aggregates. 649f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(IsMemberFunction, Inheritance)) 65079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner return FirstField; 65179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 652a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Constant *, 4> fields; 65379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner fields.push_back(FirstField); 65479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 65579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasNonVirtualBaseAdjustmentField(IsMemberFunction, Inheritance)) 656f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner fields.push_back(llvm::ConstantInt::get( 657f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGM.IntTy, NonVirtualBaseAdjustment.getQuantity())); 65879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 659a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVBPtrOffsetField(Inheritance)) { 660f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME: We actually need to search non-virtual bases for vbptrs. 661a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner int64_t VBPtrOffset = 662a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner getContext().getASTRecordLayout(RD).getVBPtrOffset().getQuantity(); 66379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (VBPtrOffset == -1) 66479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner VBPtrOffset = 0; 665a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset)); 666a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 66779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 66879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // The rest of the fields are adjusted by conversions to a more derived class. 669a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 670a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); 67179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 672a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::ConstantStruct::getAnon(fields); 673a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 674a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 67579e0291be71adb4c38431e27a683faa40bbedc61Reid Klecknerllvm::Constant * 67679e0291be71adb4c38431e27a683faa40bbedc61Reid KlecknerMicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 67779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner CharUnits offset) { 67879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 67979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Constant *FirstField = 68079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); 681f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD, 682f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits::Zero()); 683f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 684f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 685f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { 686f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return BuildMemberPointer(MD->getParent(), MD, CharUnits::Zero()); 687f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 688f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 689f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP, 690f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner QualType MPType) { 691f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); 692f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const ValueDecl *MPD = MP.getMemberPointerDecl(); 693f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!MPD) 694f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitNullMemberPointer(MPT); 695f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 696f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); 697f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 698f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME PR15713: Support virtual inheritance paths. 699f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 700f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) 701f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return BuildMemberPointer(MPT->getClass()->getAsCXXRecordDecl(), 702f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MD, ThisAdjustment); 703f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 704f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits FieldOffset = 705f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); 706f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); 70779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner} 70879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 70979e0291be71adb4c38431e27a683faa40bbedc61Reid Klecknerllvm::Constant * 710f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknerMicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD, 711f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXMethodDecl *MD, 712f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment) { 71379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner assert(MD->isInstance() && "Member function must not be static!"); 71479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner MD = MD->getCanonicalDecl(); 71579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner CodeGenTypes &Types = CGM.getTypes(); 71679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 71779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Constant *FirstField; 71879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (MD->isVirtual()) { 71979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // FIXME: We have to instantiate a thunk that loads the vftable and jumps to 72079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // the right offset. 72179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); 72279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } else { 72379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 72479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Type *Ty; 72579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // Check whether the function has a computable LLVM signature. 72679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (Types.isFuncTypeConvertible(FPT)) { 72779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // The function has a computable LLVM signature; use the correct type. 72879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); 72979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } else { 73079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // Use an arbitrary non-function type to tell GetAddrOfFunction that the 73179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // function type is incomplete. 73279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Ty = CGM.PtrDiffTy; 73379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } 73479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner FirstField = CGM.GetAddrOfFunction(MD, Ty); 73579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); 73679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } 73779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 73879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // The rest of the fields are common with data member pointers. 739f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD, 740f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NonVirtualBaseAdjustment); 74179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner} 74279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 7433d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner/// Member pointers are the same if they're either bitwise identical *or* both 7443d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner/// null. Null-ness for function members is determined by the first field, 7453d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner/// while for data member pointers we must compare all fields. 7463d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Klecknerllvm::Value * 7473d2f000df9311bfccb6d2ac350be3d3efa5a412bReid KlecknerMicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 7483d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *L, 7493d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *R, 7503d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner const MemberPointerType *MPT, 7513d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner bool Inequality) { 7523d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner CGBuilderTy &Builder = CGF.Builder; 7533d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 7543d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Handle != comparisons by switching the sense of all boolean operations. 7553d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::ICmpInst::Predicate Eq; 7563d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Instruction::BinaryOps And, Or; 7573d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner if (Inequality) { 7583d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Eq = llvm::ICmpInst::ICMP_NE; 7593d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner And = llvm::Instruction::Or; 7603d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Or = llvm::Instruction::And; 7613d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } else { 7623d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Eq = llvm::ICmpInst::ICMP_EQ; 7633d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner And = llvm::Instruction::And; 7643d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Or = llvm::Instruction::Or; 7653d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } 7663d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 7673d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // If this is a single field member pointer (single inheritance), this is a 7683d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // single icmp. 7693d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 7703d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 771f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(MPT->isMemberFunctionPointer(), Inheritance)) 7723d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner return Builder.CreateICmp(Eq, L, R); 7733d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 7743d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Compare the first field. 7753d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0"); 7763d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0"); 7773d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first"); 7783d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 7793d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Compare everything other than the first field. 7803d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Res = 0; 7813d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::StructType *LType = cast<llvm::StructType>(L->getType()); 7823d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) { 7833d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *LF = Builder.CreateExtractValue(L, I); 7843d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *RF = Builder.CreateExtractValue(R, I); 7853d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest"); 7863d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner if (Res) 7873d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Res = Builder.CreateBinOp(And, Res, Cmp); 7883d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner else 7893d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Res = Cmp; 7903d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } 7913d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 7923d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Check if the first field is 0 if this is a function pointer. 7933d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner if (MPT->isMemberFunctionPointer()) { 7943d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // (l1 == r1 && ...) || l0 == 0 7953d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType()); 7963d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero"); 7973d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Res = Builder.CreateBinOp(Or, Res, IsZero); 7983d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } 7993d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8003d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Combine the comparison of the first field, which must always be true for 8013d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // this comparison to succeeed. 8023d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp"); 8033d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner} 8043d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 805a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Value * 806a8a0f769ff4113a7f98c232fb0fc773a65371559Reid KlecknerMicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 807a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 808a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT) { 809a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CGBuilderTy &Builder = CGF.Builder; 810a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Constant *, 4> fields; 811a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // We only need one field for member functions. 812a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 813a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 814a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner else 815a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner GetNullMemberPointerFields(MPT, fields); 816a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(!fields.empty()); 817a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *FirstField = MemPtr; 818a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MemPtr->getType()->isStructTy()) 819a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner FirstField = Builder.CreateExtractValue(MemPtr, 0); 820a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0"); 821a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 822a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // For function member pointers, we only need to test the function pointer 823a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // field. The other fields if any can be garbage. 824a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 825a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Res; 826a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 827a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Otherwise, emit a series of compares and combine the results. 828a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner for (int I = 1, E = fields.size(); I < E; ++I) { 829a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I); 830a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp"); 831a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Res = Builder.CreateAnd(Res, Next, "memptr.tobool"); 832a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 833a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Res; 834a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 835a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 836f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerbool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT, 837f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Val) { 838f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Function pointers are null if the pointer in the first field is null. 839f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (MPT->isMemberFunctionPointer()) { 840f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *FirstField = Val->getType()->isStructTy() ? 841f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Val->getAggregateElement(0U) : Val; 842f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return FirstField->isNullValue(); 843f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 844f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 845f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // If it's not a function pointer and it's zero initializable, we can easily 846f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // check zero. 847f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (isZeroInitializable(MPT) && Val->isNullValue()) 848f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return true; 849f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 850f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Otherwise, break down all the fields for comparison. Hopefully these 851f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // little Constants are reused, while a big null struct might not be. 852f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::SmallVector<llvm::Constant *, 4> Fields; 853f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner GetNullMemberPointerFields(MPT, Fields); 854f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Fields.size() == 1) { 855f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner assert(Val->getType()->isIntegerTy()); 856f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Val == Fields[0]; 857f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 858f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 859f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned I, E; 860f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner for (I = 0, E = Fields.size(); I != E; ++I) { 861f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Val->getAggregateElement(I) != Fields[I]) 862f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner break; 863f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 864f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return I == E; 865f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 866f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 867b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Klecknerllvm::Value * 868b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerMicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 869b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *This, 870b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset, 871b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrOffset, 872b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value **VBPtrOut) { 873b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGBuilderTy &Builder = CGF.Builder; 874b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // Load the vbtable pointer from the vbptr in the instance. 875b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner This = Builder.CreateBitCast(This, CGM.Int8PtrTy); 876b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtr = 877b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Builder.CreateInBoundsGEP(This, VBPtrOffset, "vbptr"); 878b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (VBPtrOut) *VBPtrOut = VBPtr; 879b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBPtr = Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0)); 880b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTable = Builder.CreateLoad(VBPtr, "vbtable"); 881b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 882b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // Load an i32 offset from the vb-table. 883b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableOffset); 884b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); 885b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return Builder.CreateLoad(VBaseOffs, "vbase_offs"); 886b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 887b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 888a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Returns an adjusted base cast to i8*, since we do more address arithmetic on 889a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// it. 890a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerllvm::Value * 891a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerMicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF, 892a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD, llvm::Value *Base, 893b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset, 894a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset) { 895a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGBuilderTy &Builder = CGF.Builder; 896a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy); 897a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::BasicBlock *OriginalBB = 0; 898a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::BasicBlock *SkipAdjustBB = 0; 899a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::BasicBlock *VBaseAdjustBB = 0; 900a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 901a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // In the unspecified inheritance model, there might not be a vbtable at all, 902a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // in which case we need to skip the virtual base lookup. If there is a 903a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // vbtable, the first entry is a no-op entry that gives back the original 904a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // base, so look for a virtual base adjustment offset of zero. 905a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VBPtrOffset) { 906a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner OriginalBB = Builder.GetInsertBlock(); 907a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust"); 908a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust"); 909a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *IsVirtual = 910b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Builder.CreateICmpNE(VBTableOffset, getZeroInt(), 911a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner "memptr.is_vbase"); 912a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB); 913a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGF.EmitBlock(VBaseAdjustBB); 914a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 915a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 916a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // If we weren't given a dynamic vbptr offset, RD should be complete and we'll 917a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // know the vbptr offset. 918a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (!VBPtrOffset) { 919b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits offs = CharUnits::Zero(); 920b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (RD->getNumVBases()) { 921b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner offs = GetVBPtrOffsetFromBases(RD); 922b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 923a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity()); 924a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 925b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtr = 0; 926a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBaseOffs = 927b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner GetVBaseOffsetFromVBPtr(CGF, Base, VBTableOffset, VBPtrOffset, &VBPtr); 928a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs); 929a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 930a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Merge control flow with the case where we didn't have to adjust. 931a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VBaseAdjustBB) { 932a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Builder.CreateBr(SkipAdjustBB); 933a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGF.EmitBlock(SkipAdjustBB); 934a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base"); 935a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Phi->addIncoming(Base, OriginalBB); 936a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Phi->addIncoming(AdjustedBase, VBaseAdjustBB); 937a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Phi; 938a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 939a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return AdjustedBase; 940a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 941a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 942a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Value * 943a8a0f769ff4113a7f98c232fb0fc773a65371559Reid KlecknerMicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, 944a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *Base, 945a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 946a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT) { 947a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(MPT->isMemberDataPointer()); 948a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner unsigned AS = Base->getType()->getPointerAddressSpace(); 949a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Type *PType = 950a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS); 951a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CGBuilderTy &Builder = CGF.Builder; 952a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 953a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 954a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 955a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Extract the fields we need, regardless of model. We'll apply them if we 956a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // have them. 957a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *FieldOffset = MemPtr; 958a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset = 0; 959a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset = 0; 960a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MemPtr->getType()->isStructTy()) { 961a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // We need to extract values. 962a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner unsigned I = 0; 963a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner FieldOffset = Builder.CreateExtractValue(MemPtr, I++); 964a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVBPtrOffsetField(Inheritance)) 965a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 966a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 967a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 968a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 969a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 970a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VirtualBaseAdjustmentOffset) { 971a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset, 972a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset); 973a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 974a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Addr = 975a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset"); 976a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 977a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner // Cast the address to the appropriate pointer type, adopting the address 978a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner // space of the base pointer. 979a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner return Builder.CreateBitCast(Addr, PType); 980a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 981a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 982f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerstatic MSInheritanceModel 983f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknergetInheritanceFromMemptr(const MemberPointerType *MPT) { 984f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return MPT->getClass()->getAsCXXRecordDecl()->getMSInheritanceModel(); 985f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 986f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 987f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Value * 988f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknerMicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 989f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CastExpr *E, 990f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *Src) { 991f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 992f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getCastKind() == CK_BaseToDerivedMemberPointer || 993f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getCastKind() == CK_ReinterpretMemberPointer); 994f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 995f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Use constant emission if we can. 996f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (isa<llvm::Constant>(Src)) 997f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src)); 998f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 999f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We may be adding or dropping fields from the member pointer, so we need 1000f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // both types and the inheritance models of both records. 1001f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *SrcTy = 1002f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getSubExpr()->getType()->castAs<MemberPointerType>(); 1003f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); 1004f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); 1005f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); 1006f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsFunc = SrcTy->isMemberFunctionPointer(); 1007f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1008f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // If the classes use the same null representation, reinterpret_cast is a nop. 1009f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer; 1010f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (IsReinterpret && (IsFunc || 1011f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner nullFieldOffsetIsZero(SrcInheritance) == 1012f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner nullFieldOffsetIsZero(DstInheritance))) 1013f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Src; 1014f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1015f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGBuilderTy &Builder = CGF.Builder; 1016f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1017f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Branch past the conversion if Src is null. 1018f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy); 1019f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *DstNull = EmitNullMemberPointer(DstTy); 1020f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1021f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // C++ 5.2.10p9: The null member pointer value is converted to the null member 1022f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // pointer value of the destination type. 1023f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (IsReinterpret) { 1024f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // For reinterpret casts, sema ensures that src and dst are both functions 1025f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // or data and have the same size, which means the LLVM types should match. 1026f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner assert(Src->getType() == DstNull->getType()); 1027f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Builder.CreateSelect(IsNotNull, Src, DstNull); 1028f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1029f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1030f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock(); 1031f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::BasicBlock *ConvertBB = CGF.createBasicBlock("memptr.convert"); 1032f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::BasicBlock *ContinueBB = CGF.createBasicBlock("memptr.converted"); 1033f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB); 1034f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGF.EmitBlock(ConvertBB); 1035f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1036f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Decompose src. 1037f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *FirstField = Src; 1038f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *NonVirtualBaseAdjustment = 0; 1039f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset = 0; 1040f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *VBPtrOffset = 0; 1041f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!hasOnlyOneField(IsFunc, SrcInheritance)) { 1042f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We need to extract values. 1043f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned I = 0; 1044f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner FirstField = Builder.CreateExtractValue(Src, I++); 1045f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) 1046f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++); 1047f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(SrcInheritance)) 1048f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VBPtrOffset = Builder.CreateExtractValue(Src, I++); 1049f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(SrcInheritance)) 1050f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++); 1051f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1052f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1053f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // For data pointers, we adjust the field offset directly. For functions, we 1054f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // have a separate field. 1055f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Adj = getMemberPointerAdjustment(E); 1056f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Adj) { 1057f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); 1058f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField; 1059f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 1060f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!NVAdjustField) // If this field didn't exist in src, it's zero. 1061f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = getZeroInt(); 1062f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (isDerivedToBase) 1063f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = Builder.CreateNSWSub(NVAdjustField, Adj, "adj"); 1064f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner else 1065f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, Adj, "adj"); 1066f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1067f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1068f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME PR15713: Support conversions through virtually derived classes. 1069f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1070f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Recompose dst from the null struct and the adjusted fields from src. 1071f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *Dst; 1072f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(IsFunc, DstInheritance)) { 1073f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = FirstField; 1074f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } else { 1075f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = llvm::UndefValue::get(DstNull->getType()); 1076f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned Idx = 0; 1077f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++); 1078f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) 1079f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue( 1080f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst, getValueOrZeroInt(NonVirtualBaseAdjustment), Idx++); 1081f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(DstInheritance)) 1082f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue( 1083f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst, getValueOrZeroInt(VBPtrOffset), Idx++); 1084f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(DstInheritance)) 1085f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue( 1086f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst, getValueOrZeroInt(VirtualBaseAdjustmentOffset), Idx++); 1087f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1088f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Builder.CreateBr(ContinueBB); 1089f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1090f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // In the continuation, choose between DstNull and Dst. 1091f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGF.EmitBlock(ContinueBB); 1092f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted"); 1093f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Phi->addIncoming(DstNull, OriginalBB); 1094f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Phi->addIncoming(Dst, ConvertBB); 1095f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Phi; 1096f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 1097f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1098f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Constant * 1099f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknerMicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E, 1100f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Src) { 1101f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *SrcTy = 1102f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getSubExpr()->getType()->castAs<MemberPointerType>(); 1103f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); 1104f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1105f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // If src is null, emit a new null for dst. We can't return src because dst 1106f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // might have a new representation. 1107f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (MemberPointerConstantIsNull(SrcTy, Src)) 1108f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitNullMemberPointer(DstTy); 1109f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1110f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We don't need to do anything for reinterpret_casts of non-null member 1111f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // pointers. We should only get here when the two type representations have 1112f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // the same size. 1113f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (E->getCastKind() == CK_ReinterpretMemberPointer) 1114f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Src; 1115f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1116f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); 1117f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); 1118f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1119f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Decompose src. 1120f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *FirstField = Src; 1121f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *NonVirtualBaseAdjustment = 0; 1122f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *VirtualBaseAdjustmentOffset = 0; 1123f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *VBPtrOffset = 0; 1124f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsFunc = SrcTy->isMemberFunctionPointer(); 1125f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!hasOnlyOneField(IsFunc, SrcInheritance)) { 1126f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We need to extract values. 1127f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned I = 0; 1128f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner FirstField = Src->getAggregateElement(I++); 1129f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) 1130f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NonVirtualBaseAdjustment = Src->getAggregateElement(I++); 1131f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(SrcInheritance)) 1132f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VBPtrOffset = Src->getAggregateElement(I++); 1133f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(SrcInheritance)) 1134f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VirtualBaseAdjustmentOffset = Src->getAggregateElement(I++); 1135f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1136f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1137f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // For data pointers, we adjust the field offset directly. For functions, we 1138f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // have a separate field. 1139f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Adj = getMemberPointerAdjustment(E); 1140f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Adj) { 1141f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); 1142f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *&NVAdjustField = 1143f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner IsFunc ? NonVirtualBaseAdjustment : FirstField; 1144f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 1145f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!NVAdjustField) // If this field didn't exist in src, it's zero. 1146f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = getZeroInt(); 1147f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (IsDerivedToBase) 1148f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = llvm::ConstantExpr::getNSWSub(NVAdjustField, Adj); 1149f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner else 1150f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = llvm::ConstantExpr::getNSWAdd(NVAdjustField, Adj); 1151f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1152f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1153f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME PR15713: Support conversions through virtually derived classes. 1154f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1155f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Recompose dst from the null struct and the adjusted fields from src. 1156f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(IsFunc, DstInheritance)) 1157f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return FirstField; 1158f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1159f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::SmallVector<llvm::Constant *, 4> Fields; 1160f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(FirstField); 1161f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) 1162f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(getConstantOrZeroInt(NonVirtualBaseAdjustment)); 1163f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(DstInheritance)) 1164f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(getConstantOrZeroInt(VBPtrOffset)); 1165f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(DstInheritance)) 1166f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(getConstantOrZeroInt(VirtualBaseAdjustmentOffset)); 1167f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return llvm::ConstantStruct::getAnon(Fields); 1168f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 1169f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1170a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerllvm::Value * 1171a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerMicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 1172a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *&This, 1173a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *MemPtr, 1174a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const MemberPointerType *MPT) { 1175a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(MPT->isMemberFunctionPointer()); 1176a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const FunctionProtoType *FPT = 1177a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MPT->getPointeeType()->castAs<FunctionProtoType>(); 1178a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1179a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::FunctionType *FTy = 1180a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGM.getTypes().GetFunctionType( 1181a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGM.getTypes().arrangeCXXMethodType(RD, FPT)); 1182a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGBuilderTy &Builder = CGF.Builder; 1183a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1184a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1185a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1186a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Extract the fields we need, regardless of model. We'll apply them if we 1187a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // have them. 1188a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *FunctionPointer = MemPtr; 1189a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *NonVirtualBaseAdjustment = NULL; 1190a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset = NULL; 1191a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset = NULL; 1192a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MemPtr->getType()->isStructTy()) { 1193a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // We need to extract values. 1194a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner unsigned I = 0; 1195a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner FunctionPointer = Builder.CreateExtractValue(MemPtr, I++); 1196a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance)) 1197a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++); 119879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasVBPtrOffsetField(Inheritance)) 119979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 1200a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 1201a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 1202a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1203a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1204a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VirtualBaseAdjustmentOffset) { 1205a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset, 1206a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset); 1207a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1208a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1209a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (NonVirtualBaseAdjustment) { 1210a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Apply the adjustment and cast back to the original struct type. 1211a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); 1212a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment); 1213a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); 1214a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1215a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1216a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo()); 1217a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 1218a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1219071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { 1220c3926645d70842eae22641df1bf69da457a0ff11Charles Davis return new MicrosoftCXXABI(CGM); 1221c3926645d70842eae22641df1bf69da457a0ff11Charles Davis} 1222c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 1223