blob: 00b15c9a49c47c17866fe667053a0d204847f37a [file] [log] [blame]
Charles Davisc3926642010-06-09 23:25:41 +00001//===--- 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//
Chris Lattnerfc8f0e12011-04-15 05:22:18 +000010// This provides C++ code generation targeting the Microsoft Visual C++ ABI.
Charles Davisc3926642010-06-09 23:25:41 +000011// 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"
Charles Davisc3926642010-06-09 23:25:41 +000019#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
Charles Davisc3926642010-06-09 23:25:41 +000021
22using namespace clang;
23using namespace CodeGen;
24
25namespace {
26
Charles Davis071cc7d2010-08-16 03:33:14 +000027class MicrosoftCXXABI : public CGCXXABI {
Charles Davisc3926642010-06-09 23:25:41 +000028public:
Peter Collingbourne14110472011-01-13 18:57:25 +000029 MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
John McCall4c40d982010-08-31 07:33:07 +000030
Joao Matos285baac2012-07-17 17:10:11 +000031 StringRef GetPureVirtualCallName() { return "_purecall"; }
David Blaikie2eb9a952012-10-16 22:56:05 +000032 // No known support for deleted functions in MSVC yet, so this choice is
33 // arbitrary.
34 StringRef GetDeletedVirtualCallName() { return "_purecall"; }
Joao Matos285baac2012-07-17 17:10:11 +000035
John McCallecd03b42012-09-25 10:10:39 +000036 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
37 llvm::Value *ptr,
38 QualType type);
39
John McCall4c40d982010-08-31 07:33:07 +000040 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
41 CXXCtorType Type,
42 CanQualType &ResTy,
John McCallbd315742012-09-25 08:00:39 +000043 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +000044
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +000045 llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF);
46
John McCall4c40d982010-08-31 07:33:07 +000047 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
48 CXXDtorType Type,
49 CanQualType &ResTy,
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +000050 SmallVectorImpl<CanQualType> &ArgTys);
John McCall4c40d982010-08-31 07:33:07 +000051
52 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
53 QualType &ResTy,
John McCallbd315742012-09-25 08:00:39 +000054 FunctionArgList &Params);
John McCall4c40d982010-08-31 07:33:07 +000055
John McCallbd315742012-09-25 08:00:39 +000056 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
John McCallfd708262011-01-27 02:46:02 +000057
Manman Ren63fd4082013-03-20 16:59:38 +000058 llvm::Value *EmitConstructorCall(CodeGenFunction &CGF,
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +000059 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
Timur Iskhodzhanov0f9827f2013-02-15 14:45:22 +000066 RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
67 const CXXDestructorDecl *Dtor,
68 CXXDtorType DtorType,
69 SourceLocation CallLoc,
70 ReturnValueSlot ReturnValue,
71 llvm::Value *This);
72
John McCall20bb1752012-05-01 06:13:13 +000073 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
74 llvm::GlobalVariable *DeclPtr,
75 bool PerformInit);
76
John McCallfd708262011-01-27 02:46:02 +000077 // ==== 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.
John McCalle2b45e22012-05-01 05:23:51 +000099
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);
John McCallbd315742012-09-25 08:00:39 +0000111 static bool needThisReturn(GlobalDecl GD);
Reid Klecknera8a0f762013-03-22 19:02:54 +0000112
113private:
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
124public:
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
Charles Davisc3926642010-06-09 23:25:41 +0000139};
140
141}
142
John McCallecd03b42012-09-25 10:10:39 +0000143llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
144 llvm::Value *ptr,
145 QualType type) {
146 // FIXME: implement
147 return ptr;
148}
149
John McCallbd315742012-09-25 08:00:39 +0000150bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
151 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
152 return isa<CXXConstructorDecl>(MD);
153}
154
155void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
156 CXXCtorType Type,
157 CanQualType &ResTy,
158 SmallVectorImpl<CanQualType> &ArgTys) {
159 // 'this' is already in place
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000160
John McCallbd315742012-09-25 08:00:39 +0000161 // Ctor returns this ptr
162 ResTy = ArgTys[0];
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000163
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
171llvm::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;
John McCallbd315742012-09-25 08:00:39 +0000190}
191
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000192void 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
205static 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
John McCallbd315742012-09-25 08:00:39 +0000213void 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 }
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000220
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000221 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)) {
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000232 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 }
John McCallbd315742012-09-25 08:00:39 +0000240}
241
242void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
243 EmitThisParam(CGF);
244 if (needThisReturn(CGF.CurGD)) {
245 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
246 }
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000247
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
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000258 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 }
John McCallbd315742012-09-25 08:00:39 +0000266}
267
Manman Ren63fd4082013-03-20 16:59:38 +0000268llvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000269 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);
Manman Ren63fd4082013-03-20 16:59:38 +0000289 return Callee;
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000290}
291
Timur Iskhodzhanov0f9827f2013-02-15 14:45:22 +0000292RValue 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
John McCalle2b45e22012-05-01 05:23:51 +0000316bool 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
323bool 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
329CharUnits 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
337llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
338 llvm::Value *allocPtr,
339 CharUnits cookieSize) {
Micah Villmow956a5a12012-10-25 15:39:14 +0000340 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000341 llvm::Value *numElementsPtr =
342 CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
343 return CGF.Builder.CreateLoad(numElementsPtr);
344}
345
346llvm::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.
Micah Villmow956a5a12012-10-25 15:39:14 +0000360 unsigned AS = newPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000361 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
John McCall20bb1752012-05-01 06:13:13 +0000371void 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
Reid Klecknera8a0f762013-03-22 19:02:54 +0000382// 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.
385static 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
392llvm::Constant *
393MicrosoftCXXABI::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
405llvm::Constant *
406MicrosoftCXXABI::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
413llvm::Constant *
414MicrosoftCXXABI::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
423llvm::Value *
424MicrosoftCXXABI::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
440llvm::Value *
441MicrosoftCXXABI::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
Charles Davis071cc7d2010-08-16 03:33:14 +0000471CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davisc3926642010-06-09 23:25:41 +0000472 return new MicrosoftCXXABI(CGM);
473}
474