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