Home | History | Annotate | Download | only in CodeGen
      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   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 
    116 llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
    117                                                      llvm::Value *ptr,
    118                                                      QualType type) {
    119   // FIXME: implement
    120   return ptr;
    121 }
    122 
    123 bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
    124   const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
    125   return isa<CXXConstructorDecl>(MD);
    126 }
    127 
    128 void 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 
    144 llvm::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 
    165 void 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 
    178 static 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 
    186 void 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 
    215 void 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 
    241 void 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 
    264 RValue 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 
    288 bool 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 
    295 bool 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 
    301 CharUnits 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 
    309 llvm::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 
    318 llvm::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 
    343 void 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 
    354 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
    355   return new MicrosoftCXXABI(CGM);
    356 }
    357 
    358