Skip to content

Commit fa52788

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
1 parent 9d1857f commit fa52788

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
@@ -217,8 +217,7 @@ bool Mangled::DemangleWithRichManglingInfo(
217217
if (context.FromItaniumName(m_mangled)) {
218218
// If we got an info, we have a name. Copy to string pool and connect the
219219
// counterparts to accelerate later access in GetDemangledName().
220-
context.ParseFullName();
221-
m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(),
220+
m_demangled.SetStringWithMangledCounterpart(context.ParseFullName(),
222221
m_mangled);
223222
return true;
224223
} else {

lldb/source/Core/RichManglingContext.cpp

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

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

8990
m_ipd_buf[0] = '\0';
90-
m_buffer = llvm::StringRef(m_ipd_buf, 0);
91-
return;
91+
return llvm::StringRef(m_ipd_buf, 0);
9292
}
9393

9494
// IPD's res_size includes null terminator.
@@ -106,60 +106,54 @@ void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
106106
}
107107

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

112-
void RichManglingContext::ParseFunctionBaseName() {
112+
llvm::StringRef RichManglingContext::ParseFunctionBaseName() {
113113
assert(m_provider != None && "Initialize a provider first");
114114
switch (m_provider) {
115115
case ItaniumPartialDemangler: {
116116
auto n = m_ipd_buf_size;
117117
auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n);
118-
processIPDStrResult(buf, n);
119-
return;
118+
return processIPDStrResult(buf, n);
120119
}
121120
case PluginCxxLanguage:
122-
m_buffer =
123-
get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename();
124-
return;
121+
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
122+
->GetBasename();
125123
case None:
126-
return;
124+
return {};
127125
}
128126
}
129127

130-
void RichManglingContext::ParseFunctionDeclContextName() {
128+
llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() {
131129
assert(m_provider != None && "Initialize a provider first");
132130
switch (m_provider) {
133131
case ItaniumPartialDemangler: {
134132
auto n = m_ipd_buf_size;
135133
auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n);
136-
processIPDStrResult(buf, n);
137-
return;
134+
return processIPDStrResult(buf, n);
138135
}
139136
case PluginCxxLanguage:
140-
m_buffer =
141-
get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetContext();
142-
return;
137+
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
138+
->GetContext();
143139
case None:
144-
return;
140+
return {};
145141
}
146142
}
147143

148-
void RichManglingContext::ParseFullName() {
144+
llvm::StringRef RichManglingContext::ParseFullName() {
149145
assert(m_provider != None && "Initialize a provider first");
150146
switch (m_provider) {
151147
case ItaniumPartialDemangler: {
152148
auto n = m_ipd_buf_size;
153149
auto buf = m_ipd.finishDemangle(m_ipd_buf, &n);
154-
processIPDStrResult(buf, n);
155-
return;
150+
return processIPDStrResult(buf, n);
156151
}
157152
case PluginCxxLanguage:
158-
m_buffer = get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
159-
->GetFullName()
160-
.GetStringRef();
161-
return;
153+
return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
154+
->GetFullName()
155+
.GetStringRef();
162156
case None:
163-
return;
157+
return {};
164158
}
165159
}

lldb/source/Symbol/Symtab.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,16 +383,13 @@ void Symtab::RegisterMangledNameEntry(
383383
std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
384384
RichManglingContext &rmc) {
385385
// Only register functions that have a base name.
386-
rmc.ParseFunctionBaseName();
387-
llvm::StringRef base_name = rmc.GetBufferRef();
386+
llvm::StringRef base_name = rmc.ParseFunctionBaseName();
388387
if (base_name.empty())
389388
return;
390389

391390
// The base name will be our entry's name.
392391
NameToIndexMap::Entry entry(ConstString(base_name), value);
393-
394-
rmc.ParseFunctionDeclContextName();
395-
llvm::StringRef decl_context = rmc.GetBufferRef();
392+
llvm::StringRef decl_context = rmc.ParseFunctionDeclContextName();
396393

397394
// Register functions with no context.
398395
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)