Skip to content

Commit e456735

Browse files
[lldb] add support TemplateArguments and NameQualifiers to Swift format Entities
1 parent e73c6b6 commit e456735

File tree

8 files changed

+514
-422
lines changed

8 files changed

+514
-422
lines changed

lldb/source/Core/Mangled.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,21 @@ GetSwiftDemangledStr(ConstString m_mangled, const SymbolContext *sc,
168168
}
169169
auto [demangled, info] = SwiftLanguageRuntime::TrackedDemangleSymbolAsString(
170170
mangled_name, demangle_mode, sc);
171+
// TODO: The logic below should be in the NodePrinter.
171172
info.PrefixRange.second =
172173
std::min(info.BasenameRange.first, info.ArgumentsRange.first);
173174
info.SuffixRange.first =
174175
std::max(info.BasenameRange.second, info.ArgumentsRange.second);
175176
info.SuffixRange.second = demangled.length();
177+
if (info.hasBasename() && info.hasArguments()) {
178+
if (info.hasTemplateArguments() && info.TemplateArgumentsRange.first > 0) {
179+
info.NameQualifiersRange.second = std::min(
180+
info.ArgumentsRange.first, info.TemplateArgumentsRange.first);
181+
} else {
182+
info.NameQualifiersRange.second = info.ArgumentsRange.first;
183+
}
184+
info.NameQualifiersRange.first = info.BasenameRange.second;
185+
}
176186

177187
// Don't cache the demangled name if the function isn't available yet.
178188
// Only cache eFullName demangled functions to keep the cache consistent.

lldb/source/Plugins/Language/Swift/LanguageSwiftProperties.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td"
33
let Definition = "language_swift" in {
44
def FunctionNameFormat: Property<"function-name-format", "FormatEntity">,
55
Global,
6-
DefaultStringValue<"${function.prefix}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.formatted-arguments}${function.suffix}">,
6+
DefaultStringValue<"${function.prefix}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.name-qualifiers}${function.template-arguments}${function.formatted-arguments}${function.suffix}">,
77
Desc<"Swift specific frame format string to use when displaying stack frame information for threads.">;
88
}

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 84 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,13 +1727,7 @@ bool SwiftLanguage::GetFunctionDisplayName(
17271727
// No need to customize this.
17281728
return false;
17291729
case Language::FunctionNameRepresentation::eNameWithNoArgs: {
1730-
if (!sc.function)
1731-
return false;
1732-
if (sc.function->GetLanguage() != eLanguageTypeSwift)
1733-
return false;
1734-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
1735-
sc.function->GetMangled().GetMangledName().GetStringRef(),
1736-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1730+
std::string display_name = GetDemangledFunctionName(sc, exe_ctx);
17371731
if (display_name.empty())
17381732
return false;
17391733
s << display_name;
@@ -1768,69 +1762,81 @@ bool SwiftLanguage::GetFunctionDisplayName(
17681762
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
17691763
args);
17701764

1765+
s << GetFunctionTemplateArguments(sc, exe_ctx);
17711766
s << GetFunctionDisplayArgs(sc, args, exe_ctx);
17721767
return true;
17731768
}
17741769
}
17751770
return false;
17761771
}
17771772

1778-
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1779-
const ExecutionContext *exe_ctx) {
1773+
std::string
1774+
SwiftLanguage::GetDemangledFunctionName(const SymbolContext &sc,
1775+
const ExecutionContext *exe_ctx) {
17801776
if (!sc.function)
17811777
return {};
17821778
if (sc.function->GetLanguage() != eLanguageTypeSwift)
17831779
return {};
1784-
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1780+
return SwiftLanguageRuntime::DemangleSymbolAsString(
17851781
sc.GetPossiblyInlinedFunctionName().GetMangledName(),
17861782
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1787-
if (name.empty())
1783+
}
1784+
1785+
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1786+
const ExecutionContext *exe_ctx) {
1787+
std::string demangled_name = GetDemangledFunctionName(sc, exe_ctx);
1788+
if (demangled_name.empty())
17881789
return {};
1789-
size_t open_paren = name.find('(');
1790-
size_t generic = name.find('<');
1790+
size_t open_paren = demangled_name.find('(');
1791+
size_t generic = demangled_name.find('<');
17911792
size_t name_end = std::min(open_paren, generic);
17921793
if (name_end == std::string::npos)
1793-
return name;
1794-
return name.substr(0, name_end);
1794+
return demangled_name;
1795+
return demangled_name.substr(0, name_end);
1796+
}
1797+
1798+
std::string
1799+
SwiftLanguage::GetFunctionTemplateArguments(const SymbolContext &sc,
1800+
const ExecutionContext *exe_ctx) {
1801+
std::string demangled_name = GetDemangledFunctionName(sc, exe_ctx);
1802+
if (demangled_name.empty())
1803+
return {};
1804+
size_t open_paren = demangled_name.find('(');
1805+
size_t generic_start = demangled_name.find('<');
1806+
if (generic_start == std::string::npos || generic_start > open_paren)
1807+
return {};
1808+
1809+
int generic_depth = 1;
1810+
size_t generic_end = generic_start + 1;
1811+
1812+
while (generic_end < demangled_name.size() && generic_depth > 0) {
1813+
if (demangled_name[generic_end] == '<')
1814+
generic_depth++;
1815+
else if (demangled_name[generic_end] == '>')
1816+
generic_depth--;
1817+
generic_end++;
1818+
}
1819+
1820+
if (generic_depth != 0)
1821+
return {};
1822+
1823+
return demangled_name.substr(generic_start, generic_end - generic_start);
17951824
}
17961825

17971826
std::string SwiftLanguage::GetFunctionDisplayArgs(
17981827
const SymbolContext &sc, VariableList &args,
17991828
const lldb_private::ExecutionContext *exe_ctx) {
18001829
ExecutionContextScope *exe_scope =
18011830
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1802-
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1803-
sc.function->GetMangled().GetMangledName().GetStringRef(),
1804-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1831+
std::string name = GetDemangledFunctionName(sc, exe_ctx);
18051832
lldb_private::StreamString s;
18061833
const char *cstr = name.data();
18071834
const char *open_paren = strchr(cstr, '(');
18081835
const char *close_paren = nullptr;
1809-
const char *generic = strchr(cstr, '<');
1810-
// If before the arguments list begins there is a template sign
1811-
// then scan to the end of the generic args before you try to find
1812-
// the arguments list.
1813-
const char *generic_start = generic;
1814-
if (generic && open_paren && generic < open_paren) {
1815-
int generic_depth = 1;
1816-
++generic;
1817-
for (; *generic && generic_depth > 0; generic++) {
1818-
if (*generic == '<')
1819-
generic_depth++;
1820-
if (*generic == '>')
1821-
generic_depth--;
1822-
}
1823-
if (*generic)
1824-
open_paren = strchr(generic, '(');
1825-
else
1826-
open_paren = nullptr;
1827-
}
18281836
if (open_paren) {
18291837
close_paren = strchr(open_paren, ')');
18301838
}
18311839

1832-
if (generic_start && generic_start < open_paren)
1833-
s.Write(generic_start, open_paren - generic_start);
18341840
s.PutChar('(');
18351841

18361842
const size_t num_args = args.GetSize();
@@ -1936,7 +1942,7 @@ GetAndValidateInfo(const SymbolContext &sc) {
19361942
// Function without a basename is nonsense.
19371943
if (!info->hasBasename())
19381944
return llvm::createStringError(
1939-
"DemangledInfo for '%s does not have basename range.",
1945+
"The demangled name for '%s does not have basename range.",
19401946
demangled_name.data());
19411947

19421948
return std::make_pair(demangled_name, *info);
@@ -1954,6 +1960,23 @@ GetDemangledBasename(const SymbolContext &sc) {
19541960
info.BasenameRange.second);
19551961
}
19561962

1963+
static llvm::Expected<llvm::StringRef>
1964+
GetDemangledNameQualifiers(const SymbolContext &sc) {
1965+
auto info_or_err = GetAndValidateInfo(sc);
1966+
if (!info_or_err)
1967+
return info_or_err.takeError();
1968+
1969+
auto [demangled_name, info] = *info_or_err;
1970+
1971+
if (!info.hasPrefix())
1972+
return llvm::createStringError(
1973+
"The demangled name for '%s does not have a name qualifiers range.",
1974+
demangled_name.data());
1975+
1976+
return demangled_name.slice(info.NameQualifiersRange.first,
1977+
info.NameQualifiersRange.second);
1978+
}
1979+
19571980
static llvm::Expected<llvm::StringRef>
19581981
GetDemangledFunctionPrefix(const SymbolContext &sc) {
19591982
auto info_or_err = GetAndValidateInfo(sc);
@@ -1964,7 +1987,7 @@ GetDemangledFunctionPrefix(const SymbolContext &sc) {
19641987

19651988
if (!info.hasPrefix())
19661989
return llvm::createStringError(
1967-
"DemangledInfo for '%s does not have suffix range.",
1990+
"The demangled name for '%s does not have a prefix range.",
19681991
demangled_name.data());
19691992

19701993
return demangled_name.slice(info.PrefixRange.first, info.PrefixRange.second);
@@ -1980,7 +2003,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
19802003

19812004
if (!info.hasSuffix())
19822005
return llvm::createStringError(
1983-
"DemangledInfo for '%s does not have suffix range.",
2006+
"The demangled name for '%s does not have a suffix range.",
19842007
demangled_name.data());
19852008

19862009
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
@@ -2035,6 +2058,24 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20352058

20362059
return true;
20372060
}
2061+
case FormatEntity::Entry::Type::FunctionNameQualifiers: {
2062+
auto qualifiers_or_err = GetDemangledNameQualifiers(sc);
2063+
if (!qualifiers_or_err) {
2064+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), qualifiers_or_err.takeError(),
2065+
"Failed to handle ${{function.name-qualifiers}} "
2066+
"frame-format variable: {0}");
2067+
return false;
2068+
}
2069+
2070+
s << *qualifiers_or_err;
2071+
2072+
return true;
2073+
}
2074+
case FormatEntity::Entry::Type::FunctionTemplateArguments: {
2075+
s << GetFunctionTemplateArguments(sc, exe_ctx);
2076+
2077+
return true;
2078+
}
20382079
case FormatEntity::Entry::Type::FunctionFormattedArguments: {
20392080
// This ensures we print the arguments even when no debug-info is available.
20402081
//
@@ -2043,9 +2084,7 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20432084
// once we have a "fallback operator" in the frame-format language.
20442085
if (!sc.function && sc.symbol)
20452086
return PrintDemangledArgumentList(s, sc);
2046-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
2047-
sc.function->GetMangled().GetMangledName().GetStringRef(),
2048-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
2087+
std::string display_name = GetDemangledFunctionName(sc, exe_ctx);
20492088
if (display_name.empty())
20502089
return false;
20512090

@@ -2085,7 +2124,6 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20852124
}
20862125

20872126
case FormatEntity::Entry::Type::FunctionScope:
2088-
case FormatEntity::Entry::Type::FunctionTemplateArguments:
20892127
case FormatEntity::Entry::Type::FunctionReturnRight:
20902128
case FormatEntity::Entry::Type::FunctionReturnLeft:
20912129
case FormatEntity::Entry::Type::FunctionQualifiers:

lldb/source/Plugins/Language/Swift/SwiftLanguage.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class SwiftLanguage : public Language {
6969
FunctionNameRepresentation representation,
7070
Stream &s) override;
7171

72+
std::string GetDemangledFunctionName(const SymbolContext &sc,
73+
const ExecutionContext *exe_ctx);
74+
7275
/// Returns the name of function up to the first generic or opening
7376
/// parenthesis.
7477
///
@@ -83,6 +86,9 @@ class SwiftLanguage : public Language {
8386
std::string GetFunctionName(const SymbolContext &sc,
8487
const ExecutionContext *exe_ctx);
8588

89+
std::string GetFunctionTemplateArguments(const SymbolContext &sc,
90+
const ExecutionContext *exe_ctx);
91+
8692
/// Returns the arguments of a function call with its generics if any.
8793
///
8894
/// Calling GetFunctionDisplayArgs on the following function call will return

lldb/source/Plugins/Language/Swift/SwiftMangled.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class TrackingNodePrinter : public NodePrinter {
3232
private:
3333
lldb_private::DemangledNameInfo info;
3434
std::optional<unsigned> parametersDepth;
35+
std::optional<unsigned> genericsSignatureDepth;
3536

3637
void startName() {
3738
if (!info.hasBasename())
@@ -43,6 +44,25 @@ class TrackingNodePrinter : public NodePrinter {
4344
info.BasenameRange.second = getStreamLength();
4445
}
4546

47+
void startGenericSignature(unsigned depth) {
48+
if (genericsSignatureDepth || !info.hasBasename() ||
49+
info.TemplateArgumentsRange.first <
50+
info.TemplateArgumentsRange.second) {
51+
return;
52+
}
53+
info.TemplateArgumentsRange.first = getStreamLength();
54+
genericsSignatureDepth = depth;
55+
}
56+
57+
void endGenericSignature(unsigned depth) {
58+
if (!genericsSignatureDepth || *genericsSignatureDepth != depth ||
59+
info.TemplateArgumentsRange.first <
60+
info.TemplateArgumentsRange.second) {
61+
return;
62+
}
63+
info.TemplateArgumentsRange.second = getStreamLength();
64+
}
65+
4666
void startParameters(unsigned depth) {
4767
if (parametersDepth || !info.hasBasename() ||
4868
info.ArgumentsRange.first < info.ArgumentsRange.second) {
@@ -85,6 +105,12 @@ class TrackingNodePrinter : public NodePrinter {
85105
endName();
86106
}
87107

108+
void printGenericSignature(NodePointer Node, unsigned depth) override {
109+
startGenericSignature(depth);
110+
NodePrinter::printGenericSignature(Node, depth);
111+
endGenericSignature(depth);
112+
}
113+
88114
void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType,
89115
unsigned depth, bool showTypes) override {
90116
startParameters(depth);

lldb/test/API/lang/swift/async/tasks/TestSwiftTaskBacktrace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ def do_backtrace(self, arg):
3131
".sleep(",
3232
"`second() at main.swift:6",
3333
"`first() at main.swift:2",
34-
"`closure #1() at main.swift:12:19",
34+
"`closure #1 in static Main.main() at main.swift:12:19",
3535
],
3636
)

lldb/test/API/lang/swift/async/tasks/TestSwiftTaskSelect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def do_backtrace_selected_task(self, arg):
3333
".sleep(",
3434
"`second() at main.swift:6:",
3535
"`first() at main.swift:2:",
36-
"`closure #1() at main.swift:12:",
36+
"`closure #1 in static Main.main() at main.swift:12:",
3737
],
3838
)
3939

0 commit comments

Comments
 (0)