1 //===-- llvm/IR/Mangler.h - Self-contained name mangler ---------*- 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 // Unified name mangler for various backends.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_IR_MANGLER_H
14 #define LLVM_IR_MANGLER_H
15
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Compiler.h"
19
20 namespace llvm {
21
22 class DataLayout;
23 class GlobalValue;
24 template <typename T> class SmallVectorImpl;
25 class Triple;
26 class Twine;
27 class raw_ostream;
28
29 // TODO: The weird assignment of HybridPatchableTargetSuffix below is a
30 // temporary workaround for a linker failure that is only hit when compiling
31 // llvm for arm64ec on windows. The description and context of the issue is at
32 // https://github.com/llvm/llvm-project/issues/143575.
33 // An upstream MSVC bug is filed at
34 // https://developercommunity.visualstudio.com/t/MSVC-Linker-Issue-When-Cross-
35 // Compiling-L/10920141.
36 constexpr char HybridPatchableTargetSuffixArr[] = "$hp_target";
37 constexpr std::string_view HybridPatchableTargetSuffix =
38 HybridPatchableTargetSuffixArr;
39
40 class Mangler {
41 /// We need to give global values the same name every time they are mangled.
42 /// This keeps track of the number we give to anonymous ones.
43 mutable DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
44
45 public:
46 /// Print the appropriate prefix and the specified global variable's name.
47 /// If the global variable doesn't have a name, this fills in a unique name
48 /// for the global.
49 LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
50 bool CannotUsePrivateLabel) const;
51 LLVM_ABI void getNameWithPrefix(SmallVectorImpl<char> &OutName,
52 const GlobalValue *GV,
53 bool CannotUsePrivateLabel) const;
54
55 /// Print the appropriate prefix and the specified name as the global variable
56 /// name. GVName must not be empty.
57 LLVM_ABI static void getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
58 const DataLayout &DL);
59 LLVM_ABI static void getNameWithPrefix(SmallVectorImpl<char> &OutName,
60 const Twine &GVName,
61 const DataLayout &DL);
62 };
63
64 LLVM_ABI void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS,
65 const GlobalValue *GV,
66 const Triple &TT, Mangler &Mangler);
67
68 LLVM_ABI void emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
69 const Triple &T, Mangler &M);
70
71 /// Returns the ARM64EC mangled function name unless the input is already
72 /// mangled.
73 LLVM_ABI std::optional<std::string>
74 getArm64ECMangledFunctionName(StringRef Name);
75
76 /// Returns the ARM64EC demangled function name, unless the input is not
77 /// mangled.
78 LLVM_ABI std::optional<std::string>
79 getArm64ECDemangledFunctionName(StringRef Name);
80
81 /// Check if an ARM64EC function name is mangled.
isArm64ECMangledFunctionName(StringRef Name)82 bool inline isArm64ECMangledFunctionName(StringRef Name) {
83 return Name[0] == '#' ||
84 (Name[0] == '?' && Name.find("@$$h") != StringRef::npos);
85 }
86
87 } // End llvm namespace
88
89 #endif
90