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/Attr.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/MangleNumberingContext.h"
20#include "clang/AST/RecordLayout.h"
21#include "clang/AST/Type.h"
22#include "clang/Basic/TargetInfo.h"
23
24using namespace clang;
25
26namespace {
27
28/// \brief Numbers things which need to correspond across multiple TUs.
29/// Typically these are things like static locals, lambdas, or blocks.
30class MicrosoftNumberingContext : public MangleNumberingContext {
31public:
32  unsigned getManglingNumber(const VarDecl *VD,
33                             unsigned MSLocalManglingNumber) override {
34    return MSLocalManglingNumber;
35  }
36
37  unsigned getManglingNumber(const TagDecl *TD,
38                             unsigned MSLocalManglingNumber) override {
39    return MSLocalManglingNumber;
40  }
41};
42
43class MicrosoftCXXABI : public CXXABI {
44  ASTContext &Context;
45public:
46  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
47
48  std::pair<uint64_t, unsigned>
49  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
50
51  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
52    if (!isVariadic &&
53        Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
54      return CC_X86ThisCall;
55    return CC_C;
56  }
57
58  bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
59    // FIXME: Audit the corners
60    if (!RD->isDynamicClass())
61      return false;
62
63    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
64
65    // In the Microsoft ABI, classes can have one or two vtable pointers.
66    CharUnits PointerSize =
67      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
68    return Layout.getNonVirtualSize() == PointerSize ||
69      Layout.getNonVirtualSize() == PointerSize * 2;
70  }
71
72  MangleNumberingContext *createMangleNumberingContext() const override {
73    return new MicrosoftNumberingContext();
74  }
75};
76}
77
78// getNumBases() seems to only give us the number of direct bases, and not the
79// total.  This function tells us if we inherit from anybody that uses MI, or if
80// we have a non-primary base class, which uses the multiple inheritance model.
81static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
82  while (RD->getNumBases() > 0) {
83    if (RD->getNumBases() > 1)
84      return true;
85    assert(RD->getNumBases() == 1);
86    const CXXRecordDecl *Base =
87        RD->bases_begin()->getType()->getAsCXXRecordDecl();
88    if (RD->isPolymorphic() && !Base->isPolymorphic())
89      return true;
90    RD = Base;
91  }
92  return false;
93}
94
95MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
96  if (!hasDefinition() || isParsingBaseSpecifiers())
97    return MSInheritanceAttr::Keyword_unspecified_inheritance;
98  if (getNumVBases() > 0)
99    return MSInheritanceAttr::Keyword_virtual_inheritance;
100  if (usesMultipleInheritanceModel(this))
101    return MSInheritanceAttr::Keyword_multiple_inheritance;
102  return MSInheritanceAttr::Keyword_single_inheritance;
103}
104
105MSInheritanceAttr::Spelling
106CXXRecordDecl::getMSInheritanceModel() const {
107  MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
108  assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
109  return IA->getSemanticSpelling();
110}
111
112MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
113  if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
114    return VDA->getVtorDispMode();
115  return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
116}
117
118// Returns the number of pointer and integer slots used to represent a member
119// pointer in the MS C++ ABI.
120//
121// Member function pointers have the following general form;  however, fields
122// are dropped as permitted (under the MSVC interpretation) by the inheritance
123// model of the actual class.
124//
125//   struct {
126//     // A pointer to the member function to call.  If the member function is
127//     // virtual, this will be a thunk that forwards to the appropriate vftable
128//     // slot.
129//     void *FunctionPointerOrVirtualThunk;
130//
131//     // An offset to add to the address of the vbtable pointer after (possibly)
132//     // selecting the virtual base but before resolving and calling the function.
133//     // Only needed if the class has any virtual bases or bases at a non-zero
134//     // offset.
135//     int NonVirtualBaseAdjustment;
136//
137//     // The offset of the vb-table pointer within the object.  Only needed for
138//     // incomplete types.
139//     int VBPtrOffset;
140//
141//     // An offset within the vb-table that selects the virtual base containing
142//     // the member.  Loading from this offset produces a new offset that is
143//     // added to the address of the vb-table pointer to produce the base.
144//     int VirtualBaseAdjustmentOffset;
145//   };
146static std::pair<unsigned, unsigned>
147getMSMemberPointerSlots(const MemberPointerType *MPT) {
148  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
149  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
150  unsigned Ptrs = 0;
151  unsigned Ints = 0;
152  if (MPT->isMemberFunctionPointer())
153    Ptrs = 1;
154  else
155    Ints = 1;
156  if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
157                                          Inheritance))
158    Ints++;
159  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
160    Ints++;
161  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
162    Ints++;
163  return std::make_pair(Ptrs, Ints);
164}
165
166std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
167    const MemberPointerType *MPT) const {
168  const TargetInfo &Target = Context.getTargetInfo();
169  assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
170         Target.getTriple().getArch() == llvm::Triple::x86_64);
171  unsigned Ptrs, Ints;
172  std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
173  // The nominal struct is laid out with pointers followed by ints and aligned
174  // to a pointer width if any are present and an int width otherwise.
175  unsigned PtrSize = Target.getPointerWidth(0);
176  unsigned IntSize = Target.getIntWidth();
177  uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
178  unsigned Align;
179
180  // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
181  // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
182  // function memptrs.
183  if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
184    Align = 8 * 8;
185  else if (Ptrs)
186    Align = Target.getPointerAlign(0);
187  else
188    Align = Target.getIntAlign();
189
190  if (Target.getTriple().getArch() == llvm::Triple::x86_64)
191    Width = llvm::RoundUpToAlignment(Width, Align);
192  return std::make_pair(Width, Align);
193}
194
195CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
196  return new MicrosoftCXXABI(Ctx);
197}
198
199