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