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//
10fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner// This provides C++ AST support targeting 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"
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/Attr.h"
18071cc7deffad608165b1ddd5263e8bf181861520Charles Davis#include "clang/AST/DeclCXX.h"
19942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner#include "clang/AST/MangleNumberingContext.h"
20dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/RecordLayout.h"
21dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/AST/Type.h"
22dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson#include "clang/Basic/TargetInfo.h"
23071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
24071cc7deffad608165b1ddd5263e8bf181861520Charles Davisusing namespace clang;
25071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
26071cc7deffad608165b1ddd5263e8bf181861520Charles Davisnamespace {
27942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner
28942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner/// \brief Numbers things which need to correspond across multiple TUs.
29942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner/// Typically these are things like static locals, lambdas, or blocks.
30942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerclass MicrosoftNumberingContext : public MangleNumberingContext {
31942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Klecknerpublic:
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getManglingNumber(const VarDecl *VD,
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             unsigned MSLocalManglingNumber) override {
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return MSLocalManglingNumber;
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
36942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getManglingNumber(const TagDecl *TD,
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             unsigned MSLocalManglingNumber) override {
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return MSLocalManglingNumber;
40942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner  }
41942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner};
42942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner
43071cc7deffad608165b1ddd5263e8bf181861520Charles Davisclass MicrosoftCXXABI : public CXXABI {
44071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  ASTContext &Context;
45071cc7deffad608165b1ddd5263e8bf181861520Charles Davispublic:
46071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
47071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
4884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner  std::pair<uint64_t, unsigned>
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
50424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
52a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer    if (!isVariadic &&
53a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer        Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
54424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis      return CC_X86ThisCall;
55a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer    return CC_C;
56424ae9882e8a6eecc9dfe7c2d8623e72b2563873Charles Davis  }
57dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
59dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    // FIXME: Audit the corners
60dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    if (!RD->isDynamicClass())
61dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson      return false;
62dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson
63dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
64dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson
65dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson    // In the Microsoft ABI, classes can have one or two vtable pointers.
665c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck    CharUnits PointerSize =
67bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
685c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck    return Layout.getNonVirtualSize() == PointerSize ||
695c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck      Layout.getNonVirtualSize() == PointerSize * 2;
70dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson  }
71942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MangleNumberingContext *createMangleNumberingContext() const override {
73942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner    return new MicrosoftNumberingContext();
74942f9fe11d3a9583eef6bc4ca2549b1f0d1694daReid Kleckner  }
75071cc7deffad608165b1ddd5263e8bf181861520Charles Davis};
76071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}
77071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
7884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// getNumBases() seems to only give us the number of direct bases, and not the
7984e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// total.  This function tells us if we inherit from anybody that uses MI, or if
8084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner// we have a non-primary base class, which uses the multiple inheritance model.
81a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstatic bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
8284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner  while (RD->getNumBases() > 0) {
8384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner    if (RD->getNumBases() > 1)
8484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner      return true;
8584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner    assert(RD->getNumBases() == 1);
86a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer    const CXXRecordDecl *Base =
87a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer        RD->bases_begin()->getType()->getAsCXXRecordDecl();
8884e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner    if (RD->isPolymorphic() && !Base->isPolymorphic())
8984e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner      return true;
9084e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner    RD = Base;
9184e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner  }
9284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner  return false;
9384e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner}
9484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner
95651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
96ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (!hasDefinition() || isParsingBaseSpecifiers())
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return MSInheritanceAttr::Keyword_unspecified_inheritance;
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (getNumVBases() > 0)
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return MSInheritanceAttr::Keyword_virtual_inheritance;
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (usesMultipleInheritanceModel(this))
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return MSInheritanceAttr::Keyword_multiple_inheritance;
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return MSInheritanceAttr::Keyword_single_inheritance;
1034410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner}
10484e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner
105651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSInheritanceAttr::Spelling
106651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCXXRecordDecl::getMSInheritanceModel() const {
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return IA->getSemanticSpelling();
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
112651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return VDA->getVtorDispMode();
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
1164410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner}
1174410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner
1184410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Returns the number of pointer and integer slots used to represent a member
1194410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// pointer in the MS C++ ABI.
1204410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//
1214410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// Member function pointers have the following general form;  however, fields
1224410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// are dropped as permitted (under the MSVC interpretation) by the inheritance
1234410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner// model of the actual class.
1244410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//
1254410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//   struct {
1264410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // A pointer to the member function to call.  If the member function is
1274410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // virtual, this will be a thunk that forwards to the appropriate vftable
1284410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // slot.
1294410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     void *FunctionPointerOrVirtualThunk;
1304410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//
1314410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // An offset to add to the address of the vbtable pointer after (possibly)
1324410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // selecting the virtual base but before resolving and calling the function.
1334410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // Only needed if the class has any virtual bases or bases at a non-zero
1344410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // offset.
1354410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     int NonVirtualBaseAdjustment;
1364410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//     // The offset of the vb-table pointer within the object.  Only needed for
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//     // incomplete types.
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//     int VBPtrOffset;
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
1414410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // An offset within the vb-table that selects the virtual base containing
1424410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // the member.  Loading from this offset produces a new offset that is
1434410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     // added to the address of the vb-table pointer to produce the base.
1444410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//     int VirtualBaseAdjustmentOffset;
1454410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner//   };
146a3609b0c7685346308ed2c8022f94949bbfe7cdfReid Klecknerstatic std::pair<unsigned, unsigned>
147a3609b0c7685346308ed2c8022f94949bbfe7cdfReid KlecknergetMSMemberPointerSlots(const MemberPointerType *MPT) {
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Ptrs = 0;
1514410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  unsigned Ints = 0;
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (MPT->isMemberFunctionPointer())
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Ptrs = 1;
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  else
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Ints = 1;
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          Inheritance))
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Ints++;
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Ints++;
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Ints++;
1634410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  return std::make_pair(Ptrs, Ints);
1644410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner}
16584e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner
166a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramerstd::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
167a83297bd83ba7184935dddde04787f88dd52e182Benjamin Kramer    const MemberPointerType *MPT) const {
1684410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  const TargetInfo &Target = Context.getTargetInfo();
1694410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
1704410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner         Target.getTriple().getArch() == llvm::Triple::x86_64);
1714410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  unsigned Ptrs, Ints;
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
1734410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  // The nominal struct is laid out with pointers followed by ints and aligned
1744410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  // to a pointer width if any are present and an int width otherwise.
1754410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  unsigned PtrSize = Target.getPointerWidth(0);
1764410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  unsigned IntSize = Target.getIntWidth();
1774410489163931892b568f0a43bd49c430a3aa3f5Reid Kleckner  uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Align;
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // function memptrs.
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Align = 8 * 8;
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  else if (Ptrs)
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Align = Target.getPointerAlign(0);
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  else
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Align = Target.getIntAlign();
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (Target.getTriple().getArch() == llvm::Triple::x86_64)
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Width = llvm::RoundUpToAlignment(Width, Align);
19284e9ab44af3a16f66d62590505db2036ef0aa03bReid Kleckner  return std::make_pair(Width, Align);
193071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}
194071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
195071cc7deffad608165b1ddd5263e8bf181861520Charles DavisCXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
196071cc7deffad608165b1ddd5263e8bf181861520Charles Davis  return new MicrosoftCXXABI(Ctx);
197071cc7deffad608165b1ddd5263e8bf181861520Charles Davis}
198071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
199