Coverage Report

Created: 2022-01-18 06:27

/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
#if defined(__cplusplus)
12
13
#include "lldb/lldb-enumerations.h"
14
#include "lldb/lldb-forward.h"
15
#include "lldb/lldb-types.h"
16
#include "lldb/Utility/ConstString.h"
17
#include "llvm/ADT/StringRef.h"
18
19
#include <cstddef>
20
#include <memory>
21
22
namespace lldb_private {
23
24
/// \class Mangled Mangled.h "lldb/Core/Mangled.h"
25
/// A class that handles mangled names.
26
///
27
/// Designed to handle mangled names. The demangled version of any names will
28
/// be computed when the demangled name is accessed through the Demangled()
29
/// acccessor. This class can also tokenize the demangled version of the name
30
/// for powerful searches. Functions and symbols could make instances of this
31
/// class for their mangled names. Uniqued string pools are used for the
32
/// mangled, demangled, and token string values to allow for faster
33
/// comparisons and for efficient memory use.
34
class Mangled {
35
public:
36
  enum NamePreference {
37
    ePreferMangled,
38
    ePreferDemangled,
39
    ePreferDemangledWithoutArguments
40
  };
41
42
  enum ManglingScheme {
43
    eManglingSchemeNone = 0,
44
    eManglingSchemeMSVC,
45
    eManglingSchemeItanium,
46
    eManglingSchemeRustV0,
47
    eManglingSchemeD
48
  };
49
50
  /// Default constructor.
51
  ///
52
  /// Initialize with both mangled and demangled names empty.
53
200M
  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
38
  bool operator==(const Mangled &rhs) const {
67
38
    return m_mangled == rhs.m_mangled &&
68
38
           GetDemangledName() == rhs.GetDemangledName();
69
38
  }
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
17.0M
  void SetDemangledName(ConstString name) { m_demangled = name; }
138
139
3.50M
  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
145M
  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.85M
  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
103k
  bool NameMatches(ConstString name) const {
172
103k
    if (m_mangled == name)
173
0
      return true;
174
103k
    return GetDemangledName() == name;
175
103k
  }
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
  ///
187
  /// \see ConstString::StaticMemorySize ()
188
  size_t MemorySize() const;
189
190
  /// Set the string value in this object.
191
  ///
192
  /// If \a is_mangled is \b true, then the mangled named is set to \a name,
193
  /// else the demangled name is set to \a name.
194
  ///
195
  /// \param[in] name
196
  ///     The already const version of the name for this object.
197
  ///
198
  /// \param[in] is_mangled
199
  ///     If \b true then \a name is a mangled name, if \b false then
200
  ///     \a name is demangled.
201
  void SetValue(ConstString name, bool is_mangled);
202
203
  /// Set the string value in this object.
204
  ///
205
  /// This version auto detects if the string is mangled by inspecting the
206
  /// string value and looking for common mangling prefixes.
207
  ///
208
  /// \param[in] name
209
  ///     The already const version of the name for this object.
210
  void SetValue(ConstString name);
211
212
  /// Try to guess the language from the mangling.
213
  ///
214
  /// For a mangled name to have a language it must have both a mangled and a
215
  /// demangled name and it can be guessed from the mangling what the language
216
  /// is.  Note: this will return C++ for any language that uses Itanium ABI
217
  /// mangling.
218
  ///
219
  /// Standard C function names will return eLanguageTypeUnknown because they
220
  /// aren't mangled and it isn't clear what language the name represents
221
  /// (there will be no mangled name).
222
  ///
223
  /// \return
224
  ///     The language for the mangled/demangled name, eLanguageTypeUnknown
225
  ///     if there is no mangled or demangled counterpart.
226
  lldb::LanguageType GuessLanguage() const;
227
228
  /// Function signature for filtering mangled names.
229
  using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
230
231
  /// Trigger explicit demangling to obtain rich mangling information. This is
232
  /// optimized for batch processing while populating a name index. To get the
233
  /// pure demangled name string for a single entity, use GetDemangledName()
234
  /// instead.
235
  ///
236
  /// For names that match the Itanium mangling scheme, this uses LLVM's
237
  /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
238
  /// parser currently.
239
  ///
240
  /// This function is thread-safe when used with different \a context
241
  /// instances in different threads.
242
  ///
243
  /// \param[in] context
244
  ///     The context for this function. A single instance can be stack-
245
  ///     allocated in the caller's frame and used for multiple calls.
246
  ///
247
  /// \param[in] skip_mangled_name
248
  ///     A filtering function for skipping entities based on name and mangling
249
  ///     scheme. This can be null if unused.
250
  ///
251
  /// \return
252
  ///     True on success, false otherwise.
253
  bool DemangleWithRichManglingInfo(RichManglingContext &context,
254
                                    SkipMangledNameFn *skip_mangled_name);
255
256
  /// Try to identify the mangling scheme used.
257
  /// \param[in] name
258
  ///     The name we are attempting to identify the mangling scheme for.
259
  ///
260
  /// \return
261
  ///     eManglingSchemeNone if no known mangling scheme could be identified
262
  ///     for s, otherwise the enumerator for the mangling scheme detected.
263
  static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
264
265
  /// Decode a serialized version of this object from data.
266
  ///
267
  /// \param data
268
  ///   The decoder object that references the serialized data.
269
  ///
270
  /// \param offset_ptr
271
  ///   A pointer that contains the offset from which the data will be decoded
272
  ///   from that gets updated as data gets decoded.
273
  ///
274
  /// \param strtab
275
  ///   All strings in cache files are put into string tables for efficiency
276
  ///   and cache file size reduction. Strings are stored as uint32_t string
277
  ///   table offsets in the cache data.
278
  bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
279
              const StringTableReader &strtab);
280
281
  /// Encode this object into a data encoder object.
282
  ///
283
  /// This allows this object to be serialized to disk.
284
  ///
285
  /// \param encoder
286
  ///   A data encoder object that serialized bytes will be encoded into.
287
  ///
288
  /// \param strtab
289
  ///   All strings in cache files are put into string tables for efficiency
290
  ///   and cache file size reduction. Strings are stored as uint32_t string
291
  ///   table offsets in the cache data.
292
  void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
293
294
private:
295
  /// Mangled member variables.
296
  ConstString m_mangled;           ///< The mangled version of the name
297
  mutable ConstString m_demangled; ///< Mutable so we can get it on demand with
298
                                   ///a const version of this object
299
};
300
301
Stream &operator<<(Stream &s, const Mangled &obj);
302
303
} // namespace lldb_private
304
305
#endif // #if defined(__cplusplus)
306
#endif // LLDB_CORE_MANGLED_H