blob: 4dc4156df9ca4749dee949bc5323247513830a0a [file] [log] [blame]
Charles Davis53c59df2010-08-16 03:33:14 +00001//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Charles Davis53c59df2010-08-16 03:33:14 +00006//
7//===----------------------------------------------------------------------===//
8//
Chris Lattner57540c52011-04-15 05:22:18 +00009// This provides C++ AST support targeting the Microsoft Visual C++
Charles Davis53c59df2010-08-16 03:33:14 +000010// ABI.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CXXABI.h"
15#include "clang/AST/ASTContext.h"
Chandler Carruth5553d0d2014-01-07 11:51:46 +000016#include "clang/AST/Attr.h"
Charles Davis53c59df2010-08-16 03:33:14 +000017#include "clang/AST/DeclCXX.h"
Reid Klecknerd8110b62013-09-10 20:14:30 +000018#include "clang/AST/MangleNumberingContext.h"
Anders Carlsson60a62632010-11-25 01:51:53 +000019#include "clang/AST/RecordLayout.h"
20#include "clang/AST/Type.h"
21#include "clang/Basic/TargetInfo.h"
Charles Davis53c59df2010-08-16 03:33:14 +000022
23using namespace clang;
24
25namespace {
Reid Klecknerd8110b62013-09-10 20:14:30 +000026
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000027/// Numbers things which need to correspond across multiple TUs.
Reid Klecknerd8110b62013-09-10 20:14:30 +000028/// Typically these are things like static locals, lambdas, or blocks.
29class MicrosoftNumberingContext : public MangleNumberingContext {
David Majnemer118da502014-08-22 04:22:50 +000030 llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
31 unsigned LambdaManglingNumber;
32 unsigned StaticLocalNumber;
David Majnemerec8e54b2015-05-07 21:19:06 +000033 unsigned StaticThreadlocalNumber;
David Majnemer118da502014-08-22 04:22:50 +000034
Reid Klecknerd8110b62013-09-10 20:14:30 +000035public:
David Majnemer118da502014-08-22 04:22:50 +000036 MicrosoftNumberingContext()
37 : MangleNumberingContext(), LambdaManglingNumber(0),
David Majnemerec8e54b2015-05-07 21:19:06 +000038 StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
David Majnemer118da502014-08-22 04:22:50 +000039
40 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
41 return ++LambdaManglingNumber;
42 }
43
Fariborz Jahanian5afc8692014-10-01 16:56:40 +000044 unsigned getManglingNumber(const BlockDecl *BD) override {
David Majnemer118da502014-08-22 04:22:50 +000045 const Type *Ty = nullptr;
46 return ++ManglingNumbers[Ty];
47 }
48
49 unsigned getStaticLocalNumber(const VarDecl *VD) override {
David Majnemerec8e54b2015-05-07 21:19:06 +000050 if (VD->getTLSKind())
51 return ++StaticThreadlocalNumber;
David Majnemer118da502014-08-22 04:22:50 +000052 return ++StaticLocalNumber;
53 }
54
Craig Toppercbce6e92014-03-11 06:22:39 +000055 unsigned getManglingNumber(const VarDecl *VD,
56 unsigned MSLocalManglingNumber) override {
David Majnemerf27217f2014-03-05 18:55:38 +000057 return MSLocalManglingNumber;
David Majnemer2206bf52014-03-05 08:57:59 +000058 }
Reid Klecknerd8110b62013-09-10 20:14:30 +000059
Craig Toppercbce6e92014-03-11 06:22:39 +000060 unsigned getManglingNumber(const TagDecl *TD,
61 unsigned MSLocalManglingNumber) override {
David Majnemerf27217f2014-03-05 18:55:38 +000062 return MSLocalManglingNumber;
Reid Klecknerd8110b62013-09-10 20:14:30 +000063 }
64};
65
Charles Davis53c59df2010-08-16 03:33:14 +000066class MicrosoftCXXABI : public CXXABI {
67 ASTContext &Context;
David Majnemere7a818f2015-03-06 18:53:55 +000068 llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
69
David Majnemer00350522015-08-31 18:48:39 +000070 llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
71 UnnamedTagDeclToDeclaratorDecl;
72 llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
73 UnnamedTagDeclToTypedefNameDecl;
74
Charles Davis53c59df2010-08-16 03:33:14 +000075public:
76 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
77
Erich Keane8a6b7402017-11-30 16:37:02 +000078 MemberPointerInfo
79 getMemberPointerInfo(const MemberPointerType *MPT) const override;
Charles Davis31575f72010-10-29 03:25:11 +000080
Craig Toppercbce6e92014-03-11 06:22:39 +000081 CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
Benjamin Kramer08db4612013-04-04 17:07:04 +000082 if (!isVariadic &&
83 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
Charles Davis31575f72010-10-29 03:25:11 +000084 return CC_X86ThisCall;
Benjamin Kramer08db4612013-04-04 17:07:04 +000085 return CC_C;
Charles Davis31575f72010-10-29 03:25:11 +000086 }
Anders Carlsson60a62632010-11-25 01:51:53 +000087
Craig Toppercbce6e92014-03-11 06:22:39 +000088 bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
David Majnemeree6c4092015-10-22 07:15:56 +000089 llvm_unreachable("unapplicable to the MS ABI");
David Majnemere7a818f2015-03-06 18:53:55 +000090 }
91
92 const CXXConstructorDecl *
93 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
94 return RecordToCopyCtor[RD];
95 }
96
97 void
98 addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
99 CXXConstructorDecl *CD) override {
100 assert(CD != nullptr);
101 assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
102 RecordToCopyCtor[RD] = CD;
103 }
Reid Klecknerd8110b62013-09-10 20:14:30 +0000104
David Majnemer00350522015-08-31 18:48:39 +0000105 void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
106 TypedefNameDecl *DD) override {
107 TD = TD->getCanonicalDecl();
George Burgess IV00f70bd2018-03-01 05:43:23 +0000108 DD = DD->getCanonicalDecl();
David Majnemer00350522015-08-31 18:48:39 +0000109 TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
110 if (!I)
111 I = DD;
112 }
113
114 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
David Majnemer7f0674d2015-09-01 01:53:07 +0000115 return UnnamedTagDeclToTypedefNameDecl.lookup(
116 const_cast<TagDecl *>(TD->getCanonicalDecl()));
David Majnemer00350522015-08-31 18:48:39 +0000117 }
118
119 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
120 DeclaratorDecl *DD) override {
121 TD = TD->getCanonicalDecl();
122 DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
123 DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
124 if (!I)
125 I = DD;
126 }
127
128 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
David Majnemer7f0674d2015-09-01 01:53:07 +0000129 return UnnamedTagDeclToDeclaratorDecl.lookup(
130 const_cast<TagDecl *>(TD->getCanonicalDecl()));
David Majnemer00350522015-08-31 18:48:39 +0000131 }
132
Justin Lebar20ebffc2016-10-10 16:26:19 +0000133 std::unique_ptr<MangleNumberingContext>
134 createMangleNumberingContext() const override {
135 return llvm::make_unique<MicrosoftNumberingContext>();
Reid Klecknerd8110b62013-09-10 20:14:30 +0000136 }
Charles Davis53c59df2010-08-16 03:33:14 +0000137};
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000138}
Charles Davis53c59df2010-08-16 03:33:14 +0000139
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000140// getNumBases() seems to only give us the number of direct bases, and not the
141// total. This function tells us if we inherit from anybody that uses MI, or if
142// we have a non-primary base class, which uses the multiple inheritance model.
Benjamin Kramer08db4612013-04-04 17:07:04 +0000143static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000144 while (RD->getNumBases() > 0) {
145 if (RD->getNumBases() > 1)
146 return true;
147 assert(RD->getNumBases() == 1);
Benjamin Kramer08db4612013-04-04 17:07:04 +0000148 const CXXRecordDecl *Base =
149 RD->bases_begin()->getType()->getAsCXXRecordDecl();
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000150 if (RD->isPolymorphic() && !Base->isPolymorphic())
151 return true;
152 RD = Base;
153 }
154 return false;
155}
156
David Majnemer2c4e00a2014-01-29 22:07:36 +0000157MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
David Majnemer5ef4fe72014-06-13 06:43:46 +0000158 if (!hasDefinition() || isParsingBaseSpecifiers())
David Majnemer1cdd96d2014-01-17 09:01:00 +0000159 return MSInheritanceAttr::Keyword_unspecified_inheritance;
David Majnemer2c4e00a2014-01-29 22:07:36 +0000160 if (getNumVBases() > 0)
David Majnemer1cdd96d2014-01-17 09:01:00 +0000161 return MSInheritanceAttr::Keyword_virtual_inheritance;
David Majnemer2c4e00a2014-01-29 22:07:36 +0000162 if (usesMultipleInheritanceModel(this))
David Majnemer1cdd96d2014-01-17 09:01:00 +0000163 return MSInheritanceAttr::Keyword_multiple_inheritance;
164 return MSInheritanceAttr::Keyword_single_inheritance;
165}
166
167MSInheritanceAttr::Spelling
168CXXRecordDecl::getMSInheritanceModel() const {
169 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
170 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
David Majnemer2c4e00a2014-01-29 22:07:36 +0000171 return IA->getSemanticSpelling();
David Majnemer1cdd96d2014-01-17 09:01:00 +0000172}
173
Reid Klecknerc0dca6d2014-02-12 23:50:26 +0000174MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
175 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
176 return VDA->getVtorDispMode();
177 return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
178}
179
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000180// Returns the number of pointer and integer slots used to represent a member
181// pointer in the MS C++ ABI.
182//
183// Member function pointers have the following general form; however, fields
184// are dropped as permitted (under the MSVC interpretation) by the inheritance
185// model of the actual class.
186//
187// struct {
188// // A pointer to the member function to call. If the member function is
189// // virtual, this will be a thunk that forwards to the appropriate vftable
190// // slot.
191// void *FunctionPointerOrVirtualThunk;
192//
Nico Weber9c39f832015-06-12 04:44:52 +0000193// // An offset to add to the address of the vbtable pointer after
194// // (possibly) selecting the virtual base but before resolving and calling
195// // the function.
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000196// // Only needed if the class has any virtual bases or bases at a non-zero
197// // offset.
198// int NonVirtualBaseAdjustment;
199//
Reid Kleckner96f8f932014-02-05 17:27:08 +0000200// // The offset of the vb-table pointer within the object. Only needed for
201// // incomplete types.
202// int VBPtrOffset;
203//
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000204// // An offset within the vb-table that selects the virtual base containing
205// // the member. Loading from this offset produces a new offset that is
206// // added to the address of the vb-table pointer to produce the base.
207// int VirtualBaseAdjustmentOffset;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000208// };
Reid Kleckner2341ae32013-04-11 18:13:19 +0000209static std::pair<unsigned, unsigned>
210getMSMemberPointerSlots(const MemberPointerType *MPT) {
David Majnemer1cdd96d2014-01-17 09:01:00 +0000211 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
212 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
213 unsigned Ptrs = 0;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000214 unsigned Ints = 0;
Reid Kleckner96f8f932014-02-05 17:27:08 +0000215 if (MPT->isMemberFunctionPointer())
216 Ptrs = 1;
217 else
218 Ints = 1;
219 if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
220 Inheritance))
221 Ints++;
222 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
223 Ints++;
224 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
225 Ints++;
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000226 return std::make_pair(Ptrs, Ints);
227}
Reid Kleckner3a52abf2013-03-28 20:02:56 +0000228
Erich Keane8a6b7402017-11-30 16:37:02 +0000229CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
Benjamin Kramer08db4612013-04-04 17:07:04 +0000230 const MemberPointerType *MPT) const {
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000231 // The nominal struct is laid out with pointers followed by ints and aligned
232 // to a pointer width if any are present and an int width otherwise.
David Majnemer37ea5782015-04-24 01:24:59 +0000233 const TargetInfo &Target = Context.getTargetInfo();
Reid Klecknerbe377cd2013-04-02 16:23:57 +0000234 unsigned PtrSize = Target.getPointerWidth(0);
235 unsigned IntSize = Target.getIntWidth();
David Majnemer37ea5782015-04-24 01:24:59 +0000236
237 unsigned Ptrs, Ints;
238 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
Erich Keane8a6b7402017-11-30 16:37:02 +0000239 MemberPointerInfo MPI;
240 MPI.HasPadding = false;
241 MPI.Width = Ptrs * PtrSize + Ints * IntSize;
Reid Klecknerbd63b332014-01-31 22:28:50 +0000242
243 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
244 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
245 // function memptrs.
David Majnemer37ea5782015-04-24 01:24:59 +0000246 if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
Erich Keane8a6b7402017-11-30 16:37:02 +0000247 MPI.Align = 64;
Reid Klecknerbd63b332014-01-31 22:28:50 +0000248 else if (Ptrs)
Erich Keane8a6b7402017-11-30 16:37:02 +0000249 MPI.Align = Target.getPointerAlign(0);
Reid Klecknerbd63b332014-01-31 22:28:50 +0000250 else
Erich Keane8a6b7402017-11-30 16:37:02 +0000251 MPI.Align = Target.getIntAlign();
Reid Klecknerbd63b332014-01-31 22:28:50 +0000252
Erich Keane8a6b7402017-11-30 16:37:02 +0000253 if (Target.getTriple().isArch64Bit()) {
254 MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
255 MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
256 }
257 return MPI;
Charles Davis53c59df2010-08-16 03:33:14 +0000258}
259
260CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
261 return new MicrosoftCXXABI(Ctx);
262}
263