clang 24.0.0git
Mangle.h
Go to the documentation of this file.
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"
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#include <optional>
23
24namespace llvm {
25class raw_ostream;
26}
27
28namespace clang {
29class ASTContext;
30class BlockDecl;
33class CXXMethodDecl;
34class FunctionDecl;
36class NamedDecl;
37class ObjCMethodDecl;
38class StringLiteral;
39struct ThisAdjustment;
40struct ThunkInfo;
41class VarDecl;
42
43/// Extract mangling function name from MangleContext such that swift can call
44/// it to prepare for ObjCDirect in swift.
45/// Produces the mangling:
46/// \01-[ClassName(Category) method:arg1:arg2:]
47/// Or, if useDirectABI is true (for Direct ABI):
48/// -[ClassName(Category) method:arg1:arg2:]D
49void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte,
50 bool isInstanceMethod, StringRef ClassName,
51 std::optional<StringRef> CategoryName,
52 StringRef MethodName, bool useDirectABI);
53
54/// MangleContext - Context for tracking state which persists across multiple
55/// calls to the C++ name mangler.
57public:
59
60private:
61 virtual void anchor();
62
63 ASTContext &Context;
64 DiagnosticsEngine &Diags;
65 const ManglerKind Kind;
66 /// For aux target. If true, uses mangling number for aux target from
67 /// ASTContext.
68 bool IsAux = false;
69
70 llvm::DenseMap<const BlockDecl *, unsigned> GlobalBlockIds;
71 llvm::DenseMap<const BlockDecl *, unsigned> LocalBlockIds;
72 llvm::DenseMap<const NamedDecl *, uint64_t> AnonStructIds;
73 llvm::DenseMap<const FunctionDecl *, unsigned> FuncAnonStructSize;
74
75public:
76 ManglerKind getKind() const { return Kind; }
77
78 bool isAux() const { return IsAux; }
79
80 explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
81 ManglerKind Kind, bool IsAux = false)
82 : Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
83
84 virtual ~MangleContext() {}
85
86 ASTContext &getASTContext() const { return Context; }
87
88 DiagnosticsEngine &getDiags() const { return Diags; }
89
90 virtual void startNewFunction() { LocalBlockIds.clear(); }
91
92 unsigned getBlockId(const BlockDecl *BD, bool Local) {
93 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds =
94 Local ? LocalBlockIds : GlobalBlockIds;
95 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
96 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
97 return Result.first->second;
98 }
99
101 const FunctionDecl *FD = nullptr) {
102 auto FindResult = AnonStructIds.find(D);
103 if (FindResult != AnonStructIds.end())
104 return FindResult->second;
105
106 // If FunctionDecl is passed in, the anonymous structID will be per-function
107 // based.
108 unsigned Id = FD ? FuncAnonStructSize[FD]++ : AnonStructIds.size();
109 std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
110 Result = AnonStructIds.insert(std::make_pair(D, Id));
111 return Result.first->second;
112 }
113
115 llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
116 AnonStructIds.find(D);
117 // The decl should already be inserted, but return 0 in case it is not.
118 if (Result == AnonStructIds.end())
119 return 0;
120 return Result->second;
121 }
122
123 virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
124
125 /// @name Mangler Entry Points
126 /// @{
127
128 bool shouldMangleDeclName(const NamedDecl *D);
130 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
131 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
132
133 /// Return true if \p FD's body contains a direct call back to the symbol it
134 /// links as, through an asm label or a __builtin_* alias (PR9614 / glibc's
135 /// btowc pattern). An available_externally body of such a function is not a
136 /// valid stand-in for the real implementation and should be dropped before
137 /// codegen. The check keys off the mangled/asm name, hence it lives on
138 /// MangleContext.
139 bool isTriviallyRecursive(const FunctionDecl *FD);
140
141 virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
142 return false;
143 }
144
146
147 // FIXME: consider replacing raw_ostream & with something like SmallString &.
148 void mangleName(GlobalDecl GD, raw_ostream &);
149 void mangleNameIgnoringAsmLabel(GlobalDecl GD, raw_ostream &);
150 virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
151 virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
152 bool ElideOverrideInfo, raw_ostream &) = 0;
154 const ThunkInfo &Thunk,
155 bool ElideOverrideInfo, raw_ostream &) = 0;
156 virtual void mangleReferenceTemporary(const VarDecl *D,
157 unsigned ManglingNumber,
158 raw_ostream &) = 0;
159 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
160 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
161 virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
162 bool NormalizeIntegers = false) = 0;
163 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
164 virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &) const;
165
166 void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID,
167 raw_ostream &Out);
169 const BlockDecl *BD, raw_ostream &Out);
171 const BlockDecl *BD, raw_ostream &Out);
172 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
173 raw_ostream &Out);
174
175 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
176 bool includePrefixByte = true,
177 bool includeCategoryNamespace = true,
178 bool useDirectABI = false) const;
180 raw_ostream &) const;
181
182 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
183
184 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
185
187 raw_ostream &) = 0;
188
189 virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
190 raw_ostream &Out) = 0;
191
192 virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
193 raw_ostream &Out) = 0;
194
195 /// Generates a unique string for an externally visible type for use with TBAA
196 /// or type uniquing.
197 /// TODO: Extend this to internal types by generating names that are unique
198 /// across translation units so it can be used with LTO.
199 virtual void mangleCanonicalTypeName(QualType T, raw_ostream &,
200 bool NormalizeIntegers = false) = 0;
201
202 /// @}
203};
204
206public:
208 const NamedDecl *);
210 bool IsAux = false)
211 : MangleContext(C, D, MK_Itanium, IsAux) {}
212
213 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
214 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
215 const CXXRecordDecl *Type,
216 raw_ostream &) = 0;
218 raw_ostream &) = 0;
220 raw_ostream &) = 0;
221
223 raw_ostream &) = 0;
225 raw_ostream &) = 0;
226
227 virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
228
229 virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
230
231 virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
232
233 // This has to live here, otherwise the CXXNameMangler won't have access to
234 // it.
236 static bool classof(const MangleContext *C) {
237 return C->getKind() == MK_Itanium;
238 }
239
240 static ItaniumMangleContext *
241 create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
242 static ItaniumMangleContext *create(ASTContext &Context,
243 DiagnosticsEngine &Diags,
244 DiscriminatorOverrideTy Discriminator,
245 bool IsAux = false);
246};
247
249public:
251 bool IsAux = false)
252 : MangleContext(C, D, MK_Microsoft, IsAux) {}
253
254 /// Mangle vftable symbols. Only a subset of the bases along the path
255 /// to the vftable are included in the name. It's up to the caller to pick
256 /// them correctly.
257 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
259 raw_ostream &Out) = 0;
260
261 /// Mangle vbtable symbols. Only a subset of the bases along the path
262 /// to the vbtable are included in the name. It's up to the caller to pick
263 /// them correctly.
264 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
266 raw_ostream &Out) = 0;
267
269 unsigned GuardNum,
270 raw_ostream &Out) = 0;
271
273 const MethodVFTableLocation &ML,
274 raw_ostream &Out) = 0;
275
277 const CXXRecordDecl *DstRD,
278 raw_ostream &Out) = 0;
279
280 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
281 bool IsUnaligned, uint32_t NumEntries,
282 raw_ostream &Out) = 0;
283
285 raw_ostream &Out) = 0;
286
288 CXXCtorType CT, uint32_t Size,
289 uint32_t NVOffset, int32_t VBPtrOffset,
290 uint32_t VBIndex, raw_ostream &Out) = 0;
291
293 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
294 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
295
296 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
297 raw_ostream &Out) = 0;
298 virtual void
300 raw_ostream &Out) = 0;
301
302 virtual void
305 raw_ostream &Out) = 0;
306
307 static bool classof(const MangleContext *C) {
308 return C->getKind() == MK_Microsoft;
309 }
310
312 create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
313};
314
316public:
317 explicit ASTNameGenerator(ASTContext &Ctx);
319
320 /// Writes name for \p D to \p OS.
321 /// \returns true on failure, false on success.
322 bool writeName(const Decl *D, raw_ostream &OS);
323
324 /// \returns name for \p D
325 std::string getName(const Decl *D);
326
327 /// \returns all applicable mangled names.
328 /// For example C++ constructors/destructors can have multiple.
329 std::vector<std::string> getAllManglings(const Decl *D);
330
331private:
332 class Implementation;
333 std::unique_ptr<Implementation> Impl;
334};
335
336/// Constants used by LLDB for mangling.
338 static constexpr llvm::StringLiteral FunctionLabelPrefix = "$__lldb_func:";
339};
340} // namespace clang
341
342#endif
Enums/classes describing ABI related information about constructors, destructors and thunks.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
std::string getName(const Decl *D)
Definition Mangle.cpp:740
ASTNameGenerator(ASTContext &Ctx)
Definition Mangle.cpp:731
bool writeName(const Decl *D, raw_ostream &OS)
Writes name for D to OS.
Definition Mangle.cpp:736
std::vector< std::string > getAllManglings(const Decl *D)
Definition Mangle.cpp:744
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4814
Represents a C++ constructor within a class.
Definition DeclCXX.h:2642
Represents a C++ destructor within a class.
Definition DeclCXX.h:2907
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2150
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:241
Represents a function declaration or definition.
Definition Decl.h:2059
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:60
virtual DiscriminatorOverrideTy getDiscriminatorOverride() const =0
virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &)=0
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &)=0
ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)
Definition Mangle.h:209
virtual void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &)=0
virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &)=0
virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &)=0
virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &)=0
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &)=0
static ItaniumMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, const CXXRecordDecl *Type, raw_ostream &)=0
virtual void mangleModuleInitializer(const Module *Module, raw_ostream &)=0
static bool classof(const MangleContext *C)
Definition Mangle.h:236
UnsignedOrNone(*)(ASTContext &, const NamedDecl *) DiscriminatorOverrideTy
Definition Mangle.h:207
A global _GUID constant.
Definition DeclCXX.h:4451
void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:415
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
bool isAux() const
Definition Mangle.h:78
unsigned getBlockId(const BlockDecl *BD, bool Local)
Definition Mangle.h:92
virtual std::string getLambdaString(const CXXRecordDecl *Lambda)=0
virtual bool shouldMangleStringLiteral(const StringLiteral *SL)=0
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:397
ASTContext & getASTContext() const
Definition Mangle.h:86
uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D)
Definition Mangle.h:114
virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &)=0
void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, raw_ostream &Out)
Definition Mangle.cpp:380
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS, bool includePrefixByte=true, bool includeCategoryNamespace=true, bool useDirectABI=false) const
Definition Mangle.cpp:450
virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND)
Definition Mangle.h:141
uint64_t getAnonymousStructId(const NamedDecl *D, const FunctionDecl *FD=nullptr)
Definition Mangle.h:100
bool isTriviallyRecursive(const FunctionDecl *FD)
Return true if FD's body contains a direct call back to the symbol it links as, through an asm label ...
Definition Mangle.cpp:202
bool shouldMangleDeclName(const NamedDecl *D)
Definition Mangle.cpp:129
virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream &) const
Definition Mangle.cpp:365
virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, bool ElideOverrideInfo, raw_ostream &)=0
void mangleName(GlobalDecl GD, raw_ostream &)
Definition Mangle.cpp:249
virtual ~MangleContext()
Definition Mangle.h:84
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &)=0
void mangleNameIgnoringAsmLabel(GlobalDecl GD, raw_ostream &)
Definition Mangle.cpp:292
virtual void mangleCXXName(GlobalDecl GD, raw_ostream &)=0
ManglerKind getKind() const
Definition Mangle.h:76
virtual void needsUniqueInternalLinkageNames()
Definition Mangle.h:145
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
virtual void startNewFunction()
Definition Mangle.h:90
DiagnosticsEngine & getDiags() const
Definition Mangle.h:88
bool shouldMangleDeclNameIgnoringAsmLabel(const NamedDecl *D)
Definition Mangle.cpp:138
virtual bool shouldMangleCXXName(const NamedDecl *D)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0
void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, const BlockDecl *BD, raw_ostream &Out)
Definition Mangle.cpp:406
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &)=0
MangleContext(ASTContext &Context, DiagnosticsEngine &Diags, ManglerKind Kind, bool IsAux=false)
Definition Mangle.h:80
virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0
void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD, raw_ostream &) const
Definition Mangle.cpp:518
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &)=0
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
Mangle vftable symbols.
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, const MethodVFTableLocation &ML, raw_ostream &Out)=0
virtual void mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, bool IsUnaligned, uint32_t NumEntries, raw_ostream &Out)=0
static bool classof(const MangleContext *C)
Definition Mangle.h:307
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
Mangle vbtable symbols.
virtual void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived, raw_ostream &Out)=0
virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD, unsigned GuardNum, raw_ostream &Out)=0
static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)
virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out)=0
virtual void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out)=0
virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out)=0
virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived, raw_ostream &Out)=0
virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out)=0
MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)
Definition Mangle.h:250
Describes a module or submodule.
Definition Module.h:340
This represents a decl that may have a name.
Definition Decl.h:275
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
A (possibly-)qualified type.
Definition TypeBase.h:938
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1823
The base class of the type hierarchy.
Definition TypeBase.h:1879
Represents a variable declaration or definition.
Definition Decl.h:933
Top level wrappers for InstallAPI frontend operations.
CXXCtorType
C++ constructor types.
Definition ABI.h:24
bool isInstanceMethod(const Decl *D)
Definition Attr.h:158
void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName, bool useDirectABI)
Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...
Definition Mangle.cpp:34
@ Result
The result type of a method or function.
Definition TypeBase.h:906
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
Definition ABI.h:34
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t
Constants used by LLDB for mangling.
Definition Mangle.h:337
static constexpr llvm::StringLiteral FunctionLabelPrefix
Definition Mangle.h:338
A this pointer adjustment.
Definition Thunk.h:92
The this pointer adjustment as well as an optional return adjustment for a thunk.
Definition Thunk.h:157