[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / AST / MicrosoftCXXABI.cpp
blob1c020c3ad4ad55d6433566a49133fabc67102eec
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.
12 //===----------------------------------------------------------------------===//
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/Mangle.h"
20 #include "clang/AST/MangleNumberingContext.h"
21 #include "clang/AST/RecordLayout.h"
22 #include "clang/AST/Type.h"
23 #include "clang/Basic/TargetInfo.h"
25 using namespace clang;
27 namespace {
29 /// Numbers things which need to correspond across multiple TUs.
30 /// Typically these are things like static locals, lambdas, or blocks.
31 class MicrosoftNumberingContext : public MangleNumberingContext {
32 llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
33 unsigned LambdaManglingNumber = 0;
34 unsigned StaticLocalNumber = 0;
35 unsigned StaticThreadlocalNumber = 0;
37 public:
38 MicrosoftNumberingContext() = default;
40 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
41 return ++LambdaManglingNumber;
44 unsigned getManglingNumber(const BlockDecl *BD) override {
45 const Type *Ty = nullptr;
46 return ++ManglingNumbers[Ty];
49 unsigned getStaticLocalNumber(const VarDecl *VD) override {
50 if (VD->getTLSKind())
51 return ++StaticThreadlocalNumber;
52 return ++StaticLocalNumber;
55 unsigned getManglingNumber(const VarDecl *VD,
56 unsigned MSLocalManglingNumber) override {
57 return MSLocalManglingNumber;
60 unsigned getManglingNumber(const TagDecl *TD,
61 unsigned MSLocalManglingNumber) override {
62 return MSLocalManglingNumber;
66 class MSHIPNumberingContext : public MicrosoftNumberingContext {
67 std::unique_ptr<MangleNumberingContext> DeviceCtx;
69 public:
70 using MicrosoftNumberingContext::getManglingNumber;
71 MSHIPNumberingContext(MangleContext *DeviceMangler) {
72 DeviceCtx = createItaniumNumberingContext(DeviceMangler);
75 unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
76 return DeviceCtx->getManglingNumber(CallOperator);
79 unsigned getManglingNumber(const TagDecl *TD,
80 unsigned MSLocalManglingNumber) override {
81 unsigned DeviceN = DeviceCtx->getManglingNumber(TD, MSLocalManglingNumber);
82 unsigned HostN =
83 MicrosoftNumberingContext::getManglingNumber(TD, MSLocalManglingNumber);
84 if (DeviceN > 0xFFFF || HostN > 0xFFFF) {
85 DiagnosticsEngine &Diags = TD->getASTContext().getDiagnostics();
86 unsigned DiagID = Diags.getCustomDiagID(
87 DiagnosticsEngine::Error, "Mangling number exceeds limit (65535)");
88 Diags.Report(TD->getLocation(), DiagID);
90 return (DeviceN << 16) | HostN;
94 class MSSYCLNumberingContext : public MicrosoftNumberingContext {
95 std::unique_ptr<MangleNumberingContext> DeviceCtx;
97 public:
98 MSSYCLNumberingContext(MangleContext *DeviceMangler) {
99 DeviceCtx = createItaniumNumberingContext(DeviceMangler);
102 unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
103 return DeviceCtx->getManglingNumber(CallOperator);
107 class MicrosoftCXXABI : public CXXABI {
108 ASTContext &Context;
109 llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
111 llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
112 UnnamedTagDeclToDeclaratorDecl;
113 llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
114 UnnamedTagDeclToTypedefNameDecl;
116 // MangleContext for device numbering context, which is based on Itanium C++
117 // ABI.
118 std::unique_ptr<MangleContext> DeviceMangler;
120 public:
121 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) {
122 if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
123 assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
124 Context.getAuxTargetInfo()->getCXXABI().isItaniumFamily() &&
125 "Unexpected combination of C++ ABIs.");
126 DeviceMangler.reset(
127 Context.createMangleContext(Context.getAuxTargetInfo()));
129 else if (Context.getLangOpts().isSYCL()) {
130 DeviceMangler.reset(
131 ItaniumMangleContext::create(Context, Context.getDiagnostics()));
135 MemberPointerInfo
136 getMemberPointerInfo(const MemberPointerType *MPT) const override;
138 CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
139 if (!isVariadic &&
140 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
141 return CC_X86ThisCall;
142 return Context.getTargetInfo().getDefaultCallingConv();
145 bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
146 llvm_unreachable("unapplicable to the MS ABI");
149 const CXXConstructorDecl *
150 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
151 return RecordToCopyCtor[RD];
154 void
155 addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
156 CXXConstructorDecl *CD) override {
157 assert(CD != nullptr);
158 assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
159 RecordToCopyCtor[RD] = CD;
162 void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
163 TypedefNameDecl *DD) override {
164 TD = TD->getCanonicalDecl();
165 DD = DD->getCanonicalDecl();
166 TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
167 if (!I)
168 I = DD;
171 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
172 return UnnamedTagDeclToTypedefNameDecl.lookup(
173 const_cast<TagDecl *>(TD->getCanonicalDecl()));
176 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
177 DeclaratorDecl *DD) override {
178 TD = TD->getCanonicalDecl();
179 DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
180 DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
181 if (!I)
182 I = DD;
185 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
186 return UnnamedTagDeclToDeclaratorDecl.lookup(
187 const_cast<TagDecl *>(TD->getCanonicalDecl()));
190 std::unique_ptr<MangleNumberingContext>
191 createMangleNumberingContext() const override {
192 if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
193 assert(DeviceMangler && "Missing device mangler");
194 return std::make_unique<MSHIPNumberingContext>(DeviceMangler.get());
195 } else if (Context.getLangOpts().isSYCL()) {
196 assert(DeviceMangler && "Missing device mangler");
197 return std::make_unique<MSSYCLNumberingContext>(DeviceMangler.get());
200 return std::make_unique<MicrosoftNumberingContext>();
205 // getNumBases() seems to only give us the number of direct bases, and not the
206 // total. This function tells us if we inherit from anybody that uses MI, or if
207 // we have a non-primary base class, which uses the multiple inheritance model.
208 static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
209 while (RD->getNumBases() > 0) {
210 if (RD->getNumBases() > 1)
211 return true;
212 assert(RD->getNumBases() == 1);
213 const CXXRecordDecl *Base =
214 RD->bases_begin()->getType()->getAsCXXRecordDecl();
215 if (RD->isPolymorphic() && !Base->isPolymorphic())
216 return true;
217 RD = Base;
219 return false;
222 MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const {
223 if (!hasDefinition() || isParsingBaseSpecifiers())
224 return MSInheritanceModel::Unspecified;
225 if (getNumVBases() > 0)
226 return MSInheritanceModel::Virtual;
227 if (usesMultipleInheritanceModel(this))
228 return MSInheritanceModel::Multiple;
229 return MSInheritanceModel::Single;
232 MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
233 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
234 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
235 return IA->getInheritanceModel();
238 bool CXXRecordDecl::nullFieldOffsetIsZero() const {
239 return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
240 getMSInheritanceModel()) ||
241 (hasDefinition() && isPolymorphic());
244 MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
245 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
246 return VDA->getVtorDispMode();
247 return getASTContext().getLangOpts().getVtorDispMode();
250 // Returns the number of pointer and integer slots used to represent a member
251 // pointer in the MS C++ ABI.
253 // Member function pointers have the following general form; however, fields
254 // are dropped as permitted (under the MSVC interpretation) by the inheritance
255 // model of the actual class.
257 // struct {
258 // // A pointer to the member function to call. If the member function is
259 // // virtual, this will be a thunk that forwards to the appropriate vftable
260 // // slot.
261 // void *FunctionPointerOrVirtualThunk;
263 // // An offset to add to the address of the vbtable pointer after
264 // // (possibly) selecting the virtual base but before resolving and calling
265 // // the function.
266 // // Only needed if the class has any virtual bases or bases at a non-zero
267 // // offset.
268 // int NonVirtualBaseAdjustment;
270 // // The offset of the vb-table pointer within the object. Only needed for
271 // // incomplete types.
272 // int VBPtrOffset;
274 // // An offset within the vb-table that selects the virtual base containing
275 // // the member. Loading from this offset produces a new offset that is
276 // // added to the address of the vb-table pointer to produce the base.
277 // int VirtualBaseAdjustmentOffset;
278 // };
279 static std::pair<unsigned, unsigned>
280 getMSMemberPointerSlots(const MemberPointerType *MPT) {
281 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
282 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
283 unsigned Ptrs = 0;
284 unsigned Ints = 0;
285 if (MPT->isMemberFunctionPointer())
286 Ptrs = 1;
287 else
288 Ints = 1;
289 if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
290 Inheritance))
291 Ints++;
292 if (inheritanceModelHasVBPtrOffsetField(Inheritance))
293 Ints++;
294 if (inheritanceModelHasVBTableOffsetField(Inheritance))
295 Ints++;
296 return std::make_pair(Ptrs, Ints);
299 CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
300 const MemberPointerType *MPT) const {
301 // The nominal struct is laid out with pointers followed by ints and aligned
302 // to a pointer width if any are present and an int width otherwise.
303 const TargetInfo &Target = Context.getTargetInfo();
304 unsigned PtrSize = Target.getPointerWidth(LangAS::Default);
305 unsigned IntSize = Target.getIntWidth();
307 unsigned Ptrs, Ints;
308 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
309 MemberPointerInfo MPI;
310 MPI.HasPadding = false;
311 MPI.Width = Ptrs * PtrSize + Ints * IntSize;
313 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
314 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
315 // function memptrs.
316 if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
317 MPI.Align = 64;
318 else if (Ptrs)
319 MPI.Align = Target.getPointerAlign(LangAS::Default);
320 else
321 MPI.Align = Target.getIntAlign();
323 if (Target.getTriple().isArch64Bit()) {
324 MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
325 MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
327 return MPI;
330 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
331 return new MicrosoftCXXABI(Ctx);