MicrosoftCXXABI.cpp revision dae0cb52e4e3d46bbfc9a4510909522197a92e54
1071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
2071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//
3071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//                     The LLVM Compiler Infrastructure
4071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//
5071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// This file is distributed under the University of Illinois Open Source
6071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// License. See LICENSE.TXT for details.
7071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//
8071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===----------------------------------------------------------------------===//
9071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//
10071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// This provides C++ AST support targetting the Microsoft Visual C++
11071cc7deffad608165b1ddd5263e8bf181861520Charles Davis// ABI.
12071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//
13071cc7deffad608165b1ddd5263e8bf181861520Charles Davis//===----------------------------------------------------------------------===//
14071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
15071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "CXXABI.h"
16071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/ASTContext.h"
17071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/DeclCXX.h"
18dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/RecordLayout.h"
19dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/Type.h"
20dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/Basic/TargetInfo.h"
21071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
22071cc7deffad608165b1ddd5263e8bf181861520Charles Davisusing namespace clang;
23071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
24071cc7deffad608165b1ddd5263e8bf181861520Charles Davisnamespace {
25071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CXXABI {
26071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  ASTContext &Context;
27071cc7deffad608165b1ddd5263e8bf181861520Charles Davispublic:
28071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
29071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
30071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  unsigned getMemberPointerSize(const MemberPointerType *MPT) const;
31424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis
32424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis  CallingConv getDefaultMethodCallConv() const {
33424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis    if (Context.Target.getTriple().getArch() == llvm::Triple::x86)
34424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis      return CC_X86ThisCall;
35424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis    else
36424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis      return CC_C;
37424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis  }
38dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson
39dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson  bool isNearlyEmpty(const CXXRecordDecl *RD) const {
40dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    // FIXME: Audit the corners
41dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    if (!RD->isDynamicClass())
42dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson      return false;
43dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson
44dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
45dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson
46dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    // In the Microsoft ABI, classes can have one or two vtable pointers.
47dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    return Layout.getNonVirtualSize() == Context.Target.getPointerWidth(0) ||
48dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson      Layout.getNonVirtualSize() == Context.Target.getPointerWidth(0) * 2;
49dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson  }
50071cc7deffad608165b1ddd5263e8bf181861520Charles Davis};
51071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}
52071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
53071cc7deffad608165b1ddd5263e8bf181861520Charles Davisunsigned MicrosoftCXXABI::getMemberPointerSize(const MemberPointerType *MPT) const {
54071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  QualType Pointee = MPT->getPointeeType();
55071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
56071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  if (RD->getNumVBases() > 0) {
57071cc7deffad608165b1ddd5263e8bf181861520Charles Davis    if (Pointee->isFunctionType())
58071cc7deffad608165b1ddd5263e8bf181861520Charles Davis      return 3;
59071cc7deffad608165b1ddd5263e8bf181861520Charles Davis    else
60071cc7deffad608165b1ddd5263e8bf181861520Charles Davis      return 2;
61071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  } else if (RD->getNumBases() > 1 && Pointee->isFunctionType())
62071cc7deffad608165b1ddd5263e8bf181861520Charles Davis    return 2;
63071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  return 1;
64071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}
65071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
66071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
67071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  return new MicrosoftCXXABI(Ctx);
68071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}
69071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
70