blob: fb6b86d87883ddded20d7fad3a17744b1f5ac718 [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
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +000058 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
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);
Charles Davisc3926642010-06-09 23:25:41 +0000112};
113
114}
115
John McCallecd03b42012-09-25 10:10:39 +0000116llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
117 llvm::Value *ptr,
118 QualType type) {
119 // FIXME: implement
120 return ptr;
121}
122
John McCallbd315742012-09-25 08:00:39 +0000123bool 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
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000133
John McCallbd315742012-09-25 08:00:39 +0000134 // Ctor returns this ptr
135 ResTy = ArgTys[0];
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000136
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;
John McCallbd315742012-09-25 08:00:39 +0000163}
164
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000165void 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
John McCallbd315742012-09-25 08:00:39 +0000186void 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 }
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000193
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000194 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)) {
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000205 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 }
John McCallbd315742012-09-25 08:00:39 +0000213}
214
215void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
216 EmitThisParam(CGF);
217 if (needThisReturn(CGF.CurGD)) {
218 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
219 }
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000220
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
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000231 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 }
John McCallbd315742012-09-25 08:00:39 +0000239}
240
Timur Iskhodzhanov1d4fff52013-02-27 13:46:31 +0000241void 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
Timur Iskhodzhanov0f9827f2013-02-15 14:45:22 +0000264RValue 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
John McCalle2b45e22012-05-01 05:23:51 +0000288bool 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) {
Micah Villmow956a5a12012-10-25 15:39:14 +0000312 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000313 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.
Micah Villmow956a5a12012-10-25 15:39:14 +0000332 unsigned AS = newPtr->getType()->getPointerAddressSpace();
John McCalle2b45e22012-05-01 05:23:51 +0000333 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
John McCall20bb1752012-05-01 06:13:13 +0000343void 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
Charles Davis071cc7d2010-08-16 03:33:14 +0000354CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
Charles Davisc3926642010-06-09 23:25:41 +0000355 return new MicrosoftCXXABI(CGM);
356}
357