Skip to content

Commit faf969d

Browse files
Merge pull request #10828 from swiftlang/charles-zablit/lldb/extract-logic-out-of-GetFunctionDisplayName-to-next
🍒 [lldb] Extract logic out of GetFunctionDisplayName into a helper function
2 parents 07104d3 + e3eebf5 commit faf969d

File tree

3 files changed

+199
-101
lines changed

3 files changed

+199
-101
lines changed

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

Lines changed: 116 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,17 +1725,10 @@ bool SwiftLanguage::GetFunctionDisplayName(
17251725
return true;
17261726
}
17271727
case Language::FunctionNameRepresentation::eNameWithArgs: {
1728-
if (!sc->function)
1729-
return false;
1730-
if (sc->function->GetLanguage() != eLanguageTypeSwift)
1731-
return false;
1732-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
1733-
sc->function->GetMangled().GetMangledName().GetStringRef(),
1734-
SwiftLanguageRuntime::eSimplified, sc, exe_ctx);
1728+
std::string display_name = GetFunctionName(sc, exe_ctx);
17351729
if (display_name.empty())
17361730
return false;
1737-
ExecutionContextScope *exe_scope =
1738-
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1731+
s << display_name;
17391732
const InlineFunctionInfo *inline_info = NULL;
17401733
VariableListSP variable_list_sp;
17411734
bool get_function_vars = true;
@@ -1755,109 +1748,131 @@ bool SwiftLanguage::GetFunctionDisplayName(
17551748
sc->function->GetBlock(true).GetBlockVariableList(true);
17561749
}
17571750

1758-
if (inline_info) {
1759-
s << display_name;
1760-
s.PutCString(" [inlined] ");
1761-
display_name = inline_info->GetName().GetString();
1762-
}
1763-
17641751
VariableList args;
17651752
if (variable_list_sp)
17661753
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
17671754
args);
1768-
if (args.GetSize() == 0) {
1769-
s << display_name;
1770-
return true;
1771-
}
1772-
const char *cstr = display_name.data();
1773-
const char *open_paren = strchr(cstr, '(');
1774-
const char *close_paren = nullptr;
1775-
const char *generic = strchr(cstr, '<');
1776-
// If before the arguments list begins there is a template sign
1777-
// then scan to the end of the generic args before you try to find
1778-
// the arguments list.
1779-
if (generic && open_paren && generic < open_paren) {
1780-
int generic_depth = 1;
1781-
++generic;
1782-
for (; *generic && generic_depth > 0; generic++) {
1783-
if (*generic == '<')
1784-
generic_depth++;
1785-
if (*generic == '>')
1786-
generic_depth--;
1787-
}
1788-
if (*generic)
1789-
open_paren = strchr(generic, '(');
1790-
else
1791-
open_paren = nullptr;
1792-
}
1793-
if (open_paren) {
1794-
close_paren = strchr(open_paren, ')');
1795-
}
17961755

1797-
if (open_paren)
1798-
s.Write(cstr, open_paren - cstr + 1);
1799-
else {
1800-
s << display_name;
1801-
s.PutChar('(');
1756+
s << GetFunctionDisplayArgs(sc, args, exe_ctx);
1757+
return true;
18021758
}
1803-
const size_t num_args = args.GetSize();
1804-
for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
1805-
std::string buffer;
1806-
1807-
VariableSP var_sp(args.GetVariableAtIndex(arg_idx));
1808-
ValueObjectSP var_value_sp(
1809-
ValueObjectVariable::Create(exe_scope, var_sp));
1810-
if (!var_sp || !var_value_sp || var_sp->IsArtificial())
1811-
continue;
1812-
StreamString ss;
1813-
const char *var_representation = nullptr;
1814-
const char *var_name = var_value_sp->GetName().GetCString();
1815-
if (var_value_sp->GetCompilerType().IsValid()) {
1816-
if (var_value_sp && exe_scope->CalculateTarget())
1817-
var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
1818-
exe_scope->CalculateTarget()
1819-
->TargetProperties::GetPreferDynamicValue(),
1820-
exe_scope->CalculateTarget()
1821-
->TargetProperties::GetEnableSyntheticValue());
1822-
if (var_value_sp->GetCompilerType().IsAggregateType() &&
1823-
DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) {
1824-
static StringSummaryFormat format(TypeSummaryImpl::Flags()
1825-
.SetHideItemNames(false)
1826-
.SetShowMembersOneLiner(true),
1827-
"");
1828-
format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
1829-
var_representation = buffer.c_str();
1830-
} else
1831-
var_value_sp->DumpPrintableRepresentation(
1832-
ss,
1833-
ValueObject::ValueObjectRepresentationStyle::
1834-
eValueObjectRepresentationStyleSummary,
1835-
eFormatDefault,
1836-
ValueObject::PrintableRepresentationSpecialCases::eAllow, false);
1837-
}
1838-
if (ss.GetData() && ss.GetSize())
1839-
var_representation = ss.GetData();
1840-
if (arg_idx > 0)
1841-
s.PutCString(", ");
1842-
if (var_value_sp->GetError().Success()) {
1843-
if (var_representation)
1844-
s.Printf("%s=%s", var_name, var_representation);
1845-
else
1846-
s.Printf("%s=%s at %s", var_name,
1847-
var_value_sp->GetTypeName().GetCString(),
1848-
var_value_sp->GetLocationAsCString());
1849-
} else
1850-
s.Printf("%s=<unavailable>", var_name);
18511759
}
1760+
return false;
1761+
}
18521762

1853-
if (close_paren)
1854-
s.PutCString(close_paren);
1763+
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1764+
const ExecutionContext *exe_ctx) {
1765+
if (!sc.function)
1766+
return {};
1767+
if (sc.function->GetLanguage() != eLanguageTypeSwift)
1768+
return {};
1769+
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1770+
sc.function->GetMangled().GetMangledName().GetStringRef(),
1771+
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1772+
if (name.empty())
1773+
return {};
1774+
size_t open_paren = name.find('(');
1775+
size_t generic = name.find('<');
1776+
size_t name_end = std::min(open_paren, generic);
1777+
if (name_end == std::string::npos)
1778+
return name;
1779+
return name.substr(0, name_end);
1780+
}
1781+
1782+
std::string SwiftLanguage::GetFunctionDisplayArgs(
1783+
const SymbolContext &sc, VariableList &args,
1784+
const lldb_private::ExecutionContext *exe_ctx) {
1785+
ExecutionContextScope *exe_scope =
1786+
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1787+
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1788+
sc.function->GetMangled().GetMangledName().GetStringRef(),
1789+
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1790+
lldb_private::StreamString s;
1791+
const char *cstr = name.data();
1792+
const char *open_paren = strchr(cstr, '(');
1793+
const char *close_paren = nullptr;
1794+
const char *generic = strchr(cstr, '<');
1795+
// If before the arguments list begins there is a template sign
1796+
// then scan to the end of the generic args before you try to find
1797+
// the arguments list.
1798+
const char *generic_start = generic;
1799+
if (generic && open_paren && generic < open_paren) {
1800+
int generic_depth = 1;
1801+
++generic;
1802+
for (; *generic && generic_depth > 0; generic++) {
1803+
if (*generic == '<')
1804+
generic_depth++;
1805+
if (*generic == '>')
1806+
generic_depth--;
1807+
}
1808+
if (*generic)
1809+
open_paren = strchr(generic, '(');
18551810
else
1856-
s.PutChar(')');
1811+
open_paren = nullptr;
18571812
}
1858-
return true;
1813+
if (open_paren) {
1814+
close_paren = strchr(open_paren, ')');
18591815
}
1860-
return false;
1816+
1817+
if (generic_start && generic_start < open_paren)
1818+
s.Write(generic_start, open_paren - generic_start);
1819+
s.PutChar('(');
1820+
1821+
const size_t num_args = args.GetSize();
1822+
for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
1823+
std::string buffer;
1824+
1825+
VariableSP var_sp(args.GetVariableAtIndex(arg_idx));
1826+
ValueObjectSP var_value_sp(ValueObjectVariable::Create(exe_scope, var_sp));
1827+
if (!var_sp || !var_value_sp || var_sp->IsArtificial())
1828+
continue;
1829+
StreamString ss;
1830+
const char *var_representation = nullptr;
1831+
const char *var_name = var_value_sp->GetName().GetCString();
1832+
if (var_value_sp->GetCompilerType().IsValid()) {
1833+
if (var_value_sp && exe_scope->CalculateTarget())
1834+
var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
1835+
exe_scope->CalculateTarget()
1836+
->TargetProperties::GetPreferDynamicValue(),
1837+
exe_scope->CalculateTarget()
1838+
->TargetProperties::GetEnableSyntheticValue());
1839+
if (var_value_sp->GetCompilerType().IsAggregateType() &&
1840+
DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) {
1841+
static StringSummaryFormat format(TypeSummaryImpl::Flags()
1842+
.SetHideItemNames(false)
1843+
.SetShowMembersOneLiner(true),
1844+
"");
1845+
format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
1846+
var_representation = buffer.c_str();
1847+
} else
1848+
var_value_sp->DumpPrintableRepresentation(
1849+
ss,
1850+
ValueObject::ValueObjectRepresentationStyle::
1851+
eValueObjectRepresentationStyleSummary,
1852+
eFormatDefault,
1853+
ValueObject::PrintableRepresentationSpecialCases::eAllow, false);
1854+
}
1855+
if (ss.GetData() && ss.GetSize())
1856+
var_representation = ss.GetData();
1857+
if (arg_idx > 0)
1858+
s.PutCString(", ");
1859+
if (var_value_sp->GetError().Success()) {
1860+
if (var_representation)
1861+
s.Printf("%s=%s", var_name, var_representation);
1862+
else
1863+
s.Printf("%s=%s at %s", var_name,
1864+
var_value_sp->GetTypeName().GetCString(),
1865+
var_value_sp->GetLocationAsCString());
1866+
} else
1867+
s.Printf("%s=<unavailable>", var_name);
1868+
}
1869+
1870+
if (close_paren)
1871+
s.PutCString(close_paren);
1872+
else
1873+
s.PutChar(')');
1874+
1875+
return s.GetString().str();
18611876
}
18621877

18631878
void SwiftLanguage::GetExceptionResolverDescription(bool catch_on,

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

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

72+
/// Returns the name of function up to the first generic or opening
73+
/// parenthesis.
74+
///
75+
/// The following function will have the name "foo":
76+
/// \code{.swift}
77+
/// func foo<T>(bar: T) {}
78+
/// \endcode
79+
///
80+
/// \param sc The associated SymbolContext.
81+
/// \param exe_ctx The associated ExecutionContext.
82+
/// \returns The name of a function as an std::string.
83+
std::string GetFunctionName(const SymbolContext &sc,
84+
const ExecutionContext *exe_ctx);
85+
86+
/// Returns the arguments of a function call with its generics if any.
87+
///
88+
/// Calling GetFunctionDisplayArgs on the following function call will return
89+
/// "<Int>(bar=1)"
90+
/// \code{.swift}
91+
/// func foo<T>(bar: T) {}
92+
/// foo(1)
93+
/// \endcode
94+
///
95+
/// \param sc The associated SymbolContext.
96+
/// \param args The VariableList that are passed to the function.
97+
/// \param exe_ctx The associated ExecutionContext.
98+
/// \returns The generics and arguments of a function call as an std::string.
99+
std::string
100+
GetFunctionDisplayArgs(const SymbolContext &sc, VariableList &args,
101+
const lldb_private::ExecutionContext *exe_ctx);
102+
72103
void GetExceptionResolverDescription(bool catch_on, bool throw_on,
73104
Stream &s) override;
74105

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# XFAIL: target-windows
2+
3+
# Test Swift function name printing in backtraces.
4+
5+
# RUN: split-file %s %t
6+
# RUN: %target-swiftc -g %t/main.swift -o %t.out
7+
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
8+
# RUN: | FileCheck %s
9+
10+
#--- main.swift
11+
func foo() async -> Int {
12+
return await try! bar(a: 1, b: 1)
13+
}
14+
15+
var res = {
16+
(index: Int) -> Int in
17+
return index + 10
18+
}(1)
19+
20+
fileprivate func bar(a: Int, b: Int) async throws -> Int {
21+
var baz = Baz(baz: 1)
22+
return res + a + b + Foo.foo_(a: baz)
23+
}
24+
25+
struct Foo {
26+
let foo: Int
27+
static func foo_<T>(a: T) -> Int {
28+
var a_ = a as! Baz
29+
return a_.qux(a: 1)
30+
}
31+
}
32+
33+
struct Baz {
34+
var baz: Int
35+
mutating func qux<T>(a: T) -> Int {
36+
baz += 1
37+
return baz
38+
}
39+
}
40+
41+
await foo()
42+
43+
#--- commands.input
44+
b qux
45+
46+
run
47+
bt
48+
49+
# CHECK: `Baz.qux<Int>(a=1)
50+
# CHECK: `static Foo.foo_<main.Baz>(a=(baz = 1))
51+
# CHECK: `bar(a=1, b=1)
52+
# CHECK: `foo()

0 commit comments

Comments
 (0)