Skip to content

Commit 2d5fab8

Browse files
authored
Merge pull request #3902 from apple/demangling
Cherrypick upstream demangling commits
2 parents e6fbc13 + d9a39c7 commit 2d5fab8

File tree

8 files changed

+64
-115
lines changed

8 files changed

+64
-115
lines changed

lldb/include/lldb/Core/Mangled.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,9 @@ class Mangled {
236236
/// Function signature for filtering mangled names.
237237
using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
238238

239-
/// Trigger explicit demangling to obtain rich mangling information. This is
240-
/// optimized for batch processing while populating a name index. To get the
241-
/// pure demangled name string for a single entity, use GetDemangledName()
242-
/// instead.
239+
/// Get rich mangling information. This is optimized for batch processing
240+
/// while populating a name index. To get the pure demangled name string for
241+
/// a single entity, use GetDemangledName() instead.
243242
///
244243
/// For names that match the Itanium mangling scheme, this uses LLVM's
245244
/// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
@@ -258,8 +257,8 @@ class Mangled {
258257
///
259258
/// \return
260259
/// True on success, false otherwise.
261-
bool DemangleWithRichManglingInfo(RichManglingContext &context,
262-
SkipMangledNameFn *skip_mangled_name);
260+
bool GetRichManglingInfo(RichManglingContext &context,
261+
SkipMangledNameFn *skip_mangled_name);
263262

264263
/// Try to identify the mangling scheme used.
265264
/// \param[in] name

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: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ static char *GetRustV0DemangledStr(const char *M) {
221221

222222
// Explicit demangling for scheduled requests during batch processing. This
223223
// makes use of ItaniumPartialDemangler's rich demangle info
224-
bool Mangled::DemangleWithRichManglingInfo(
225-
RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) {
224+
bool Mangled::GetRichManglingInfo(RichManglingContext &context,
225+
SkipMangledNameFn *skip_mangled_name) {
226226
// Others are not meant to arrive here. ObjC names or C's main() for example
227227
// have their names stored in m_demangled, while m_mangled is empty.
228228
assert(m_mangled);
@@ -240,25 +240,16 @@ bool Mangled::DemangleWithRichManglingInfo(
240240
case eManglingSchemeItanium:
241241
// We want the rich mangling info here, so we don't care whether or not
242242
// there is a demangled string in the pool already.
243-
if (context.FromItaniumName(m_mangled)) {
244-
// If we got an info, we have a name. Copy to string pool and connect the
245-
// counterparts to accelerate later access in GetDemangledName().
246-
context.ParseFullName();
247-
m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(),
248-
m_mangled);
249-
return true;
250-
} else {
251-
m_demangled.SetCString("");
252-
return false;
253-
}
243+
return context.FromItaniumName(m_mangled);
254244

255245
case eManglingSchemeMSVC: {
256246
// We have no rich mangling for MSVC-mangled names yet, so first try to
257247
// demangle it if necessary.
258248
if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) {
259249
if (char *d = GetMSVCDemangledStr(m_mangled.GetCString())) {
260-
// If we got an info, we have a name. Copy to string pool and connect
261-
// the counterparts to accelerate later access in GetDemangledName().
250+
// Without the rich mangling info we have to demangle the full name.
251+
// Copy it to string pool and connect the counterparts to accelerate
252+
// later access in GetDemangledName().
262253
m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d),
263254
m_mangled);
264255
::free(d);

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/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ void InstrumentationRuntimeASan::Activate() {
285285
if (!process_sp)
286286
return;
287287

288-
ConstString symbol_name("__asan::AsanDie()");
288+
ConstString symbol_name("_ZN6__asanL7AsanDieEv");
289289
const Symbol *symbol = GetRuntimeModuleSP()->FindFirstSymbolWithNameAndType(
290290
symbol_name, eSymbolTypeCode);
291291

lldb/source/Symbol/Symtab.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,13 @@ void Symtab::InitNameIndexes() {
330330

331331
const SymbolType type = symbol->GetType();
332332
if (type == eSymbolTypeCode || type == eSymbolTypeResolver) {
333-
if (mangled.DemangleWithRichManglingInfo(rmc, lldb_skip_name))
333+
if (mangled.GetRichManglingInfo(rmc, lldb_skip_name)) {
334334
RegisterMangledNameEntry(value, class_contexts, backlog, rmc);
335+
continue;
336+
}
335337
#ifdef LLDB_ENABLE_SWIFT
336-
else if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetStringRef())) {
338+
else if (SwiftLanguageRuntime::IsSwiftMangledName(
339+
name.GetStringRef())) {
337340
lldb_private::ConstString basename;
338341
bool is_method = false;
339342
ConstString mangled_name = mangled.GetMangledName();
@@ -346,6 +349,7 @@ void Symtab::InitNameIndexes() {
346349
else
347350
basename_to_index.Append(basename, value);
348351
}
352+
continue;
349353
}
350354
}
351355
#endif // LLDB_ENABLE_SWIFT
@@ -405,16 +409,13 @@ void Symtab::RegisterMangledNameEntry(
405409
std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
406410
RichManglingContext &rmc) {
407411
// Only register functions that have a base name.
408-
rmc.ParseFunctionBaseName();
409-
llvm::StringRef base_name = rmc.GetBufferRef();
412+
llvm::StringRef base_name = rmc.ParseFunctionBaseName();
410413
if (base_name.empty())
411414
return;
412415

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

419420
// Register functions with no context.
420421
if (decl_context.empty()) {

lldb/test/API/macosx/dyld-trie-symbols/TestDyldTrieSymbols.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ def test_dyld_trie_symbols(self):
4343
self.assertEqual(unstripped_Z3pat_symbols.GetSize(), 1)
4444
unstripped_pat_symbols = unstripped_target.FindSymbols("pat")
4545
self.assertEqual(unstripped_pat_symbols.GetSize(), 1)
46-
unstripped_patint_symbols = unstripped_target.FindSymbols("pat(int)")
47-
self.assertEqual(unstripped_patint_symbols.GetSize(), 1)
4846

4947
unstripped_bar_symbols = unstripped_target.FindSymbols("bar")
5048
self.assertEqual(unstripped_bar_symbols.GetSize(), 1)
@@ -77,8 +75,6 @@ def test_dyld_trie_symbols(self):
7775
self.assertEqual(stripped_Z3pat_symbols.GetSize(), 1)
7876
stripped_pat_symbols = stripped_target.FindSymbols("pat")
7977
self.assertEqual(stripped_pat_symbols.GetSize(), 1)
80-
stripped_patint_symbols = stripped_target.FindSymbols("pat(int)")
81-
self.assertEqual(stripped_patint_symbols.GetSize(), 1)
8278

8379
# bar should have been strippped. We should not find it, or the
8480
# stripping went wrong.

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)