Skip to content

Commit e2cad86

Browse files
committed
[lldb] Improve RichManglingContext ergonomics (NFC)
Have the different ::Parse.* methods return the demangled string directly instead of having to go through ::GetBufferRef. Differential revision: https://reviews.llvm.org/D118953 (cherry picked from commit fa52788)
1 parent cd2992b commit e2cad86

File tree

5 files changed

+47
-89
lines changed

5 files changed

+47
-89
lines changed

lldb/include/lldb/Core/RichManglingContext.h

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,35 +43,22 @@ class RichManglingContext {
4343
bool IsCtorOrDtor() const;
4444

4545
/// Get the base name of a function. This doesn't include trailing template
46-
/// arguments, ie "a::b<int>" gives "b". The result will overwrite the
47-
/// internal buffer. It can be obtained via GetBufferRef().
48-
void ParseFunctionBaseName();
46+
/// arguments, ie "a::b<int>" gives "b".
47+
llvm::StringRef ParseFunctionBaseName();
4948

5049
/// Get the context name for a function. For "a::b::c", this function returns
51-
/// "a::b". The result will overwrite the internal buffer. It can be obtained
52-
/// via GetBufferRef().
53-
void ParseFunctionDeclContextName();
54-
55-
/// Get the entire demangled name. The result will overwrite the internal
56-
/// buffer. It can be obtained via GetBufferRef().
57-
void ParseFullName();
58-
59-
/// Obtain a StringRef to the internal buffer that holds the result of the
60-
/// most recent ParseXy() operation. The next ParseXy() call invalidates it.
61-
llvm::StringRef GetBufferRef() const {
62-
assert(m_provider != None && "Initialize a provider first");
63-
return m_buffer;
64-
}
50+
/// "a::b".
51+
llvm::StringRef ParseFunctionDeclContextName();
52+
53+
/// Get the entire demangled name.
54+
llvm::StringRef ParseFullName();
6555

6656
private:
6757
enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage };
6858

6959
/// Selects the rich mangling info provider.
7060
InfoProvider m_provider = None;
7161

72-
/// Reference to the buffer used for results of ParseXy() operations.
73-
llvm::StringRef m_buffer;
74-
7562
/// Members for ItaniumPartialDemangler
7663
llvm::ItaniumPartialDemangler m_ipd;
7764
/// Note: m_ipd_buf is a raw pointer due to being resized by realloc via
@@ -93,7 +80,7 @@ class RichManglingContext {
9380
void ResetProvider(InfoProvider new_provider);
9481

9582
/// Uniform handling of string buffers for ItaniumPartialDemangler.
96-
void processIPDStrResult(char *ipd_res, size_t res_len);
83+
llvm::StringRef processIPDStrResult(char *ipd_res, size_t res_len);
9784

9885
/// Cast the given parser to the given type. Ideally we would have a type
9986
/// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we

lldb/source/Core/Mangled.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,7 @@ bool Mangled::DemangleWithRichManglingInfo(
243243
if (context.FromItaniumName(m_mangled)) {
244244
// If we got an info, we have a name. Copy to string pool and connect the
245245
// counterparts to accelerate later access in GetDemangledName().
246-
context.ParseFullName();
247-
m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(),
246+
m_demangled.SetStringWithMangledCounterpart(context.ParseFullName(),
248247
m_mangled);
249248
return true;
250249
} else {

lldb/source/Core/RichManglingContext.cpp

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ bool RichManglingContext::IsCtorOrDtor() const {
8383
llvm_unreachable("Fully covered switch above!");
8484
}
8585

86-
void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
86+
llvm::StringRef RichManglingContext::processIPDStrResult(char *ipd_res,
87+
size_t res_size) {
8788
// Error case: Clear the buffer.
8889
if (LLVM_UNLIKELY(ipd_res == nullptr)) {
8990
assert(res_size == m_ipd_buf_size &&
9091
"Failed IPD queries keep the original size in the N parameter");
9192

9293
m_ipd_buf[0] = '\0';
93-
m_buffer = llvm::StringRef(m_ipd_buf, 0);
94-
return;
94+
return llvm::StringRef(m_ipd_buf, 0);
9595
}
9696

9797
// IPD's res_size includes null terminator.
@@ -109,60 +109,54 @@ void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
109109
}
110110

111111
// 99% case: Just remember the string length.
112-
m_buffer = llvm::StringRef(m_ipd_buf, res_size - 1);
112+
return llvm::StringRef(m_ipd_buf, res_size - 1);
113113
}
114114

115-
void RichManglingContext::ParseFunctionBaseName() {
115+
llvm::StringRef RichManglingContext::ParseFunctionBaseName() {
116116
assert(m_provider != None && "Initialize a provider first");
117117
switch (m_provider) {
118118
case ItaniumPartialDemangler: {
119119
auto n = m_ipd_buf_size;
120120
auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n);
121-
processIPDStrResult(buf, n);
122-
return;
121+
return processIPDStrResult(buf, n);
123122
}
124123
case PluginCxxLanguage:
125-
m_buffer =
126-
get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename();
127-
return;
124+
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
125+
->GetBasename();
128126
case None:
129-
return;
127+
return {};
130128
}
131129
}
132130

133-
void RichManglingContext::ParseFunctionDeclContextName() {
131+
llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() {
134132
assert(m_provider != None && "Initialize a provider first");
135133
switch (m_provider) {
136134
case ItaniumPartialDemangler: {
137135
auto n = m_ipd_buf_size;
138136
auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n);
139-
processIPDStrResult(buf, n);
140-
return;
137+
return processIPDStrResult(buf, n);
141138
}
142139
case PluginCxxLanguage:
143-
m_buffer =
144-
get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetContext();
145-
return;
140+
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
141+
->GetContext();
146142
case None:
147-
return;
143+
return {};
148144
}
149145
}
150146

151-
void RichManglingContext::ParseFullName() {
147+
llvm::StringRef RichManglingContext::ParseFullName() {
152148
assert(m_provider != None && "Initialize a provider first");
153149
switch (m_provider) {
154150
case ItaniumPartialDemangler: {
155151
auto n = m_ipd_buf_size;
156152
auto buf = m_ipd.finishDemangle(m_ipd_buf, &n);
157-
processIPDStrResult(buf, n);
158-
return;
153+
return processIPDStrResult(buf, n);
159154
}
160155
case PluginCxxLanguage:
161-
m_buffer = get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
162-
->GetFullName()
163-
.GetStringRef();
164-
return;
156+
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
157+
->GetFullName()
158+
.GetStringRef();
165159
case None:
166-
return;
160+
return {};
167161
}
168162
}

lldb/source/Symbol/Symtab.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,16 +405,13 @@ void Symtab::RegisterMangledNameEntry(
405405
std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
406406
RichManglingContext &rmc) {
407407
// Only register functions that have a base name.
408-
rmc.ParseFunctionBaseName();
409-
llvm::StringRef base_name = rmc.GetBufferRef();
408+
llvm::StringRef base_name = rmc.ParseFunctionBaseName();
410409
if (base_name.empty())
411410
return;
412411

413412
// The base name will be our entry's name.
414413
NameToIndexMap::Entry entry(ConstString(base_name), value);
415-
416-
rmc.ParseFunctionDeclContextName();
417-
llvm::StringRef decl_context = rmc.GetBufferRef();
414+
llvm::StringRef decl_context = rmc.ParseFunctionDeclContextName();
418415

419416
// Register functions with no context.
420417
if (decl_context.empty()) {

lldb/unittests/Core/RichManglingContextTest.cpp

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,12 @@ using namespace lldb_private;
1818
TEST(RichManglingContextTest, Basic) {
1919
RichManglingContext RMC;
2020
ConstString mangled("_ZN3foo3barEv");
21-
EXPECT_TRUE(RMC.FromItaniumName(mangled));
2221

22+
EXPECT_TRUE(RMC.FromItaniumName(mangled));
2323
EXPECT_FALSE(RMC.IsCtorOrDtor());
24-
25-
RMC.ParseFunctionDeclContextName();
26-
EXPECT_EQ("foo", RMC.GetBufferRef());
27-
28-
RMC.ParseFunctionBaseName();
29-
EXPECT_EQ("bar", RMC.GetBufferRef());
30-
31-
RMC.ParseFullName();
32-
EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
24+
EXPECT_EQ("foo", RMC.ParseFunctionDeclContextName());
25+
EXPECT_EQ("bar", RMC.ParseFunctionBaseName());
26+
EXPECT_EQ("foo::bar()", RMC.ParseFullName());
3327
}
3428

3529
TEST(RichManglingContextTest, FromCxxMethodName) {
@@ -41,19 +35,12 @@ TEST(RichManglingContextTest, FromCxxMethodName) {
4135
ConstString demangled("foo::bar()");
4236
EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(demangled));
4337

44-
EXPECT_TRUE(ItaniumRMC.IsCtorOrDtor() == CxxMethodRMC.IsCtorOrDtor());
45-
46-
ItaniumRMC.ParseFunctionDeclContextName();
47-
CxxMethodRMC.ParseFunctionDeclContextName();
48-
EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef());
49-
50-
ItaniumRMC.ParseFunctionBaseName();
51-
CxxMethodRMC.ParseFunctionBaseName();
52-
EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef());
53-
54-
ItaniumRMC.ParseFullName();
55-
CxxMethodRMC.ParseFullName();
56-
EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef());
38+
EXPECT_EQ(ItaniumRMC.IsCtorOrDtor(), CxxMethodRMC.IsCtorOrDtor());
39+
EXPECT_EQ(ItaniumRMC.ParseFunctionDeclContextName(),
40+
CxxMethodRMC.ParseFunctionDeclContextName());
41+
EXPECT_EQ(ItaniumRMC.ParseFunctionBaseName(),
42+
CxxMethodRMC.ParseFunctionBaseName());
43+
EXPECT_EQ(ItaniumRMC.ParseFullName(), CxxMethodRMC.ParseFullName());
5744

5845
// Construct with a random name.
5946
{
@@ -68,8 +55,7 @@ TEST(RichManglingContextTest, FromCxxMethodName) {
6855
ConstString("void * operator new(unsigned __int64)")));
6956

7057
// We expect its context is empty.
71-
CxxMethodRMC.ParseFunctionDeclContextName();
72-
EXPECT_TRUE(CxxMethodRMC.GetBufferRef().empty());
58+
EXPECT_TRUE(CxxMethodRMC.ParseFunctionDeclContextName().empty());
7359
}
7460
}
7561

@@ -79,16 +65,13 @@ TEST(RichManglingContextTest, SwitchProvider) {
7965
llvm::StringRef demangled = "foo::bar()";
8066

8167
EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled)));
82-
RMC.ParseFullName();
83-
EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
68+
EXPECT_EQ("foo::bar()", RMC.ParseFullName());
8469

8570
EXPECT_TRUE(RMC.FromCxxMethodName(ConstString(demangled)));
86-
RMC.ParseFullName();
87-
EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
71+
EXPECT_EQ("foo::bar()", RMC.ParseFullName());
8872

8973
EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled)));
90-
RMC.ParseFullName();
91-
EXPECT_EQ("foo::bar()", RMC.GetBufferRef());
74+
EXPECT_EQ("foo::bar()", RMC.ParseFullName());
9275
}
9376

9477
TEST(RichManglingContextTest, IPDRealloc) {
@@ -116,13 +99,11 @@ TEST(RichManglingContextTest, IPDRealloc) {
11699

117100
// Demangle the short one.
118101
EXPECT_TRUE(RMC.FromItaniumName(ConstString(ShortMangled)));
119-
RMC.ParseFullName();
120-
const char *ShortDemangled = RMC.GetBufferRef().data();
102+
const char *ShortDemangled = RMC.ParseFullName().data();
121103

122104
// Demangle the long one.
123105
EXPECT_TRUE(RMC.FromItaniumName(ConstString(LongMangled)));
124-
RMC.ParseFullName();
125-
const char *LongDemangled = RMC.GetBufferRef().data();
106+
const char *LongDemangled = RMC.ParseFullName().data();
126107

127108
// Make sure a new buffer was allocated or the default buffer was extended.
128109
bool AllocatedNewBuffer = (ShortDemangled != LongDemangled);

0 commit comments

Comments
 (0)