Home | History | Annotate | Download | only in AST
      1 //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
      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++ AST support targeting the Microsoft Visual C++
     11 // ABI.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "CXXABI.h"
     16 #include "clang/AST/ASTContext.h"
     17 #include "clang/AST/DeclCXX.h"
     18 #include "clang/AST/RecordLayout.h"
     19 #include "clang/AST/Type.h"
     20 #include "clang/Basic/TargetInfo.h"
     21 
     22 using namespace clang;
     23 
     24 namespace {
     25 class MicrosoftCXXABI : public CXXABI {
     26   ASTContext &Context;
     27 public:
     28   MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
     29 
     30   unsigned getMemberPointerSize(const MemberPointerType *MPT) const;
     31 
     32   CallingConv getDefaultMethodCallConv(bool isVariadic) const {
     33     if (!isVariadic && Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
     34       return CC_X86ThisCall;
     35     else
     36       return CC_C;
     37   }
     38 
     39   bool isNearlyEmpty(const CXXRecordDecl *RD) const {
     40     // FIXME: Audit the corners
     41     if (!RD->isDynamicClass())
     42       return false;
     43 
     44     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     45 
     46     // In the Microsoft ABI, classes can have one or two vtable pointers.
     47     CharUnits PointerSize =
     48       Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
     49     return Layout.getNonVirtualSize() == PointerSize ||
     50       Layout.getNonVirtualSize() == PointerSize * 2;
     51   }
     52 };
     53 }
     54 
     55 unsigned MicrosoftCXXABI::getMemberPointerSize(const MemberPointerType *MPT) const {
     56   QualType Pointee = MPT->getPointeeType();
     57   CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
     58   if (RD->getNumVBases() > 0) {
     59     if (Pointee->isFunctionType())
     60       return 3;
     61     else
     62       return 2;
     63   } else if (RD->getNumBases() > 1 && Pointee->isFunctionType())
     64     return 2;
     65   return 1;
     66 }
     67 
     68 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
     69   return new MicrosoftCXXABI(Ctx);
     70 }
     71 
     72