xref: /openbsd-src/gnu/llvm/lldb/include/lldb/Core/Mangled.h (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
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 
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   };
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 
273 private:
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 
280 Stream &operator<<(Stream &s, const Mangled &obj);
281 
282 } // namespace lldb_private
283 
284 #endif // #if defined(__cplusplus)
285 #endif // liblldb_Mangled_h_
286