clang API Documentation

CodeGen/MicrosoftCXXABI.cpp
Go to the documentation of this file.
00001 //===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This provides C++ code generation targeting the Microsoft Visual C++ ABI.
00011 // The class in this file generates structures that follow the Microsoft
00012 // Visual C++ ABI, which is actually not very well documented at all outside
00013 // of Microsoft.
00014 //
00015 //===----------------------------------------------------------------------===//
00016 
00017 #include "CGCXXABI.h"
00018 #include "CodeGenModule.h"
00019 #include "clang/AST/Decl.h"
00020 #include "clang/AST/DeclCXX.h"
00021 
00022 using namespace clang;
00023 using namespace CodeGen;
00024 
00025 namespace {
00026 
00027 class MicrosoftCXXABI : public CGCXXABI {
00028 public:
00029   MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
00030 
00031   void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
00032                                  CXXCtorType Type,
00033                                  CanQualType &ResTy,
00034                                  SmallVectorImpl<CanQualType> &ArgTys) {
00035     // 'this' is already in place
00036     // TODO: 'for base' flag
00037   }  
00038 
00039   void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
00040                                 CXXDtorType Type,
00041                                 CanQualType &ResTy,
00042                                 SmallVectorImpl<CanQualType> &ArgTys) {
00043     // 'this' is already in place
00044     // TODO: 'for base' flag
00045   }
00046 
00047   void BuildInstanceFunctionParams(CodeGenFunction &CGF,
00048                                    QualType &ResTy,
00049                                    FunctionArgList &Params) {
00050     BuildThisParam(CGF, Params);
00051     // TODO: 'for base' flag
00052   }
00053 
00054   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
00055     EmitThisParam(CGF);
00056     // TODO: 'for base' flag
00057   }
00058 
00059   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
00060                        llvm::GlobalVariable *DeclPtr,
00061                        bool PerformInit);
00062 
00063 
00064   // ==== Notes on array cookies =========
00065   //
00066   // MSVC seems to only use cookies when the class has a destructor; a
00067   // two-argument usual array deallocation function isn't sufficient.
00068   //
00069   // For example, this code prints "100" and "1":
00070   //   struct A {
00071   //     char x;
00072   //     void *operator new[](size_t sz) {
00073   //       printf("%u\n", sz);
00074   //       return malloc(sz);
00075   //     }
00076   //     void operator delete[](void *p, size_t sz) {
00077   //       printf("%u\n", sz);
00078   //       free(p);
00079   //     }
00080   //   };
00081   //   int main() {
00082   //     A *p = new A[100];
00083   //     delete[] p;
00084   //   }
00085   // Whereas it prints "104" and "104" if you give A a destructor.
00086 
00087   bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
00088   bool requiresArrayCookie(const CXXNewExpr *expr);
00089   CharUnits getArrayCookieSizeImpl(QualType type);
00090   llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
00091                                      llvm::Value *NewPtr,
00092                                      llvm::Value *NumElements,
00093                                      const CXXNewExpr *expr,
00094                                      QualType ElementType);
00095   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
00096                                    llvm::Value *allocPtr,
00097                                    CharUnits cookieSize);
00098 };
00099 
00100 }
00101 
00102 bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
00103                                    QualType elementType) {
00104   // Microsoft seems to completely ignore the possibility of a
00105   // two-argument usual deallocation function.
00106   return elementType.isDestructedType();
00107 }
00108 
00109 bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
00110   // Microsoft seems to completely ignore the possibility of a
00111   // two-argument usual deallocation function.
00112   return expr->getAllocatedType().isDestructedType();
00113 }
00114 
00115 CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
00116   // The array cookie is always a size_t; we then pad that out to the
00117   // alignment of the element type.
00118   ASTContext &Ctx = getContext();
00119   return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
00120                   Ctx.getTypeAlignInChars(type));
00121 }
00122 
00123 llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
00124                                                   llvm::Value *allocPtr,
00125                                                   CharUnits cookieSize) {
00126   unsigned AS = cast<llvm::PointerType>(allocPtr->getType())->getAddressSpace();
00127   llvm::Value *numElementsPtr =
00128     CGF.Builder.CreateBitCast(allocPtr, CGF.SizeTy->getPointerTo(AS));
00129   return CGF.Builder.CreateLoad(numElementsPtr);
00130 }
00131 
00132 llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
00133                                                     llvm::Value *newPtr,
00134                                                     llvm::Value *numElements,
00135                                                     const CXXNewExpr *expr,
00136                                                     QualType elementType) {
00137   assert(requiresArrayCookie(expr));
00138 
00139   // The size of the cookie.
00140   CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
00141 
00142   // Compute an offset to the cookie.
00143   llvm::Value *cookiePtr = newPtr;
00144 
00145   // Write the number of elements into the appropriate slot.
00146   unsigned AS = cast<llvm::PointerType>(newPtr->getType())->getAddressSpace();
00147   llvm::Value *numElementsPtr
00148     = CGF.Builder.CreateBitCast(cookiePtr, CGF.SizeTy->getPointerTo(AS));
00149   CGF.Builder.CreateStore(numElements, numElementsPtr);
00150 
00151   // Finally, compute a pointer to the actual data buffer by skipping
00152   // over the cookie completely.
00153   return CGF.Builder.CreateConstInBoundsGEP1_64(newPtr,
00154                                                 cookieSize.getQuantity());
00155 }
00156 
00157 void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
00158                                       llvm::GlobalVariable *DeclPtr,
00159                                       bool PerformInit) {
00160   // FIXME: this code was only tested for global initialization.
00161   // Not sure whether we want thread-safe static local variables as VS
00162   // doesn't make them thread-safe.
00163 
00164   // Emit the initializer and add a global destructor if appropriate.
00165   CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
00166 }
00167 
00168 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
00169   return new MicrosoftCXXABI(CGM);
00170 }
00171