LLVM 20.0.0git
Mangler.cpp
Go to the documentation of this file.
1//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
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// Unified name mangler for assembly backends.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/IR/Mangler.h"
16#include "llvm/ADT/Twine.h"
18#include "llvm/IR/DataLayout.h"
20#include "llvm/IR/Function.h"
21#include "llvm/IR/Module.h"
24
25using namespace llvm;
26
27namespace {
28enum ManglerPrefixTy {
29 Default, ///< Emit default string before each symbol.
30 Private, ///< Emit "private" prefix before each symbol.
31 LinkerPrivate ///< Emit "linker private" prefix before each symbol.
32};
33}
34
35static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
36 ManglerPrefixTy PrefixTy,
37 const DataLayout &DL, char Prefix) {
38 SmallString<256> TmpData;
39 StringRef Name = GVName.toStringRef(TmpData);
40 assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
41
42 // No need to do anything special if the global has the special "do not
43 // mangle" flag in the name.
44 if (Name[0] == '\1') {
45 OS << Name.substr(1);
46 return;
47 }
48
49 if (DL.doNotMangleLeadingQuestionMark() && Name[0] == '?')
50 Prefix = '\0';
51
52 if (PrefixTy == Private)
53 OS << DL.getPrivateGlobalPrefix();
54 else if (PrefixTy == LinkerPrivate)
55 OS << DL.getLinkerPrivateGlobalPrefix();
56
57 if (Prefix != '\0')
58 OS << Prefix;
59
60 // If this is a simple string that doesn't need escaping, just append it.
61 OS << Name;
62}
63
64static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
65 const DataLayout &DL,
66 ManglerPrefixTy PrefixTy) {
67 char Prefix = DL.getGlobalPrefix();
68 return getNameWithPrefixImpl(OS, GVName, PrefixTy, DL, Prefix);
69}
70
72 const DataLayout &DL) {
73 return getNameWithPrefixImpl(OS, GVName, DL, Default);
74}
75
77 const Twine &GVName, const DataLayout &DL) {
78 raw_svector_ostream OS(OutName);
79 char Prefix = DL.getGlobalPrefix();
80 return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix);
81}
82
84 switch (CC) {
88 return true;
89 default:
90 return false;
91 }
92}
93
94/// Microsoft fastcall and stdcall functions require a suffix on their name
95/// indicating the number of words of arguments they take.
97 const DataLayout &DL) {
98 // Calculate arguments size total.
99 unsigned ArgWords = 0;
100
101 const unsigned PtrSize = DL.getPointerSize();
102
103 for (const Argument &A : F->args()) {
104 // For the purposes of the byte count suffix, structs returned by pointer
105 // do not count as function arguments.
106 if (A.hasStructRetAttr())
107 continue;
108
109 // 'Dereference' type in case of byval or inalloca parameter attribute.
110 uint64_t AllocSize = A.hasPassPointeeByValueCopyAttr() ?
111 A.getPassPointeeByValueCopySize(DL) :
112 DL.getTypeAllocSize(A.getType());
113
114 // Size should be aligned to pointer size.
115 ArgWords += alignTo(AllocSize, PtrSize);
116 }
117
118 OS << '@' << ArgWords;
119}
120
122 bool CannotUsePrivateLabel) const {
123 ManglerPrefixTy PrefixTy = Default;
124 assert(GV != nullptr && "Invalid Global Value");
125 if (GV->hasPrivateLinkage()) {
126 if (CannotUsePrivateLabel)
127 PrefixTy = LinkerPrivate;
128 else
129 PrefixTy = Private;
130 }
131
132 const DataLayout &DL = GV->getDataLayout();
133 if (!GV->hasName()) {
134 // Get the ID for the global, assigning a new one if we haven't got one
135 // already.
136 unsigned &ID = AnonGlobalIDs[GV];
137 if (ID == 0)
138 ID = AnonGlobalIDs.size();
139
140 // Must mangle the global into a unique ID.
141 getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy);
142 return;
143 }
144
145 StringRef Name = GV->getName();
146 char Prefix = DL.getGlobalPrefix();
147
148 // Mangle functions with Microsoft calling conventions specially. Only do
149 // this mangling for x86_64 vectorcall and 32-bit x86.
150 const Function *MSFunc = dyn_cast_or_null<Function>(GV->getAliaseeObject());
151
152 // Don't add byte count suffixes when '\01' or '?' are in the first
153 // character.
154 if (Name.starts_with("\01") ||
155 (DL.doNotMangleLeadingQuestionMark() && Name.starts_with("?")))
156 MSFunc = nullptr;
157
159 MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
160 if (!DL.hasMicrosoftFastStdCallMangling() &&
162 MSFunc = nullptr;
163 if (MSFunc) {
165 Prefix = '@'; // fastcall functions have an @ prefix instead of _.
167 Prefix = '\0'; // vectorcall functions have no prefix.
168 }
169
170 getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix);
171
172 if (!MSFunc)
173 return;
174
175 // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
176 // or vectorcall, add it. These functions have a suffix of @N where N is the
177 // cumulative byte size of all of the parameters to the function in decimal.
179 OS << '@'; // vectorcall functions use a double @ suffix.
180 FunctionType *FT = MSFunc->getFunctionType();
181 if (hasByteCountSuffix(CC) &&
182 // "Pure" variadic functions do not receive @0 suffix.
183 (!FT->isVarArg() || FT->getNumParams() == 0 ||
184 (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
185 addByteCountSuffix(OS, MSFunc, DL);
186}
187
189 const GlobalValue *GV,
190 bool CannotUsePrivateLabel) const {
191 raw_svector_ostream OS(OutName);
192 getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
193}
194
195// Check if the name needs quotes to be safe for the linker to interpret.
196static bool canBeUnquotedInDirective(char C) {
197 return isAlnum(C) || C == '_' || C == '@' || C == '#';
198}
199
201 if (Name.empty())
202 return false;
203
204 // If any of the characters in the string is an unacceptable character, force
205 // quotes.
206 for (char C : Name) {
208 return false;
209 }
210
211 return true;
212}
213
215 const Triple &TT, Mangler &Mangler) {
216 if (GV->hasDLLExportStorageClass() && !GV->isDeclaration()) {
217
218 if (TT.isWindowsMSVCEnvironment())
219 OS << " /EXPORT:";
220 else
221 OS << " -export:";
222
223 bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
224 if (NeedQuotes)
225 OS << "\"";
226 if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
227 std::string Flag;
228 raw_string_ostream FlagOS(Flag);
229 Mangler.getNameWithPrefix(FlagOS, GV, false);
230 FlagOS.flush();
231 if (Flag[0] == GV->getDataLayout().getGlobalPrefix())
232 OS << Flag.substr(1);
233 else
234 OS << Flag;
235 } else {
236 Mangler.getNameWithPrefix(OS, GV, false);
237 }
238 if (TT.isWindowsArm64EC()) {
239 // Use EXPORTAS for mangled ARM64EC symbols.
240 // FIXME: During LTO, we're invoked prior to the EC lowering pass,
241 // so symbols are not yet mangled. Emitting the unmangled name
242 // typically functions correctly; the linker can resolve the export
243 // with the demangled alias.
244 if (std::optional<std::string> demangledName =
246 OS << ",EXPORTAS," << *demangledName;
247 }
248 if (NeedQuotes)
249 OS << "\"";
250
251 if (!GV->getValueType()->isFunctionTy()) {
252 if (TT.isWindowsMSVCEnvironment())
253 OS << ",DATA";
254 else
255 OS << ",data";
256 }
257 }
258 if (GV->hasHiddenVisibility() && !GV->isDeclaration() && TT.isOSCygMing()) {
259
260 OS << " -exclude-symbols:";
261
262 bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
263 if (NeedQuotes)
264 OS << "\"";
265
266 std::string Flag;
267 raw_string_ostream FlagOS(Flag);
268 Mangler.getNameWithPrefix(FlagOS, GV, false);
269 FlagOS.flush();
270 if (Flag[0] == GV->getDataLayout().getGlobalPrefix())
271 OS << Flag.substr(1);
272 else
273 OS << Flag;
274
275 if (NeedQuotes)
276 OS << "\"";
277 }
278}
279
281 const Triple &T, Mangler &M) {
282 if (!T.isWindowsMSVCEnvironment())
283 return;
284
285 OS << " /INCLUDE:";
286 bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
287 if (NeedQuotes)
288 OS << "\"";
289 M.getNameWithPrefix(OS, GV, false);
290 if (NeedQuotes)
291 OS << "\"";
292}
293
295 if (Name[0] != '?') {
296 // For non-C++ symbols, prefix the name with "#" unless it's already
297 // mangled.
298 if (Name[0] == '#')
299 return std::nullopt;
300 return std::optional<std::string>(("#" + Name).str());
301 }
302
303 // If the name contains $$h, then it is already mangled.
304 if (Name.contains("$$h"))
305 return std::nullopt;
306
307 // Ask the demangler where we should insert "$$h".
309 if (!InsertIdx)
310 return std::nullopt;
311
312 return std::optional<std::string>(
313 (Name.substr(0, *InsertIdx) + "$$h" + Name.substr(*InsertIdx)).str());
314}
315
316std::optional<std::string>
318 // For non-C++ names, drop the "#" prefix.
319 if (Name[0] == '#')
320 return std::optional<std::string>(Name.substr(1));
321 if (Name[0] != '?')
322 return std::nullopt;
323
324 // Drop the ARM64EC "$$h" tag.
325 std::pair<StringRef, StringRef> Pair = Name.split("$$h");
326 if (Pair.second.empty())
327 return std::nullopt;
328 return std::optional<std::string>((Pair.first + Pair.second).str());
329}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
@ Default
Definition: DwarfDebug.cpp:87
std::string Name
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
static bool canBeUnquotedInDirective(char C)
Definition: Mangler.cpp:196
static void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName, ManglerPrefixTy PrefixTy, const DataLayout &DL, char Prefix)
Definition: Mangler.cpp:35
static void addByteCountSuffix(raw_ostream &OS, const Function *F, const DataLayout &DL)
Microsoft fastcall and stdcall functions require a suffix on their name indicating the number of word...
Definition: Mangler.cpp:96
static bool hasByteCountSuffix(CallingConv::ID CC)
Definition: Mangler.cpp:83
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file contains some functions that are useful when dealing with strings.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
char getGlobalPrefix() const
Definition: DataLayout.h:269
Class to represent function types.
Definition: DerivedTypes.h:105
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:144
bool isVarArg() const
Definition: DerivedTypes.h:125
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:216
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:277
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:688
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:296
bool hasPrivateLinkage() const
Definition: GlobalValue.h:527
bool hasHiddenVisibility() const
Definition: GlobalValue.h:250
bool hasDLLExportStorageClass() const
Definition: GlobalValue.h:281
const GlobalObject * getAliaseeObject() const
Definition: Globals.cpp:400
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition: Globals.cpp:130
Type * getValueType() const
Definition: GlobalValue.h:296
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition: Mangler.cpp:121
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
Definition: Twine.h:492
bool isFunctionTy() const
True if this is an instance of FunctionType.
Definition: Type.h:255
bool hasName() const
Definition: Value.h:261
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
@ X86_StdCall
stdcall is mostly used by the Win32 API.
Definition: CallingConv.h:99
@ X86_VectorCall
MSVC calling convention that passes vectors and vector aggregates in SSE registers.
Definition: CallingConv.h:163
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ X86_FastCall
'fast' analog of X86_StdCall.
Definition: CallingConv.h:103
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::optional< std::string > getArm64ECMangledFunctionName(StringRef Name)
Returns the ARM64EC mangled function name unless the input is already mangled.
Definition: Mangler.cpp:294
std::optional< std::string > getArm64ECDemangledFunctionName(StringRef Name)
Returns the ARM64EC demangled function name, unless the input is not mangled.
Definition: Mangler.cpp:317
std::optional< size_t > getArm64ECInsertionPointInMangledName(std::string_view MangledName)
void emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV, const Triple &T, Mangler &M)
Definition: Mangler.cpp:280
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV, const Triple &TT, Mangler &Mangler)
Definition: Mangler.cpp:214
@ Default
The result values are uniform if and only if all operands are uniform.