]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/CodeGen/MicrosoftCXXABI.cpp
Vendor import of clang trunk r178860:
[FreeBSD/FreeBSD.git] / lib / CodeGen / MicrosoftCXXABI.cpp
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
22 using namespace clang;
23 using namespace CodeGen;
24
25 namespace {
26
27 class MicrosoftCXXABI : public CGCXXABI {
28 public:
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   llvm::Value *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 private:
114   llvm::Constant *getSimpleNullMemberPointer(const MemberPointerType *MPT);
115
116   llvm::Constant *getZeroPtrDiff() {
117     return llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
118   }
119
120   llvm::Constant *getAllOnesPtrDiff() {
121     return  llvm::Constant::getAllOnesValue(CGM.PtrDiffTy);
122   }
123
124 public:
125   virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
126
127   virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
128                                                 CharUnits offset);
129
130   virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
131                                                   llvm::Value *MemPtr,
132                                                   const MemberPointerType *MPT);
133
134   virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
135                                                     llvm::Value *Base,
136                                                     llvm::Value *MemPtr,
137                                                   const MemberPointerType *MPT);
138
139 };
140
141 }
142
143 llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
144                                                      llvm::Value *ptr,
145                                                      QualType type) {
146   // FIXME: implement
147   return ptr;
148 }
149
150 bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
151   const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
152   return isa<CXXConstructorDecl>(MD);
153 }
154
155 void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
156                                  CXXCtorType Type,
157                                  CanQualType &ResTy,
158                                  SmallVectorImpl<CanQualType> &ArgTys) {
159   // 'this' is already in place
160
161   // Ctor returns this ptr
162   ResTy = ArgTys[0];
163
164   const CXXRecordDecl *Class = Ctor->getParent();
165   if (Class->getNumVBases()) {
166     // Constructors of classes with virtual bases take an implicit parameter.
167     ArgTys.push_back(CGM.getContext().IntTy);
168   }
169 }
170
171 llvm::BasicBlock *MicrosoftCXXABI::EmitCtorCompleteObjectHandler(
172                                                          CodeGenFunction &CGF) {
173   llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
174   assert(IsMostDerivedClass &&
175          "ctor for a class with virtual bases must have an implicit parameter");
176   llvm::Value *IsCompleteObject
177     = CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
178
179   llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases");
180   llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases");
181   CGF.Builder.CreateCondBr(IsCompleteObject,
182                            CallVbaseCtorsBB, SkipVbaseCtorsBB);
183
184   CGF.EmitBlock(CallVbaseCtorsBB);
185   // FIXME: emit vbtables somewhere around here.
186
187   // CGF will put the base ctor calls in this basic block for us later.
188
189   return SkipVbaseCtorsBB;
190 }
191
192 void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
193                                                CXXDtorType Type,
194                                                CanQualType &ResTy,
195                                         SmallVectorImpl<CanQualType> &ArgTys) {
196   // 'this' is already in place
197   // TODO: 'for base' flag
198
199   if (Type == Dtor_Deleting) {
200     // The scalar deleting destructor takes an implicit bool parameter.
201     ArgTys.push_back(CGM.getContext().BoolTy);
202   }
203 }
204
205 static bool IsDeletingDtor(GlobalDecl GD) {
206   const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
207   if (isa<CXXDestructorDecl>(MD)) {
208     return GD.getDtorType() == Dtor_Deleting;
209   }
210   return false;
211 }
212
213 void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
214                                                   QualType &ResTy,
215                                                   FunctionArgList &Params) {
216   BuildThisParam(CGF, Params);
217   if (needThisReturn(CGF.CurGD)) {
218     ResTy = Params[0]->getType();
219   }
220
221   ASTContext &Context = getContext();
222   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
223   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
224     ImplicitParamDecl *IsMostDerived
225       = ImplicitParamDecl::Create(Context, 0,
226                                   CGF.CurGD.getDecl()->getLocation(),
227                                   &Context.Idents.get("is_most_derived"),
228                                   Context.IntTy);
229     Params.push_back(IsMostDerived);
230     getStructorImplicitParamDecl(CGF) = IsMostDerived;
231   } else if (IsDeletingDtor(CGF.CurGD)) {
232     ImplicitParamDecl *ShouldDelete
233       = ImplicitParamDecl::Create(Context, 0,
234                                   CGF.CurGD.getDecl()->getLocation(),
235                                   &Context.Idents.get("should_call_delete"),
236                                   Context.BoolTy);
237     Params.push_back(ShouldDelete);
238     getStructorImplicitParamDecl(CGF) = ShouldDelete;
239   }
240 }
241
242 void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
243   EmitThisParam(CGF);
244   if (needThisReturn(CGF.CurGD)) {
245     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
246   }
247
248   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
249   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
250     assert(getStructorImplicitParamDecl(CGF) &&
251            "no implicit parameter for a constructor with virtual bases?");
252     getStructorImplicitParamValue(CGF)
253       = CGF.Builder.CreateLoad(
254           CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
255           "is_most_derived");
256   }
257
258   if (IsDeletingDtor(CGF.CurGD)) {
259     assert(getStructorImplicitParamDecl(CGF) &&
260            "no implicit parameter for a deleting destructor?");
261     getStructorImplicitParamValue(CGF)
262       = CGF.Builder.CreateLoad(
263           CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
264           "should_call_delete");
265   }
266 }
267
268 llvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
269                                           const CXXConstructorDecl *D,
270                                           CXXCtorType Type, bool ForVirtualBase,
271                                           bool Delegating,
272                                           llvm::Value *This,
273                                           CallExpr::const_arg_iterator ArgBeg,
274                                           CallExpr::const_arg_iterator ArgEnd) {
275   assert(Type == Ctor_Complete || Type == Ctor_Base);
276   llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete);
277
278   llvm::Value *ImplicitParam = 0;
279   QualType ImplicitParamTy;
280   if (D->getParent()->getNumVBases()) {
281     ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
282     ImplicitParamTy = getContext().IntTy;
283   }
284
285   // FIXME: Provide a source location here.
286   CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
287                         ImplicitParam, ImplicitParamTy,
288                         ArgBeg, ArgEnd);
289   return Callee;
290 }
291
292 RValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
293                                                   const CXXDestructorDecl *Dtor,
294                                                   CXXDtorType DtorType,
295                                                   SourceLocation CallLoc,
296                                                   ReturnValueSlot ReturnValue,
297                                                   llvm::Value *This) {
298   assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
299
300   // We have only one destructor in the vftable but can get both behaviors
301   // by passing an implicit bool parameter.
302   const CGFunctionInfo *FInfo
303       = &CGM.getTypes().arrangeCXXDestructor(Dtor, Dtor_Deleting);
304   llvm::Type *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
305   llvm::Value *Callee = CGF.BuildVirtualCall(Dtor, Dtor_Deleting, This, Ty);
306
307   ASTContext &Context = CGF.getContext();
308   llvm::Value *ImplicitParam
309     = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()),
310                              DtorType == Dtor_Deleting);
311
312   return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
313                                ImplicitParam, Context.BoolTy, 0, 0);
314 }
315
316 bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
317                                    QualType elementType) {
318   // Microsoft seems to completely ignore the possibility of a
319   // two-argument usual deallocation function.
320   return elementType.isDestructedType();
321 }
322
323 bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
324   // Microsoft seems to completely ignore the possibility of a
325   // two-argument usual deallocation function.
326   return expr->getAllocatedType().isDestructedType();
327 }
328
329 CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
330   // The array cookie is always a size_t; we then pad that out to the
331   // alignment of the element type.
332   ASTContext &Ctx = getContext();
333   return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
334                   Ctx.getTypeAlignInChars(type));
335 }
336
337 llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
338                                                   llvm::Value *allocPtr,
339                                                   CharUnits cookieSize) {
340   unsigned AS = allocPtr->getType()->getPointerAddressSpace();
341   llvm::Value *numElementsPtr =
342     CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
343   return CGF.Builder.CreateLoad(numElementsPtr);
344 }
345
346 llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
347                                                     llvm::Value *newPtr,
348                                                     llvm::Value *numElements,
349                                                     const CXXNewExpr *expr,
350                                                     QualType elementType) {
351   assert(requiresArrayCookie(expr));
352
353   // The size of the cookie.
354   CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
355
356   // Compute an offset to the cookie.
357   llvm::Value *cookiePtr = newPtr;
358
359   // Write the number of elements into the appropriate slot.
360   unsigned AS = newPtr->getType()->getPointerAddressSpace();
361   llvm::Value *numElementsPtr
362     = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
363   CGF.Builder.CreateStore(numElements, numElementsPtr);
364
365   // Finally, compute a pointer to the actual data buffer by skipping
366   // over the cookie completely.
367   return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
368                                                 cookieSize.getQuantity());
369 }
370
371 void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
372                                       llvm::GlobalVariable *DeclPtr,
373                                       bool PerformInit) {
374   // FIXME: this code was only tested for global initialization.
375   // Not sure whether we want thread-safe static local variables as VS
376   // doesn't make them thread-safe.
377
378   // Emit the initializer and add a global destructor if appropriate.
379   CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
380 }
381
382 // Returns true for member pointer types that we know how to represent with a
383 // simple ptrdiff_t.  Currently we only know how to emit, test, and load member
384 // data pointers for complete single inheritance classes.
385 static bool isSimpleMemberPointer(const MemberPointerType *MPT) {
386   const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
387   return (MPT->isMemberDataPointer() &&
388           !MPT->getClass()->isIncompleteType() &&
389           RD->getNumVBases() == 0);
390 }
391
392 llvm::Constant *
393 MicrosoftCXXABI::getSimpleNullMemberPointer(const MemberPointerType *MPT) {
394   if (isSimpleMemberPointer(MPT)) {
395     const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
396     // A null member data pointer is represented as -1 if the class is not
397     // polymorphic, and 0 otherwise.
398     if (RD->isPolymorphic())
399       return getZeroPtrDiff();
400     return getAllOnesPtrDiff();
401   }
402   return GetBogusMemberPointer(QualType(MPT, 0));
403 }
404
405 llvm::Constant *
406 MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
407   if (isSimpleMemberPointer(MPT))
408     return getSimpleNullMemberPointer(MPT);
409   // FIXME: Implement function member pointers.
410   return GetBogusMemberPointer(QualType(MPT, 0));
411 }
412
413 llvm::Constant *
414 MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
415                                        CharUnits offset) {
416   // Member data pointers are plain offsets when no virtual bases are involved.
417   if (isSimpleMemberPointer(MPT))
418     return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
419   // FIXME: Implement member pointers other inheritance models.
420   return GetBogusMemberPointer(QualType(MPT, 0));
421 }
422
423 llvm::Value *
424 MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
425                                             llvm::Value *MemPtr,
426                                             const MemberPointerType *MPT) {
427   CGBuilderTy &Builder = CGF.Builder;
428
429   // For member data pointers, this is just a check against -1 or 0.
430   if (isSimpleMemberPointer(MPT)) {
431     llvm::Constant *Val = getSimpleNullMemberPointer(MPT);
432     return Builder.CreateICmpNE(MemPtr, Val, "memptr.tobool");
433   }
434
435   // FIXME: Implement member pointers other inheritance models.
436   ErrorUnsupportedABI(CGF, "function member pointer tests");
437   return GetBogusMemberPointer(QualType(MPT, 0));
438 }
439
440 llvm::Value *
441 MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
442                                               llvm::Value *Base,
443                                               llvm::Value *MemPtr,
444                                               const MemberPointerType *MPT) {
445   unsigned AS = Base->getType()->getPointerAddressSpace();
446   llvm::Type *PType =
447       CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
448   CGBuilderTy &Builder = CGF.Builder;
449
450   if (MPT->isMemberFunctionPointer()) {
451     ErrorUnsupportedABI(CGF, "function member pointer address");
452     return llvm::Constant::getNullValue(PType);
453   }
454
455   llvm::Value *Addr;
456   if (isSimpleMemberPointer(MPT)) {
457     // Add the offset with GEP and i8*.
458     assert(MemPtr->getType() == CGM.PtrDiffTy);
459     Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
460     Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
461   } else {
462     ErrorUnsupportedABI(CGF, "non-scalar member pointers");
463     return llvm::Constant::getNullValue(PType);
464   }
465
466   // Cast the address to the appropriate pointer type, adopting the address
467   // space of the base pointer.
468   return Builder.CreateBitCast(Addr, PType);
469 }
470
471 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
472   return new MicrosoftCXXABI(CGM);
473 }
474