]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/MicrosoftCXXABI.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / lib / AST / MicrosoftCXXABI.cpp
1 //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This provides C++ AST support targeting the Microsoft Visual C++
11 // ABI.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "CXXABI.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/Attr.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
24 using namespace clang;
25
26 namespace {
27
28 /// Numbers things which need to correspond across multiple TUs.
29 /// Typically these are things like static locals, lambdas, or blocks.
30 class MicrosoftNumberingContext : public MangleNumberingContext {
31   llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
32   unsigned LambdaManglingNumber;
33   unsigned StaticLocalNumber;
34   unsigned StaticThreadlocalNumber;
35
36 public:
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
67 class 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
76 public:
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 CC_C;
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 llvm::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.
144 static 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
158 MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
159   if (!hasDefinition() || isParsingBaseSpecifiers())
160     return MSInheritanceAttr::Keyword_unspecified_inheritance;
161   if (getNumVBases() > 0)
162     return MSInheritanceAttr::Keyword_virtual_inheritance;
163   if (usesMultipleInheritanceModel(this))
164     return MSInheritanceAttr::Keyword_multiple_inheritance;
165   return MSInheritanceAttr::Keyword_single_inheritance;
166 }
167
168 MSInheritanceAttr::Spelling
169 CXXRecordDecl::getMSInheritanceModel() const {
170   MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
171   assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
172   return IA->getSemanticSpelling();
173 }
174
175 MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
176   if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
177     return VDA->getVtorDispMode();
178   return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
179 }
180
181 // Returns the number of pointer and integer slots used to represent a member
182 // pointer in the MS C++ ABI.
183 //
184 // Member function pointers have the following general form;  however, fields
185 // are dropped as permitted (under the MSVC interpretation) by the inheritance
186 // model of the actual class.
187 //
188 //   struct {
189 //     // A pointer to the member function to call.  If the member function is
190 //     // virtual, this will be a thunk that forwards to the appropriate vftable
191 //     // slot.
192 //     void *FunctionPointerOrVirtualThunk;
193 //
194 //     // An offset to add to the address of the vbtable pointer after
195 //     // (possibly) selecting the virtual base but before resolving and calling
196 //     // the function.
197 //     // Only needed if the class has any virtual bases or bases at a non-zero
198 //     // offset.
199 //     int NonVirtualBaseAdjustment;
200 //
201 //     // The offset of the vb-table pointer within the object.  Only needed for
202 //     // incomplete types.
203 //     int VBPtrOffset;
204 //
205 //     // An offset within the vb-table that selects the virtual base containing
206 //     // the member.  Loading from this offset produces a new offset that is
207 //     // added to the address of the vb-table pointer to produce the base.
208 //     int VirtualBaseAdjustmentOffset;
209 //   };
210 static std::pair<unsigned, unsigned>
211 getMSMemberPointerSlots(const MemberPointerType *MPT) {
212   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
213   MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
214   unsigned Ptrs = 0;
215   unsigned Ints = 0;
216   if (MPT->isMemberFunctionPointer())
217     Ptrs = 1;
218   else
219     Ints = 1;
220   if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
221                                           Inheritance))
222     Ints++;
223   if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
224     Ints++;
225   if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
226     Ints++;
227   return std::make_pair(Ptrs, Ints);
228 }
229
230 CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
231     const MemberPointerType *MPT) const {
232   // The nominal struct is laid out with pointers followed by ints and aligned
233   // to a pointer width if any are present and an int width otherwise.
234   const TargetInfo &Target = Context.getTargetInfo();
235   unsigned PtrSize = Target.getPointerWidth(0);
236   unsigned IntSize = Target.getIntWidth();
237
238   unsigned Ptrs, Ints;
239   std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
240   MemberPointerInfo MPI;
241   MPI.HasPadding = false;
242   MPI.Width = Ptrs * PtrSize + Ints * IntSize;
243
244   // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
245   // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
246   // function memptrs.
247   if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
248     MPI.Align = 64;
249   else if (Ptrs)
250     MPI.Align = Target.getPointerAlign(0);
251   else
252     MPI.Align = Target.getIntAlign();
253
254   if (Target.getTriple().isArch64Bit()) {
255     MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
256     MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
257   }
258   return MPI;
259 }
260
261 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
262   return new MicrosoftCXXABI(Ctx);
263 }
264