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