annotate clang/lib/AST/MicrosoftCXXABI.cpp @ 222:81f6424ef0e3 llvm-original

LLVM original branch
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 18 Jul 2021 22:10:01 +0900
parents 79ff65ed7e25
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // This provides C++ AST support targeting the Microsoft Visual C++
anatofuz
parents:
diff changeset
10 // ABI.
anatofuz
parents:
diff changeset
11 //
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #include "CXXABI.h"
anatofuz
parents:
diff changeset
15 #include "clang/AST/ASTContext.h"
anatofuz
parents:
diff changeset
16 #include "clang/AST/Attr.h"
anatofuz
parents:
diff changeset
17 #include "clang/AST/CXXInheritance.h"
anatofuz
parents:
diff changeset
18 #include "clang/AST/DeclCXX.h"
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
19 #include "clang/AST/Mangle.h"
150
anatofuz
parents:
diff changeset
20 #include "clang/AST/MangleNumberingContext.h"
anatofuz
parents:
diff changeset
21 #include "clang/AST/RecordLayout.h"
anatofuz
parents:
diff changeset
22 #include "clang/AST/Type.h"
anatofuz
parents:
diff changeset
23 #include "clang/Basic/TargetInfo.h"
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 using namespace clang;
anatofuz
parents:
diff changeset
26
anatofuz
parents:
diff changeset
27 namespace {
anatofuz
parents:
diff changeset
28
anatofuz
parents:
diff changeset
29 /// Numbers things which need to correspond across multiple TUs.
anatofuz
parents:
diff changeset
30 /// Typically these are things like static locals, lambdas, or blocks.
anatofuz
parents:
diff changeset
31 class MicrosoftNumberingContext : public MangleNumberingContext {
anatofuz
parents:
diff changeset
32 llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
anatofuz
parents:
diff changeset
33 unsigned LambdaManglingNumber;
anatofuz
parents:
diff changeset
34 unsigned StaticLocalNumber;
anatofuz
parents:
diff changeset
35 unsigned StaticThreadlocalNumber;
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 public:
anatofuz
parents:
diff changeset
38 MicrosoftNumberingContext()
anatofuz
parents:
diff changeset
39 : MangleNumberingContext(), LambdaManglingNumber(0),
anatofuz
parents:
diff changeset
40 StaticLocalNumber(0), StaticThreadlocalNumber(0) {}
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 unsigned getManglingNumber(const CXXMethodDecl *CallOperator) override {
anatofuz
parents:
diff changeset
43 return ++LambdaManglingNumber;
anatofuz
parents:
diff changeset
44 }
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 unsigned getManglingNumber(const BlockDecl *BD) override {
anatofuz
parents:
diff changeset
47 const Type *Ty = nullptr;
anatofuz
parents:
diff changeset
48 return ++ManglingNumbers[Ty];
anatofuz
parents:
diff changeset
49 }
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 unsigned getStaticLocalNumber(const VarDecl *VD) override {
anatofuz
parents:
diff changeset
52 if (VD->getTLSKind())
anatofuz
parents:
diff changeset
53 return ++StaticThreadlocalNumber;
anatofuz
parents:
diff changeset
54 return ++StaticLocalNumber;
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 unsigned getManglingNumber(const VarDecl *VD,
anatofuz
parents:
diff changeset
58 unsigned MSLocalManglingNumber) override {
anatofuz
parents:
diff changeset
59 return MSLocalManglingNumber;
anatofuz
parents:
diff changeset
60 }
anatofuz
parents:
diff changeset
61
anatofuz
parents:
diff changeset
62 unsigned getManglingNumber(const TagDecl *TD,
anatofuz
parents:
diff changeset
63 unsigned MSLocalManglingNumber) override {
anatofuz
parents:
diff changeset
64 return MSLocalManglingNumber;
anatofuz
parents:
diff changeset
65 }
anatofuz
parents:
diff changeset
66 };
anatofuz
parents:
diff changeset
67
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
68 class MSHIPNumberingContext : public MicrosoftNumberingContext {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
69 std::unique_ptr<MangleNumberingContext> DeviceCtx;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
70
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
71 public:
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
72 MSHIPNumberingContext(MangleContext *DeviceMangler) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
73 DeviceCtx = createItaniumNumberingContext(DeviceMangler);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
74 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
75
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
76 unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
77 return DeviceCtx->getManglingNumber(CallOperator);
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
78 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
79 };
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
80
150
anatofuz
parents:
diff changeset
81 class MicrosoftCXXABI : public CXXABI {
anatofuz
parents:
diff changeset
82 ASTContext &Context;
anatofuz
parents:
diff changeset
83 llvm::SmallDenseMap<CXXRecordDecl *, CXXConstructorDecl *> RecordToCopyCtor;
anatofuz
parents:
diff changeset
84
anatofuz
parents:
diff changeset
85 llvm::SmallDenseMap<TagDecl *, DeclaratorDecl *>
anatofuz
parents:
diff changeset
86 UnnamedTagDeclToDeclaratorDecl;
anatofuz
parents:
diff changeset
87 llvm::SmallDenseMap<TagDecl *, TypedefNameDecl *>
anatofuz
parents:
diff changeset
88 UnnamedTagDeclToTypedefNameDecl;
anatofuz
parents:
diff changeset
89
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
90 // MangleContext for device numbering context, which is based on Itanium C++
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
91 // ABI.
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
92 std::unique_ptr<MangleContext> DeviceMangler;
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
93
150
anatofuz
parents:
diff changeset
94 public:
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
95 MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
96 if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
97 assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
98 Context.getAuxTargetInfo()->getCXXABI().isItaniumFamily() &&
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
99 "Unexpected combination of C++ ABIs.");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
100 DeviceMangler.reset(
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
101 Context.createMangleContext(Context.getAuxTargetInfo()));
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
102 }
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
103 }
150
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 MemberPointerInfo
anatofuz
parents:
diff changeset
106 getMemberPointerInfo(const MemberPointerType *MPT) const override;
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
anatofuz
parents:
diff changeset
109 if (!isVariadic &&
anatofuz
parents:
diff changeset
110 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
anatofuz
parents:
diff changeset
111 return CC_X86ThisCall;
anatofuz
parents:
diff changeset
112 return Context.getTargetInfo().getDefaultCallingConv();
anatofuz
parents:
diff changeset
113 }
anatofuz
parents:
diff changeset
114
anatofuz
parents:
diff changeset
115 bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
anatofuz
parents:
diff changeset
116 llvm_unreachable("unapplicable to the MS ABI");
anatofuz
parents:
diff changeset
117 }
anatofuz
parents:
diff changeset
118
anatofuz
parents:
diff changeset
119 const CXXConstructorDecl *
anatofuz
parents:
diff changeset
120 getCopyConstructorForExceptionObject(CXXRecordDecl *RD) override {
anatofuz
parents:
diff changeset
121 return RecordToCopyCtor[RD];
anatofuz
parents:
diff changeset
122 }
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 void
anatofuz
parents:
diff changeset
125 addCopyConstructorForExceptionObject(CXXRecordDecl *RD,
anatofuz
parents:
diff changeset
126 CXXConstructorDecl *CD) override {
anatofuz
parents:
diff changeset
127 assert(CD != nullptr);
anatofuz
parents:
diff changeset
128 assert(RecordToCopyCtor[RD] == nullptr || RecordToCopyCtor[RD] == CD);
anatofuz
parents:
diff changeset
129 RecordToCopyCtor[RD] = CD;
anatofuz
parents:
diff changeset
130 }
anatofuz
parents:
diff changeset
131
anatofuz
parents:
diff changeset
132 void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
anatofuz
parents:
diff changeset
133 TypedefNameDecl *DD) override {
anatofuz
parents:
diff changeset
134 TD = TD->getCanonicalDecl();
anatofuz
parents:
diff changeset
135 DD = DD->getCanonicalDecl();
anatofuz
parents:
diff changeset
136 TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
anatofuz
parents:
diff changeset
137 if (!I)
anatofuz
parents:
diff changeset
138 I = DD;
anatofuz
parents:
diff changeset
139 }
anatofuz
parents:
diff changeset
140
anatofuz
parents:
diff changeset
141 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
anatofuz
parents:
diff changeset
142 return UnnamedTagDeclToTypedefNameDecl.lookup(
anatofuz
parents:
diff changeset
143 const_cast<TagDecl *>(TD->getCanonicalDecl()));
anatofuz
parents:
diff changeset
144 }
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
anatofuz
parents:
diff changeset
147 DeclaratorDecl *DD) override {
anatofuz
parents:
diff changeset
148 TD = TD->getCanonicalDecl();
anatofuz
parents:
diff changeset
149 DD = cast<DeclaratorDecl>(DD->getCanonicalDecl());
anatofuz
parents:
diff changeset
150 DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
anatofuz
parents:
diff changeset
151 if (!I)
anatofuz
parents:
diff changeset
152 I = DD;
anatofuz
parents:
diff changeset
153 }
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
anatofuz
parents:
diff changeset
156 return UnnamedTagDeclToDeclaratorDecl.lookup(
anatofuz
parents:
diff changeset
157 const_cast<TagDecl *>(TD->getCanonicalDecl()));
anatofuz
parents:
diff changeset
158 }
anatofuz
parents:
diff changeset
159
anatofuz
parents:
diff changeset
160 std::unique_ptr<MangleNumberingContext>
anatofuz
parents:
diff changeset
161 createMangleNumberingContext() const override {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
162 if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
163 assert(DeviceMangler && "Missing device mangler");
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
164 return std::make_unique<MSHIPNumberingContext>(DeviceMangler.get());
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
165 }
150
anatofuz
parents:
diff changeset
166 return std::make_unique<MicrosoftNumberingContext>();
anatofuz
parents:
diff changeset
167 }
anatofuz
parents:
diff changeset
168 };
anatofuz
parents:
diff changeset
169 }
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 // getNumBases() seems to only give us the number of direct bases, and not the
anatofuz
parents:
diff changeset
172 // total. This function tells us if we inherit from anybody that uses MI, or if
anatofuz
parents:
diff changeset
173 // we have a non-primary base class, which uses the multiple inheritance model.
anatofuz
parents:
diff changeset
174 static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
175 while (RD->getNumBases() > 0) {
anatofuz
parents:
diff changeset
176 if (RD->getNumBases() > 1)
anatofuz
parents:
diff changeset
177 return true;
anatofuz
parents:
diff changeset
178 assert(RD->getNumBases() == 1);
anatofuz
parents:
diff changeset
179 const CXXRecordDecl *Base =
anatofuz
parents:
diff changeset
180 RD->bases_begin()->getType()->getAsCXXRecordDecl();
anatofuz
parents:
diff changeset
181 if (RD->isPolymorphic() && !Base->isPolymorphic())
anatofuz
parents:
diff changeset
182 return true;
anatofuz
parents:
diff changeset
183 RD = Base;
anatofuz
parents:
diff changeset
184 }
anatofuz
parents:
diff changeset
185 return false;
anatofuz
parents:
diff changeset
186 }
anatofuz
parents:
diff changeset
187
anatofuz
parents:
diff changeset
188 MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const {
anatofuz
parents:
diff changeset
189 if (!hasDefinition() || isParsingBaseSpecifiers())
anatofuz
parents:
diff changeset
190 return MSInheritanceModel::Unspecified;
anatofuz
parents:
diff changeset
191 if (getNumVBases() > 0)
anatofuz
parents:
diff changeset
192 return MSInheritanceModel::Virtual;
anatofuz
parents:
diff changeset
193 if (usesMultipleInheritanceModel(this))
anatofuz
parents:
diff changeset
194 return MSInheritanceModel::Multiple;
anatofuz
parents:
diff changeset
195 return MSInheritanceModel::Single;
anatofuz
parents:
diff changeset
196 }
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
anatofuz
parents:
diff changeset
199 MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
anatofuz
parents:
diff changeset
200 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
anatofuz
parents:
diff changeset
201 return IA->getInheritanceModel();
anatofuz
parents:
diff changeset
202 }
anatofuz
parents:
diff changeset
203
anatofuz
parents:
diff changeset
204 bool CXXRecordDecl::nullFieldOffsetIsZero() const {
anatofuz
parents:
diff changeset
205 return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false,
anatofuz
parents:
diff changeset
206 getMSInheritanceModel()) ||
anatofuz
parents:
diff changeset
207 (hasDefinition() && isPolymorphic());
anatofuz
parents:
diff changeset
208 }
anatofuz
parents:
diff changeset
209
anatofuz
parents:
diff changeset
210 MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
anatofuz
parents:
diff changeset
211 if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
anatofuz
parents:
diff changeset
212 return VDA->getVtorDispMode();
anatofuz
parents:
diff changeset
213 return getASTContext().getLangOpts().getVtorDispMode();
anatofuz
parents:
diff changeset
214 }
anatofuz
parents:
diff changeset
215
anatofuz
parents:
diff changeset
216 // Returns the number of pointer and integer slots used to represent a member
anatofuz
parents:
diff changeset
217 // pointer in the MS C++ ABI.
anatofuz
parents:
diff changeset
218 //
anatofuz
parents:
diff changeset
219 // Member function pointers have the following general form; however, fields
anatofuz
parents:
diff changeset
220 // are dropped as permitted (under the MSVC interpretation) by the inheritance
anatofuz
parents:
diff changeset
221 // model of the actual class.
anatofuz
parents:
diff changeset
222 //
anatofuz
parents:
diff changeset
223 // struct {
anatofuz
parents:
diff changeset
224 // // A pointer to the member function to call. If the member function is
anatofuz
parents:
diff changeset
225 // // virtual, this will be a thunk that forwards to the appropriate vftable
anatofuz
parents:
diff changeset
226 // // slot.
anatofuz
parents:
diff changeset
227 // void *FunctionPointerOrVirtualThunk;
anatofuz
parents:
diff changeset
228 //
anatofuz
parents:
diff changeset
229 // // An offset to add to the address of the vbtable pointer after
anatofuz
parents:
diff changeset
230 // // (possibly) selecting the virtual base but before resolving and calling
anatofuz
parents:
diff changeset
231 // // the function.
anatofuz
parents:
diff changeset
232 // // Only needed if the class has any virtual bases or bases at a non-zero
anatofuz
parents:
diff changeset
233 // // offset.
anatofuz
parents:
diff changeset
234 // int NonVirtualBaseAdjustment;
anatofuz
parents:
diff changeset
235 //
anatofuz
parents:
diff changeset
236 // // The offset of the vb-table pointer within the object. Only needed for
anatofuz
parents:
diff changeset
237 // // incomplete types.
anatofuz
parents:
diff changeset
238 // int VBPtrOffset;
anatofuz
parents:
diff changeset
239 //
anatofuz
parents:
diff changeset
240 // // An offset within the vb-table that selects the virtual base containing
anatofuz
parents:
diff changeset
241 // // the member. Loading from this offset produces a new offset that is
anatofuz
parents:
diff changeset
242 // // added to the address of the vb-table pointer to produce the base.
anatofuz
parents:
diff changeset
243 // int VirtualBaseAdjustmentOffset;
anatofuz
parents:
diff changeset
244 // };
anatofuz
parents:
diff changeset
245 static std::pair<unsigned, unsigned>
anatofuz
parents:
diff changeset
246 getMSMemberPointerSlots(const MemberPointerType *MPT) {
anatofuz
parents:
diff changeset
247 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
anatofuz
parents:
diff changeset
248 MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
anatofuz
parents:
diff changeset
249 unsigned Ptrs = 0;
anatofuz
parents:
diff changeset
250 unsigned Ints = 0;
anatofuz
parents:
diff changeset
251 if (MPT->isMemberFunctionPointer())
anatofuz
parents:
diff changeset
252 Ptrs = 1;
anatofuz
parents:
diff changeset
253 else
anatofuz
parents:
diff changeset
254 Ints = 1;
anatofuz
parents:
diff changeset
255 if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
anatofuz
parents:
diff changeset
256 Inheritance))
anatofuz
parents:
diff changeset
257 Ints++;
anatofuz
parents:
diff changeset
258 if (inheritanceModelHasVBPtrOffsetField(Inheritance))
anatofuz
parents:
diff changeset
259 Ints++;
anatofuz
parents:
diff changeset
260 if (inheritanceModelHasVBTableOffsetField(Inheritance))
anatofuz
parents:
diff changeset
261 Ints++;
anatofuz
parents:
diff changeset
262 return std::make_pair(Ptrs, Ints);
anatofuz
parents:
diff changeset
263 }
anatofuz
parents:
diff changeset
264
anatofuz
parents:
diff changeset
265 CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
anatofuz
parents:
diff changeset
266 const MemberPointerType *MPT) const {
anatofuz
parents:
diff changeset
267 // The nominal struct is laid out with pointers followed by ints and aligned
anatofuz
parents:
diff changeset
268 // to a pointer width if any are present and an int width otherwise.
anatofuz
parents:
diff changeset
269 const TargetInfo &Target = Context.getTargetInfo();
anatofuz
parents:
diff changeset
270 unsigned PtrSize = Target.getPointerWidth(0);
anatofuz
parents:
diff changeset
271 unsigned IntSize = Target.getIntWidth();
anatofuz
parents:
diff changeset
272
anatofuz
parents:
diff changeset
273 unsigned Ptrs, Ints;
anatofuz
parents:
diff changeset
274 std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
anatofuz
parents:
diff changeset
275 MemberPointerInfo MPI;
anatofuz
parents:
diff changeset
276 MPI.HasPadding = false;
anatofuz
parents:
diff changeset
277 MPI.Width = Ptrs * PtrSize + Ints * IntSize;
anatofuz
parents:
diff changeset
278
anatofuz
parents:
diff changeset
279 // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
anatofuz
parents:
diff changeset
280 // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
anatofuz
parents:
diff changeset
281 // function memptrs.
anatofuz
parents:
diff changeset
282 if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
anatofuz
parents:
diff changeset
283 MPI.Align = 64;
anatofuz
parents:
diff changeset
284 else if (Ptrs)
anatofuz
parents:
diff changeset
285 MPI.Align = Target.getPointerAlign(0);
anatofuz
parents:
diff changeset
286 else
anatofuz
parents:
diff changeset
287 MPI.Align = Target.getIntAlign();
anatofuz
parents:
diff changeset
288
anatofuz
parents:
diff changeset
289 if (Target.getTriple().isArch64Bit()) {
anatofuz
parents:
diff changeset
290 MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
anatofuz
parents:
diff changeset
291 MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
anatofuz
parents:
diff changeset
292 }
anatofuz
parents:
diff changeset
293 return MPI;
anatofuz
parents:
diff changeset
294 }
anatofuz
parents:
diff changeset
295
anatofuz
parents:
diff changeset
296 CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
anatofuz
parents:
diff changeset
297 return new MicrosoftCXXABI(Ctx);
anatofuz
parents:
diff changeset
298 }