Skip to content

Commit ab6923b

Browse files
[lldb] add TemplateRange and NameQualifiersRange to DemangledNameInfo (#150999)
This patch adds 2 new attributes to `DemangledNameInfo`: `TemplateRange` and `NameQualifiersRange`. It also introduces the `function.name-qualifiers` entity formatter which allows tracking qualifiers between the name of a function and its arguments/template. This will be used downstream in Swift but may have applications in C++: swiftlang#11068.
1 parent 3cf072d commit ab6923b

File tree

7 files changed

+242
-86
lines changed

7 files changed

+242
-86
lines changed

lldb/docs/use/formatting.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ A complete list of currently supported format string variables is listed below:
8989
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
9090
| ``function.name-without-args`` | The name of the current function without arguments and values (used to include a function name in-line in the ``disassembly-format``) |
9191
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
92+
| ``function.name-qualifiers`` | Any qualifiers added after the name of a function and before its arguments or template arguments. E.g., for Swift the name qualifier for ``closure #1 in A.foo<Int>()`` is `` in A.foo``. |
93+
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
9294
| ``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``. |
9395
+---------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
9496
| ``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. |
@@ -332,6 +334,7 @@ The function names displayed in backtraces/``frame info``/``thread info`` are th
332334
- ``${function.prefix}``
333335
- ``${function.scope}``
334336
- ``${function.basename}``
337+
- ``${function.name-qualifiers}``
335338
- ``${function.template-arguments}``
336339
- ``${function.formatted-arguments}``
337340
- ``${function.qualifiers}``

lldb/include/lldb/Core/DemangledNameInfo.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,29 @@ namespace lldb_private {
2222
struct DemangledNameInfo {
2323
/// A [start, end) pair for the function basename.
2424
/// The basename is the name without scope qualifiers
25-
/// and without template parameters. E.g.,
25+
/// and without template parameters.
26+
///
27+
/// E.g.,
2628
/// \code{.cpp}
2729
/// void foo::bar<int>::someFunc<float>(int) const &&
2830
/// ^ ^
2931
/// start end
3032
/// \endcode
3133
std::pair<size_t, size_t> BasenameRange;
3234

35+
/// A [start, end) pair for the function template arguments.
36+
///
37+
/// E.g.,
38+
/// \code{.cpp}
39+
/// void foo::bar<int>::someFunc<float>(int) const &&
40+
/// ^ ^
41+
/// start end
42+
/// \endcode
43+
std::pair<size_t, size_t> TemplateArgumentsRange;
44+
3345
/// A [start, end) pair for the function scope qualifiers.
34-
/// E.g., for
46+
///
47+
/// E.g.,
3548
/// \code{.cpp}
3649
/// void foo::bar<int>::qux<float>(int) const &&
3750
/// ^ ^
@@ -40,6 +53,7 @@ struct DemangledNameInfo {
4053
std::pair<size_t, size_t> ScopeRange;
4154

4255
/// Indicates the [start, end) of the function argument list.
56+
///
4357
/// E.g.,
4458
/// \code{.cpp}
4559
/// int (*getFunc<float>(float, double))(int, int)
@@ -59,6 +73,19 @@ struct DemangledNameInfo {
5973
/// \endcode
6074
std::pair<size_t, size_t> QualifiersRange;
6175

76+
/// Indicates the [start, end) of the function's name qualifiers. This is a
77+
/// catch-all range for anything in between the basename and the function's
78+
/// arguments or template arguments, that is not tracked by the rest of the
79+
/// pairs.
80+
///
81+
/// E.g.,
82+
/// \code{.swift}
83+
/// closure #1 in A.foo<Int>()
84+
/// ^ ^
85+
/// start end
86+
/// \endcode
87+
std::pair<size_t, size_t> NameQualifiersRange;
88+
6289
/// Indicates the [start, end) of the function's prefix. This is a
6390
/// catch-all range for anything that is not tracked by the rest of
6491
/// the pairs.
@@ -75,6 +102,11 @@ struct DemangledNameInfo {
75102
return BasenameRange.second > BasenameRange.first;
76103
}
77104

105+
/// Returns \c true if this object holds a valid template arguments range.
106+
bool hasTemplateArguments() const {
107+
return TemplateArgumentsRange.second >= TemplateArgumentsRange.first;
108+
}
109+
78110
/// Returns \c true if this object holds a valid scope range.
79111
bool hasScope() const { return ScopeRange.second >= ScopeRange.first; }
80112

@@ -88,6 +120,11 @@ struct DemangledNameInfo {
88120
return QualifiersRange.second >= QualifiersRange.first;
89121
}
90122

123+
/// Returns \c true if this object holds a valid name qualifiers range.
124+
bool hasNameQualifiers() const {
125+
return NameQualifiersRange.second >= NameQualifiersRange.first;
126+
}
127+
91128
/// Returns \c true if this object holds a valid prefix range.
92129
bool hasPrefix() const { return PrefixRange.second >= PrefixRange.first; }
93130

lldb/include/lldb/Core/FormatEntity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ struct Entry {
9191
FunctionPrefix,
9292
FunctionScope,
9393
FunctionBasename,
94+
FunctionNameQualifiers,
9495
FunctionTemplateArguments,
9596
FunctionFormattedArguments,
9697
FunctionReturnLeft,

lldb/source/Core/DemangledNameInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ void TrackingOutputBuffer::finalizeStart() {
9292
if (NameInfo.BasenameRange.second == 0)
9393
NameInfo.BasenameRange.second = getCurrentPosition();
9494

95+
// There is something between the basename and the start of the function
96+
// arguments. Assume those are template arguments (which *should* be true for
97+
// C++ demangled names, but this assumption may change in the future, in
98+
// which case this needs to be adjusted).
99+
if (NameInfo.BasenameRange.second != NameInfo.ArgumentsRange.first)
100+
NameInfo.TemplateArgumentsRange = {NameInfo.BasenameRange.second,
101+
NameInfo.ArgumentsRange.first};
102+
95103
assert(!shouldTrack());
96104
assert(canFinalize());
97105
}

lldb/source/Core/FormatEntity.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ constexpr Definition g_function_child_entries[] = {
128128
Definition("prefix", EntryType::FunctionPrefix),
129129
Definition("scope", EntryType::FunctionScope),
130130
Definition("basename", EntryType::FunctionBasename),
131+
Definition("name-qualifiers", EntryType::FunctionNameQualifiers),
131132
Definition("template-arguments", EntryType::FunctionTemplateArguments),
132133
Definition("formatted-arguments", EntryType::FunctionFormattedArguments),
133134
Definition("return-left", EntryType::FunctionReturnLeft),
@@ -390,6 +391,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
390391
ENUM_TO_CSTR(FunctionPrefix);
391392
ENUM_TO_CSTR(FunctionScope);
392393
ENUM_TO_CSTR(FunctionBasename);
394+
ENUM_TO_CSTR(FunctionNameQualifiers);
393395
ENUM_TO_CSTR(FunctionTemplateArguments);
394396
ENUM_TO_CSTR(FunctionFormattedArguments);
395397
ENUM_TO_CSTR(FunctionReturnLeft);
@@ -1842,6 +1844,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
18421844
case Entry::Type::FunctionPrefix:
18431845
case Entry::Type::FunctionScope:
18441846
case Entry::Type::FunctionBasename:
1847+
case Entry::Type::FunctionNameQualifiers:
18451848
case Entry::Type::FunctionTemplateArguments:
18461849
case Entry::Type::FunctionFormattedArguments:
18471850
case Entry::Type::FunctionReturnRight:

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,12 @@ GetDemangledTemplateArguments(const SymbolContext &sc) {
283283

284284
auto [demangled_name, info] = *info_or_err;
285285

286-
if (info.ArgumentsRange.first < info.BasenameRange.second)
287-
return llvm::createStringError("Arguments range for '%s' is invalid.",
288-
demangled_name.data());
286+
if (!info.hasTemplateArguments())
287+
return llvm::createStringError(
288+
"Template arguments range for '%s' is invalid.", demangled_name.data());
289289

290-
return demangled_name.slice(info.BasenameRange.second,
291-
info.ArgumentsRange.first);
290+
return demangled_name.slice(info.TemplateArgumentsRange.first,
291+
info.TemplateArgumentsRange.second);
292292
}
293293

294294
static llvm::Expected<llvm::StringRef>

0 commit comments

Comments
 (0)