1 //===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
15 //===----------------------------------------------------------------------===//
18 #include "CodeGenModule.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
22 using namespace clang;
23 using namespace CodeGen;
27 class MicrosoftCXXABI : public CGCXXABI {
29 MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
31 StringRef GetPureVirtualCallName() { return "_purecall"; }
32 // No known support for deleted functions in MSVC yet, so this choice is
34 StringRef GetDeletedVirtualCallName() { return "_purecall"; }
36 llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
40 void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
43 SmallVectorImpl<CanQualType> &ArgTys);
45 llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF);
47 void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
50 SmallVectorImpl<CanQualType> &ArgTys);
52 void BuildInstanceFunctionParams(CodeGenFunction &CGF,
54 FunctionArgList &Params);
56 void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
58 llvm::Value *EmitConstructorCall(CodeGenFunction &CGF,
59 const CXXConstructorDecl *D,
60 CXXCtorType Type, bool ForVirtualBase,
63 CallExpr::const_arg_iterator ArgBeg,
64 CallExpr::const_arg_iterator ArgEnd);
66 RValue EmitVirtualDestructorCall(CodeGenFunction &CGF,
67 const CXXDestructorDecl *Dtor,
69 SourceLocation CallLoc,
70 ReturnValueSlot ReturnValue,
73 void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
74 llvm::GlobalVariable *DeclPtr,
77 // ==== Notes on array cookies =========
79 // MSVC seems to only use cookies when the class has a destructor; a
80 // two-argument usual array deallocation function isn't sufficient.
82 // For example, this code prints "100" and "1":
85 // void *operator new[](size_t sz) {
86 // printf("%u\n", sz);
89 // void operator delete[](void *p, size_t sz) {
90 // printf("%u\n", sz);
98 // Whereas it prints "104" and "104" if you give A a destructor.
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,
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);
114 llvm::Constant *getSimpleNullMemberPointer(const MemberPointerType *MPT);
116 llvm::Constant *getZeroPtrDiff() {
117 return llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
120 llvm::Constant *getAllOnesPtrDiff() {
121 return llvm::Constant::getAllOnesValue(CGM.PtrDiffTy);
125 virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
127 virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
130 virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
132 const MemberPointerType *MPT);
134 virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
137 const MemberPointerType *MPT);
143 llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
150 bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
151 const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
152 return isa<CXXConstructorDecl>(MD);
155 void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
158 SmallVectorImpl<CanQualType> &ArgTys) {
159 // 'this' is already in place
161 // Ctor returns this ptr
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);
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");
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);
184 CGF.EmitBlock(CallVbaseCtorsBB);
185 // FIXME: emit vbtables somewhere around here.
187 // CGF will put the base ctor calls in this basic block for us later.
189 return SkipVbaseCtorsBB;
192 void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Dtor,
195 SmallVectorImpl<CanQualType> &ArgTys) {
196 // 'this' is already in place
197 // TODO: 'for base' flag
199 if (Type == Dtor_Deleting) {
200 // The scalar deleting destructor takes an implicit bool parameter.
201 ArgTys.push_back(CGM.getContext().BoolTy);
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;
213 void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
215 FunctionArgList &Params) {
216 BuildThisParam(CGF, Params);
217 if (needThisReturn(CGF.CurGD)) {
218 ResTy = Params[0]->getType();
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"),
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"),
237 Params.push_back(ShouldDelete);
238 getStructorImplicitParamDecl(CGF) = ShouldDelete;
242 void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
244 if (needThisReturn(CGF.CurGD)) {
245 CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
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)),
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");
268 llvm::Value *MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
269 const CXXConstructorDecl *D,
270 CXXCtorType Type, bool ForVirtualBase,
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);
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;
285 // FIXME: Provide a source location here.
286 CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
287 ImplicitParam, ImplicitParamTy,
292 RValue MicrosoftCXXABI::EmitVirtualDestructorCall(CodeGenFunction &CGF,
293 const CXXDestructorDecl *Dtor,
294 CXXDtorType DtorType,
295 SourceLocation CallLoc,
296 ReturnValueSlot ReturnValue,
298 assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
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);
307 ASTContext &Context = CGF.getContext();
308 llvm::Value *ImplicitParam
309 = llvm::ConstantInt::get(llvm::IntegerType::getInt1Ty(CGF.getLLVMContext()),
310 DtorType == Dtor_Deleting);
312 return CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValue, This,
313 ImplicitParam, Context.BoolTy, 0, 0);
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();
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();
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));
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);
346 llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
348 llvm::Value *numElements,
349 const CXXNewExpr *expr,
350 QualType elementType) {
351 assert(requiresArrayCookie(expr));
353 // The size of the cookie.
354 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
356 // Compute an offset to the cookie.
357 llvm::Value *cookiePtr = newPtr;
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);
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());
371 void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
372 llvm::GlobalVariable *DeclPtr,
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.
378 // Emit the initializer and add a global destructor if appropriate.
379 CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
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);
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();
402 return GetBogusMemberPointer(QualType(MPT, 0));
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));
414 MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
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));
424 MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
426 const MemberPointerType *MPT) {
427 CGBuilderTy &Builder = CGF.Builder;
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");
435 // FIXME: Implement member pointers other inheritance models.
436 ErrorUnsupportedABI(CGF, "function member pointer tests");
437 return GetBogusMemberPointer(QualType(MPT, 0));
441 MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
444 const MemberPointerType *MPT) {
445 unsigned AS = Base->getType()->getPointerAddressSpace();
447 CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
448 CGBuilderTy &Builder = CGF.Builder;
450 if (MPT->isMemberFunctionPointer()) {
451 ErrorUnsupportedABI(CGF, "function member pointer address");
452 return llvm::Constant::getNullValue(PType);
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");
462 ErrorUnsupportedABI(CGF, "non-scalar member pointers");
463 return llvm::Constant::getNullValue(PType);
466 // Cast the address to the appropriate pointer type, adopting the address
467 // space of the base pointer.
468 return Builder.CreateBitCast(Addr, PType);
471 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
472 return new MicrosoftCXXABI(CGM);