Mangled.h revision 360784
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 liblldb_Mangled_h_
10#define liblldb_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(lldb::LanguageType language) 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(lldb::LanguageType language) 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(lldb::LanguageType language,
169                      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.
178  bool NameMatches(ConstString name, lldb::LanguageType language) const {
179    if (m_mangled == name)
180      return true;
181    return GetDemangledName(language) == name;
182  }
183  bool NameMatches(const RegularExpression &regex,
184                   lldb::LanguageType language) const;
185
186  /// Get the memory cost of this object.
187  ///
188  /// Return the size in bytes that this object takes in memory. This returns
189  /// the size in bytes of this object, not any shared string values it may
190  /// refer to.
191  ///
192  /// \return
193  ///     The number of bytes that this object occupies in memory.
194  ///
195  /// \see ConstString::StaticMemorySize ()
196  size_t MemorySize() const;
197
198  /// Set the string value in this object.
199  ///
200  /// If \a is_mangled is \b true, then the mangled named is set to \a name,
201  /// else the demangled name is set to \a name.
202  ///
203  /// \param[in] name
204  ///     The already const version of the name for this object.
205  ///
206  /// \param[in] is_mangled
207  ///     If \b true then \a name is a mangled name, if \b false then
208  ///     \a name is demangled.
209  void SetValue(ConstString name, bool is_mangled);
210
211  /// Set the string value in this object.
212  ///
213  /// This version auto detects if the string is mangled by inspecting the
214  /// string value and looking for common mangling prefixes.
215  ///
216  /// \param[in] name
217  ///     The already const version of the name for this object.
218  void SetValue(ConstString name);
219
220  /// Try to guess the language from the mangling.
221  ///
222  /// For a mangled name to have a language it must have both a mangled and a
223  /// demangled name and it can be guessed from the mangling what the language
224  /// is.  Note: this will return C++ for any language that uses Itanium ABI
225  /// mangling.
226  ///
227  /// Standard C function names will return eLanguageTypeUnknown because they
228  /// aren't mangled and it isn't clear what language the name represents
229  /// (there will be no mangled name).
230  ///
231  /// \return
232  ///     The language for the mangled/demangled name, eLanguageTypeUnknown
233  ///     if there is no mangled or demangled counterpart.
234  lldb::LanguageType GuessLanguage() const;
235
236  /// Function signature for filtering mangled names.
237  using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
238
239  /// Trigger explicit demangling to obtain rich mangling information. This is
240  /// optimized for batch processing while populating a name index. To get the
241  /// pure demangled name string for a single entity, use GetDemangledName()
242  /// instead.
243  ///
244  /// For names that match the Itanium mangling scheme, this uses LLVM's
245  /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
246  /// parser currently.
247  ///
248  /// This function is thread-safe when used with different \a context
249  /// instances in different threads.
250  ///
251  /// \param[in] context
252  ///     The context for this function. A single instance can be stack-
253  ///     allocated in the caller's frame and used for multiple calls.
254  ///
255  /// \param[in] skip_mangled_name
256  ///     A filtering function for skipping entities based on name and mangling
257  ///     scheme. This can be null if unused.
258  ///
259  /// \return
260  ///     True on success, false otherwise.
261  bool DemangleWithRichManglingInfo(RichManglingContext &context,
262                                    SkipMangledNameFn *skip_mangled_name);
263
264  /// Try to identify the mangling scheme used.
265  /// \param[in] name
266  ///     The name we are attempting to identify the mangling scheme for.
267  ///
268  /// \return
269  ///     eManglingSchemeNone if no known mangling scheme could be identified
270  ///     for s, otherwise the enumerator for the mangling scheme detected.
271  static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
272
273private:
274  /// Mangled member variables.
275  ConstString m_mangled;           ///< The mangled version of the name
276  mutable ConstString m_demangled; ///< Mutable so we can get it on demand with
277                                   ///a const version of this object
278};
279
280Stream &operator<<(Stream &s, const Mangled &obj);
281
282} // namespace lldb_private
283
284#endif // #if defined(__cplusplus)
285#endif // liblldb_Mangled_h_
286