xref: /openbsd-src/gnu/llvm/lldb/include/lldb/Core/Mangled.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===-- Mangled.h -----------------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9dda28197Spatrick #ifndef LLDB_CORE_MANGLED_H
10dda28197Spatrick #define LLDB_CORE_MANGLED_H
11061da546Spatrick #if defined(__cplusplus)
12061da546Spatrick 
13061da546Spatrick #include "lldb/lldb-enumerations.h"
14061da546Spatrick #include "lldb/lldb-forward.h"
15*f6aab3d8Srobert #include "lldb/lldb-types.h"
16061da546Spatrick #include "lldb/Utility/ConstString.h"
17061da546Spatrick #include "llvm/ADT/StringRef.h"
18061da546Spatrick 
19be691f3bSpatrick #include <cstddef>
20061da546Spatrick #include <memory>
21061da546Spatrick 
22061da546Spatrick namespace lldb_private {
23061da546Spatrick 
24061da546Spatrick /// \class Mangled Mangled.h "lldb/Core/Mangled.h"
25061da546Spatrick /// A class that handles mangled names.
26061da546Spatrick ///
27061da546Spatrick /// Designed to handle mangled names. The demangled version of any names will
28061da546Spatrick /// be computed when the demangled name is accessed through the Demangled()
29*f6aab3d8Srobert /// accessor. This class can also tokenize the demangled version of the name
30061da546Spatrick /// for powerful searches. Functions and symbols could make instances of this
31061da546Spatrick /// class for their mangled names. Uniqued string pools are used for the
32061da546Spatrick /// mangled, demangled, and token string values to allow for faster
33061da546Spatrick /// comparisons and for efficient memory use.
34061da546Spatrick class Mangled {
35061da546Spatrick public:
36061da546Spatrick   enum NamePreference {
37061da546Spatrick     ePreferMangled,
38061da546Spatrick     ePreferDemangled,
39061da546Spatrick     ePreferDemangledWithoutArguments
40061da546Spatrick   };
41061da546Spatrick 
42061da546Spatrick   enum ManglingScheme {
43061da546Spatrick     eManglingSchemeNone = 0,
44061da546Spatrick     eManglingSchemeMSVC,
45be691f3bSpatrick     eManglingSchemeItanium,
46*f6aab3d8Srobert     eManglingSchemeRustV0,
47*f6aab3d8Srobert     eManglingSchemeD
48061da546Spatrick   };
49061da546Spatrick 
50061da546Spatrick   /// Default constructor.
51061da546Spatrick   ///
52061da546Spatrick   /// Initialize with both mangled and demangled names empty.
53061da546Spatrick   Mangled() = default;
54061da546Spatrick 
55061da546Spatrick   /// Construct with name.
56061da546Spatrick   ///
57061da546Spatrick   /// Constructor with an optional string and auto-detect if \a name is
58061da546Spatrick   /// mangled or not.
59061da546Spatrick   ///
60061da546Spatrick   /// \param[in] name
61061da546Spatrick   ///     The already const name to copy into this object.
62061da546Spatrick   explicit Mangled(ConstString name);
63061da546Spatrick 
64061da546Spatrick   explicit Mangled(llvm::StringRef name);
65061da546Spatrick 
66*f6aab3d8Srobert   bool operator==(const Mangled &rhs) const {
67*f6aab3d8Srobert     return m_mangled == rhs.m_mangled &&
68*f6aab3d8Srobert            GetDemangledName() == rhs.GetDemangledName();
69*f6aab3d8Srobert   }
70*f6aab3d8Srobert 
71*f6aab3d8Srobert   bool operator!=(const Mangled &rhs) const {
72*f6aab3d8Srobert     return !(*this == rhs);
73*f6aab3d8Srobert   }
74*f6aab3d8Srobert 
75*f6aab3d8Srobert   /// Convert to bool operator.
76061da546Spatrick   ///
77*f6aab3d8Srobert   /// This allows code to check any Mangled objects to see if they contain
78*f6aab3d8Srobert   /// anything valid using code such as:
79061da546Spatrick   ///
80061da546Spatrick   /// \code
81061da546Spatrick   /// Mangled mangled(...);
82061da546Spatrick   /// if (mangled)
83061da546Spatrick   /// { ...
84061da546Spatrick   /// \endcode
85061da546Spatrick   ///
86061da546Spatrick   /// \return
87*f6aab3d8Srobert   ///     Returns \b true if either the mangled or unmangled name is set,
88*f6aab3d8Srobert   ///     \b false if the object has an empty mangled and unmangled name.
89*f6aab3d8Srobert   explicit operator bool() const;
90061da546Spatrick 
91061da546Spatrick   /// Clear the mangled and demangled values.
92061da546Spatrick   void Clear();
93061da546Spatrick 
94061da546Spatrick   /// Compare the mangled string values
95061da546Spatrick   ///
96061da546Spatrick   /// Compares the Mangled::GetName() string in \a lhs and \a rhs.
97061da546Spatrick   ///
98061da546Spatrick   /// \param[in] lhs
99061da546Spatrick   ///     A const reference to the Left Hand Side object to compare.
100061da546Spatrick   ///
101061da546Spatrick   /// \param[in] rhs
102061da546Spatrick   ///     A const reference to the Right Hand Side object to compare.
103061da546Spatrick   ///
104061da546Spatrick   /// \return
105061da546Spatrick   ///     -1 if \a lhs is less than \a rhs
106061da546Spatrick   ///     0 if \a lhs is equal to \a rhs
107061da546Spatrick   ///     1 if \a lhs is greater than \a rhs
108061da546Spatrick   static int Compare(const Mangled &lhs, const Mangled &rhs);
109061da546Spatrick 
110061da546Spatrick   /// Dump a description of this object to a Stream \a s.
111061da546Spatrick   ///
112061da546Spatrick   /// Dump a Mangled object to stream \a s. We don't force our demangled name
113061da546Spatrick   /// to be computed currently (we don't use the accessor).
114061da546Spatrick   ///
115061da546Spatrick   /// \param[in] s
116061da546Spatrick   ///     The stream to which to dump the object description.
117061da546Spatrick   void Dump(Stream *s) const;
118061da546Spatrick 
119061da546Spatrick   /// Dump a debug description of this object to a Stream \a s.
120061da546Spatrick   ///
121061da546Spatrick   /// \param[in] s
122061da546Spatrick   ///     The stream to which to dump the object description.
123061da546Spatrick   void DumpDebug(Stream *s) const;
124061da546Spatrick 
125061da546Spatrick   /// Demangled name get accessor.
126061da546Spatrick   ///
127061da546Spatrick   /// \return
128061da546Spatrick   ///     A const reference to the demangled name string object.
129dda28197Spatrick   ConstString GetDemangledName() const;
130061da546Spatrick 
131061da546Spatrick   /// Display demangled name get accessor.
132061da546Spatrick   ///
133061da546Spatrick   /// \return
134061da546Spatrick   ///     A const reference to the display demangled name string object.
135dda28197Spatrick   ConstString GetDisplayDemangledName() const;
136061da546Spatrick 
SetDemangledName(ConstString name)137061da546Spatrick   void SetDemangledName(ConstString name) { m_demangled = name; }
138061da546Spatrick 
SetMangledName(ConstString name)139061da546Spatrick   void SetMangledName(ConstString name) { m_mangled = name; }
140061da546Spatrick 
141061da546Spatrick   /// Mangled name get accessor.
142061da546Spatrick   ///
143061da546Spatrick   /// \return
144061da546Spatrick   ///     A reference to the mangled name string object.
GetMangledName()145061da546Spatrick   ConstString &GetMangledName() { return m_mangled; }
146061da546Spatrick 
147061da546Spatrick   /// Mangled name get accessor.
148061da546Spatrick   ///
149061da546Spatrick   /// \return
150061da546Spatrick   ///     A const reference to the mangled name string object.
GetMangledName()151061da546Spatrick   ConstString GetMangledName() const { return m_mangled; }
152061da546Spatrick 
153061da546Spatrick   /// Best name get accessor.
154061da546Spatrick   ///
155061da546Spatrick   /// \param[in] preference
156061da546Spatrick   ///     Which name would you prefer to get?
157061da546Spatrick   ///
158061da546Spatrick   /// \return
159061da546Spatrick   ///     A const reference to the preferred name string object if this
160061da546Spatrick   ///     object has a valid name of that kind, else a const reference to the
161061da546Spatrick   ///     other name is returned.
162dda28197Spatrick   ConstString GetName(NamePreference preference = ePreferDemangled) const;
163061da546Spatrick 
164061da546Spatrick   /// Check if "name" matches either the mangled or demangled name.
165061da546Spatrick   ///
166061da546Spatrick   /// \param[in] name
167061da546Spatrick   ///     A name to match against both strings.
168061da546Spatrick   ///
169061da546Spatrick   /// \return
170061da546Spatrick   ///     \b True if \a name matches either name, \b false otherwise.
NameMatches(ConstString name)171dda28197Spatrick   bool NameMatches(ConstString name) const {
172061da546Spatrick     if (m_mangled == name)
173061da546Spatrick       return true;
174dda28197Spatrick     return GetDemangledName() == name;
175061da546Spatrick   }
176dda28197Spatrick   bool NameMatches(const RegularExpression &regex) const;
177061da546Spatrick 
178061da546Spatrick   /// Get the memory cost of this object.
179061da546Spatrick   ///
180061da546Spatrick   /// Return the size in bytes that this object takes in memory. This returns
181061da546Spatrick   /// the size in bytes of this object, not any shared string values it may
182061da546Spatrick   /// refer to.
183061da546Spatrick   ///
184061da546Spatrick   /// \return
185061da546Spatrick   ///     The number of bytes that this object occupies in memory.
186061da546Spatrick   size_t MemorySize() const;
187061da546Spatrick 
188061da546Spatrick   /// Set the string value in this object.
189061da546Spatrick   ///
190061da546Spatrick   /// If \a is_mangled is \b true, then the mangled named is set to \a name,
191061da546Spatrick   /// else the demangled name is set to \a name.
192061da546Spatrick   ///
193061da546Spatrick   /// \param[in] name
194061da546Spatrick   ///     The already const version of the name for this object.
195061da546Spatrick   ///
196061da546Spatrick   /// \param[in] is_mangled
197061da546Spatrick   ///     If \b true then \a name is a mangled name, if \b false then
198061da546Spatrick   ///     \a name is demangled.
199061da546Spatrick   void SetValue(ConstString name, bool is_mangled);
200061da546Spatrick 
201061da546Spatrick   /// Set the string value in this object.
202061da546Spatrick   ///
203061da546Spatrick   /// This version auto detects if the string is mangled by inspecting the
204061da546Spatrick   /// string value and looking for common mangling prefixes.
205061da546Spatrick   ///
206061da546Spatrick   /// \param[in] name
207061da546Spatrick   ///     The already const version of the name for this object.
208061da546Spatrick   void SetValue(ConstString name);
209061da546Spatrick 
210061da546Spatrick   /// Try to guess the language from the mangling.
211061da546Spatrick   ///
212061da546Spatrick   /// For a mangled name to have a language it must have both a mangled and a
213061da546Spatrick   /// demangled name and it can be guessed from the mangling what the language
214061da546Spatrick   /// is.  Note: this will return C++ for any language that uses Itanium ABI
215061da546Spatrick   /// mangling.
216061da546Spatrick   ///
217061da546Spatrick   /// Standard C function names will return eLanguageTypeUnknown because they
218061da546Spatrick   /// aren't mangled and it isn't clear what language the name represents
219061da546Spatrick   /// (there will be no mangled name).
220061da546Spatrick   ///
221061da546Spatrick   /// \return
222061da546Spatrick   ///     The language for the mangled/demangled name, eLanguageTypeUnknown
223061da546Spatrick   ///     if there is no mangled or demangled counterpart.
224061da546Spatrick   lldb::LanguageType GuessLanguage() const;
225061da546Spatrick 
226061da546Spatrick   /// Function signature for filtering mangled names.
227061da546Spatrick   using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
228061da546Spatrick 
229*f6aab3d8Srobert   /// Get rich mangling information. This is optimized for batch processing
230*f6aab3d8Srobert   /// while populating a name index. To get the pure demangled name string for
231*f6aab3d8Srobert   /// a single entity, use GetDemangledName() instead.
232061da546Spatrick   ///
233061da546Spatrick   /// For names that match the Itanium mangling scheme, this uses LLVM's
234061da546Spatrick   /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
235061da546Spatrick   /// parser currently.
236061da546Spatrick   ///
237061da546Spatrick   /// This function is thread-safe when used with different \a context
238061da546Spatrick   /// instances in different threads.
239061da546Spatrick   ///
240061da546Spatrick   /// \param[in] context
241061da546Spatrick   ///     The context for this function. A single instance can be stack-
242061da546Spatrick   ///     allocated in the caller's frame and used for multiple calls.
243061da546Spatrick   ///
244061da546Spatrick   /// \param[in] skip_mangled_name
245061da546Spatrick   ///     A filtering function for skipping entities based on name and mangling
246061da546Spatrick   ///     scheme. This can be null if unused.
247061da546Spatrick   ///
248061da546Spatrick   /// \return
249061da546Spatrick   ///     True on success, false otherwise.
250*f6aab3d8Srobert   bool GetRichManglingInfo(RichManglingContext &context,
251061da546Spatrick                            SkipMangledNameFn *skip_mangled_name);
252061da546Spatrick 
253061da546Spatrick   /// Try to identify the mangling scheme used.
254061da546Spatrick   /// \param[in] name
255061da546Spatrick   ///     The name we are attempting to identify the mangling scheme for.
256061da546Spatrick   ///
257061da546Spatrick   /// \return
258061da546Spatrick   ///     eManglingSchemeNone if no known mangling scheme could be identified
259061da546Spatrick   ///     for s, otherwise the enumerator for the mangling scheme detected.
260061da546Spatrick   static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
261061da546Spatrick 
262*f6aab3d8Srobert   /// Decode a serialized version of this object from data.
263*f6aab3d8Srobert   ///
264*f6aab3d8Srobert   /// \param data
265*f6aab3d8Srobert   ///   The decoder object that references the serialized data.
266*f6aab3d8Srobert   ///
267*f6aab3d8Srobert   /// \param offset_ptr
268*f6aab3d8Srobert   ///   A pointer that contains the offset from which the data will be decoded
269*f6aab3d8Srobert   ///   from that gets updated as data gets decoded.
270*f6aab3d8Srobert   ///
271*f6aab3d8Srobert   /// \param strtab
272*f6aab3d8Srobert   ///   All strings in cache files are put into string tables for efficiency
273*f6aab3d8Srobert   ///   and cache file size reduction. Strings are stored as uint32_t string
274*f6aab3d8Srobert   ///   table offsets in the cache data.
275*f6aab3d8Srobert   bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
276*f6aab3d8Srobert               const StringTableReader &strtab);
277*f6aab3d8Srobert 
278*f6aab3d8Srobert   /// Encode this object into a data encoder object.
279*f6aab3d8Srobert   ///
280*f6aab3d8Srobert   /// This allows this object to be serialized to disk.
281*f6aab3d8Srobert   ///
282*f6aab3d8Srobert   /// \param encoder
283*f6aab3d8Srobert   ///   A data encoder object that serialized bytes will be encoded into.
284*f6aab3d8Srobert   ///
285*f6aab3d8Srobert   /// \param strtab
286*f6aab3d8Srobert   ///   All strings in cache files are put into string tables for efficiency
287*f6aab3d8Srobert   ///   and cache file size reduction. Strings are stored as uint32_t string
288*f6aab3d8Srobert   ///   table offsets in the cache data.
289*f6aab3d8Srobert   void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
290*f6aab3d8Srobert 
291061da546Spatrick private:
292061da546Spatrick   /// Mangled member variables.
293061da546Spatrick   ConstString m_mangled;           ///< The mangled version of the name
294061da546Spatrick   mutable ConstString m_demangled; ///< Mutable so we can get it on demand with
295061da546Spatrick                                    ///a const version of this object
296061da546Spatrick };
297061da546Spatrick 
298061da546Spatrick Stream &operator<<(Stream &s, const Mangled &obj);
299061da546Spatrick 
300061da546Spatrick } // namespace lldb_private
301061da546Spatrick 
302061da546Spatrick #endif // #if defined(__cplusplus)
303dda28197Spatrick #endif // LLDB_CORE_MANGLED_H
304