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" 199063302a82423cb83f002257a416741850739a70Reid Kleckner#include "CGVTables.h" 209063302a82423cb83f002257a416741850739a70Reid Kleckner#include "MicrosoftVBTables.h" 21c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "clang/AST/Decl.h" 22c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "clang/AST/DeclCXX.h" 23635de28950ef84ae26308ff734e778bad1ddde92Timur Iskhodzhanov#include "clang/AST/VTableBuilder.h" 24c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 25c3926645d70842eae22641df1bf69da457a0ff11Charles Davisusing namespace clang; 26c3926645d70842eae22641df1bf69da457a0ff11Charles Davisusing namespace CodeGen; 27c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 28c3926645d70842eae22641df1bf69da457a0ff11Charles Davisnamespace { 29c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 30071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CGCXXABI { 31c3926645d70842eae22641df1bf69da457a0ff11Charles Davispublic: 3214110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {} 334c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 343b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin bool HasThisReturn(GlobalDecl GD) const; 353b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin 36ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov bool isReturnTypeIndirect(const CXXRecordDecl *RD) const { 37ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov // Structures that are not C++03 PODs are always indirect. 38ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return !RD->isPOD(); 39ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov } 40ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov 41ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const { 429b60195ad4843c9e2e231673a0dbc0d5c8c6eb2bReid Kleckner if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialDestructor()) 43ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return RAA_DirectInMemory; 44ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov return RAA_Default; 45ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov } 46ed23bdf69dd63e4fd01c02b12a13d1e6cbff9c2fTimur Iskhodzhanov 47285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos StringRef GetPureVirtualCallName() { return "_purecall"; } 482eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie // No known support for deleted functions in MSVC yet, so this choice is 492eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie // arbitrary. 502eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie StringRef GetDeletedVirtualCallName() { return "_purecall"; } 51285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos 52ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, 53ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *ptr, 54ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall QualType type); 55ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 56b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, 57b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *This, 58b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *ClassDecl, 59b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *BaseClassDecl); 60b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 614c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildConstructorSignature(const CXXConstructorDecl *Ctor, 624c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CXXCtorType Type, 634c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CanQualType &ResTy, 64bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall SmallVectorImpl<CanQualType> &ArgTys); 654c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 669063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 679063302a82423cb83f002257a416741850739a70Reid Kleckner const CXXRecordDecl *RD); 681d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 69bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov void EmitCXXConstructors(const CXXConstructorDecl *D); 70bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov 71a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Background on MSVC destructors 72a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // ============================== 73a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // 74a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Both Itanium and MSVC ABIs have destructor variants. The variant names 75a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // roughly correspond in the following way: 76a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Itanium Microsoft 77a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Base -> no name, just ~Class 78a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Complete -> vbase destructor 79a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // Deleting -> scalar deleting destructor 80a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // vector deleting destructor 81a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // 82a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // The base and complete destructors are the same as in Itanium, although the 83a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // complete destructor does not accept a VTT parameter when there are virtual 84a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // bases. A separate mechanism involving vtordisps is used to ensure that 85a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // virtual methods of destroyed subobjects are not called. 86a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // 87a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // The deleting destructors accept an i32 bitfield as a second parameter. Bit 88a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // 1 indicates if the memory should be deleted. Bit 2 indicates if the this 89a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // pointer points to an array. The scalar deleting destructor assumes that 90a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // bit 2 is zero, and therefore does not contain a loop. 91a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // 92a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // For virtual destructors, only one entry is reserved in the vftable, and it 93a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // always points to the vector deleting destructor. The vector deleting 94a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // destructor is the most general, so it can be used to destroy objects in 95a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // place, delete single heap objects, or delete arrays. 96a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // 97a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // A TU defining a non-inline destructor is only guaranteed to emit a base 98a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // destructor, and all of the other variants are emitted on an as-needed basis 99a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // in COMDATs. Because a non-base destructor can be emitted in a TU that 100a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // lacks a definition for the destructor, non-base destructors must always 101a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // delegate to or alias the base destructor. 102a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 103a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner void BuildDestructorSignature(const CXXDestructorDecl *Dtor, 1044c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CXXDtorType Type, 1054c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CanQualType &ResTy, 10659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov SmallVectorImpl<CanQualType> &ArgTys); 1074c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 108a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner /// Non-base dtors should be emitted as delegating thunks in this ABI. 109a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, 110a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner CXXDtorType DT) const { 111a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner return DT != Dtor_Base; 112a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner } 113a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 114a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner void EmitCXXDestructors(const CXXDestructorDecl *D); 115a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 1164c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildInstanceFunctionParams(CodeGenFunction &CGF, 1174c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall QualType &ResTy, 118bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall FunctionArgList &Params); 1194c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 120bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall void EmitInstanceFunctionProlog(CodeGenFunction &CGF); 121fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall 1223b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin void EmitConstructorCall(CodeGenFunction &CGF, 1233b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin const CXXConstructorDecl *D, CXXCtorType Type, 1243b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin bool ForVirtualBase, bool Delegating, 1254444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin llvm::Value *This, 1264444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin CallExpr::const_arg_iterator ArgBeg, 1274444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin CallExpr::const_arg_iterator ArgEnd); 1283b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin 1293b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin void EmitVirtualDestructorCall(CodeGenFunction &CGF, 1303b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin const CXXDestructorDecl *Dtor, 1313b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin CXXDtorType DtorType, SourceLocation CallLoc, 1323b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin llvm::Value *This); 1330f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 1349063302a82423cb83f002257a416741850739a70Reid Kleckner void EmitVirtualInheritanceTables(llvm::GlobalVariable::LinkageTypes Linkage, 1359063302a82423cb83f002257a416741850739a70Reid Kleckner const CXXRecordDecl *RD); 1369063302a82423cb83f002257a416741850739a70Reid Kleckner 13720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 13820bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::GlobalVariable *DeclPtr, 13920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall bool PerformInit); 14020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 141fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // ==== Notes on array cookies ========= 142fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // 143fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // MSVC seems to only use cookies when the class has a destructor; a 144fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // two-argument usual array deallocation function isn't sufficient. 145fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // 146fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // For example, this code prints "100" and "1": 147fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // struct A { 148fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // char x; 149fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // void *operator new[](size_t sz) { 150fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // printf("%u\n", sz); 151fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // return malloc(sz); 152fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 153fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // void operator delete[](void *p, size_t sz) { 154fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // printf("%u\n", sz); 155fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // free(p); 156fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 157fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // }; 158fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // int main() { 159fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // A *p = new A[100]; 160fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // delete[] p; 161fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 162fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // Whereas it prints "104" and "104" if you give A a destructor. 163e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 164e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType); 165e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall bool requiresArrayCookie(const CXXNewExpr *expr); 166e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits getArrayCookieSizeImpl(QualType type); 167e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 168e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *NewPtr, 169e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *NumElements, 170e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall const CXXNewExpr *expr, 171e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType ElementType); 172e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 173e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *allocPtr, 174e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize); 175a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 176a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerprivate: 177a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Constant *getZeroInt() { 178a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::ConstantInt::get(CGM.IntTy, 0); 179a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 180a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 181a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Constant *getAllOnesInt() { 182a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::Constant::getAllOnesValue(CGM.IntTy); 183a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 184a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 185f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *getConstantOrZeroInt(llvm::Constant *C) { 186f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return C ? C : getZeroInt(); 187f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 188f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 189f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *getValueOrZeroInt(llvm::Value *C) { 190f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return C ? C : getZeroInt(); 191f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 192f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 193a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner void 194a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner GetNullMemberPointerFields(const MemberPointerType *MPT, 195a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVectorImpl<llvm::Constant *> &fields); 196a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 197b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// \brief Finds the offset from the base of RD to the vbptr it uses, even if 198b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// it is reusing a vbptr from a non-virtual base. RD must have morally 199b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// virtual bases. 200b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD); 201b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 202b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// \brief Shared code for virtual base adjustment. Returns the offset from 203b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// the vbptr to the virtual base. Optionally returns the address of the 204b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// vbptr itself. 205b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 206b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *Base, 207b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrOffset, 208b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset, 209b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value **VBPtr = 0); 210b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 211b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// \brief Performs a full virtual base adjustment. Used to dereference 212b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner /// pointers to members of virtual bases. 213a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD, 214a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Base, 215a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset, 216a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset /* optional */); 217a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 21879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner /// \brief Emits a full member pointer with the fields common to data and 21979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner /// function member pointers. 22079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField, 22179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner bool IsMemberFunction, 222f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXRecordDecl *RD, 223f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment); 224f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 225f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *BuildMemberPointer(const CXXRecordDecl *RD, 226f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXMethodDecl *MD, 227f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment); 228f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 229f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool MemberPointerConstantIsNull(const MemberPointerType *MPT, 230f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *MP); 23179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 2329063302a82423cb83f002257a416741850739a70Reid Kleckner /// \brief - Initialize all vbptrs of 'this' with RD as the complete type. 2339063302a82423cb83f002257a416741850739a70Reid Kleckner void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD); 2349063302a82423cb83f002257a416741850739a70Reid Kleckner 2359063302a82423cb83f002257a416741850739a70Reid Kleckner /// \brief Caching wrapper around VBTableBuilder::enumerateVBTables(). 2369063302a82423cb83f002257a416741850739a70Reid Kleckner const VBTableVector &EnumerateVBTables(const CXXRecordDecl *RD); 2379063302a82423cb83f002257a416741850739a70Reid Kleckner 238a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerpublic: 239a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT); 240a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 241a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner virtual bool isZeroInitializable(const MemberPointerType *MPT); 242a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 243a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); 244a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 245a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 246a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CharUnits offset); 24779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD); 24879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); 249a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 2503d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner virtual llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF, 2513d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *L, 2523d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *R, 2533d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner const MemberPointerType *MPT, 2543d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner bool Inequality); 2553d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 256a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 257a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 258a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT); 259a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 260a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, 261a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *Base, 262a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 263a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT); 264a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 265f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, 266f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CastExpr *E, 267f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *Src); 268f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 269f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, 270f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Src); 271f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 272a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner virtual llvm::Value * 273a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 274a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *&This, 275a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *MemPtr, 276a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const MemberPointerType *MPT); 277a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 2789063302a82423cb83f002257a416741850739a70Reid Klecknerprivate: 2799063302a82423cb83f002257a416741850739a70Reid Kleckner /// VBTables - All the vbtables which have been referenced. 2809063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::DenseMap<const CXXRecordDecl *, VBTableVector> VBTablesMap; 281c3926645d70842eae22641df1bf69da457a0ff11Charles Davis}; 282c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 283c3926645d70842eae22641df1bf69da457a0ff11Charles Davis} 284c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 285ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCallllvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, 286ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *ptr, 287ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall QualType type) { 288ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall // FIXME: implement 289ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall return ptr; 290ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall} 291ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 2928c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner/// \brief Finds the first non-virtual base of RD that has virtual bases. If RD 2938c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner/// doesn't have a vbptr, it will reuse the vbptr of the returned class. 2948c47432b747d51e40a1e23a99403e78c2c864bd1Reid Klecknerstatic const CXXRecordDecl *FindFirstNVBaseWithVBases(const CXXRecordDecl *RD) { 2958c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 2968c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner E = RD->bases_end(); I != E; ++I) { 2978c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl(); 2988c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner if (!I->isVirtual() && Base->getNumVBases() > 0) 2998c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner return Base; 3008c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner } 3018c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner llvm_unreachable("RD must have an nv base with vbases"); 3028c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner} 3038c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner 304b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerCharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) { 305b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner assert(RD->getNumVBases()); 306b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits Total = CharUnits::Zero(); 307b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner while (RD) { 308b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const ASTRecordLayout &RDLayout = getContext().getASTRecordLayout(RD); 309b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits VBPtrOffset = RDLayout.getVBPtrOffset(); 310b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // -1 is the sentinel for no vbptr. 311b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (VBPtrOffset != CharUnits::fromQuantity(-1)) { 312b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Total += VBPtrOffset; 313b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner break; 314b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 3158c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner RD = FindFirstNVBaseWithVBases(RD); 3168c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner Total += RDLayout.getBaseClassOffset(RD); 317b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 318b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return Total; 319b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 320b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 321b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Klecknerllvm::Value * 322b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerMicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF, 323b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *This, 324b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *ClassDecl, 325b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner const CXXRecordDecl *BaseClassDecl) { 326b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity(); 327b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars); 328b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy); 3298c47432b747d51e40a1e23a99403e78c2c864bd1Reid Kleckner CharUnits VBTableChars = IntSize * GetVBTableIndex(ClassDecl, BaseClassDecl); 330b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset = 331b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity()); 332b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 333b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrToNewBase = 334b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner GetVBaseOffsetFromVBPtr(CGF, This, VBTableOffset, VBPtrOffset); 335b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBPtrToNewBase = 336b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGF.Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy); 337b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return CGF.Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase); 338b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 339b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 3403b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Linbool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const { 3413b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin return isa<CXXConstructorDecl>(GD.getDecl()); 342bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 343bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 344bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, 345bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CXXCtorType Type, 346bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CanQualType &ResTy, 347bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall SmallVectorImpl<CanQualType> &ArgTys) { 3483b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin // 'this' parameter and 'this' return are already in place 3491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3501d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXRecordDecl *Class = Ctor->getParent(); 3511d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (Class->getNumVBases()) { 3521d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Constructors of classes with virtual bases take an implicit parameter. 3531d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ArgTys.push_back(CGM.getContext().IntTy); 3541d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 3551d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 3561d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3579063302a82423cb83f002257a416741850739a70Reid Klecknerllvm::BasicBlock * 3589063302a82423cb83f002257a416741850739a70Reid KlecknerMicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 3599063302a82423cb83f002257a416741850739a70Reid Kleckner const CXXRecordDecl *RD) { 3601d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF); 3611d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(IsMostDerivedClass && 3621d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "ctor for a class with virtual bases must have an implicit parameter"); 3639063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::Value *IsCompleteObject = 3649063302a82423cb83f002257a416741850739a70Reid Kleckner CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object"); 3651d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3661d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases"); 3671d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases"); 3681d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.Builder.CreateCondBr(IsCompleteObject, 3691d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallVbaseCtorsBB, SkipVbaseCtorsBB); 3701d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3711d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.EmitBlock(CallVbaseCtorsBB); 3729063302a82423cb83f002257a416741850739a70Reid Kleckner 3739063302a82423cb83f002257a416741850739a70Reid Kleckner // Fill in the vbtable pointers here. 3749063302a82423cb83f002257a416741850739a70Reid Kleckner EmitVBPtrStores(CGF, RD); 3751d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3761d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // CGF will put the base ctor calls in this basic block for us later. 3771d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 3781d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov return SkipVbaseCtorsBB; 379bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 380bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 381bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanovvoid MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) { 382bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov // There's only one constructor type in this ABI. 383bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete)); 384bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov} 385bb1b797d2e432293563747bd9704b22cf0787061Timur Iskhodzhanov 3869063302a82423cb83f002257a416741850739a70Reid Klecknervoid MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF, 3879063302a82423cb83f002257a416741850739a70Reid Kleckner const CXXRecordDecl *RD) { 3889063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::Value *ThisInt8Ptr = 3899063302a82423cb83f002257a416741850739a70Reid Kleckner CGF.Builder.CreateBitCast(getThisValue(CGF), CGM.Int8PtrTy, "this.int8"); 3909063302a82423cb83f002257a416741850739a70Reid Kleckner 3919063302a82423cb83f002257a416741850739a70Reid Kleckner const VBTableVector &VBTables = EnumerateVBTables(RD); 3929063302a82423cb83f002257a416741850739a70Reid Kleckner for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end(); 3939063302a82423cb83f002257a416741850739a70Reid Kleckner I != E; ++I) { 3949063302a82423cb83f002257a416741850739a70Reid Kleckner const ASTRecordLayout &SubobjectLayout = 3959063302a82423cb83f002257a416741850739a70Reid Kleckner CGM.getContext().getASTRecordLayout(I->VBPtrSubobject.getBase()); 3969063302a82423cb83f002257a416741850739a70Reid Kleckner uint64_t Offs = (I->VBPtrSubobject.getBaseOffset() + 3979063302a82423cb83f002257a416741850739a70Reid Kleckner SubobjectLayout.getVBPtrOffset()).getQuantity(); 3989063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::Value *VBPtr = 3999063302a82423cb83f002257a416741850739a70Reid Kleckner CGF.Builder.CreateConstInBoundsGEP1_64(ThisInt8Ptr, Offs); 4009063302a82423cb83f002257a416741850739a70Reid Kleckner VBPtr = CGF.Builder.CreateBitCast(VBPtr, I->GV->getType()->getPointerTo(0), 4019063302a82423cb83f002257a416741850739a70Reid Kleckner "vbptr." + I->ReusingBase->getName()); 4029063302a82423cb83f002257a416741850739a70Reid Kleckner CGF.Builder.CreateStore(I->GV, VBPtr); 4039063302a82423cb83f002257a416741850739a70Reid Kleckner } 4049063302a82423cb83f002257a416741850739a70Reid Kleckner} 4059063302a82423cb83f002257a416741850739a70Reid Kleckner 40659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanovvoid MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, 40759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CXXDtorType Type, 40859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CanQualType &ResTy, 40959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov SmallVectorImpl<CanQualType> &ArgTys) { 41059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // 'this' is already in place 4113b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin 41259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // TODO: 'for base' flag 41359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 41459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (Type == Dtor_Deleting) { 41559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // The scalar deleting destructor takes an implicit bool parameter. 41659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ArgTys.push_back(CGM.getContext().BoolTy); 41759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 41859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov} 41959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 420a4130baad9d10b7feabb7e003da53424e986d269Reid Klecknervoid MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) { 421a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // The TU defining a dtor is only guaranteed to emit a base destructor. All 422a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner // other destructor variants are delegating thunks. 423a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner CGM.EmitGlobal(GlobalDecl(D, Dtor_Base)); 424a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner} 425a4130baad9d10b7feabb7e003da53424e986d269Reid Kleckner 42659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanovstatic bool IsDeletingDtor(GlobalDecl GD) { 42759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 42859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (isa<CXXDestructorDecl>(MD)) { 42959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov return GD.getDtorType() == Dtor_Deleting; 43059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 43159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov return false; 43259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov} 43359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 434bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, 435bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall QualType &ResTy, 436bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall FunctionArgList &Params) { 437bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall BuildThisParam(CGF, Params); 43859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 4391d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ASTContext &Context = getContext(); 4401d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 4411d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 4421d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParamDecl *IsMostDerived 4431d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = ImplicitParamDecl::Create(Context, 0, 4441d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.CurGD.getDecl()->getLocation(), 4451d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov &Context.Idents.get("is_most_derived"), 4461d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Context.IntTy); 4471d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Params.push_back(IsMostDerived); 4481d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov getStructorImplicitParamDecl(CGF) = IsMostDerived; 4491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } else if (IsDeletingDtor(CGF.CurGD)) { 45059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ImplicitParamDecl *ShouldDelete 45159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = ImplicitParamDecl::Create(Context, 0, 45259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.CurGD.getDecl()->getLocation(), 45359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov &Context.Idents.get("should_call_delete"), 45459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov Context.BoolTy); 45559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov Params.push_back(ShouldDelete); 45659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov getStructorImplicitParamDecl(CGF) = ShouldDelete; 45759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 458bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 459bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 460bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 461bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall EmitThisParam(CGF); 4623b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin 4633b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// If this is a function that the ABI specifies returns 'this', initialize 4643b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// the return slot to 'this' at the start of the function. 4653b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// 4663b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// Unlike the setting of return types, this is done within the ABI 4673b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// implementation instead of by clients of CGCXXABI because: 4683b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// 1) getThisValue is currently protected 4693b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// 2) in theory, an ABI could implement 'this' returns some other way; 4703b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin /// HasThisReturn only specifies a contract, not the implementation 4713b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin if (HasThisReturn(CGF.CurGD)) 472bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 4731d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 4741d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 4751d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 4761d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(getStructorImplicitParamDecl(CGF) && 4771d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "no implicit parameter for a constructor with virtual bases?"); 4781d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov getStructorImplicitParamValue(CGF) 4791d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = CGF.Builder.CreateLoad( 4801d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 4811d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "is_most_derived"); 4821d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 4831d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 48459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (IsDeletingDtor(CGF.CurGD)) { 48559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov assert(getStructorImplicitParamDecl(CGF) && 48659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov "no implicit parameter for a deleting destructor?"); 48759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov getStructorImplicitParamValue(CGF) 48859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = CGF.Builder.CreateLoad( 48959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 49059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov "should_call_delete"); 49159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 492bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 493bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 4943b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Linvoid MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, 4954444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin const CXXConstructorDecl *D, 4963b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin CXXCtorType Type, 4973b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin bool ForVirtualBase, 4984444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin bool Delegating, 4994444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin llvm::Value *This, 5001d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgBeg, 5011d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgEnd) { 5021d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(Type == Ctor_Complete || Type == Ctor_Base); 5031d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete); 5041d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 5051d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *ImplicitParam = 0; 5061d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov QualType ImplicitParamTy; 5071d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (D->getParent()->getNumVBases()) { 5081d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); 5091d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParamTy = getContext().IntTy; 5101d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 5111d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 5121d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // FIXME: Provide a source location here. 5134444dbbb96ba55ff8a05a1918627f609a387db9fStephen Lin CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, 5143b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin ImplicitParam, ImplicitParamTy, ArgBeg, ArgEnd); 5151d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 5161d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 5173b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Linvoid MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, 5183b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin const CXXDestructorDecl *Dtor, 5193b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin CXXDtorType DtorType, 5203b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin SourceLocation CallLoc, 5213b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin llvm::Value *This) { 5220f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 5230f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 5240f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov // We have only one destructor in the vftable but can get both behaviors 5250f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov // by passing an implicit bool parameter. 5260f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CGFunctionInfo *FInfo 5270f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); 5280f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 5296e007f9fa0b9ebe5898025010c5ebc7d82decfa7Timur Iskhodzhanov llvm::Value *Callee 5306e007f9fa0b9ebe5898025010c5ebc7d82decfa7Timur Iskhodzhanov = CGF.BuildVirtualCall(GlobalDecl(Dtor, Dtor_Deleting), This, Ty); 5310f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 5320f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ASTContext &Context = CGF.getContext(); 5330f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *ImplicitParam 5340f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()), 5350f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov DtorType == Dtor_Deleting); 5360f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 5373b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This, 5383b50e8d78c34fc57e25781015a2cb0536ca54f89Stephen Lin ImplicitParam, Context.BoolTy, 0, 0); 5390f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov} 5400f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 5419063302a82423cb83f002257a416741850739a70Reid Klecknerconst VBTableVector & 5429063302a82423cb83f002257a416741850739a70Reid KlecknerMicrosoftCXXABI::EnumerateVBTables(const CXXRecordDecl *RD) { 5439063302a82423cb83f002257a416741850739a70Reid Kleckner // At this layer, we can key the cache off of a single class, which is much 5449063302a82423cb83f002257a416741850739a70Reid Kleckner // easier than caching at the GlobalVariable layer. 5459063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::DenseMap<const CXXRecordDecl*, VBTableVector>::iterator I; 5469063302a82423cb83f002257a416741850739a70Reid Kleckner bool added; 5479063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::tie(I, added) = VBTablesMap.insert(std::make_pair(RD, VBTableVector())); 5489063302a82423cb83f002257a416741850739a70Reid Kleckner VBTableVector &VBTables = I->second; 5499063302a82423cb83f002257a416741850739a70Reid Kleckner if (!added) 5509063302a82423cb83f002257a416741850739a70Reid Kleckner return VBTables; 5519063302a82423cb83f002257a416741850739a70Reid Kleckner 5529063302a82423cb83f002257a416741850739a70Reid Kleckner VBTableBuilder(CGM, RD).enumerateVBTables(VBTables); 5539063302a82423cb83f002257a416741850739a70Reid Kleckner 5549063302a82423cb83f002257a416741850739a70Reid Kleckner return VBTables; 5559063302a82423cb83f002257a416741850739a70Reid Kleckner} 5569063302a82423cb83f002257a416741850739a70Reid Kleckner 5579063302a82423cb83f002257a416741850739a70Reid Klecknervoid MicrosoftCXXABI::EmitVirtualInheritanceTables( 5589063302a82423cb83f002257a416741850739a70Reid Kleckner llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD) { 5599063302a82423cb83f002257a416741850739a70Reid Kleckner const VBTableVector &VBTables = EnumerateVBTables(RD); 5609063302a82423cb83f002257a416741850739a70Reid Kleckner for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end(); 5619063302a82423cb83f002257a416741850739a70Reid Kleckner I != E; ++I) { 5629063302a82423cb83f002257a416741850739a70Reid Kleckner I->EmitVBTableDefinition(CGM, RD, Linkage); 5639063302a82423cb83f002257a416741850739a70Reid Kleckner } 5649063302a82423cb83f002257a416741850739a70Reid Kleckner} 5659063302a82423cb83f002257a416741850739a70Reid Kleckner 566e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallbool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 567e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType elementType) { 568e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Microsoft seems to completely ignore the possibility of a 569e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // two-argument usual deallocation function. 570e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return elementType.isDestructedType(); 571e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 572e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 573e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallbool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 574e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Microsoft seems to completely ignore the possibility of a 575e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // two-argument usual deallocation function. 576e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return expr->getAllocatedType().isDestructedType(); 577e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 578e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 579e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallCharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) { 580e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The array cookie is always a size_t; we then pad that out to the 581e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // alignment of the element type. 582e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall ASTContext &Ctx = getContext(); 583e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), 584e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall Ctx.getTypeAlignInChars(type)); 585e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 586e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 587e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 588e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *allocPtr, 589e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize) { 590956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 591e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElementsPtr = 592e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS)); 593e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateLoad(numElementsPtr); 594e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 595e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 596e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 597e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *newPtr, 598e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElements, 599e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall const CXXNewExpr *expr, 600e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType elementType) { 601e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall assert(requiresArrayCookie(expr)); 602e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 603e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The size of the cookie. 604e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize = getArrayCookieSizeImpl(elementType); 605e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 606e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Compute an offset to the cookie. 607e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *cookiePtr = newPtr; 608e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 609e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Write the number of elements into the appropriate slot. 610956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AS = newPtr->getType()->getPointerAddressSpace(); 611e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElementsPtr 612e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS)); 613e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGF.Builder.CreateStore(numElements, numElementsPtr); 614e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 615e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Finally, compute a pointer to the actual data buffer by skipping 616e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // over the cookie completely. 617e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr, 618e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall cookieSize.getQuantity()); 619e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 620e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 62120bb175cb8ae5844034828db094fb948c0e3454aJohn McCallvoid MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 62220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::GlobalVariable *DeclPtr, 62320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall bool PerformInit) { 62420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // FIXME: this code was only tested for global initialization. 62520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Not sure whether we want thread-safe static local variables as VS 62620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // doesn't make them thread-safe. 62720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 62804e517650569598e847c2ab609672e6df93effe5Richard Smith if (D.getTLSKind()) 62904e517650569598e847c2ab609672e6df93effe5Richard Smith CGM.ErrorUnsupported(&D, "dynamic TLS initialization"); 63004e517650569598e847c2ab609672e6df93effe5Richard Smith 63120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Emit the initializer and add a global destructor if appropriate. 63220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit); 63320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall} 63420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 635a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Member pointer helpers. 636a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) { 637a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Inheritance == MSIM_Unspecified; 638a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 639a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 640f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerstatic bool hasOnlyOneField(bool IsMemberFunction, 641f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel Inheritance) { 642f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Inheritance <= MSIM_SinglePolymorphic || 643f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner (!IsMemberFunction && Inheritance <= MSIM_MultiplePolymorphic); 6443d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner} 6453d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 646a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Only member pointers to functions need a this adjustment, since it can be 647a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// combined with the field offset for data pointers. 64879e0291be71adb4c38431e27a683faa40bbedc61Reid Klecknerstatic bool hasNonVirtualBaseAdjustmentField(bool IsMemberFunction, 649a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance) { 65079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner return (IsMemberFunction && Inheritance >= MSIM_Multiple); 651a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 652a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 653a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) { 654a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Inheritance >= MSIM_Virtual; 655a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 656a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 657a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Use zero for the field offset of a null data member pointer if we can 658a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// guarantee that zero is not a valid field offset, or if the member pointer has 659a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// multiple fields. Polymorphic classes have a vfptr at offset zero, so we can 660a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// use zero for null. If there are multiple fields, we can use zero even if it 661a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// is a valid field offset because null-ness testing will check the other 662a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// fields. 663a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) { 664a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single; 665a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 666a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 667a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerbool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) { 668a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Null-ness for function memptrs only depends on the first field, which is 669a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // the function pointer. The rest don't matter, so we can zero initialize. 670a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 671a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return true; 672a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 673a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // The virtual base adjustment field is always -1 for null, so if we have one 674a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // we can't zero initialize. The field offset is sometimes also -1 if 0 is a 675a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // valid field offset. 676a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 677a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 678a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return (!hasVirtualBaseAdjustmentField(Inheritance) && 679a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner nullFieldOffsetIsZero(Inheritance)); 680a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 681a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 682a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerllvm::Type * 683a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerMicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { 684a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 685a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 686a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Type *, 4> fields; 687a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 688a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk 689a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner else 690a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); // FieldOffset 691a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 69279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 69379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Inheritance)) 694a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); 69579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasVBPtrOffsetField(Inheritance)) 696a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); 697a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 698a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset 699a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 700a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (fields.size() == 1) 701a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return fields[0]; 702a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::StructType::get(CGM.getLLVMContext(), fields); 703a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 704a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 705a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknervoid MicrosoftCXXABI:: 706a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerGetNullMemberPointerFields(const MemberPointerType *MPT, 707a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVectorImpl<llvm::Constant *> &fields) { 708a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(fields.empty()); 709a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 710a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 711a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) { 712a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // FunctionPointerOrVirtualThunk 713a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 714a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } else { 715a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (nullFieldOffsetIsZero(Inheritance)) 716a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); // FieldOffset 717a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner else 718a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getAllOnesInt()); // FieldOffset 719a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 720a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 72179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(), 72279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Inheritance)) 723a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); 72479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasVBPtrOffsetField(Inheritance)) 725a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); 726a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 727a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getAllOnesInt()); 728a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 729a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 730a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Constant * 731a8a0f769ff4113a7f98c232fb0fc773a65371559Reid KlecknerMicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) { 732a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Constant *, 4> fields; 733a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner GetNullMemberPointerFields(MPT, fields); 734a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (fields.size() == 1) 735a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return fields[0]; 736a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields); 737a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(Res->getType() == ConvertMemberPointerType(MPT)); 738a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Res; 739a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 740a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 741a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Constant * 74279e0291be71adb4c38431e27a683faa40bbedc61Reid KlecknerMicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, 74379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner bool IsMemberFunction, 744f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXRecordDecl *RD, 745f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment) 74679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner{ 747a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 74879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 74979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // Single inheritance class member pointer are represented as scalars instead 75079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // of aggregates. 751f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(IsMemberFunction, Inheritance)) 75279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner return FirstField; 75379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 754a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Constant *, 4> fields; 75579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner fields.push_back(FirstField); 75679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 75779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasNonVirtualBaseAdjustmentField(IsMemberFunction, Inheritance)) 758f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner fields.push_back(llvm::ConstantInt::get( 759f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGM.IntTy, NonVirtualBaseAdjustment.getQuantity())); 76079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 761a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVBPtrOffsetField(Inheritance)) { 762a06d585468ae9371eb46a69d6180c2a85e0f456eReid Kleckner fields.push_back(llvm::ConstantInt::get( 763a06d585468ae9371eb46a69d6180c2a85e0f456eReid Kleckner CGM.IntTy, GetVBPtrOffsetFromBases(RD).getQuantity())); 764a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 76579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 76679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // The rest of the fields are adjusted by conversions to a more derived class. 767a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 768a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(getZeroInt()); 76979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 770a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return llvm::ConstantStruct::getAnon(fields); 771a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 772a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 77379e0291be71adb4c38431e27a683faa40bbedc61Reid Klecknerllvm::Constant * 77479e0291be71adb4c38431e27a683faa40bbedc61Reid KlecknerMicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, 77579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner CharUnits offset) { 77679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 77779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Constant *FirstField = 77879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); 779f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD, 780f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits::Zero()); 781f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 782f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 783f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) { 784f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return BuildMemberPointer(MD->getParent(), MD, CharUnits::Zero()); 785f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 786f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 787f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP, 788f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner QualType MPType) { 789f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *MPT = MPType->castAs<MemberPointerType>(); 790f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const ValueDecl *MPD = MP.getMemberPointerDecl(); 791f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!MPD) 792f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitNullMemberPointer(MPT); 793f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 794f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP); 795f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 796f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME PR15713: Support virtual inheritance paths. 797f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 798f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) 799f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return BuildMemberPointer(MPT->getClass()->getAsCXXRecordDecl(), 800f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MD, ThisAdjustment); 801f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 802f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits FieldOffset = 803f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD)); 804f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset); 80579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner} 80679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 80779e0291be71adb4c38431e27a683faa40bbedc61Reid Klecknerllvm::Constant * 808f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknerMicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD, 809f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CXXMethodDecl *MD, 810f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CharUnits NonVirtualBaseAdjustment) { 81179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner assert(MD->isInstance() && "Member function must not be static!"); 81279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner MD = MD->getCanonicalDecl(); 81379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner CodeGenTypes &Types = CGM.getTypes(); 81479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 81579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Constant *FirstField; 81679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (MD->isVirtual()) { 81779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // FIXME: We have to instantiate a thunk that loads the vftable and jumps to 81879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // the right offset. 81979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy); 82079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } else { 82179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); 82279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner llvm::Type *Ty; 82379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // Check whether the function has a computable LLVM signature. 82479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (Types.isFuncTypeConvertible(FPT)) { 82579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // The function has a computable LLVM signature; use the correct type. 82679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD)); 82779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } else { 82879e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // Use an arbitrary non-function type to tell GetAddrOfFunction that the 82979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // function type is incomplete. 83079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner Ty = CGM.PtrDiffTy; 83179e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } 83279e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner FirstField = CGM.GetAddrOfFunction(MD, Ty); 83379e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy); 83479e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner } 83579e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 83679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner // The rest of the fields are common with data member pointers. 837f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD, 838f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NonVirtualBaseAdjustment); 83979e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner} 84079e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner 8413d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner/// Member pointers are the same if they're either bitwise identical *or* both 8423d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner/// null. Null-ness for function members is determined by the first field, 8433d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner/// while for data member pointers we must compare all fields. 8443d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Klecknerllvm::Value * 8453d2f000df9311bfccb6d2ac350be3d3efa5a412bReid KlecknerMicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, 8463d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *L, 8473d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *R, 8483d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner const MemberPointerType *MPT, 8493d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner bool Inequality) { 8503d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner CGBuilderTy &Builder = CGF.Builder; 8513d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8523d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Handle != comparisons by switching the sense of all boolean operations. 8533d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::ICmpInst::Predicate Eq; 8543d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Instruction::BinaryOps And, Or; 8553d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner if (Inequality) { 8563d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Eq = llvm::ICmpInst::ICMP_NE; 8573d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner And = llvm::Instruction::Or; 8583d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Or = llvm::Instruction::And; 8593d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } else { 8603d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Eq = llvm::ICmpInst::ICMP_EQ; 8613d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner And = llvm::Instruction::And; 8623d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Or = llvm::Instruction::Or; 8633d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } 8643d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8653d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // If this is a single field member pointer (single inheritance), this is a 8663d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // single icmp. 8673d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 8683d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 869f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(MPT->isMemberFunctionPointer(), Inheritance)) 8703d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner return Builder.CreateICmp(Eq, L, R); 8713d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8723d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Compare the first field. 8733d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0"); 8743d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0"); 8753d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first"); 8763d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8773d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Compare everything other than the first field. 8783d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Res = 0; 8793d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::StructType *LType = cast<llvm::StructType>(L->getType()); 8803d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) { 8813d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *LF = Builder.CreateExtractValue(L, I); 8823d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *RF = Builder.CreateExtractValue(R, I); 8833d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest"); 8843d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner if (Res) 8853d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Res = Builder.CreateBinOp(And, Res, Cmp); 8863d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner else 8873d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Res = Cmp; 8883d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } 8893d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8903d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Check if the first field is 0 if this is a function pointer. 8913d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner if (MPT->isMemberFunctionPointer()) { 8923d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // (l1 == r1 && ...) || l0 == 0 8933d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType()); 8943d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero"); 8953d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner Res = Builder.CreateBinOp(Or, Res, IsZero); 8963d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner } 8973d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 8983d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // Combine the comparison of the first field, which must always be true for 8993d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner // this comparison to succeeed. 9003d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp"); 9013d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner} 9023d2f000df9311bfccb6d2ac350be3d3efa5a412bReid Kleckner 903a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Value * 904a8a0f769ff4113a7f98c232fb0fc773a65371559Reid KlecknerMicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 905a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 906a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT) { 907a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CGBuilderTy &Builder = CGF.Builder; 908a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::SmallVector<llvm::Constant *, 4> fields; 909a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // We only need one field for member functions. 910a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 911a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); 912a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner else 913a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner GetNullMemberPointerFields(MPT, fields); 914a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(!fields.empty()); 915a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *FirstField = MemPtr; 916a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MemPtr->getType()->isStructTy()) 917a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner FirstField = Builder.CreateExtractValue(MemPtr, 0); 918a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0"); 919a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 920a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // For function member pointers, we only need to test the function pointer 921a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // field. The other fields if any can be garbage. 922a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MPT->isMemberFunctionPointer()) 923a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Res; 924a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 925a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Otherwise, emit a series of compares and combine the results. 926a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner for (int I = 1, E = fields.size(); I < E; ++I) { 927a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I); 928a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp"); 929a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Res = Builder.CreateAnd(Res, Next, "memptr.tobool"); 930a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 931a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Res; 932a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 933a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 934f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerbool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT, 935f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Val) { 936f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Function pointers are null if the pointer in the first field is null. 937f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (MPT->isMemberFunctionPointer()) { 938f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *FirstField = Val->getType()->isStructTy() ? 939f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Val->getAggregateElement(0U) : Val; 940f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return FirstField->isNullValue(); 941f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 942f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 943f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // If it's not a function pointer and it's zero initializable, we can easily 944f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // check zero. 945f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (isZeroInitializable(MPT) && Val->isNullValue()) 946f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return true; 947f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 948f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Otherwise, break down all the fields for comparison. Hopefully these 949f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // little Constants are reused, while a big null struct might not be. 950f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::SmallVector<llvm::Constant *, 4> Fields; 951f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner GetNullMemberPointerFields(MPT, Fields); 952f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Fields.size() == 1) { 953f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner assert(Val->getType()->isIntegerTy()); 954f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Val == Fields[0]; 955f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 956f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 957f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned I, E; 958f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner for (I = 0, E = Fields.size(); I != E; ++I) { 959f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Val->getAggregateElement(I) != Fields[I]) 960f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner break; 961f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 962f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return I == E; 963f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 964f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 965b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Klecknerllvm::Value * 966b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid KlecknerMicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF, 967b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *This, 968b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset, 969b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtrOffset, 970b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value **VBPtrOut) { 971b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CGBuilderTy &Builder = CGF.Builder; 972b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // Load the vbtable pointer from the vbptr in the instance. 973b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner This = Builder.CreateBitCast(This, CGM.Int8PtrTy); 974b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtr = 975b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Builder.CreateInBoundsGEP(This, VBPtrOffset, "vbptr"); 976b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (VBPtrOut) *VBPtrOut = VBPtr; 977b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBPtr = Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0)); 978b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTable = Builder.CreateLoad(VBPtr, "vbtable"); 979b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 980b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner // Load an i32 offset from the vb-table. 981b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableOffset); 982b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0)); 983b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner return Builder.CreateLoad(VBaseOffs, "vbase_offs"); 984b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner} 985b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner 986a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// Returns an adjusted base cast to i8*, since we do more address arithmetic on 987a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner// it. 988a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerllvm::Value * 989a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerMicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF, 990a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD, llvm::Value *Base, 991b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBTableOffset, 992a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset) { 993a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGBuilderTy &Builder = CGF.Builder; 994a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy); 995a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::BasicBlock *OriginalBB = 0; 996a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::BasicBlock *SkipAdjustBB = 0; 997a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::BasicBlock *VBaseAdjustBB = 0; 998a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 999a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // In the unspecified inheritance model, there might not be a vbtable at all, 1000a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // in which case we need to skip the virtual base lookup. If there is a 1001a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // vbtable, the first entry is a no-op entry that gives back the original 1002a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // base, so look for a virtual base adjustment offset of zero. 1003a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VBPtrOffset) { 1004a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner OriginalBB = Builder.GetInsertBlock(); 1005a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust"); 1006a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust"); 1007a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *IsVirtual = 1008b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner Builder.CreateICmpNE(VBTableOffset, getZeroInt(), 1009a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner "memptr.is_vbase"); 1010a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB); 1011a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGF.EmitBlock(VBaseAdjustBB); 1012a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 1013a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 1014a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // If we weren't given a dynamic vbptr offset, RD should be complete and we'll 1015a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // know the vbptr offset. 1016a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (!VBPtrOffset) { 1017b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner CharUnits offs = CharUnits::Zero(); 1018b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner if (RD->getNumVBases()) { 1019b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner offs = GetVBPtrOffsetFromBases(RD); 1020b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner } 1021a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity()); 1022a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1023b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner llvm::Value *VBPtr = 0; 1024a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBaseOffs = 1025b0f533e716ae5a21ca5682ea235a68082fd5ed28Reid Kleckner GetVBaseOffsetFromVBPtr(CGF, Base, VBTableOffset, VBPtrOffset, &VBPtr); 1026a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs); 1027a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1028a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Merge control flow with the case where we didn't have to adjust. 1029a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VBaseAdjustBB) { 1030a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Builder.CreateBr(SkipAdjustBB); 1031a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGF.EmitBlock(SkipAdjustBB); 1032a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base"); 1033a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Phi->addIncoming(Base, OriginalBB); 1034a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Phi->addIncoming(AdjustedBase, VBaseAdjustBB); 1035a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Phi; 1036a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1037a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return AdjustedBase; 1038a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 1039a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 1040a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Klecknerllvm::Value * 1041a8a0f769ff4113a7f98c232fb0fc773a65371559Reid KlecknerMicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, 1042a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *Base, 1043a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Value *MemPtr, 1044a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner const MemberPointerType *MPT) { 1045a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(MPT->isMemberDataPointer()); 1046a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner unsigned AS = Base->getType()->getPointerAddressSpace(); 1047a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner llvm::Type *PType = 1048a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS); 1049a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner CGBuilderTy &Builder = CGF.Builder; 1050a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1051a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1052a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1053a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Extract the fields we need, regardless of model. We'll apply them if we 1054a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // have them. 1055a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *FieldOffset = MemPtr; 1056a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset = 0; 1057a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset = 0; 1058a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MemPtr->getType()->isStructTy()) { 1059a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // We need to extract values. 1060a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner unsigned I = 0; 1061a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner FieldOffset = Builder.CreateExtractValue(MemPtr, I++); 1062a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVBPtrOffsetField(Inheritance)) 1063a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 1064a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 1065a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 1066a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 1067a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 1068a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VirtualBaseAdjustmentOffset) { 1069a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset, 1070a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset); 1071a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner } 1072a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Addr = 1073a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset"); 1074a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 1075a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner // Cast the address to the appropriate pointer type, adopting the address 1076a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner // space of the base pointer. 1077a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner return Builder.CreateBitCast(Addr, PType); 1078a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner} 1079a8a0f769ff4113a7f98c232fb0fc773a65371559Reid Kleckner 1080f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerstatic MSInheritanceModel 1081f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknergetInheritanceFromMemptr(const MemberPointerType *MPT) { 1082f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return MPT->getClass()->getAsCXXRecordDecl()->getMSInheritanceModel(); 1083f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 1084f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1085f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Value * 1086f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknerMicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF, 1087f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const CastExpr *E, 1088f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *Src) { 1089f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner assert(E->getCastKind() == CK_DerivedToBaseMemberPointer || 1090f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getCastKind() == CK_BaseToDerivedMemberPointer || 1091f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getCastKind() == CK_ReinterpretMemberPointer); 1092f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1093f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Use constant emission if we can. 1094f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (isa<llvm::Constant>(Src)) 1095f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src)); 1096f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1097f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We may be adding or dropping fields from the member pointer, so we need 1098f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // both types and the inheritance models of both records. 1099f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *SrcTy = 1100f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getSubExpr()->getType()->castAs<MemberPointerType>(); 1101f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); 1102f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); 1103f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); 1104f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsFunc = SrcTy->isMemberFunctionPointer(); 1105f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1106f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // If the classes use the same null representation, reinterpret_cast is a nop. 1107f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer; 1108f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (IsReinterpret && (IsFunc || 1109f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner nullFieldOffsetIsZero(SrcInheritance) == 1110f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner nullFieldOffsetIsZero(DstInheritance))) 1111f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Src; 1112f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1113f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGBuilderTy &Builder = CGF.Builder; 1114f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1115f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Branch past the conversion if Src is null. 1116f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy); 1117f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *DstNull = EmitNullMemberPointer(DstTy); 1118f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1119f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // C++ 5.2.10p9: The null member pointer value is converted to the null member 1120f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // pointer value of the destination type. 1121f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (IsReinterpret) { 1122f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // For reinterpret casts, sema ensures that src and dst are both functions 1123f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // or data and have the same size, which means the LLVM types should match. 1124f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner assert(Src->getType() == DstNull->getType()); 1125f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Builder.CreateSelect(IsNotNull, Src, DstNull); 1126f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1127f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1128f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock(); 1129f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::BasicBlock *ConvertBB = CGF.createBasicBlock("memptr.convert"); 1130f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::BasicBlock *ContinueBB = CGF.createBasicBlock("memptr.converted"); 1131f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB); 1132f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGF.EmitBlock(ConvertBB); 1133f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1134f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Decompose src. 1135f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *FirstField = Src; 1136f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *NonVirtualBaseAdjustment = 0; 1137f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset = 0; 1138f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *VBPtrOffset = 0; 1139f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!hasOnlyOneField(IsFunc, SrcInheritance)) { 1140f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We need to extract values. 1141f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned I = 0; 1142f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner FirstField = Builder.CreateExtractValue(Src, I++); 1143f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) 1144f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++); 1145f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(SrcInheritance)) 1146f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VBPtrOffset = Builder.CreateExtractValue(Src, I++); 1147f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(SrcInheritance)) 1148f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++); 1149f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1150f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1151f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // For data pointers, we adjust the field offset directly. For functions, we 1152f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // have a separate field. 1153f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Adj = getMemberPointerAdjustment(E); 1154f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Adj) { 1155f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); 1156f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField; 1157f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 1158f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!NVAdjustField) // If this field didn't exist in src, it's zero. 1159f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = getZeroInt(); 1160f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (isDerivedToBase) 1161f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = Builder.CreateNSWSub(NVAdjustField, Adj, "adj"); 1162f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner else 1163f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, Adj, "adj"); 1164f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1165f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1166f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME PR15713: Support conversions through virtually derived classes. 1167f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1168f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Recompose dst from the null struct and the adjusted fields from src. 1169f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Value *Dst; 1170f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(IsFunc, DstInheritance)) { 1171f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = FirstField; 1172f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } else { 1173f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = llvm::UndefValue::get(DstNull->getType()); 1174f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned Idx = 0; 1175f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++); 1176f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) 1177f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue( 1178f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst, getValueOrZeroInt(NonVirtualBaseAdjustment), Idx++); 1179f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(DstInheritance)) 1180f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue( 1181f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst, getValueOrZeroInt(VBPtrOffset), Idx++); 1182f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(DstInheritance)) 1183f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst = Builder.CreateInsertValue( 1184f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Dst, getValueOrZeroInt(VirtualBaseAdjustmentOffset), Idx++); 1185f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1186f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Builder.CreateBr(ContinueBB); 1187f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1188f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // In the continuation, choose between DstNull and Dst. 1189f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner CGF.EmitBlock(ContinueBB); 1190f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted"); 1191f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Phi->addIncoming(DstNull, OriginalBB); 1192f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Phi->addIncoming(Dst, ConvertBB); 1193f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Phi; 1194f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 1195f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1196f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Klecknerllvm::Constant * 1197f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid KlecknerMicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E, 1198f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Src) { 1199f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *SrcTy = 1200f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner E->getSubExpr()->getType()->castAs<MemberPointerType>(); 1201f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>(); 1202f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1203f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // If src is null, emit a new null for dst. We can't return src because dst 1204f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // might have a new representation. 1205f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (MemberPointerConstantIsNull(SrcTy, Src)) 1206f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return EmitNullMemberPointer(DstTy); 1207f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1208f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We don't need to do anything for reinterpret_casts of non-null member 1209f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // pointers. We should only get here when the two type representations have 1210f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // the same size. 1211f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (E->getCastKind() == CK_ReinterpretMemberPointer) 1212f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return Src; 1213f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1214f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy); 1215f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy); 1216f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1217f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Decompose src. 1218f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *FirstField = Src; 1219f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *NonVirtualBaseAdjustment = 0; 1220f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *VirtualBaseAdjustmentOffset = 0; 1221f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *VBPtrOffset = 0; 1222f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsFunc = SrcTy->isMemberFunctionPointer(); 1223f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!hasOnlyOneField(IsFunc, SrcInheritance)) { 1224f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // We need to extract values. 1225f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner unsigned I = 0; 1226f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner FirstField = Src->getAggregateElement(I++); 1227f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance)) 1228f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NonVirtualBaseAdjustment = Src->getAggregateElement(I++); 1229f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(SrcInheritance)) 1230f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VBPtrOffset = Src->getAggregateElement(I++); 1231f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(SrcInheritance)) 1232f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner VirtualBaseAdjustmentOffset = Src->getAggregateElement(I++); 1233f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1234f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1235f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // For data pointers, we adjust the field offset directly. For functions, we 1236f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // have a separate field. 1237f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *Adj = getMemberPointerAdjustment(E); 1238f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (Adj) { 1239f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Adj = llvm::ConstantExpr::getTruncOrBitCast(Adj, CGM.IntTy); 1240f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::Constant *&NVAdjustField = 1241f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner IsFunc ? NonVirtualBaseAdjustment : FirstField; 1242f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner bool IsDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer); 1243f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (!NVAdjustField) // If this field didn't exist in src, it's zero. 1244f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = getZeroInt(); 1245f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (IsDerivedToBase) 1246f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = llvm::ConstantExpr::getNSWSub(NVAdjustField, Adj); 1247f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner else 1248f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner NVAdjustField = llvm::ConstantExpr::getNSWAdd(NVAdjustField, Adj); 1249f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner } 1250f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1251f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // FIXME PR15713: Support conversions through virtually derived classes. 1252f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1253f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner // Recompose dst from the null struct and the adjusted fields from src. 1254f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasOnlyOneField(IsFunc, DstInheritance)) 1255f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return FirstField; 1256f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1257f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner llvm::SmallVector<llvm::Constant *, 4> Fields; 1258f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(FirstField); 1259f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance)) 1260f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(getConstantOrZeroInt(NonVirtualBaseAdjustment)); 1261f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVBPtrOffsetField(DstInheritance)) 1262f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(getConstantOrZeroInt(VBPtrOffset)); 1263f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner if (hasVirtualBaseAdjustmentField(DstInheritance)) 1264f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner Fields.push_back(getConstantOrZeroInt(VirtualBaseAdjustmentOffset)); 1265f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner return llvm::ConstantStruct::getAnon(Fields); 1266f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner} 1267f632730ffb0b8ca531a35e737b29cc9f9774ca1dReid Kleckner 1268a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerllvm::Value * 1269a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknerMicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, 1270a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *&This, 1271a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *MemPtr, 1272a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const MemberPointerType *MPT) { 1273a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner assert(MPT->isMemberFunctionPointer()); 1274a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const FunctionProtoType *FPT = 1275a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MPT->getPointeeType()->castAs<FunctionProtoType>(); 1276a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); 1277a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::FunctionType *FTy = 1278a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGM.getTypes().GetFunctionType( 1279a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGM.getTypes().arrangeCXXMethodType(RD, FPT)); 1280a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner CGBuilderTy &Builder = CGF.Builder; 1281a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1282a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); 1283a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1284a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Extract the fields we need, regardless of model. We'll apply them if we 1285a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // have them. 1286a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *FunctionPointer = MemPtr; 1287a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *NonVirtualBaseAdjustment = NULL; 1288a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VirtualBaseAdjustmentOffset = NULL; 1289a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *VBPtrOffset = NULL; 1290a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (MemPtr->getType()->isStructTy()) { 1291a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // We need to extract values. 1292a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner unsigned I = 0; 1293a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner FunctionPointer = Builder.CreateExtractValue(MemPtr, I++); 1294a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance)) 1295a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++); 129679e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner if (hasVBPtrOffsetField(Inheritance)) 129779e0291be71adb4c38431e27a683faa40bbedc61Reid Kleckner VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); 1298a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (hasVirtualBaseAdjustmentField(Inheritance)) 1299a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); 1300a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1301a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1302a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (VirtualBaseAdjustmentOffset) { 1303a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset, 1304a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner VBPtrOffset); 1305a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1306a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1307a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner if (NonVirtualBaseAdjustment) { 1308a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner // Apply the adjustment and cast back to the original struct type. 1309a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy()); 1310a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment); 1311a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted"); 1312a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner } 1313a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1314a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo()); 1315a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner} 1316a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Kleckner 1317071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { 1318c3926645d70842eae22641df1bf69da457a0ff11Charles Davis return new MicrosoftCXXABI(CGM); 1319c3926645d70842eae22641df1bf69da457a0ff11Charles Davis} 1320c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 1321