LLDB mainline
DemangledNameInfo.h
Go to the documentation of this file.
1//===-- DemangledNameInfo.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_DEMANGLEDNAMEINFO_H
10#define LLDB_CORE_DEMANGLEDNAMEINFO_H
11
13#include "lldb/Utility/Locked.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/Demangle/ItaniumDemangle.h"
16#include "llvm/Demangle/Utility.h"
17
18#include <cstddef>
19#include <optional>
20#include <random>
21#include <utility>
22#include <vector>
23
24namespace lldb_private {
25
26class Mangled;
27
28/// Stores information about where certain portions of a demangled
29/// function name begin and end.
31 /// A [start, end) pair for the function basename.
32 /// The basename is the name without scope qualifiers
33 /// and without template parameters.
34 ///
35 /// E.g.,
36 /// \code{.cpp}
37 /// void foo::bar<int>::someFunc<float>(int) const &&
38 /// ^ ^
39 /// start end
40 /// \endcode
41 std::pair<uint32_t, uint32_t> BasenameRange;
42
43 /// A [start, end) pair for the function template arguments.
44 ///
45 /// E.g.,
46 /// \code{.cpp}
47 /// void foo::bar<int>::someFunc<float>(int) const &&
48 /// ^ ^
49 /// start end
50 /// \endcode
51 std::pair<uint32_t, uint32_t> TemplateArgumentsRange;
52
53 /// A [start, end) pair for the function scope qualifiers.
54 ///
55 /// E.g.,
56 /// \code{.cpp}
57 /// void foo::bar<int>::qux<float>(int) const &&
58 /// ^ ^
59 /// start end
60 /// \endcode
61 std::pair<uint32_t, uint32_t> ScopeRange;
62
63 /// Indicates the [start, end) of the function argument list.
64 ///
65 /// E.g.,
66 /// \code{.cpp}
67 /// int (*getFunc<float>(float, double))(int, int)
68 /// ^ ^
69 /// start end
70 /// \endcode
71 std::pair<uint32_t, uint32_t> ArgumentsRange;
72
73 /// Indicates the [start, end) of the function qualifiers
74 /// (e.g., CV-qualifiers, reference qualifiers, requires clauses).
75 ///
76 /// E.g.,
77 /// \code{.cpp}
78 /// void foo::bar<int>::qux<float>(int) const &&
79 /// ^ ^
80 /// start end
81 /// \endcode
82 std::pair<uint32_t, uint32_t> QualifiersRange;
83
84 /// Indicates the [start, end) of the function's name qualifiers. This is a
85 /// catch-all range for anything in between the basename and the function's
86 /// arguments or template arguments, that is not tracked by the rest of the
87 /// pairs.
88 ///
89 /// E.g.,
90 /// \code{.swift}
91 /// closure #1 in A.foo<Int>()
92 /// ^ ^
93 /// start end
94 /// \endcode
95 std::pair<uint32_t, uint32_t> NameQualifiersRange;
96
97 /// Indicates the [start, end) of the function's prefix. This is a
98 /// catch-all range for anything that is not tracked by the rest of
99 /// the pairs.
100 std::pair<uint32_t, uint32_t> PrefixRange;
101
102 /// Indicates the [start, end) of the function's suffix. This is a
103 /// catch-all range for anything that is not tracked by the rest of
104 /// the pairs.
105 std::pair<uint32_t, uint32_t> SuffixRange;
106
107 /// Returns \c true if this object holds a valid basename range.
108 bool hasBasename() const {
109 // A function always has a name.
110 return BasenameRange.second > BasenameRange.first;
111 }
112
113 /// Returns \c true if this object holds a valid template arguments range.
114 bool hasTemplateArguments() const {
115 return TemplateArgumentsRange.second >= TemplateArgumentsRange.first;
116 }
117
118 /// Returns \c true if this object holds a valid scope range.
119 bool hasScope() const { return ScopeRange.second >= ScopeRange.first; }
120
121 /// Returns \c true if this object holds a valid arguments range.
122 bool hasArguments() const {
123 return ArgumentsRange.second >= ArgumentsRange.first;
124 }
125
126 /// Returns \c true if this object holds a valid qualifiers range.
127 bool hasQualifiers() const {
128 return QualifiersRange.second >= QualifiersRange.first;
129 }
130
131 /// Returns \c true if this object holds a valid name qualifiers range.
132 bool hasNameQualifiers() const {
133 return NameQualifiersRange.second >= NameQualifiersRange.first;
134 }
135
136 /// Returns \c true if this object holds a valid prefix range.
137 bool hasPrefix() const { return PrefixRange.second >= PrefixRange.first; }
138
139 /// Returns \c true if this object holds a valid suffix range.
140 bool hasSuffix() const { return SuffixRange.second >= SuffixRange.first; }
141};
142
143/// A cache from mangled names to DemangledNameInfo.
145public:
146 /// Calculates the DemangledNameInfo and caches the result.
147 ///
148 /// \return std::nullopt if no info could be computed for \c mangled.
149 std::optional<DemangledNameInfo> Get(const Mangled &mangled);
150
151 void Clear();
152
153 size_t GetMaxEntries() const;
154
155 size_t GetNumEntries() const;
156
157 /// Changes the maximum number of entries. A limit of 0 disables the cache.
158 void SetMaxEntries(size_t max_entries);
159
160private:
161 struct State {
162 /// Drops a random entry from the cache.
163 void EvictRandomEntry();
164
165 /// Maps a ConstString to its DemangledNameInfo.
166 /// Values can be empty if no name info could be computed for a name.
167 llvm::DenseMap<ConstString, std::optional<DemangledNameInfo>> infos;
168
169 /// The mangled names.
170 std::vector<ConstString> mangled_names;
171
172 std::minstd_rand rng;
173
174 size_t max_entries = 0;
175 };
176
178};
179
180/// An OutputBuffer which keeps a record of where certain parts of a
181/// demangled name begin/end (e.g., basename, scope, argument list, etc.).
182/// The tracking occurs during printing of the Itanium demangle tree.
183///
184/// Usage:
185/// \code{.cpp}
186///
187/// Node *N = mangling_parser.parseType();
188///
189/// TrackingOutputBuffer buffer;
190/// N->printLeft(OB);
191///
192/// assert (buffer.NameInfo.hasBasename());
193///
194/// \endcode
196 using OutputBuffer::OutputBuffer;
197
198 /// Holds information about the demangled name that is
199 /// being printed into this buffer.
201
202 void printLeft(const llvm::itanium_demangle::Node &N) override;
203 void printRight(const llvm::itanium_demangle::Node &N) override;
204
205private:
206 void printLeftImpl(const llvm::itanium_demangle::FunctionType &N);
207 void printRightImpl(const llvm::itanium_demangle::FunctionType &N);
208
209 void printLeftImpl(const llvm::itanium_demangle::FunctionEncoding &N);
210 void printRightImpl(const llvm::itanium_demangle::FunctionEncoding &N);
211
212 void printLeftImpl(const llvm::itanium_demangle::NestedName &N);
213 void printLeftImpl(const llvm::itanium_demangle::NameWithTemplateArgs &N);
214
215 /// Called whenever we start printing a function type in the Itanium
216 /// mangling scheme. Examples include \ref FunctionEncoding, \ref
217 /// FunctionType, etc.
218 ///
219 /// \returns A ScopedOverride which will update the nesting depth of
220 /// currently printed function types on destruction.
221 [[nodiscard]] llvm::itanium_demangle::ScopedOverride<unsigned>
223
224 /// Returns \c true if we're not printing any nested function types,
225 /// just a \ref FunctionEncoding in the Itanium mangling scheme.
227
228 /// If this object \ref shouldTrack, then update the end of
229 /// the basename range to the current \c OB position.
230 void updateBasenameEnd();
231
232 /// If this object \ref shouldTrack, then update the beginning
233 /// of the scope range to the current \c OB position.
234 void updateScopeStart();
235
236 /// If this object \ref shouldTrack, then update the end of
237 /// the scope range to the current \c OB position.
238 void updateScopeEnd();
239
240 /// Returns \c true if the members of this object can be
241 /// updated. E.g., when we're printing nested template
242 /// arguments, we don't need to be tracking basename
243 /// locations.
244 bool shouldTrack() const;
245
246 /// Helpers called to track beginning and end of the function
247 /// arguments.
248 void finalizeArgumentEnd();
249 void finalizeStart();
250 void finalizeEnd();
253
254 /// Helper used in the finalize APIs.
255 bool canFinalize() const;
256
257 /// Incremented each time we start printing a function type node
258 /// in the Itanium mangling scheme (e.g., \ref FunctionEncoding
259 /// or \ref FunctionType).
261};
262} // namespace lldb_private
263
264#endif // LLDB_CORE_DEMANGLEDNAMEINFO_H
A cache from mangled names to DemangledNameInfo.
void SetMaxEntries(size_t max_entries)
Changes the maximum number of entries. A limit of 0 disables the cache.
std::optional< DemangledNameInfo > Get(const Mangled &mangled)
Calculates the DemangledNameInfo and caches the result.
Bundles a value of type T with the Mutex that guards it.
Definition Locked.h:178
A class that handles mangled names.
Definition Mangled.h:34
A class that represents a running process on the host machine.
std::vector< ConstString > mangled_names
The mangled names.
llvm::DenseMap< ConstString, std::optional< DemangledNameInfo > > infos
Maps a ConstString to its DemangledNameInfo.
void EvictRandomEntry()
Drops a random entry from the cache.
Stores information about where certain portions of a demangled function name begin and end.
bool hasSuffix() const
Returns true if this object holds a valid suffix range.
bool hasBasename() const
Returns true if this object holds a valid basename range.
std::pair< uint32_t, uint32_t > NameQualifiersRange
Indicates the [start, end) of the function's name qualifiers.
bool hasPrefix() const
Returns true if this object holds a valid prefix range.
std::pair< uint32_t, uint32_t > TemplateArgumentsRange
A [start, end) pair for the function template arguments.
bool hasTemplateArguments() const
Returns true if this object holds a valid template arguments range.
std::pair< uint32_t, uint32_t > PrefixRange
Indicates the [start, end) of the function's prefix.
std::pair< uint32_t, uint32_t > QualifiersRange
Indicates the [start, end) of the function qualifiers (e.g., CV-qualifiers, reference qualifiers,...
std::pair< uint32_t, uint32_t > BasenameRange
A [start, end) pair for the function basename.
std::pair< uint32_t, uint32_t > SuffixRange
Indicates the [start, end) of the function's suffix.
bool hasScope() const
Returns true if this object holds a valid scope range.
bool hasNameQualifiers() const
Returns true if this object holds a valid name qualifiers range.
std::pair< uint32_t, uint32_t > ScopeRange
A [start, end) pair for the function scope qualifiers.
bool hasQualifiers() const
Returns true if this object holds a valid qualifiers range.
std::pair< uint32_t, uint32_t > ArgumentsRange
Indicates the [start, end) of the function argument list.
bool hasArguments() const
Returns true if this object holds a valid arguments range.
An OutputBuffer which keeps a record of where certain parts of a demangled name begin/end (e....
void updateScopeStart()
If this object shouldTrack, then update the beginning of the scope range to the current OB position.
void printLeftImpl(const llvm::itanium_demangle::NameWithTemplateArgs &N)
bool canFinalize() const
Helper used in the finalize APIs.
void printRightImpl(const llvm::itanium_demangle::FunctionType &N)
void printLeftImpl(const llvm::itanium_demangle::FunctionType &N)
bool isPrintingTopLevelFunctionType() const
Returns true if we're not printing any nested function types, just a FunctionEncoding in the Itanium ...
llvm::itanium_demangle::ScopedOverride< unsigned > enterFunctionTypePrinting()
Called whenever we start printing a function type in the Itanium mangling scheme.
void printLeftImpl(const llvm::itanium_demangle::FunctionEncoding &N)
void updateBasenameEnd()
If this object shouldTrack, then update the end of the basename range to the current OB position.
unsigned FunctionPrintingDepth
Incremented each time we start printing a function type node in the Itanium mangling scheme (e....
void printLeft(const llvm::itanium_demangle::Node &N) override
void printRightImpl(const llvm::itanium_demangle::FunctionEncoding &N)
void finalizeArgumentEnd()
Helpers called to track beginning and end of the function arguments.
void updateScopeEnd()
If this object shouldTrack, then update the end of the scope range to the current OB position.
void printLeftImpl(const llvm::itanium_demangle::NestedName &N)
void printRight(const llvm::itanium_demangle::Node &N) override
bool shouldTrack() const
Returns true if the members of this object can be updated.
DemangledNameInfo NameInfo
Holds information about the demangled name that is being printed into this buffer.