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
22using namespace clang;
23
24namespace {
25class MicrosoftCXXABI : public CXXABI {
26  ASTContext &Context;
27public:
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
55unsigned 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
68CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
69  return new MicrosoftCXXABI(Ctx);
70}
71
72