1 //===-- Mangled.h -----------------------------------------------*- 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 #ifndef LLDB_CORE_MANGLED_H
10 #define LLDB_CORE_MANGLED_H
11 #if defined(__cplusplus)
12 
13 #include "lldb/lldb-enumerations.h"
14 #include "lldb/lldb-forward.h"
15 
16 #include "lldb/Utility/ConstString.h"
17 
18 #include "llvm/ADT/StringRef.h"
19 
20 #include <cstddef>
21 #include <memory>
22 
23 namespace lldb_private {
24 
25 /// \class Mangled Mangled.h "lldb/Core/Mangled.h"
26 /// A class that handles mangled names.
27 ///
28 /// Designed to handle mangled names. The demangled version of any names will
29 /// be computed when the demangled name is accessed through the Demangled()
30 /// acccessor. This class can also tokenize the demangled version of the name
31 /// for powerful searches. Functions and symbols could make instances of this
32 /// class for their mangled names. Uniqued string pools are used for the
33 /// mangled, demangled, and token string values to allow for faster
34 /// comparisons and for efficient memory use.
35 class Mangled {
36 public:
37   enum NamePreference {
38     ePreferMangled,
39     ePreferDemangled,
40     ePreferDemangledWithoutArguments
41   };
42 
43   enum ManglingScheme {
44     eManglingSchemeNone = 0,
45     eManglingSchemeMSVC,
46     eManglingSchemeItanium,
47     eManglingSchemeRustV0
48   };
49 
50   /// Default constructor.
51   ///
52   /// Initialize with both mangled and demangled names empty.
53   Mangled() = default;
54 
55   /// Construct with name.
56   ///
57   /// Constructor with an optional string and auto-detect if \a name is
58   /// mangled or not.
59   ///
60   /// \param[in] name
61   ///     The already const name to copy into this object.
62   explicit Mangled(ConstString name);
63 
64   explicit Mangled(llvm::StringRef name);
65 
66   /// Convert to pointer operator.
67   ///
68   /// This allows code to check a Mangled object to see if it contains a valid
69   /// mangled name using code such as:
70   ///
71   /// \code
72   /// Mangled mangled(...);
73   /// if (mangled)
74   /// { ...
75   /// \endcode
76   ///
77   /// \return
78   ///     A pointer to this object if either the mangled or unmangled
79   ///     name is set, NULL otherwise.
80   operator void *() const;
81 
82   /// Logical NOT operator.
83   ///
84   /// This allows code to check a Mangled object to see if it contains an
85   /// empty mangled name using code such as:
86   ///
87   /// \code
88   /// Mangled mangled(...);
89   /// if (!mangled)
90   /// { ...
91   /// \endcode
92   ///
93   /// \return
94   ///     Returns \b true if the object has an empty mangled and
95   ///     unmangled name, \b false otherwise.
96   bool operator!() const;
97 
98   /// Clear the mangled and demangled values.
99   void Clear();
100 
101   /// Compare the mangled string values
102   ///
103   /// Compares the Mangled::GetName() string in \a lhs and \a rhs.
104   ///
105   /// \param[in] lhs
106   ///     A const reference to the Left Hand Side object to compare.
107   ///
108   /// \param[in] rhs
109   ///     A const reference to the Right Hand Side object to compare.
110   ///
111   /// \return
112   ///     -1 if \a lhs is less than \a rhs
113   ///     0 if \a lhs is equal to \a rhs
114   ///     1 if \a lhs is greater than \a rhs
115   static int Compare(const Mangled &lhs, const Mangled &rhs);
116 
117   /// Dump a description of this object to a Stream \a s.
118   ///
119   /// Dump a Mangled object to stream \a s. We don't force our demangled name
120   /// to be computed currently (we don't use the accessor).
121   ///
122   /// \param[in] s
123   ///     The stream to which to dump the object description.
124   void Dump(Stream *s) const;
125 
126   /// Dump a debug description of this object to a Stream \a s.
127   ///
128   /// \param[in] s
129   ///     The stream to which to dump the object description.
130   void DumpDebug(Stream *s) const;
131 
132   /// Demangled name get accessor.
133   ///
134   /// \return
135   ///     A const reference to the demangled name string object.
136   ConstString GetDemangledName() const;
137 
138   /// Display demangled name get accessor.
139   ///
140   /// \return
141   ///     A const reference to the display demangled name string object.
142   ConstString GetDisplayDemangledName() const;
143 
SetDemangledName(ConstString name)144   void SetDemangledName(ConstString name) { m_demangled = name; }
145 
SetMangledName(ConstString name)146   void SetMangledName(ConstString name) { m_mangled = name; }
147 
148   /// Mangled name get accessor.
149   ///
150   /// \return
151   ///     A reference to the mangled name string object.
GetMangledName()152   ConstString &GetMangledName() { return m_mangled; }
153 
154   /// Mangled name get accessor.
155   ///
156   /// \return
157   ///     A const reference to the mangled name string object.
GetMangledName()158   ConstString GetMangledName() const { return m_mangled; }
159 
160   /// Best name get accessor.
161   ///
162   /// \param[in] preference
163   ///     Which name would you prefer to get?
164   ///
165   /// \return
166   ///     A const reference to the preferred name string object if this
167   ///     object has a valid name of that kind, else a const reference to the
168   ///     other name is returned.
169   ConstString GetName(NamePreference preference = ePreferDemangled) const;
170 
171   /// Check if "name" matches either the mangled or demangled name.
172   ///
173   /// \param[in] name
174   ///     A name to match against both strings.
175   ///
176   /// \return
177   ///     \b True if \a name matches either name, \b false otherwise.
NameMatches(ConstString name)178   bool NameMatches(ConstString name) const {
179     if (m_mangled == name)
180       return true;
181     return GetDemangledName() == name;
182   }
183   bool NameMatches(const RegularExpression &regex) const;
184 
185   /// Get the memory cost of this object.
186   ///
187   /// Return the size in bytes that this object takes in memory. This returns
188   /// the size in bytes of this object, not any shared string values it may
189   /// refer to.
190   ///
191   /// \return
192   ///     The number of bytes that this object occupies in memory.
193   ///
194   /// \see ConstString::StaticMemorySize ()
195   size_t MemorySize() const;
196 
197   /// Set the string value in this object.
198   ///
199   /// If \a is_mangled is \b true, then the mangled named is set to \a name,
200   /// else the demangled name is set to \a name.
201   ///
202   /// \param[in] name
203   ///     The already const version of the name for this object.
204   ///
205   /// \param[in] is_mangled
206   ///     If \b true then \a name is a mangled name, if \b false then
207   ///     \a name is demangled.
208   void SetValue(ConstString name, bool is_mangled);
209 
210   /// Set the string value in this object.
211   ///
212   /// This version auto detects if the string is mangled by inspecting the
213   /// string value and looking for common mangling prefixes.
214   ///
215   /// \param[in] name
216   ///     The already const version of the name for this object.
217   void SetValue(ConstString name);
218 
219   /// Try to guess the language from the mangling.
220   ///
221   /// For a mangled name to have a language it must have both a mangled and a
222   /// demangled name and it can be guessed from the mangling what the language
223   /// is.  Note: this will return C++ for any language that uses Itanium ABI
224   /// mangling.
225   ///
226   /// Standard C function names will return eLanguageTypeUnknown because they
227   /// aren't mangled and it isn't clear what language the name represents
228   /// (there will be no mangled name).
229   ///
230   /// \return
231   ///     The language for the mangled/demangled name, eLanguageTypeUnknown
232   ///     if there is no mangled or demangled counterpart.
233   lldb::LanguageType GuessLanguage() const;
234 
235   /// Function signature for filtering mangled names.
236   using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
237 
238   /// Trigger explicit demangling to obtain rich mangling information. This is
239   /// optimized for batch processing while populating a name index. To get the
240   /// pure demangled name string for a single entity, use GetDemangledName()
241   /// instead.
242   ///
243   /// For names that match the Itanium mangling scheme, this uses LLVM's
244   /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
245   /// parser currently.
246   ///
247   /// This function is thread-safe when used with different \a context
248   /// instances in different threads.
249   ///
250   /// \param[in] context
251   ///     The context for this function. A single instance can be stack-
252   ///     allocated in the caller's frame and used for multiple calls.
253   ///
254   /// \param[in] skip_mangled_name
255   ///     A filtering function for skipping entities based on name and mangling
256   ///     scheme. This can be null if unused.
257   ///
258   /// \return
259   ///     True on success, false otherwise.
260   bool DemangleWithRichManglingInfo(RichManglingContext &context,
261                                     SkipMangledNameFn *skip_mangled_name);
262 
263   /// Try to identify the mangling scheme used.
264   /// \param[in] name
265   ///     The name we are attempting to identify the mangling scheme for.
266   ///
267   /// \return
268   ///     eManglingSchemeNone if no known mangling scheme could be identified
269   ///     for s, otherwise the enumerator for the mangling scheme detected.
270   static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
271 
272 private:
273   /// Mangled member variables.
274   ConstString m_mangled;           ///< The mangled version of the name
275   mutable ConstString m_demangled; ///< Mutable so we can get it on demand with
276                                    ///a const version of this object
277 };
278 
279 Stream &operator<<(Stream &s, const Mangled &obj);
280 
281 } // namespace lldb_private
282 
283 #endif // #if defined(__cplusplus)
284 #endif // LLDB_CORE_MANGLED_H
285