1//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This provides C++ code generation targeting the Microsoft Visual C++ ABI.
11// The class in this file generates structures that follow the Microsoft
12// Visual C++ ABI, which is actually not very well documented at all outside
13// of Microsoft.
14//
15//===----------------------------------------------------------------------===//
16
17#include "CGCXXABI.h"
18#include "CodeGenModule.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
21
22using namespace clang;
23using namespace CodeGen;
24
25namespace {
26
27class MicrosoftCXXABI : public CGCXXABI {
28public:
29  MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
30
31  StringRef GetPureVirtualCallName() { return "_purecall"; }
32  // No known support for deleted functions in MSVC yet, so this choice is
33  // arbitrary.
34  StringRef GetDeletedVirtualCallName() { return "_purecall"; }
35
36  llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
37                                      llvm::Value *ptr,
38                                      QualType type);
39
40  void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
41                                 CXXCtorType Type,
42                                 CanQualType &ResTy,
43                                 SmallVectorImpl<CanQualType> &ArgTys);
44
45  llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF);
46
47  void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
48                                CXXDtorType Type,
49                                CanQualType &ResTy,
50                                SmallVectorImpl<CanQualType> &ArgTys);
51
52  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
53                                   QualType &ResTy,
54                                   FunctionArgList &Params);
55
56  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
57
58  void EmitConstructorCall(CodeGenFunction &CGF,
59                           const CXXConstructorDecl *D,
60                           CXXCtorType Type, bool ForVirtualBase,
61                           bool Delegating,
62                           llvm::Value *This,
63                           CallExpr::const_arg_iterator ArgBeg,
64                           CallExpr::const_arg_iterator ArgEnd);
65
66  RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
67                                   const CXXDestructorDecl *Dtor,
68                                   CXXDtorType DtorType,
69                                   SourceLocation CallLoc,
70                                   ReturnValueSlot ReturnValue,
71                                   llvm::Value *This);
72
73  void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
74                       llvm::GlobalVariable *DeclPtr,
75                       bool PerformInit);
76
77  // ==== Notes on array cookies =========
78  //
79  // MSVC seems to only use cookies when the class has a destructor; a
80  // two-argument usual array deallocation function isn't sufficient.
81  //
82  // For example, this code prints "100" and "1":
83  //   struct A {
84  //     char x;
85  //     void *operator new[](size_t sz) {
86  //       printf("%u\n", sz);
87  //       return malloc(sz);
88  //     }
89  //     void operator delete[](void *p, size_t sz) {
90  //       printf("%u\n", sz);
91  //       free(p);
92  //     }
93  //   };
94  //   int main() {
95  //     A *p = new A[100];
96  //     delete[] p;
97  //   }
98  // Whereas it prints "104" and "104" if you give A a destructor.
99
100  bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
101  bool requiresArrayCookie(const CXXNewExpr *expr);
102  CharUnits getArrayCookieSizeImpl(QualType type);
103  llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
104                                     llvm::Value *NewPtr,
105                                     llvm::Value *NumElements,
106                                     const CXXNewExpr *expr,
107                                     QualType ElementType);
108  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
109                                   llvm::Value *allocPtr,
110                                   CharUnits cookieSize);
111  static bool needThisReturn(GlobalDecl GD);
112};
113
114}
115
116llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
117                                                     llvm::Value *ptr,
118                                                     QualType type) {
119  // FIXME: implement
120  return ptr;
121}
122
123bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
124  const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
125  return isa<CXXConstructorDecl>(MD);
126}
127
128void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
129                                 CXXCtorType Type,
130                                 CanQualType &ResTy,
131                                 SmallVectorImpl<CanQualType> &ArgTys) {
132  // 'this' is already in place
133
134  // Ctor returns this ptr
135  ResTy = ArgTys[0];
136
137  const CXXRecordDecl *Class = Ctor->getParent();
138  if (Class->getNumVBases()) {
139    // Constructors of classes with virtual bases take an implicit parameter.
140    ArgTys.push_back(CGM.getContext().IntTy);
141  }
142}
143
144llvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler(
145                                                         CodeGenFunction &CGF) {
146  llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
147  assert(IsMostDerivedClass &&
148         "ctor for a class with virtual bases must have an implicit parameter");
149  llvm::Value *IsCompleteObject
150    = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
151
152  llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases");
153  llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases");
154  CGF.Builder.CreateCondBr(IsCompleteObject,
155                           CallVbaseCtorsBB, SkipVbaseCtorsBB);
156
157  CGF.EmitBlock(CallVbaseCtorsBB);
158  // FIXME: emit vbtables somewhere around here.
159
160  // CGF will put the base ctor calls in this basic block for us later.
161
162  return SkipVbaseCtorsBB;
163}
164
165void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
166                                               CXXDtorType Type,
167                                               CanQualType &ResTy,
168                                        SmallVectorImpl<CanQualType> &ArgTys) {
169  // 'this' is already in place
170  // TODO: 'for base' flag
171
172  if (Type == Dtor_Deleting) {
173    // The scalar deleting destructor takes an implicit bool parameter.
174    ArgTys.push_back(CGM.getContext().BoolTy);
175  }
176}
177
178static bool IsDeletingDtor(GlobalDecl GD) {
179  const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
180  if (isa<CXXDestructorDecl>(MD)) {
181    return GD.getDtorType() == Dtor_Deleting;
182  }
183  return false;
184}
185
186void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
187                                                  QualType &ResTy,
188                                                  FunctionArgList &Params) {
189  BuildThisParam(CGF, Params);
190  if (needThisReturn(CGF.CurGD)) {
191    ResTy = Params[0]->getType();
192  }
193
194  ASTContext &Context = getContext();
195  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
196  if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
197    ImplicitParamDecl *IsMostDerived
198      = ImplicitParamDecl::Create(Context, 0,
199                                  CGF.CurGD.getDecl()->getLocation(),
200                                  &Context.Idents.get("is_most_derived"),
201                                  Context.IntTy);
202    Params.push_back(IsMostDerived);
203    getStructorImplicitParamDecl(CGF) = IsMostDerived;
204  } else if (IsDeletingDtor(CGF.CurGD)) {
205    ImplicitParamDecl *ShouldDelete
206      = ImplicitParamDecl::Create(Context, 0,
207                                  CGF.CurGD.getDecl()->getLocation(),
208                                  &Context.Idents.get("should_call_delete"),
209                                  Context.BoolTy);
210    Params.push_back(ShouldDelete);
211    getStructorImplicitParamDecl(CGF) = ShouldDelete;
212  }
213}
214
215void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
216  EmitThisParam(CGF);
217  if (needThisReturn(CGF.CurGD)) {
218    CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
219  }
220
221  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
222  if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
223    assert(getStructorImplicitParamDecl(CGF) &&
224           "no implicit parameter for a constructor with virtual bases?");
225    getStructorImplicitParamValue(CGF)
226      = CGF.Builder.CreateLoad(
227          CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
228          "is_most_derived");
229  }
230
231  if (IsDeletingDtor(CGF.CurGD)) {
232    assert(getStructorImplicitParamDecl(CGF) &&
233           "no implicit parameter for a deleting destructor?");
234    getStructorImplicitParamValue(CGF)
235      = CGF.Builder.CreateLoad(
236          CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
237          "should_call_delete");
238  }
239}
240
241void MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
242                                          const CXXConstructorDecl *D,
243                                          CXXCtorType Type, bool ForVirtualBase,
244                                          bool Delegating,
245                                          llvm::Value *This,
246                                          CallExpr::const_arg_iterator ArgBeg,
247                                          CallExpr::const_arg_iterator ArgEnd) {
248  assert(Type == Ctor_Complete || Type == Ctor_Base);
249  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete);
250
251  llvm::Value *ImplicitParam = 0;
252  QualType ImplicitParamTy;
253  if (D->getParent()->getNumVBases()) {
254    ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
255    ImplicitParamTy = getContext().IntTy;
256  }
257
258  // FIXME: Provide a source location here.
259  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
260                        ImplicitParam, ImplicitParamTy,
261                        ArgBeg, ArgEnd);
262}
263
264RValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
265                                                  const CXXDestructorDecl *Dtor,
266                                                  CXXDtorType DtorType,
267                                                  SourceLocation CallLoc,
268                                                  ReturnValueSlot ReturnValue,
269                                                  llvm::Value *This) {
270  assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
271
272  // We have only one destructor in the vftable but can get both behaviors
273  // by passing an implicit bool parameter.
274  const CGFunctionInfo *FInfo
275      = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting);
276  llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
277  llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty);
278
279  ASTContext &Context = CGF.getContext();
280  llvm::Value *ImplicitParam
281    = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()),
282                             DtorType == Dtor_Deleting);
283
284  return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
285                               ImplicitParam, Context.BoolTy, 0, 0);
286}
287
288bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
289                                   QualType elementType) {
290  // Microsoft seems to completely ignore the possibility of a
291  // two-argument usual deallocation function.
292  return elementType.isDestructedType();
293}
294
295bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
296  // Microsoft seems to completely ignore the possibility of a
297  // two-argument usual deallocation function.
298  return expr->getAllocatedType().isDestructedType();
299}
300
301CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
302  // The array cookie is always a size_t; we then pad that out to the
303  // alignment of the element type.
304  ASTContext &Ctx = getContext();
305  return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
306                  Ctx.getTypeAlignInChars(type));
307}
308
309llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
310                                                  llvm::Value *allocPtr,
311                                                  CharUnits cookieSize) {
312  unsigned AS = allocPtr->getType()->getPointerAddressSpace();
313  llvm::Value *numElementsPtr =
314    CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
315  return CGF.Builder.CreateLoad(numElementsPtr);
316}
317
318llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
319                                                    llvm::Value *newPtr,
320                                                    llvm::Value *numElements,
321                                                    const CXXNewExpr *expr,
322                                                    QualType elementType) {
323  assert(requiresArrayCookie(expr));
324
325  // The size of the cookie.
326  CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
327
328  // Compute an offset to the cookie.
329  llvm::Value *cookiePtr = newPtr;
330
331  // Write the number of elements into the appropriate slot.
332  unsigned AS = newPtr->getType()->getPointerAddressSpace();
333  llvm::Value *numElementsPtr
334    = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
335  CGF.Builder.CreateStore(numElements, numElementsPtr);
336
337  // Finally, compute a pointer to the actual data buffer by skipping
338  // over the cookie completely.
339  return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
340                                                cookieSize.getQuantity());
341}
342
343void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
344                                      llvm::GlobalVariable *DeclPtr,
345                                      bool PerformInit) {
346  // FIXME: this code was only tested for global initialization.
347  // Not sure whether we want thread-safe static local variables as VS
348  // doesn't make them thread-safe.
349
350  // Emit the initializer and add a global destructor if appropriate.
351  CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
352}
353
354CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
355  return new MicrosoftCXXABI(CGM);
356}
357
358