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