Skip to content

Commit 268253b

Browse files
committed
[lldb][Mangled] Retrieve and cache demangled name info (llvm#131836)
Uses the `TrackingOutputBuffer` to populate the new member `Mangled::m_demangled_info`. `m_demangled_info` is lazily popluated by `GetDemangledInfo`. To ensure `m_demangled` and `m_demangled_info` are in-sync we clear `m_demangled_info` anytime `m_demangled` is set/cleared. llvm#131836 (cherry picked from commit a267225)
1 parent 8e5e1b2 commit 268253b

File tree

7 files changed

+243
-44
lines changed

7 files changed

+243
-44
lines changed

lldb/include/lldb/Core/DemangledNameInfo.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,20 @@ struct DemangledNameInfo {
4848
/// \endcode
4949
std::pair<size_t, size_t> ArgumentsRange;
5050

51+
/// Indicates the [start, end) of the function qualifiers
52+
/// (e.g., CV-qualifiers, reference qualifiers, requires clauses).
53+
///
54+
/// E.g.,
55+
/// \code{.cpp}
56+
/// void foo::bar<int>::qux<float>(int) const &&
57+
/// ^ ^
58+
/// start end
59+
/// \endcode
60+
std::pair<size_t, size_t> QualifiersRange;
61+
5162
/// Returns \c true if this object holds a valid basename range.
5263
bool hasBasename() const {
53-
return BasenameRange.first != BasenameRange.second &&
64+
return BasenameRange.second > BasenameRange.first &&
5465
BasenameRange.second > 0;
5566
}
5667

@@ -139,6 +150,8 @@ struct TrackingOutputBuffer : public llvm::itanium_demangle::OutputBuffer {
139150
void finalizeArgumentEnd();
140151
void finalizeStart();
141152
void finalizeEnd();
153+
void finalizeQualifiersStart();
154+
void finalizeQualifiersEnd();
142155

143156
/// Helper used in the finalize APIs.
144157
bool canFinalize() const;

lldb/include/lldb/Core/Mangled.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
#ifndef LLDB_CORE_MANGLED_H
1010
#define LLDB_CORE_MANGLED_H
1111

12+
#include "lldb/Core/DemangledNameInfo.h"
13+
#include "lldb/Utility/ConstString.h"
1214
#include "lldb/lldb-enumerations.h"
1315
#include "lldb/lldb-forward.h"
1416
#include "lldb/lldb-types.h"
15-
#include "lldb/Utility/ConstString.h"
1617
#include "llvm/ADT/StringRef.h"
1718

1819
#include <cstddef>
@@ -134,9 +135,15 @@ class Mangled {
134135
/// A const reference to the display demangled name string object.
135136
ConstString GetDisplayDemangledName(const SymbolContext *sc = nullptr) const;
136137

137-
void SetDemangledName(ConstString name) { m_demangled = name; }
138+
void SetDemangledName(ConstString name) {
139+
m_demangled = name;
140+
m_demangled_info.reset();
141+
}
138142

139-
void SetMangledName(ConstString name) { m_mangled = name; }
143+
void SetMangledName(ConstString name) {
144+
m_mangled = name;
145+
m_demangled_info.reset();
146+
}
140147

141148
/// Mangled name get accessor.
142149
///
@@ -276,6 +283,9 @@ class Mangled {
276283
/// table offsets in the cache data.
277284
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
278285

286+
/// Retrieve \c DemangledNameInfo of the demangled name held by this object.
287+
const std::optional<DemangledNameInfo> &GetDemangledInfo() const;
288+
279289
private:
280290
/// If \c force is \c false, this function will re-use the previously
281291
/// demangled name (if any). If \c force is \c true (or the mangled name
@@ -290,6 +300,10 @@ class Mangled {
290300
/// Mutable so we can get it on demand with
291301
/// a const version of this object.
292302
mutable ConstString m_demangled;
303+
304+
/// If available, holds information about where in \c m_demangled certain
305+
/// parts of the name (e.g., basename, arguments, etc.) begin and end.
306+
mutable std::optional<DemangledNameInfo> m_demangled_info = std::nullopt;
293307
};
294308

295309
Stream &operator<<(Stream &s, const Mangled &obj);

lldb/source/Core/DemangledNameInfo.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ void TrackingOutputBuffer::finalizeArgumentEnd() {
6666
NameInfo.ArgumentsRange.second = getCurrentPosition();
6767
}
6868

69+
void TrackingOutputBuffer::finalizeQualifiersStart() {
70+
if (!canFinalize())
71+
return;
72+
73+
NameInfo.QualifiersRange.first = getCurrentPosition();
74+
}
75+
76+
void TrackingOutputBuffer::finalizeQualifiersEnd() {
77+
if (!canFinalize())
78+
return;
79+
80+
NameInfo.QualifiersRange.second = getCurrentPosition();
81+
}
82+
6983
void TrackingOutputBuffer::finalizeStart() {
7084
if (!shouldTrack())
7185
return;
@@ -171,6 +185,8 @@ void TrackingOutputBuffer::printRightImpl(const FunctionEncoding &N) {
171185
if (Ret)
172186
printRight(*Ret);
173187

188+
finalizeQualifiersStart();
189+
174190
auto CVQuals = N.getCVQuals();
175191
auto RefQual = N.getRefQual();
176192
auto *Attrs = N.getAttrs();
@@ -193,6 +209,7 @@ void TrackingOutputBuffer::printRightImpl(const FunctionEncoding &N) {
193209
Requires->print(*this);
194210
}
195211

212+
finalizeQualifiersEnd();
196213
finalizeEnd();
197214
}
198215

lldb/source/Core/Mangled.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "lldb/Core/Mangled.h"
1010

1111
#include "lldb/Core/DataFileCache.h"
12+
#include "lldb/Core/DemangledNameInfo.h"
1213
#include "lldb/Core/RichManglingContext.h"
1314
#include "lldb/Target/Language.h"
1415
#include "lldb/Utility/ConstString.h"
@@ -120,6 +121,7 @@ Mangled::operator bool() const { return m_mangled || m_demangled; }
120121
void Mangled::Clear() {
121122
m_mangled.Clear();
122123
m_demangled.Clear();
124+
m_demangled_info.reset();
123125
}
124126

125127
// Compare the string values.
@@ -133,13 +135,16 @@ void Mangled::SetValue(ConstString name) {
133135
if (cstring_is_mangled(name.GetStringRef())) {
134136
m_demangled.Clear();
135137
m_mangled = name;
138+
m_demangled_info.reset();
136139
} else {
137140
m_demangled = name;
138141
m_mangled.Clear();
142+
m_demangled_info.reset();
139143
}
140144
} else {
141145
m_demangled.Clear();
142146
m_mangled.Clear();
147+
m_demangled_info.reset();
143148
}
144149
}
145150

@@ -161,20 +166,26 @@ static char *GetMSVCDemangledStr(llvm::StringRef M) {
161166
return demangled_cstr;
162167
}
163168

164-
static char *GetItaniumDemangledStr(const char *M) {
169+
static std::pair<char *, DemangledNameInfo>
170+
GetItaniumDemangledStr(const char *M) {
165171
char *demangled_cstr = nullptr;
166172

173+
DemangledNameInfo info;
167174
llvm::ItaniumPartialDemangler ipd;
168175
bool err = ipd.partialDemangle(M);
169176
if (!err) {
170-
// Default buffer and size (will realloc in case it's too small).
177+
// Default buffer and size (OutputBuffer will realloc in case it's too
178+
// small).
171179
size_t demangled_size = 80;
172-
demangled_cstr = static_cast<char *>(std::malloc(demangled_size));
173-
demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size);
180+
demangled_cstr = static_cast<char *>(std::malloc(80));
181+
182+
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
183+
demangled_cstr = ipd.finishDemangle(&OB);
184+
info = std::move(OB.NameInfo);
174185

175186
assert(demangled_cstr &&
176187
"finishDemangle must always succeed if partialDemangle did");
177-
assert(demangled_cstr[demangled_size - 1] == '\0' &&
188+
assert(demangled_cstr[OB.getCurrentPosition() - 1] == '\0' &&
178189
"Expected demangled_size to return length including trailing null");
179190
}
180191

@@ -183,9 +194,14 @@ static char *GetItaniumDemangledStr(const char *M) {
183194
LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr);
184195
else
185196
LLDB_LOGF(log, "demangled itanium: %s -> error: failed to demangle", M);
197+
198+
if (!info.hasBasename())
199+
LLDB_LOGF(log,
200+
"demangled itanium: %s -> error: failed to retrieve name info",
201+
M);
186202
}
187203

188-
return demangled_cstr;
204+
return {demangled_cstr, std::move(info)};
189205
}
190206

191207
static char *GetRustV0DemangledStr(llvm::StringRef M) {
@@ -281,6 +297,13 @@ ConstString Mangled::GetDemangledName( // BEGIN SWIFT
281297
return GetDemangledNameImpl(/*force=*/false, sc);
282298
}
283299

300+
std::optional<DemangledNameInfo> const &Mangled::GetDemangledInfo() const {
301+
if (!m_demangled_info)
302+
GetDemangledNameImpl(/*force=*/true);
303+
304+
return m_demangled_info;
305+
}
306+
284307
// Generate the demangled name on demand using this accessor. Code in this
285308
// class will need to use this accessor if it wishes to decode the demangled
286309
// name. The result is cached and will be kept until a new string value is
@@ -308,7 +331,10 @@ ConstString Mangled::GetDemangledNameImpl(bool force, // BEGIN SWIFT
308331
demangled_name = GetMSVCDemangledStr(m_mangled);
309332
break;
310333
case eManglingSchemeItanium: {
311-
demangled_name = GetItaniumDemangledStr(m_mangled.GetCString());
334+
std::pair<char *, DemangledNameInfo> demangled =
335+
GetItaniumDemangledStr(m_mangled.GetCString());
336+
demangled_name = demangled.first;
337+
m_demangled_info.emplace(std::move(demangled.second));
312338
break;
313339
}
314340
case eManglingSchemeRustV0:
@@ -506,6 +532,7 @@ bool Mangled::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
506532
const StringTableReader &strtab) {
507533
m_mangled.Clear();
508534
m_demangled.Clear();
535+
m_demangled_info.reset();
509536
MangledEncoding encoding = (MangledEncoding)data.GetU8(offset_ptr);
510537
switch (encoding) {
511538
case Empty:

0 commit comments

Comments
 (0)