xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/Mangler.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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