Skip to content

Commit 981cf4c

Browse files
committed
[lldb][Mangled] Retrieve and cache demangled name info
1 parent cde3baf commit 981cf4c

File tree

6 files changed

+59
-5
lines changed

6 files changed

+59
-5
lines changed

lldb/include/lldb/Core/Mangled.h

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

12+
#include "lldb/Core/Demangle.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"
18+
#include "llvm/Demangle/Utility.h"
1719

1820
#include <cstddef>
1921
#include <memory>
@@ -275,6 +277,8 @@ class Mangled {
275277
/// table offsets in the cache data.
276278
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
277279

280+
const std::optional<FunctionNameInfo> &GetDemangledInfo() const;
281+
278282
private:
279283
/// If \c force is \c false, this function will re-use the previously
280284
/// demangled name (if any). If \c force is \c true (or the mangled name
@@ -288,6 +292,11 @@ class Mangled {
288292
///< Mutable so we can get it on demand with
289293
///< a const version of this object.
290294
mutable ConstString m_demangled;
295+
296+
/// If available, holds details information about where
297+
/// in \c m_demangled parts of the name begin end (e.g.,
298+
/// basename, arguments, etc.).
299+
mutable std::optional<FunctionNameInfo> m_demangled_info = std::nullopt;
291300
};
292301

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

lldb/include/lldb/Symbol/Function.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "lldb/Core/AddressRange.h"
1313
#include "lldb/Core/Declaration.h"
14+
#include "lldb/Core/Demangle.h"
1415
#include "lldb/Core/Mangled.h"
1516
#include "lldb/Expression/DWARFExpressionList.h"
1617
#include "lldb/Symbol/Block.h"
@@ -534,6 +535,8 @@ class Function : public UserID, public SymbolContextScope {
534535

535536
ConstString GetDisplayName() const;
536537

538+
const std::optional<FunctionNameInfo> &GetDemangledInfo() const;
539+
537540
const Mangled &GetMangled() const { return m_mangled; }
538541

539542
/// Get the DeclContext for this function, if available.

lldb/source/Core/Mangled.cpp

Lines changed: 26 additions & 4 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/Demangle.h"
1213
#include "lldb/Core/RichManglingContext.h"
1314
#include "lldb/Target/Language.h"
1415
#include "lldb/Utility/ConstString.h"
@@ -22,6 +23,7 @@
2223
#include "llvm/ADT/StringExtras.h"
2324
#include "llvm/ADT/StringRef.h"
2425
#include "llvm/Demangle/Demangle.h"
26+
#include "llvm/Demangle/Utility.h"
2527
#include "llvm/Support/Compiler.h"
2628

2729
#include <mutex>
@@ -152,16 +154,21 @@ static char *GetMSVCDemangledStr(llvm::StringRef M) {
152154
return demangled_cstr;
153155
}
154156

155-
static char *GetItaniumDemangledStr(const char *M) {
157+
static std::pair<char *, FunctionNameInfo>
158+
GetItaniumDemangledStr(const char *M) {
156159
char *demangled_cstr = nullptr;
157160

161+
FunctionNameInfo info;
158162
llvm::ItaniumPartialDemangler ipd;
159163
bool err = ipd.partialDemangle(M);
160164
if (!err) {
161165
// Default buffer and size (will realloc in case it's too small).
162166
size_t demangled_size = 80;
163167
demangled_cstr = static_cast<char *>(std::malloc(demangled_size));
164-
demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size);
168+
169+
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
170+
demangled_cstr = ipd.finishDemangle(&OB, &demangled_size);
171+
info = std::move(OB.FunctionInfo);
165172

166173
assert(demangled_cstr &&
167174
"finishDemangle must always succeed if partialDemangle did");
@@ -174,9 +181,14 @@ static char *GetItaniumDemangledStr(const char *M) {
174181
LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr);
175182
else
176183
LLDB_LOGF(log, "demangled itanium: %s -> error: failed to demangle", M);
184+
185+
if (!info.hasBasename())
186+
LLDB_LOGF(log,
187+
"demangled itanium: %s -> error: failed to retrieve name info",
188+
M);
177189
}
178190

179-
return demangled_cstr;
191+
return {demangled_cstr, std::move(info)};
180192
}
181193

182194
static char *GetRustV0DemangledStr(llvm::StringRef M) {
@@ -269,6 +281,13 @@ ConstString Mangled::GetDemangledName() const {
269281
return GetDemangledNameImpl(/*force=*/false);
270282
}
271283

284+
std::optional<FunctionNameInfo> const &Mangled::GetDemangledInfo() const {
285+
if (!m_demangled_info)
286+
GetDemangledNameImpl(/*force=*/true);
287+
288+
return m_demangled_info;
289+
}
290+
272291
// Generate the demangled name on demand using this accessor. Code in this
273292
// class will need to use this accessor if it wishes to decode the demangled
274293
// name. The result is cached and will be kept until a new string value is
@@ -293,7 +312,10 @@ ConstString Mangled::GetDemangledNameImpl(bool force) const {
293312
demangled_name = GetMSVCDemangledStr(m_mangled);
294313
break;
295314
case eManglingSchemeItanium: {
296-
demangled_name = GetItaniumDemangledStr(m_mangled.GetCString());
315+
std::pair<char *, FunctionNameInfo> demangled =
316+
GetItaniumDemangledStr(m_mangled.GetCString());
317+
demangled_name = demangled.first;
318+
m_demangled_info = std::move(demangled.second);
297319
break;
298320
}
299321
case eManglingSchemeRustV0:

lldb/source/Symbol/Function.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,3 +729,7 @@ ConstString Function::GetName() const {
729729
ConstString Function::GetNameNoArguments() const {
730730
return m_mangled.GetName(Mangled::ePreferDemangledWithoutArguments);
731731
}
732+
733+
const std::optional<FunctionNameInfo> &Function::GetDemangledInfo() const {
734+
return m_mangled.GetDemangledInfo();
735+
}

llvm/include/llvm/Demangle/Demangle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct ItaniumPartialDemangler {
9292
/// Just print the entire mangled name into Buf. Buf and N behave like the
9393
/// second and third parameters to __cxa_demangle.
9494
char *finishDemangle(char *Buf, size_t *N) const;
95+
char *finishDemangle(void *OB, size_t *N) const;
9596

9697
/// Get the base name of a function. This doesn't include trailing template
9798
/// arguments, ie for "a::b<int>" this function returns "b".

llvm/lib/Demangle/ItaniumDemangle.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,14 @@ static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
421421
return OB.getBuffer();
422422
}
423423

424+
static char *printNode(const Node *RootNode, OutputBuffer &OB, size_t *N) {
425+
RootNode->print(OB);
426+
OB += '\0';
427+
if (N != nullptr)
428+
*N = OB.getCurrentPosition();
429+
return OB.getBuffer();
430+
}
431+
424432
char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
425433
if (!isFunction())
426434
return nullptr;
@@ -540,6 +548,13 @@ char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
540548
return printNode(static_cast<Node *>(RootNode), Buf, N);
541549
}
542550

551+
char *ItaniumPartialDemangler::finishDemangle(void *OB, size_t *N) const {
552+
assert(RootNode != nullptr && "must call partialDemangle()");
553+
assert(OB != nullptr && "valid OutputBuffer argument required");
554+
return printNode(static_cast<Node *>(RootNode),
555+
*static_cast<OutputBuffer *>(OB), N);
556+
}
557+
543558
bool ItaniumPartialDemangler::hasFunctionQualifiers() const {
544559
assert(RootNode != nullptr && "must call partialDemangle()");
545560
if (!isFunction())

0 commit comments

Comments
 (0)