1//===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
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// Defines the C++ name mangling interface.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_MANGLE_H
14#define LLVM_CLANG_AST_MANGLE_H
15
16#include "clang/AST/Decl.h"
17#include "clang/AST/GlobalDecl.h"
18#include "clang/AST/Type.h"
19#include "clang/Basic/ABI.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/Support/Casting.h"
22
23namespace llvm {
24 class raw_ostream;
25}
26
27namespace clang {
28 class ASTContext;
29 class BlockDecl;
30 class CXXConstructorDecl;
31 class CXXDestructorDecl;
32 class CXXMethodDecl;
33 class FunctionDecl;
34 struct MethodVFTableLocation;
35 class NamedDecl;
36 class ObjCMethodDecl;
37 class StringLiteral;
38 struct ThisAdjustment;
39 struct ThunkInfo;
40 class VarDecl;
41
42/// MangleContext - Context for tracking state which persists across multiple
43/// calls to the C++ name mangler.
44class MangleContext {
45public:
46 enum ManglerKind {
47 MK_Itanium,
48 MK_Microsoft
49 };
50
51private:
52 virtual void anchor();
53
54 ASTContext &Context;
55 DiagnosticsEngine &Diags;
56 const ManglerKind Kind;
57
58 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
59 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
60 llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
61
62public:
63 ManglerKind getKind() const { return Kind; }
64
65 explicit MangleContext(ASTContext &Context,
66 DiagnosticsEngine &Diags,
67 ManglerKind Kind)
68 : Context(Context), Diags(Diags), Kind(Kind) {}
69
70 virtual ~MangleContext() { }
71
72 ASTContext &getASTContext() const { return Context; }
73
74 DiagnosticsEngine &getDiags() const { return Diags; }
75
76 virtual void startNewFunction() { LocalBlockIds.clear(); }
77
78 unsigned getBlockId(const BlockDecl *BD, bool Local) {
79 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
80 = Local? LocalBlockIds : GlobalBlockIds;
81 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
82 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
83 return Result.first->second;
84 }
85
86 uint64_t getAnonymousStructId(const NamedDecl *D) {
87 std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
88 Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
89 return Result.first->second;
90 }
91
92 uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
93 llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
94 AnonStructIds.find(D);
95 // The decl should already be inserted, but return 0 in case it is not.
96 if (Result == AnonStructIds.end())
97 return 0;
98 return Result->second;
99 }
100
101 virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
102
103 /// @name Mangler Entry Points
104 /// @{
105
106 bool shouldMangleDeclName(const NamedDecl *D);
107 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
108 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
109
110 virtual bool isDeviceMangleContext() const { return false; }
111 virtual void setDeviceMangleContext(bool) {}
112
113 virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
114 return false;
115 }
116
117 virtual void needsUniqueInternalLinkageNames() { }
118
119 // FIXME: consider replacing raw_ostream & with something like SmallString &.
120 void mangleName(GlobalDecl GD, raw_ostream &);
121 virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
122 virtual void mangleThunk(const CXXMethodDecl *MD,
123 const ThunkInfo &Thunk,
124 raw_ostream &) = 0;
125 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
126 const ThisAdjustment &ThisAdjustment,
127 raw_ostream &) = 0;
128 virtual void mangleReferenceTemporary(const VarDecl *D,
129 unsigned ManglingNumber,
130 raw_ostream &) = 0;
131 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
132 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
133 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
134 virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
135
136 void mangleGlobalBlock(const BlockDecl *BD,
137 const NamedDecl *ID,
138 raw_ostream &Out);
139 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
140 const BlockDecl *BD, raw_ostream &Out);
141 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
142 const BlockDecl *BD, raw_ostream &Out);
143 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
144 raw_ostream &Out);
145
146 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
147 bool includePrefixByte = true,
148 bool includeCategoryNamespace = true);
149 void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
150 raw_ostream &);
151
152 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
153
154 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
155
156 virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
157 raw_ostream &) = 0;
158
159 virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
160 raw_ostream &Out) = 0;
161
162 virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
163 raw_ostream &Out) = 0;
164
165 /// Generates a unique string for an externally visible type for use with TBAA
166 /// or type uniquing.
167 /// TODO: Extend this to internal types by generating names that are unique
168 /// across translation units so it can be used with LTO.
169 virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
170
171 /// @}
172};
173
174class ItaniumMangleContext : public MangleContext {
175public:
176 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
177 : MangleContext(C, D, MK_Itanium) {}
178
179 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
180 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
181 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
182 const CXXRecordDecl *Type,
183 raw_ostream &) = 0;
184 virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
185 raw_ostream &) = 0;
186 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
187 raw_ostream &) = 0;
188
189 virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
190 raw_ostream &) = 0;
191 virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
192 raw_ostream &) = 0;
193
194 virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
195
196 virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
197
198 static bool classof(const MangleContext *C) {
199 return C->getKind() == MK_Itanium;
200 }
201
202 static ItaniumMangleContext *create(ASTContext &Context,
203 DiagnosticsEngine &Diags);
204};
205
206class MicrosoftMangleContext : public MangleContext {
207public:
208 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
209 : MangleContext(C, D, MK_Microsoft) {}
210
211 /// Mangle vftable symbols. Only a subset of the bases along the path
212 /// to the vftable are included in the name. It's up to the caller to pick
213 /// them correctly.
214 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
215 ArrayRef<const CXXRecordDecl *> BasePath,
216 raw_ostream &Out) = 0;
217
218 /// Mangle vbtable symbols. Only a subset of the bases along the path
219 /// to the vbtable are included in the name. It's up to the caller to pick
220 /// them correctly.
221 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
222 ArrayRef<const CXXRecordDecl *> BasePath,
223 raw_ostream &Out) = 0;
224
225 virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
226 unsigned GuardNum,
227 raw_ostream &Out) = 0;
228
229 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
230 const MethodVFTableLocation &ML,
231 raw_ostream &Out) = 0;
232
233 virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
234 const CXXRecordDecl *DstRD,
235 raw_ostream &Out) = 0;
236
237 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
238 bool IsUnaligned, uint32_t NumEntries,
239 raw_ostream &Out) = 0;
240
241 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
242 raw_ostream &Out) = 0;
243
244 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
245 CXXCtorType CT, uint32_t Size,
246 uint32_t NVOffset, int32_t VBPtrOffset,
247 uint32_t VBIndex, raw_ostream &Out) = 0;
248
249 virtual void mangleCXXRTTIBaseClassDescriptor(
250 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
251 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
252
253 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
254 raw_ostream &Out) = 0;
255 virtual void
256 mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
257 raw_ostream &Out) = 0;
258
259 virtual void
260 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
261 ArrayRef<const CXXRecordDecl *> BasePath,
262 raw_ostream &Out) = 0;
263
264 static bool classof(const MangleContext *C) {
265 return C->getKind() == MK_Microsoft;
266 }
267
268 static MicrosoftMangleContext *create(ASTContext &Context,
269 DiagnosticsEngine &Diags);
270};
271
272class ASTNameGenerator {
273public:
274 explicit ASTNameGenerator(ASTContext &Ctx);
275 ~ASTNameGenerator();
276
277 /// Writes name for \p D to \p OS.
278 /// \returns true on failure, false on success.
279 bool writeName(const Decl *D, raw_ostream &OS);
280
281 /// \returns name for \p D
282 std::string getName(const Decl *D);
283
284 /// \returns all applicable mangled names.
285 /// For example C++ constructors/destructors can have multiple.
286 std::vector<std::string> getAllManglings(const Decl *D);
287
288private:
289 class Implementation;
290 std::unique_ptr<Implementation> Impl;
291};
292}
293
294#endif
295