Coverage Report

Created: 2023-09-30 09:22

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