Skip to content

Commit 842c4ff

Browse files
committed
[lldb][Mangled] Retrieve and cache demangled name info
1 parent 02bc0b4 commit 842c4ff

File tree

6 files changed

+59
-5
lines changed

6 files changed

+59
-5
lines changed

lldb/include/lldb/Core/Mangled.h

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

12+
#include "lldb/Utility/ConstString.h"
1213
#include "lldb/lldb-enumerations.h"
1314
#include "lldb/lldb-forward.h"
1415
#include "lldb/lldb-types.h"
15-
#include "lldb/Utility/ConstString.h"
1616
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/Demangle/Utility.h"
1718

1819
#include <cstddef>
1920
#include <memory>
@@ -275,6 +276,10 @@ class Mangled {
275276
/// table offsets in the cache data.
276277
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
277278

279+
using DemangledInfo = llvm::itanium_demangle::OutputBuffer::FunctionNameInfo;
280+
281+
const DemangledInfo &GetDemangledInfo() const;
282+
278283
private:
279284
///< If \c force is \c false, this function will re-use the previously
280285
///< demangled name (if any). If \c force is \c true (or the mangled name
@@ -288,6 +293,9 @@ class Mangled {
288293
///< Mutable so we can get it on demand with
289294
///< a const version of this object.
290295
mutable ConstString m_demangled;
296+
297+
// TODO: should this be an optional?
298+
mutable DemangledInfo m_demangled_info;
291299
};
292300

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

lldb/include/lldb/Symbol/Function.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,8 @@ class Function : public UserID, public SymbolContextScope {
534534

535535
ConstString GetDisplayName() const;
536536

537+
Mangled::DemangledInfo GetDemangledInfo() const;
538+
537539
const Mangled &GetMangled() const { return m_mangled; }
538540

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

lldb/source/Core/Mangled.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/ADT/StringExtras.h"
2323
#include "llvm/ADT/StringRef.h"
2424
#include "llvm/Demangle/Demangle.h"
25+
#include "llvm/Demangle/Utility.h"
2526
#include "llvm/Support/Compiler.h"
2627

2728
#include <mutex>
@@ -152,16 +153,21 @@ static char *GetMSVCDemangledStr(llvm::StringRef M) {
152153
return demangled_cstr;
153154
}
154155

155-
static char *GetItaniumDemangledStr(const char *M) {
156+
static std::pair<char *, Mangled::DemangledInfo>
157+
GetItaniumDemangledStr(const char *M) {
156158
char *demangled_cstr = nullptr;
157159

160+
Mangled::DemangledInfo info;
158161
llvm::ItaniumPartialDemangler ipd;
159162
bool err = ipd.partialDemangle(M);
160163
if (!err) {
161164
// Default buffer and size (will realloc in case it's too small).
162165
size_t demangled_size = 80;
163166
demangled_cstr = static_cast<char *>(std::malloc(demangled_size));
164-
demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size);
167+
168+
llvm::itanium_demangle::OutputBuffer OB(demangled_cstr, demangled_size);
169+
demangled_cstr = ipd.finishDemangle(&OB, &demangled_size);
170+
info = std::move(OB.FunctionInfo);
165171

166172
assert(demangled_cstr &&
167173
"finishDemangle must always succeed if partialDemangle did");
@@ -174,9 +180,14 @@ static char *GetItaniumDemangledStr(const char *M) {
174180
LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr);
175181
else
176182
LLDB_LOGF(log, "demangled itanium: %s -> error: failed to demangle", M);
183+
184+
if (!info.hasBasename())
185+
LLDB_LOGF(log,
186+
"demangled itanium: %s -> error: failed to retrieve name info",
187+
M);
177188
}
178189

179-
return demangled_cstr;
190+
return {demangled_cstr, std::move(info)};
180191
}
181192

182193
static char *GetRustV0DemangledStr(llvm::StringRef M) {
@@ -269,6 +280,16 @@ ConstString Mangled::GetDemangledName() const {
269280
return GetDemangledNameImpl(/*force=*/false);
270281
}
271282

283+
const Mangled::DemangledInfo &Mangled::GetDemangledInfo() const {
284+
// TODO: if setting m_demangled_info previously failed
285+
// we still end up re-demangling. If m_demangled_info
286+
// was an optional we could prevent that.
287+
if (!m_demangled_info.hasBasename())
288+
GetDemangledNameImpl(/*force=*/true);
289+
290+
return m_demangled_info;
291+
}
292+
272293
// Generate the demangled name on demand using this accessor. Code in this
273294
// class will need to use this accessor if it wishes to decode the demangled
274295
// name. The result is cached and will be kept until a new string value is
@@ -293,7 +314,10 @@ ConstString Mangled::GetDemangledNameImpl(bool force) const {
293314
demangled_name = GetMSVCDemangledStr(m_mangled);
294315
break;
295316
case eManglingSchemeItanium: {
296-
demangled_name = GetItaniumDemangledStr(m_mangled.GetCString());
317+
std::pair<char *, Mangled::DemangledInfo> demangled =
318+
GetItaniumDemangledStr(m_mangled.GetCString());
319+
demangled_name = demangled.first;
320+
m_demangled_info = std::move(demangled.second);
297321
break;
298322
}
299323
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+
Mangled::DemangledInfo 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)