Skip to content

Commit 88f358a

Browse files
🍒 [LLDB] Refactor demangler range tracking (#10767)
* [Demangling] Refactor Demangler range tracking (llvm#140762) This PR is a subset of the commits made in #10710. The most notable change is the addition of `PrefixRange` and `SuffixRange` which are a catch-all to track anything after or before a function's demangled name. In the case of Swift, this allows to add support for name highlighting without having to track the range of the scope and specifiers of a function (this will come in another PR). * add explicit default initialization to DemangledNameInfo to remove warning (llvm#141790) llvm#140762 introduces some compilation warnings in `lldb/unittests/Core/MangledTest.cpp`. This patch adds explicit default initialization to `DemangledNameInfo` to suppress those warnings. We only had the default initialization values to `PrefixRange` and `SuffixRange` because they are the only _optional_ fields of the structure.
1 parent 7e5f224 commit 88f358a

File tree

8 files changed

+93
-20
lines changed

8 files changed

+93
-20
lines changed

lldb/docs/use/formatting.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ A complete list of currently supported format string variables is listed below:
9191
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
9292
| ``function.basename`` | The basename of the current function depending on the frame's language. E.g., for C++ the basename for ``void ns::foo<float>::bar<int>(int) const`` is ``bar``. |
9393
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
94-
| ``function.scope`` | The scope qualifiers of the current function depending on the frame's language. E.g., for C++ the scope for ``void ns::foo<float>::bar<int>(int) const`` is ``ns::foo<float>``. |
94+
| ``function.prefix`` | Any prefix added to the demangled function name of the current function. This depends on the frame's language. E.g., for C++ the prefix will always be empty. |
95+
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
96+
| ``function.scope`` | The scope qualifiers of the current function depending on the frame's language. E.g., for C++ the scope for ``void ns::foo<float>::bar<int>(int) const`` is ``ns::foo<float>``. |
9597
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
9698
| ``function.template-arguments`` | The template arguments of the current function depending on the frame's language. E.g., for C++ the template arguments for ``void ns::foo<float>::bar<int>(int) const`` are ``<float>``. |
9799
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -325,6 +327,7 @@ _____________________
325327
The function names displayed in backtraces/``frame info``/``thread info`` are the demangled names of functions. On some platforms (like ones using Itanium the mangling scheme), LLDB supports decomposing these names into fine-grained components. These are currently:
326328

327329
- ``${function.return-left}``
330+
- ``${function.prefix}``
328331
- ``${function.scope}``
329332
- ``${function.basename}``
330333
- ``${function.template-arguments}``

lldb/include/lldb/Core/DemangledNameInfo.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct DemangledNameInfo {
3939
/// \endcode
4040
std::pair<size_t, size_t> ScopeRange;
4141

42-
/// Indicates the [start, end) of the function argument lits.
42+
/// Indicates the [start, end) of the function argument list.
4343
/// E.g.,
4444
/// \code{.cpp}
4545
/// int (*getFunc<float>(float, double))(int, int)
@@ -59,6 +59,16 @@ struct DemangledNameInfo {
5959
/// \endcode
6060
std::pair<size_t, size_t> QualifiersRange;
6161

62+
/// Indicates the [start, end) of the function's prefix. This is a
63+
/// catch-all range for anything that is not tracked by the rest of
64+
/// the pairs.
65+
std::pair<size_t, size_t> PrefixRange;
66+
67+
/// Indicates the [start, end) of the function's suffix. This is a
68+
/// catch-all range for anything that is not tracked by the rest of
69+
/// the pairs.
70+
std::pair<size_t, size_t> SuffixRange;
71+
6272
/// Returns \c true if this object holds a valid basename range.
6373
bool hasBasename() const {
6474
return BasenameRange.second > BasenameRange.first;

lldb/include/lldb/Core/FormatEntity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct Entry {
8888
FunctionNameWithArgs,
8989
FunctionNameNoArgs,
9090
FunctionMangledName,
91+
FunctionPrefix,
9192
FunctionScope,
9293
FunctionBasename,
9394
FunctionTemplateArguments,

lldb/source/Core/FormatEntity.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ constexpr Definition g_function_child_entries[] = {
124124
Definition("initial-function", EntryType::FunctionInitial),
125125
Definition("changed", EntryType::FunctionChanged),
126126
Definition("is-optimized", EntryType::FunctionIsOptimized),
127+
Definition("prefix", EntryType::FunctionPrefix),
127128
Definition("scope", EntryType::FunctionScope),
128129
Definition("basename", EntryType::FunctionBasename),
129130
Definition("template-arguments", EntryType::FunctionTemplateArguments),
@@ -385,6 +386,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
385386
ENUM_TO_CSTR(FunctionNameWithArgs);
386387
ENUM_TO_CSTR(FunctionNameNoArgs);
387388
ENUM_TO_CSTR(FunctionMangledName);
389+
ENUM_TO_CSTR(FunctionPrefix);
388390
ENUM_TO_CSTR(FunctionScope);
389391
ENUM_TO_CSTR(FunctionBasename);
390392
ENUM_TO_CSTR(FunctionTemplateArguments);
@@ -1843,6 +1845,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
18431845
return true;
18441846
}
18451847

1848+
case Entry::Type::FunctionPrefix:
18461849
case Entry::Type::FunctionScope:
18471850
case Entry::Type::FunctionBasename:
18481851
case Entry::Type::FunctionTemplateArguments:

lldb/source/Core/Mangled.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ GetItaniumDemangledStr(const char *M) {
181181

182182
TrackingOutputBuffer OB(demangled_cstr, demangled_size);
183183
demangled_cstr = ipd.finishDemangle(&OB);
184+
OB.NameInfo.SuffixRange.first = OB.NameInfo.QualifiersRange.second;
185+
OB.NameInfo.SuffixRange.second = std::string_view(OB).size();
184186
info = std::move(OB.NameInfo);
185187

186188
assert(demangled_cstr &&

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
374374
if (!info->hasBasename())
375375
return std::nullopt;
376376

377-
return demangled_name.slice(info->QualifiersRange.second,
378-
llvm::StringRef::npos);
377+
return demangled_name.slice(info->SuffixRange.first,
378+
info->SuffixRange.second);
379379
}
380380

381381
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Check that we have an appropriate fallback for ${function.prefix} in languages that
2+
# don't implement this frame format variable (in this case Objective-C).
3+
#
4+
# RUN: split-file %s %t
5+
# RUN: %clang_host -g -gdwarf %t/main.m -o %t.objc.out
6+
# RUN: %lldb -x -b -s %t/commands.input %t.objc.out -o exit 2>&1 \
7+
# RUN: | FileCheck %s
8+
9+
#--- main.m
10+
11+
int func() {}
12+
int bar() { func(); }
13+
14+
int main() { return bar(); }
15+
16+
#--- commands.input
17+
settings set -f frame-format "custom-frame '${function.prefix}'\n"
18+
break set -n bar
19+
20+
run
21+
bt
22+
23+
# CHECK: bt
24+
# CHECK-NOT: custom-frame

lldb/unittests/Core/MangledTest.cpp

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -414,114 +414,144 @@ DemanglingPartsTestCase g_demangling_parts_test_cases[] = {
414414
// clang-format off
415415
{ "_ZNVKO3BarIN2ns3QuxIiEEE1CIPFi3FooIS_IiES6_EEE6methodIS6_EENS5_IT_SC_E5InnerIiEESD_SD_",
416416
{ /*.BasenameRange=*/{92, 98}, /*.ScopeRange=*/{36, 92}, /*.ArgumentsRange=*/{ 108, 158 },
417-
/*.QualifiersRange=*/{158, 176} },
417+
/*.QualifiersRange=*/{158, 176}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
418418
/*.basename=*/"method",
419419
/*.scope=*/"Bar<ns::Qux<int>>::C<int (*)(Foo<Bar<int>, Bar<int>>)>::",
420420
/*.qualifiers=*/" const volatile &&"
421421
},
422422
{ "_Z7getFuncIfEPFiiiET_",
423-
{ /*.BasenameRange=*/{6, 13}, /*.ScopeRange=*/{6, 6}, /*.ArgumentsRange=*/{ 20, 27 }, /*.QualifiersRange=*/{38, 38} },
423+
{ /*.BasenameRange=*/{6, 13}, /*.ScopeRange=*/{6, 6}, /*.ArgumentsRange=*/{ 20, 27 },
424+
/*.QualifiersRange=*/{38, 38}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
424425
/*.basename=*/"getFunc",
425426
/*.scope=*/"",
426427
/*.qualifiers=*/""
427428
},
428429
{ "_ZN1f1b1c1gEv",
429430
{ /*.BasenameRange=*/{9, 10}, /*.ScopeRange=*/{0, 9}, /*.ArgumentsRange=*/{ 10, 12 },
430-
/*.QualifiersRange=*/{12, 12} },
431+
/*.QualifiersRange=*/{12, 12}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
431432
/*.basename=*/"g",
432433
/*.scope=*/"f::b::c::",
433434
/*.qualifiers=*/""
434435
},
435436
{ "_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_",
436437
{ /*.BasenameRange=*/{45, 48}, /*.ScopeRange=*/{38, 45}, /*.ArgumentsRange=*/{ 53, 58 },
437-
/*.QualifiersRange=*/{58, 58} },
438+
/*.QualifiersRange=*/{58, 58}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
438439
/*.basename=*/"fD1",
439440
/*.scope=*/"test7::",
440441
/*.qualifiers=*/""
441442
},
442443
{ "_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bINDT1cE1dEEEEEcvT__EES2_",
443444
{ /*.BasenameRange=*/{61, 64}, /*.ScopeRange=*/{54, 61}, /*.ArgumentsRange=*/{ 69, 79 },
444-
/*.QualifiersRange=*/{79, 79} },
445+
/*.QualifiersRange=*/{79, 79}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
445446
/*.basename=*/"fD1",
446447
/*.scope=*/"test7::",
447448
/*.qualifiers=*/""
448449
},
449450
{ "_ZN5test7INDT1cE1dINDT1cE1dEEEE3fD1INDT1cE1dINDT1cE1dEEEEEDTcmtlNS_1DEL_ZNS_1bINDT1cE1dEEEEEcvT__EES2_",
450451
{ /*.BasenameRange=*/{120, 123}, /*.ScopeRange=*/{81, 120}, /*.ArgumentsRange=*/{ 155, 168 },
451-
/*.QualifiersRange=*/{168, 168} },
452+
/*.QualifiersRange=*/{168, 168}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
452453
/*.basename=*/"fD1",
453454
/*.scope=*/"test7<decltype(c)::d<decltype(c)::d>>::",
454455
/*.qualifiers=*/""
455456
},
456457
{ "_ZN8nlohmann16json_abi_v3_11_310basic_jsonINSt3__13mapENS2_6vectorENS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEbxydS8_NS0_14adl_serializerENS4_IhNS8_IhEEEEvE5parseIRA29_KcEESE_OT_NS2_8functionIFbiNS0_6detail13parse_event_tERSE_EEEbb",
457458
{ /*.BasenameRange=*/{687, 692}, /*.ScopeRange=*/{343, 687}, /*.ArgumentsRange=*/{ 713, 1174 },
458-
/*.QualifiersRange=*/{1174, 1174} },
459+
/*.QualifiersRange=*/{1174, 1174}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
459460
/*.basename=*/"parse",
460461
/*.scope=*/"nlohmann::json_abi_v3_11_3::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, bool, long long, unsigned long long, double, std::__1::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>, void>::",
461462
/*.qualifiers=*/""
462463
},
463464
{ "_ZN8nlohmann16json_abi_v3_11_310basic_jsonINSt3__13mapENS2_6vectorENS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEbxydS8_NS0_14adl_serializerENS4_IhNS8_IhEEEEvEC1EDn",
464465
{ /*.BasenameRange=*/{344, 354}, /*.ScopeRange=*/{0, 344}, /*.ArgumentsRange=*/{ 354, 370 },
465-
/*.QualifiersRange=*/{370, 370} },
466+
/*.QualifiersRange=*/{370, 370}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
466467
/*.basename=*/"basic_json",
467468
/*.scope=*/"nlohmann::json_abi_v3_11_3::basic_json<std::__1::map, std::__1::vector, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, bool, long long, unsigned long long, double, std::__1::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::__1::vector<unsigned char, std::__1::allocator<unsigned char>>, void>::",
468469
/*.qualifiers=*/""
469470
},
470471
{ "_Z3fppIiEPFPFvvEiEf",
471-
{ /*.BasenameRange=*/{10, 13}, /*.ScopeRange=*/{10, 10}, /*.ArgumentsRange=*/{ 18, 25 }, /*.QualifiersRange=*/{34,34} },
472+
{ /*.BasenameRange=*/{10, 13}, /*.ScopeRange=*/{10, 10}, /*.ArgumentsRange=*/{ 18, 25 },
473+
/*.QualifiersRange=*/{34,34}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
472474
/*.basename=*/"fpp",
473475
/*.scope=*/"",
474476
/*.qualifiers=*/""
475477
},
476478
{ "_Z3fppIiEPFPFvvEN2ns3FooIiEEEf",
477479
{ /*.BasenameRange=*/{10, 13}, /*.ScopeRange=*/{10, 10}, /*.ArgumentsRange=*/{ 18, 25 },
478-
/*.QualifiersRange=*/{43, 43} },
480+
/*.QualifiersRange=*/{43, 43}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
479481
/*.basename=*/"fpp",
480482
/*.scope=*/"",
481483
/*.qualifiers=*/""
482484
},
483485
{ "_Z3fppIiEPFPFvPFN2ns3FooIiEENS2_3BarIfE3QuxEEEPFS2_S2_EEf",
484486
{ /*.BasenameRange=*/{10, 13}, /*.ScopeRange=*/{10, 10}, /*.ArgumentsRange=*/{ 18, 25 },
485-
/*.QualifiersRange=*/{108, 108} },
487+
/*.QualifiersRange=*/{108, 108}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
486488
/*.basename=*/"fpp",
487489
/*.scope=*/"",
488490
/*.qualifiers=*/""
489491
},
490492
{ "_ZN2ns8HasFuncsINS_3FooINS1_IiE3BarIfE3QuxEEEE3fppIiEEPFPFvvEiEf",
491493
{ /*.BasenameRange=*/{64, 67}, /*.ScopeRange=*/{10, 64}, /*.ArgumentsRange=*/{ 72, 79 },
492-
/*.QualifiersRange=*/{88, 88} },
494+
/*.QualifiersRange=*/{88, 88}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
493495
/*.basename=*/"fpp",
494496
/*.scope=*/"ns::HasFuncs<ns::Foo<ns::Foo<int>::Bar<float>::Qux>>::",
495497
/*.qualifiers=*/""
496498
},
497499
{ "_ZN2ns8HasFuncsINS_3FooINS1_IiE3BarIfE3QuxEEEE3fppIiEEPFPFvvES2_Ef",
498500
{ /*.BasenameRange=*/{64, 67}, /*.ScopeRange=*/{10, 64}, /*.ArgumentsRange=*/{ 72, 79 },
499-
/*.QualifiersRange=*/{97, 97} },
501+
/*.QualifiersRange=*/{97, 97}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
500502
/*.basename=*/"fpp",
501503
/*.scope=*/"ns::HasFuncs<ns::Foo<ns::Foo<int>::Bar<float>::Qux>>::",
502504
/*.qualifiers=*/"",
503505
},
504506
{ "_ZN2ns8HasFuncsINS_3FooINS1_IiE3BarIfE3QuxEEEE3fppIiEEPFPFvPFS2_S5_EEPFS2_S2_EEf",
505507
{ /*.BasenameRange=*/{64, 67}, /*.ScopeRange=*/{10, 64}, /*.ArgumentsRange=*/{ 72, 79 },
506-
/*.QualifiersRange=*/{162, 162} },
508+
/*.QualifiersRange=*/{162, 162}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
507509
/*.basename=*/"fpp",
508510
/*.scope=*/"ns::HasFuncs<ns::Foo<ns::Foo<int>::Bar<float>::Qux>>::",
509511
/*.qualifiers=*/"",
510512
},
511513
{ "_ZNKO2ns3ns23Bar3fooIiEEPFPFNS0_3FooIiEEiENS3_IfEEEi",
512514
{ /*.BasenameRange=*/{37, 40}, /*.ScopeRange=*/{23, 37}, /*.ArgumentsRange=*/{ 45, 50 },
513-
/*.QualifiersRange=*/{78, 87} },
515+
/*.QualifiersRange=*/{78, 87}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
514516
/*.basename=*/"foo",
515517
/*.scope=*/"ns::ns2::Bar::",
516518
/*.qualifiers=*/" const &&",
517519
},
518520
{ "_ZTV11ImageLoader",
519521
{ /*.BasenameRange=*/{0, 0}, /*.ScopeRange=*/{0, 0}, /*.ArgumentsRange=*/{ 0, 0 },
520-
/*.QualifiersRange=*/{0, 0} },
522+
/*.QualifiersRange=*/{0, 0}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
521523
/*.basename=*/"",
522524
/*.scope=*/"",
523525
/*.qualifiers=*/"",
524526
/*.valid_basename=*/false
527+
},
528+
{ "___ZNK5dyld313MachOAnalyzer18forEachInitializerER11DiagnosticsRKNS0_15VMAddrConverterEU13block_pointerFvjEPKv_block_invoke.204",
529+
{ /*.BasenameRange=*/{55, 73}, /*.ScopeRange=*/{33, 55}, /*.ArgumentsRange=*/{ 73, 181 },
530+
/*.QualifiersRange=*/{181, 187}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
531+
/*.basename=*/"forEachInitializer",
532+
/*.scope=*/"dyld3::MachOAnalyzer::",
533+
/*.qualifiers=*/" const",
534+
},
535+
{ "_ZZN5dyld45startEPNS_10KernelArgsEPvS2_ENK3$_1clEv",
536+
{ /*.BasenameRange=*/{53, 63}, /*.ScopeRange=*/{0, 53}, /*.ArgumentsRange=*/{ 63, 65 },
537+
/*.QualifiersRange=*/{65, 71}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
538+
/*.basename=*/"operator()",
539+
/*.scope=*/"dyld4::start(dyld4::KernelArgs*, void*, void*)::$_1::",
540+
/*.qualifiers=*/" const",
541+
},
542+
{ "_ZZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateEENK3$_0clEv",
543+
{ /*.BasenameRange=*/{88, 98}, /*.ScopeRange=*/{0, 88}, /*.ArgumentsRange=*/{ 98, 100 },
544+
/*.QualifiersRange=*/{100, 106}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
545+
/*.basename=*/"operator()",
546+
/*.scope=*/"dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::",
547+
/*.qualifiers=*/" const",
548+
},
549+
{ "_ZZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateEENK3$_0clEv.cold",
550+
{ /*.BasenameRange=*/{88, 98}, /*.ScopeRange=*/{0, 88}, /*.ArgumentsRange=*/{ 98, 100 },
551+
/*.QualifiersRange=*/{100, 106}, /*.PrefixRange=*/{0, 0}, /*.SuffixRange=*/{0, 0} },
552+
/*.basename=*/"operator()",
553+
/*.scope=*/"dyld4::Loader::runInitializersBottomUpPlusUpwardLinks(dyld4::RuntimeState&) const::$_0::",
554+
/*.qualifiers=*/" const",
525555
}
526556
// clang-format on
527557
};

0 commit comments

Comments
 (0)