MicrosoftCXXABI.cpp revision 63fd408a61ae9b94e8d8a986832f526f7cdbfa84
1c3926645d70842eae22641df1bf69da457a0ff11Charles Davis//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===// 2c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 3c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// The LLVM Compiler Infrastructure 4c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 5c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// This file is distributed under the University of Illinois Open Source 6c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// License. See LICENSE.TXT for details. 7c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 8c3926645d70842eae22641df1bf69da457a0ff11Charles Davis//===----------------------------------------------------------------------===// 9c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides C++ code generation targeting the Microsoft Visual C++ ABI. 11c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// The class in this file generates structures that follow the Microsoft 12c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// Visual C++ ABI, which is actually not very well documented at all outside 13c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// of Microsoft. 14c3926645d70842eae22641df1bf69da457a0ff11Charles Davis// 15c3926645d70842eae22641df1bf69da457a0ff11Charles Davis//===----------------------------------------------------------------------===// 16c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 17c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "CGCXXABI.h" 18c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "CodeGenModule.h" 19c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "clang/AST/Decl.h" 20c3926645d70842eae22641df1bf69da457a0ff11Charles Davis#include "clang/AST/DeclCXX.h" 21c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 22c3926645d70842eae22641df1bf69da457a0ff11Charles Davisusing namespace clang; 23c3926645d70842eae22641df1bf69da457a0ff11Charles Davisusing namespace CodeGen; 24c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 25c3926645d70842eae22641df1bf69da457a0ff11Charles Davisnamespace { 26c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 27071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CGCXXABI { 28c3926645d70842eae22641df1bf69da457a0ff11Charles Davispublic: 2914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {} 304c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 31285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos StringRef GetPureVirtualCallName() { return "_purecall"; } 322eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie // No known support for deleted functions in MSVC yet, so this choice is 332eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie // arbitrary. 342eb9a959d24ad757a82ecab61f343635ad67749aDavid Blaikie StringRef GetDeletedVirtualCallName() { return "_purecall"; } 35285baac67d722beb6854f5faa45ee1aa62a7ce92Joao Matos 36ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, 37ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *ptr, 38ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall QualType type); 39ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 404c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildConstructorSignature(const CXXConstructorDecl *Ctor, 414c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CXXCtorType Type, 424c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CanQualType &ResTy, 43bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall SmallVectorImpl<CanQualType> &ArgTys); 444c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 451d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF); 461d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 474c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildDestructorSignature(const CXXDestructorDecl *Ctor, 484c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CXXDtorType Type, 494c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall CanQualType &ResTy, 5059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov SmallVectorImpl<CanQualType> &ArgTys); 514c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 524c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall void BuildInstanceFunctionParams(CodeGenFunction &CGF, 534c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall QualType &ResTy, 54bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall FunctionArgList &Params); 554c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall 56bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall void EmitInstanceFunctionProlog(CodeGenFunction &CGF); 57fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall 5863fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren llvm::Value *EmitConstructorCall(CodeGenFunction &CGF, 591d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXConstructorDecl *D, 601d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXCtorType Type, bool ForVirtualBase, 611d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool Delegating, 621d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *This, 631d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgBeg, 641d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgEnd); 651d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 660f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov RValue EmitVirtualDestructorCall(CodeGenFunction &CGF, 670f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CXXDestructorDecl *Dtor, 680f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov CXXDtorType DtorType, 690f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov SourceLocation CallLoc, 700f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ReturnValueSlot ReturnValue, 710f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *This); 720f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 7320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 7420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::GlobalVariable *DeclPtr, 7520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall bool PerformInit); 7620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 77fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // ==== Notes on array cookies ========= 78fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // 79fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // MSVC seems to only use cookies when the class has a destructor; a 80fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // two-argument usual array deallocation function isn't sufficient. 81fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // 82fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // For example, this code prints "100" and "1": 83fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // struct A { 84fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // char x; 85fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // void *operator new[](size_t sz) { 86fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // printf("%u\n", sz); 87fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // return malloc(sz); 88fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 89fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // void operator delete[](void *p, size_t sz) { 90fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // printf("%u\n", sz); 91fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // free(p); 92fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 93fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // }; 94fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // int main() { 95fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // A *p = new A[100]; 96fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // delete[] p; 97fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // } 98fd708265e3b1dcfaae6a6832186aabb0de0c0aefJohn McCall // Whereas it prints "104" and "104" if you give A a destructor. 99e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 100e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType); 101e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall bool requiresArrayCookie(const CXXNewExpr *expr); 102e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits getArrayCookieSizeImpl(QualType type); 103e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, 104e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *NewPtr, 105e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *NumElements, 106e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall const CXXNewExpr *expr, 107e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType ElementType); 108e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, 109e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *allocPtr, 110e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize); 111bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall static bool needThisReturn(GlobalDecl GD); 112c3926645d70842eae22641df1bf69da457a0ff11Charles Davis}; 113c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 114c3926645d70842eae22641df1bf69da457a0ff11Charles Davis} 115c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 116ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCallllvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF, 117ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall llvm::Value *ptr, 118ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall QualType type) { 119ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall // FIXME: implement 120ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall return ptr; 121ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall} 122ecd03b447bb0e2ed1954c77441d49a4a17ca8138John McCall 123bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallbool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) { 124bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 125bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall return isa<CXXConstructorDecl>(MD); 126bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 127bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 128bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor, 129bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CXXCtorType Type, 130bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CanQualType &ResTy, 131bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall SmallVectorImpl<CanQualType> &ArgTys) { 132bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall // 'this' is already in place 1331d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 134bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall // Ctor returns this ptr 135bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall ResTy = ArgTys[0]; 1361d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1371d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXRecordDecl *Class = Ctor->getParent(); 1381d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (Class->getNumVBases()) { 1391d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // Constructors of classes with virtual bases take an implicit parameter. 1401d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ArgTys.push_back(CGM.getContext().IntTy); 1411d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 1421d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 1431d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1441d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanovllvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler( 1451d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CodeGenFunction &CGF) { 1461d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF); 1471d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(IsMostDerivedClass && 1481d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "ctor for a class with virtual bases must have an implicit parameter"); 1491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *IsCompleteObject 1501d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object"); 1511d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1521d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases"); 1531d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases"); 1541d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.Builder.CreateCondBr(IsCompleteObject, 1551d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallVbaseCtorsBB, SkipVbaseCtorsBB); 1561d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1571d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.EmitBlock(CallVbaseCtorsBB); 1581d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // FIXME: emit vbtables somewhere around here. 1591d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1601d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // CGF will put the base ctor calls in this basic block for us later. 1611d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 1621d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov return SkipVbaseCtorsBB; 163bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 164bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 16559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanovvoid MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor, 16659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CXXDtorType Type, 16759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CanQualType &ResTy, 16859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov SmallVectorImpl<CanQualType> &ArgTys) { 16959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // 'this' is already in place 17059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // TODO: 'for base' flag 17159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 17259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (Type == Dtor_Deleting) { 17359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov // The scalar deleting destructor takes an implicit bool parameter. 17459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ArgTys.push_back(CGM.getContext().BoolTy); 17559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 17659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov} 17759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 17859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanovstatic bool IsDeletingDtor(GlobalDecl GD) { 17959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl()); 18059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (isa<CXXDestructorDecl>(MD)) { 18159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov return GD.getDtorType() == Dtor_Deleting; 18259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 18359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov return false; 18459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov} 18559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 186bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, 187bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall QualType &ResTy, 188bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall FunctionArgList &Params) { 189bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall BuildThisParam(CGF, Params); 190bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall if (needThisReturn(CGF.CurGD)) { 191bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall ResTy = Params[0]->getType(); 192bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall } 19359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov 1941d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ASTContext &Context = getContext(); 1951d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 1961d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 1971d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParamDecl *IsMostDerived 1981d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = ImplicitParamDecl::Create(Context, 0, 1991d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.CurGD.getDecl()->getLocation(), 2001d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov &Context.Idents.get("is_most_derived"), 2011d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Context.IntTy); 2021d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov Params.push_back(IsMostDerived); 2031d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov getStructorImplicitParamDecl(CGF) = IsMostDerived; 2041d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } else if (IsDeletingDtor(CGF.CurGD)) { 20559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov ImplicitParamDecl *ShouldDelete 20659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = ImplicitParamDecl::Create(Context, 0, 20759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.CurGD.getDecl()->getLocation(), 20859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov &Context.Idents.get("should_call_delete"), 20959660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov Context.BoolTy); 21059660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov Params.push_back(ShouldDelete); 21159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov getStructorImplicitParamDecl(CGF) = ShouldDelete; 21259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 213bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 214bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 215bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCallvoid MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) { 216bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall EmitThisParam(CGF); 217bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall if (needThisReturn(CGF.CurGD)) { 218bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue); 219bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall } 2201d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 2211d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl()); 2221d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) { 2231d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(getStructorImplicitParamDecl(CGF) && 2241d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "no implicit parameter for a constructor with virtual bases?"); 2251d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov getStructorImplicitParamValue(CGF) 2261d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov = CGF.Builder.CreateLoad( 2271d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 2281d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov "is_most_derived"); 2291d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 2301d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 23159660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov if (IsDeletingDtor(CGF.CurGD)) { 23259660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov assert(getStructorImplicitParamDecl(CGF) && 23359660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov "no implicit parameter for a deleting destructor?"); 23459660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov getStructorImplicitParamValue(CGF) 23559660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov = CGF.Builder.CreateLoad( 23659660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), 23759660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov "should_call_delete"); 23859660c21178b6af518bd4b564e032d5c9cc218cbTimur Iskhodzhanov } 239bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall} 240bd31574a0f01da2cb2abde004b36772eb8a048dcJohn McCall 24163fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Renllvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF, 2421d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov const CXXConstructorDecl *D, 2431d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CXXCtorType Type, bool ForVirtualBase, 2441d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov bool Delegating, 2451d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *This, 2461d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgBeg, 2471d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CallExpr::const_arg_iterator ArgEnd) { 2481d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov assert(Type == Ctor_Complete || Type == Ctor_Base); 2491d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete); 2501d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 2511d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov llvm::Value *ImplicitParam = 0; 2521d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov QualType ImplicitParamTy; 2531d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov if (D->getParent()->getNumVBases()) { 2541d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete); 2551d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParamTy = getContext().IntTy; 2561d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov } 2571d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 2581d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov // FIXME: Provide a source location here. 2591d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This, 2601d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ImplicitParam, ImplicitParamTy, 2611d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov ArgBeg, ArgEnd); 26263fd408a61ae9b94e8d8a986832f526f7cdbfa84Manman Ren return Callee; 2631d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov} 2641d4fff5551c2347010b955b4337a2aa7d65a050eTimur Iskhodzhanov 2650f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur IskhodzhanovRValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF, 2660f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CXXDestructorDecl *Dtor, 2670f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov CXXDtorType DtorType, 2680f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov SourceLocation CallLoc, 2690f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ReturnValueSlot ReturnValue, 2700f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *This) { 2710f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); 2720f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 2730f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov // We have only one destructor in the vftable but can get both behaviors 2740f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov // by passing an implicit bool parameter. 2750f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov const CGFunctionInfo *FInfo 2760f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting); 2770f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); 2780f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty); 2790f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 2800f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ASTContext &Context = CGF.getContext(); 2810f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov llvm::Value *ImplicitParam 2820f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()), 2830f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov DtorType == Dtor_Deleting); 2840f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 2850f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This, 2860f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov ImplicitParam, Context.BoolTy, 0, 0); 2870f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov} 2880f9827f5d6248d7008063768eb5f2c3e6ba83e94Timur Iskhodzhanov 289e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallbool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr, 290e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType elementType) { 291e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Microsoft seems to completely ignore the possibility of a 292e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // two-argument usual deallocation function. 293e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return elementType.isDestructedType(); 294e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 295e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 296e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallbool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) { 297e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Microsoft seems to completely ignore the possibility of a 298e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // two-argument usual deallocation function. 299e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return expr->getAllocatedType().isDestructedType(); 300e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 301e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 302e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallCharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) { 303e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The array cookie is always a size_t; we then pad that out to the 304e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // alignment of the element type. 305e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall ASTContext &Ctx = getContext(); 306e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), 307e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall Ctx.getTypeAlignInChars(type)); 308e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 309e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 310e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF, 311e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *allocPtr, 312e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize) { 313956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AS = allocPtr->getType()->getPointerAddressSpace(); 314e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElementsPtr = 315e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS)); 316e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateLoad(numElementsPtr); 317e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 318e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 319e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCallllvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, 320e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *newPtr, 321e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElements, 322e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall const CXXNewExpr *expr, 323e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall QualType elementType) { 324e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall assert(requiresArrayCookie(expr)); 325e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 326e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // The size of the cookie. 327e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CharUnits cookieSize = getArrayCookieSizeImpl(elementType); 328e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 329e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Compute an offset to the cookie. 330e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *cookiePtr = newPtr; 331e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 332e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Write the number of elements into the appropriate slot. 333956a5a17713deb1b5b27893303c4f308a1bd2a62Micah Villmow unsigned AS = newPtr->getType()->getPointerAddressSpace(); 334e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall llvm::Value *numElementsPtr 335e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS)); 336e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall CGF.Builder.CreateStore(numElements, numElementsPtr); 337e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 338e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // Finally, compute a pointer to the actual data buffer by skipping 339e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall // over the cookie completely. 340e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr, 341e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall cookieSize.getQuantity()); 342e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall} 343e2b45e2a43ae46bc00026b63ba7c04ef2b78c3ffJohn McCall 34420bb175cb8ae5844034828db094fb948c0e3454aJohn McCallvoid MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 34520bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::GlobalVariable *DeclPtr, 34620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall bool PerformInit) { 34720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // FIXME: this code was only tested for global initialization. 34820bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Not sure whether we want thread-safe static local variables as VS 34920bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // doesn't make them thread-safe. 35020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 35120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall // Emit the initializer and add a global destructor if appropriate. 35220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit); 35320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall} 35420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall 355071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) { 356c3926645d70842eae22641df1bf69da457a0ff11Charles Davis return new MicrosoftCXXABI(CGM); 357c3926645d70842eae22641df1bf69da457a0ff11Charles Davis} 358c3926645d70842eae22641df1bf69da457a0ff11Charles Davis 359