clang: lib/AST/MicrosoftCXXABI.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
24
25using namespace clang;
26
27namespace {
28
29
30
32 llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
33 unsigned LambdaManglingNumber = 0;
34 unsigned StaticLocalNumber = 0;
35 unsigned StaticThreadlocalNumber = 0;
36
37public:
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 {
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
66class MSHIPNumberingContext : public MicrosoftNumberingContext {
67 std::unique_ptr DeviceCtx;
68
69public:
70 using MicrosoftNumberingContext::getManglingNumber;
71 MSHIPNumberingContext(MangleContext *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) {
89 }
90 return (DeviceN << 16) | HostN;
91 }
92};
93
94class MSSYCLNumberingContext : public MicrosoftNumberingContext {
95 std::unique_ptr DeviceCtx;
96
97public:
98 MSSYCLNumberingContext(MangleContext *DeviceMangler) {
100 }
101
102 unsigned getDeviceManglingNumber(const CXXMethodDecl *CallOperator) override {
103 return DeviceCtx->getManglingNumber(CallOperator);
104 }
105};
106
107class 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
117
118 std::unique_ptr DeviceMangler;
119
120public:
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)
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 {
166 TypedefNameDecl *&I = UnnamedTagDeclToTypedefNameDecl[TD];
167 if (!I)
168 I = DD;
169 }
170
171 TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD) override {
172 return UnnamedTagDeclToTypedefNameDecl.lookup(
174 }
175
176 void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
177 DeclaratorDecl *DD) override {
180 DeclaratorDecl *&I = UnnamedTagDeclToDeclaratorDecl[TD];
181 if (!I)
182 I = DD;
183 }
184
185 DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) override {
186 return UnnamedTagDeclToDeclaratorDecl.lookup(
188 }
189
190 std::unique_ptr
191 createMangleNumberingContext() const override {
192 if (Context.getLangOpts().CUDA && Context.getAuxTargetInfo()) {
193 assert(DeviceMangler && "Missing device mangler");
194 return std::make_unique(DeviceMangler.get());
195 } else if (Context.getLangOpts().isSYCL()) {
196 assert(DeviceMangler && "Missing device mangler");
197 return std::make_unique(DeviceMangler.get());
198 }
199
200 return std::make_unique();
201 }
202};
203}
204
205
206
207
211 return true;
216 return true;
218 }
219 return false;
220}
221
231
234 assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
235 return IA->getInheritanceModel();
236}
237
243
246 return VDA->getVtorDispMode();
248}
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279static std::pair<unsigned, unsigned>
283 unsigned Ptrs = 0;
284 unsigned Ints = 0;
286 Ptrs = 1;
287 else
288 Ints = 1;
290 Inheritance))
291 Ints++;
293 Ints++;
295 Ints++;
296 return std::make_pair(Ptrs, Ints);
297}
298
301
302
305 unsigned IntSize = Target.getIntWidth();
306
307 unsigned Ptrs, Ints;
309 MemberPointerInfo MPI;
310 MPI.HasPadding = false;
311 MPI.Width = Ptrs * PtrSize + Ints * IntSize;
312
313
314
315
316 if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
317 MPI.Align = 64;
318 else if (Ptrs)
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
331 return new MicrosoftCXXABI(Ctx);
332}
Defines the clang::ASTContext interface.
static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD)
Definition MicrosoftCXXABI.cpp:208
static std::pair< unsigned, unsigned > getMSMemberPointerSlots(const MemberPointerType *MPT)
Definition MicrosoftCXXABI.cpp:280
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define CXXABI(Name, Str)
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
Implements C++ ABI-specific semantic analysis functions.
QualType getType() const
Retrieves the type of the base class.
Represents a C++ struct/union/class.
bool isParsingBaseSpecifiers() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
Definition MicrosoftCXXABI.cpp:232
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
Definition MicrosoftCXXABI.cpp:238
bool hasDefinition() const
MSInheritanceModel calculateInheritanceModel() const
Calculate what the inheritance model would be for this class.
Definition MicrosoftCXXABI.cpp:222
MSVtorDispMode getMSVtorDispMode() const
Controls when vtordisps will be emitted if this record is used as a virtual base.
Definition MicrosoftCXXABI.cpp:244
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocation() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Keeps track of the mangled names of lambda expressions and block literals within a particular context...
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
TypedefNameDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this typedef-name.
TLSKind getTLSKind() const
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
std::unique_ptr< MangleNumberingContext > createItaniumNumberingContext(MangleContext *)
CXXABI * CreateMicrosoftCXXABI(ASTContext &Ctx)
Definition MicrosoftCXXABI.cpp:330
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
bool inheritanceModelHasOnlyOneField(bool IsMemberFunction, MSInheritanceModel Inheritance)
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
@ Type
The name was classified as a type.
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)