xref: /freebsd/contrib/llvm-project/clang/lib/AST/MicrosoftCXXABI.cpp (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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/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"
24 
25 using namespace clang;
26 
27 namespace {
28 
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;
36 
37 public:
38   MicrosoftNumberingContext() = default;
39 
40   unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
41     return ++LambdaManglingNumber;
42   }
43 
44   unsigned getManglingNumber(const BlockDecl *BD) override {
45     const Type *Ty = nullptr;
46     return ++ManglingNumbers[Ty];
47   }
48 
49   unsigned getStaticLocalNumber(const VarDecl *VD) override {
50     if (VD->getTLSKind())
51       return ++StaticThreadlocalNumber;
52     return ++StaticLocalNumber;
53   }
54 
55   unsigned getManglingNumber(const VarDecl *VD,
56                              unsigned MSLocalManglingNumber) override {
57     return MSLocalManglingNumber;
58   }
59 
60   unsigned getManglingNumber(const TagDecl *TD,
61                              unsigned MSLocalManglingNumber) override {
62     return MSLocalManglingNumber;
63   }
64 };
65 
66 class MSHIPNumberingContext : public MicrosoftNumberingContext {
67   std::unique_ptr<MangleNumberingContext> DeviceCtx;
68 
69 public:
70   using MicrosoftNumberingContext::getManglingNumber;
71   MSHIPNumberingContext(MangleContext *DeviceMangler) {
72     DeviceCtx = createItaniumNumberingContext(DeviceMangler);
73   }
74 
75   unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
76     return DeviceCtx->getManglingNumber(CallOperator);
77   }
78 
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);
89     }
90     return (DeviceN << 16) | HostN;
91   }
92 };
93 
94 class MSSYCLNumberingContext : public MicrosoftNumberingContext {
95   std::unique_ptr<MangleNumberingContext> DeviceCtx;
96 
97 public:
98   MSSYCLNumberingContext(MangleContext *DeviceMangler) {
99     DeviceCtx = createItaniumNumberingContext(DeviceMangler);
100   }
101 
102   unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
103     return DeviceCtx->getManglingNumber(CallOperator);
104   }
105 };
106 
107 class MicrosoftCXXABI : public CXXABI {
108   ASTContext &Context;
109   llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
110 
111   llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
112       UnnamedTagDeclToDeclaratorDecl;
113   llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
114       UnnamedTagDeclToTypedefNameDecl;
115 
116   // MangleContext for device numbering context, which is based on Itanium C++
117   // ABI.
118   std::unique_ptr<MangleContext> DeviceMangler;
119 
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()));
128     }
129     else if (Context.getLangOpts().isSYCL()) {
130       DeviceMangler.reset(
131           ItaniumMangleContext::create(Context, Context.getDiagnostics()));
132     }
133   }
134 
135   MemberPointerInfo
136   getMemberPointerInfo(const MemberPointerType *MPT) const override;
137 
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();
143   }
144 
145   bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
146     llvm_unreachable("unapplicable to the MS ABI");
147   }
148 
149   const CXXConstructorDecl *
150   getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
151     return RecordToCopyCtor[RD];
152   }
153 
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;
160   }
161 
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;
169   }
170 
171   TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
172     return UnnamedTagDeclToTypedefNameDecl.lookup(
173         const_cast<TagDecl *>(TD->getCanonicalDecl()));
174   }
175 
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;
183   }
184 
185   DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
186     return UnnamedTagDeclToDeclaratorDecl.lookup(
187         const_cast<TagDecl *>(TD->getCanonicalDecl()));
188   }
189 
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());
198     }
199 
200     return std::make_unique<MicrosoftNumberingContext>();
201   }
202 };
203 }
204 
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;
218   }
219   return false;
220 }
221 
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;
230 }
231 
232 MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
233   MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
234   assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
235   return IA->getInheritanceModel();
236 }
237 
238 bool CXXRecordDecl::nullFieldOffsetIsZero() const {
239   return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
240                                           getMSInheritanceModel()) ||
241          (hasDefinition() && isPolymorphic());
242 }
243 
244 MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
245   if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
246     return VDA->getVtorDispMode();
247   return getASTContext().getLangOpts().getVtorDispMode();
248 }
249 
250 // Returns the number of pointer and integer slots used to represent a member
251 // pointer in the MS C++ ABI.
252 //
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.
256 //
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;
262 //
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;
269 //
270 //     // The offset of the vb-table pointer within the object.  Only needed for
271 //     // incomplete types.
272 //     int VBPtrOffset;
273 //
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);
297 }
298 
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();
306 
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;
312 
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();
322 
323   if (Target.getTriple().isArch64Bit()) {
324     MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
325     MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
326   }
327   return MPI;
328 }
329 
330 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
331   return new MicrosoftCXXABI(Ctx);
332 }
333