MicrosoftCXXABI.cpp revision 360784
1//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This provides C++ AST support targeting the Microsoft Visual C++
10// ABI.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CXXABI.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Attr.h"
17#include "clang/AST/CXXInheritance.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/// Numbers things which need to correspond across multiple TUs.
29/// Typically these are things like static locals, lambdas, or blocks.
30class MicrosoftNumberingContext : public MangleNumberingContext {
31  llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
32  unsigned LambdaManglingNumber;
33  unsigned StaticLocalNumber;
34  unsigned StaticThreadlocalNumber;
35
36public:
37  MicrosoftNumberingContext()
38      : MangleNumberingContext(), LambdaManglingNumber(0),
39        StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
40
41  unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
42    return ++LambdaManglingNumber;
43  }
44
45  unsigned getManglingNumber(const BlockDecl *BD) override {
46    const Type *Ty = nullptr;
47    return ++ManglingNumbers[Ty];
48  }
49
50  unsigned getStaticLocalNumber(const VarDecl *VD) override {
51    if (VD->getTLSKind())
52      return ++StaticThreadlocalNumber;
53    return ++StaticLocalNumber;
54  }
55
56  unsigned getManglingNumber(const VarDecl *VD,
57                             unsigned MSLocalManglingNumber) override {
58    return MSLocalManglingNumber;
59  }
60
61  unsigned getManglingNumber(const TagDecl *TD,
62                             unsigned MSLocalManglingNumber) override {
63    return MSLocalManglingNumber;
64  }
65};
66
67class MicrosoftCXXABI : public CXXABI {
68  ASTContext &Context;
69  llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
70
71  llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
72      UnnamedTagDeclToDeclaratorDecl;
73  llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
74      UnnamedTagDeclToTypedefNameDecl;
75
76public:
77  MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
78
79  MemberPointerInfo
80  getMemberPointerInfo(const MemberPointerType *MPT) const override;
81
82  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
83    if (!isVariadic &&
84        Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
85      return CC_X86ThisCall;
86    return Context.getTargetInfo().getDefaultCallingConv();
87  }
88
89  bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
90    llvm_unreachable("unapplicable to the MS ABI");
91  }
92
93  const CXXConstructorDecl *
94  getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
95    return RecordToCopyCtor[RD];
96  }
97
98  void
99  addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
100                                       CXXConstructorDecl *CD) override {
101    assert(CD != nullptr);
102    assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
103    RecordToCopyCtor[RD] = CD;
104  }
105
106  void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
107                                       TypedefNameDecl *DD) override {
108    TD = TD->getCanonicalDecl();
109    DD = DD->getCanonicalDecl();
110    TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
111    if (!I)
112      I = DD;
113  }
114
115  TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
116    return UnnamedTagDeclToTypedefNameDecl.lookup(
117        const_cast<TagDecl *>(TD->getCanonicalDecl()));
118  }
119
120  void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
121                                      DeclaratorDecl *DD) override {
122    TD = TD->getCanonicalDecl();
123    DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
124    DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
125    if (!I)
126      I = DD;
127  }
128
129  DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
130    return UnnamedTagDeclToDeclaratorDecl.lookup(
131        const_cast<TagDecl *>(TD->getCanonicalDecl()));
132  }
133
134  std::unique_ptr<MangleNumberingContext>
135  createMangleNumberingContext() const override {
136    return std::make_unique<MicrosoftNumberingContext>();
137  }
138};
139}
140
141// getNumBases() seems to only give us the number of direct bases, and not the
142// total.  This function tells us if we inherit from anybody that uses MI, or if
143// we have a non-primary base class, which uses the multiple inheritance model.
144static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
145  while (RD->getNumBases() > 0) {
146    if (RD->getNumBases() > 1)
147      return true;
148    assert(RD->getNumBases() == 1);
149    const CXXRecordDecl *Base =
150        RD->bases_begin()->getType()->getAsCXXRecordDecl();
151    if (RD->isPolymorphic() && !Base->isPolymorphic())
152      return true;
153    RD = Base;
154  }
155  return false;
156}
157
158MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const {
159  if (!hasDefinition() || isParsingBaseSpecifiers())
160    return MSInheritanceModel::Unspecified;
161  if (getNumVBases() > 0)
162    return MSInheritanceModel::Virtual;
163  if (usesMultipleInheritanceModel(this))
164    return MSInheritanceModel::Multiple;
165  return MSInheritanceModel::Single;
166}
167
168MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
169  MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
170  assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
171  return IA->getInheritanceModel();
172}
173
174bool CXXRecordDecl::nullFieldOffsetIsZero() const {
175  return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
176                                          getMSInheritanceModel()) ||
177         (hasDefinition() && isPolymorphic());
178}
179
180MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
181  if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
182    return VDA->getVtorDispMode();
183  return getASTContext().getLangOpts().getVtorDispMode();
184}
185
186// Returns the number of pointer and integer slots used to represent a member
187// pointer in the MS C++ ABI.
188//
189// Member function pointers have the following general form;  however, fields
190// are dropped as permitted (under the MSVC interpretation) by the inheritance
191// model of the actual class.
192//
193//   struct {
194//     // A pointer to the member function to call.  If the member function is
195//     // virtual, this will be a thunk that forwards to the appropriate vftable
196//     // slot.
197//     void *FunctionPointerOrVirtualThunk;
198//
199//     // An offset to add to the address of the vbtable pointer after
200//     // (possibly) selecting the virtual base but before resolving and calling
201//     // the function.
202//     // Only needed if the class has any virtual bases or bases at a non-zero
203//     // offset.
204//     int NonVirtualBaseAdjustment;
205//
206//     // The offset of the vb-table pointer within the object.  Only needed for
207//     // incomplete types.
208//     int VBPtrOffset;
209//
210//     // An offset within the vb-table that selects the virtual base containing
211//     // the member.  Loading from this offset produces a new offset that is
212//     // added to the address of the vb-table pointer to produce the base.
213//     int VirtualBaseAdjustmentOffset;
214//   };
215static std::pair<unsigned, unsigned>
216getMSMemberPointerSlots(const MemberPointerType *MPT) {
217  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
218  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
219  unsigned Ptrs = 0;
220  unsigned Ints = 0;
221  if (MPT->isMemberFunctionPointer())
222    Ptrs = 1;
223  else
224    Ints = 1;
225  if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
226                                          Inheritance))
227    Ints++;
228  if (inheritanceModelHasVBPtrOffsetField(Inheritance))
229    Ints++;
230  if (inheritanceModelHasVBTableOffsetField(Inheritance))
231    Ints++;
232  return std::make_pair(Ptrs, Ints);
233}
234
235CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
236    const MemberPointerType *MPT) const {
237  // The nominal struct is laid out with pointers followed by ints and aligned
238  // to a pointer width if any are present and an int width otherwise.
239  const TargetInfo &Target = Context.getTargetInfo();
240  unsigned PtrSize = Target.getPointerWidth(0);
241  unsigned IntSize = Target.getIntWidth();
242
243  unsigned Ptrs, Ints;
244  std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
245  MemberPointerInfo MPI;
246  MPI.HasPadding = false;
247  MPI.Width = Ptrs * PtrSize + Ints * IntSize;
248
249  // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
250  // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
251  // function memptrs.
252  if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
253    MPI.Align = 64;
254  else if (Ptrs)
255    MPI.Align = Target.getPointerAlign(0);
256  else
257    MPI.Align = Target.getIntAlign();
258
259  if (Target.getTriple().isArch64Bit()) {
260    MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
261    MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
262  }
263  return MPI;
264}
265
266CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
267  return new MicrosoftCXXABI(Ctx);
268}
269
270