Skip to content

Commit 82d340f

Browse files
Merge pull request #11316 from charles-zablit/charles-zablit/lldb/templates-to-21.x
🍒 [lldb] add support for TemplateArguments and NameQualifiers to Swift format Entities
2 parents 06876a4 + 1fe56ad commit 82d340f

File tree

9 files changed

+514
-423
lines changed

9 files changed

+514
-423
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
@@ -1731,13 +1731,7 @@ bool SwiftLanguage::GetFunctionDisplayName(
17311731
// No need to customize this.
17321732
return false;
17331733
case Language::FunctionNameRepresentation::eNameWithNoArgs: {
1734-
if (!sc.function)
1735-
return false;
1736-
if (sc.function->GetLanguage() != eLanguageTypeSwift)
1737-
return false;
1738-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
1739-
sc.function->GetMangled().GetMangledName().GetStringRef(),
1740-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1734+
std::string display_name = GetDemangledFunctionName(sc, exe_ctx);
17411735
if (display_name.empty())
17421736
return false;
17431737
s << display_name;
@@ -1772,69 +1766,81 @@ bool SwiftLanguage::GetFunctionDisplayName(
17721766
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
17731767
args);
17741768

1769+
s << GetFunctionTemplateArguments(sc, exe_ctx);
17751770
s << GetFunctionDisplayArgs(sc, args, exe_ctx);
17761771
return true;
17771772
}
17781773
}
17791774
return false;
17801775
}
17811776

1782-
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1783-
const ExecutionContext *exe_ctx) {
1777+
std::string
1778+
SwiftLanguage::GetDemangledFunctionName(const SymbolContext &sc,
1779+
const ExecutionContext *exe_ctx) {
17841780
if (!sc.function)
17851781
return {};
17861782
if (sc.function->GetLanguage() != eLanguageTypeSwift)
17871783
return {};
1788-
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1784+
return SwiftLanguageRuntime::DemangleSymbolAsString(
17891785
sc.GetPossiblyInlinedFunctionName().GetMangledName(),
17901786
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1791-
if (name.empty())
1787+
}
1788+
1789+
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1790+
const ExecutionContext *exe_ctx) {
1791+
std::string demangled_name = GetDemangledFunctionName(sc, exe_ctx);
1792+
if (demangled_name.empty())
17921793
return {};
1793-
size_t open_paren = name.find('(');
1794-
size_t generic = name.find('<');
1794+
size_t open_paren = demangled_name.find('(');
1795+
size_t generic = demangled_name.find('<');
17951796
size_t name_end = std::min(open_paren, generic);
17961797
if (name_end == std::string::npos)
1797-
return name;
1798-
return name.substr(0, name_end);
1798+
return demangled_name;
1799+
return demangled_name.substr(0, name_end);
1800+
}
1801+
1802+
std::string
1803+
SwiftLanguage::GetFunctionTemplateArguments(const SymbolContext &sc,
1804+
const ExecutionContext *exe_ctx) {
1805+
std::string demangled_name = GetDemangledFunctionName(sc, exe_ctx);
1806+
if (demangled_name.empty())
1807+
return {};
1808+
size_t open_paren = demangled_name.find('(');
1809+
size_t generic_start = demangled_name.find('<');
1810+
if (generic_start == std::string::npos || generic_start > open_paren)
1811+
return {};
1812+
1813+
int generic_depth = 1;
1814+
size_t generic_end = generic_start + 1;
1815+
1816+
while (generic_end < demangled_name.size() && generic_depth > 0) {
1817+
if (demangled_name[generic_end] == '<')
1818+
generic_depth++;
1819+
else if (demangled_name[generic_end] == '>')
1820+
generic_depth--;
1821+
generic_end++;
1822+
}
1823+
1824+
if (generic_depth != 0)
1825+
return {};
1826+
1827+
return demangled_name.substr(generic_start, generic_end - generic_start);
17991828
}
18001829

18011830
std::string SwiftLanguage::GetFunctionDisplayArgs(
18021831
const SymbolContext &sc, VariableList &args,
18031832
const lldb_private::ExecutionContext *exe_ctx) {
18041833
ExecutionContextScope *exe_scope =
18051834
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1806-
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1807-
sc.function->GetMangled().GetMangledName().GetStringRef(),
1808-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1835+
std::string name = GetDemangledFunctionName(sc, exe_ctx);
18091836
lldb_private::StreamString s;
18101837
const char *cstr = name.data();
18111838
const char *open_paren = strchr(cstr, '(');
18121839
const char *close_paren = nullptr;
1813-
const char *generic = strchr(cstr, '<');
1814-
// If before the arguments list begins there is a template sign
1815-
// then scan to the end of the generic args before you try to find
1816-
// the arguments list.
1817-
const char *generic_start = generic;
1818-
if (generic && open_paren && generic < open_paren) {
1819-
int generic_depth = 1;
1820-
++generic;
1821-
for (; *generic && generic_depth > 0; generic++) {
1822-
if (*generic == '<')
1823-
generic_depth++;
1824-
if (*generic == '>')
1825-
generic_depth--;
1826-
}
1827-
if (*generic)
1828-
open_paren = strchr(generic, '(');
1829-
else
1830-
open_paren = nullptr;
1831-
}
18321840
if (open_paren) {
18331841
close_paren = strchr(open_paren, ')');
18341842
}
18351843

1836-
if (generic_start && generic_start < open_paren)
1837-
s.Write(generic_start, open_paren - generic_start);
18381844
s.PutChar('(');
18391845

18401846
const size_t num_args = args.GetSize();
@@ -1940,7 +1946,7 @@ GetAndValidateInfo(const SymbolContext &sc) {
19401946
// Function without a basename is nonsense.
19411947
if (!info->hasBasename())
19421948
return llvm::createStringError(
1943-
"DemangledInfo for '%s does not have basename range.",
1949+
"The demangled name for '%s does not have basename range.",
19441950
demangled_name.data());
19451951

19461952
return std::make_pair(demangled_name, *info);
@@ -1958,6 +1964,23 @@ GetDemangledBasename(const SymbolContext &sc) {
19581964
info.BasenameRange.second);
19591965
}
19601966

1967+
static llvm::Expected<llvm::StringRef>
1968+
GetDemangledNameQualifiers(const SymbolContext &sc) {
1969+
auto info_or_err = GetAndValidateInfo(sc);
1970+
if (!info_or_err)
1971+
return info_or_err.takeError();
1972+
1973+
auto [demangled_name, info] = *info_or_err;
1974+
1975+
if (!info.hasPrefix())
1976+
return llvm::createStringError(
1977+
"The demangled name for '%s does not have a name qualifiers range.",
1978+
demangled_name.data());
1979+
1980+
return demangled_name.slice(info.NameQualifiersRange.first,
1981+
info.NameQualifiersRange.second);
1982+
}
1983+
19611984
static llvm::Expected<llvm::StringRef>
19621985
GetDemangledFunctionPrefix(const SymbolContext &sc) {
19631986
auto info_or_err = GetAndValidateInfo(sc);
@@ -1968,7 +1991,7 @@ GetDemangledFunctionPrefix(const SymbolContext &sc) {
19681991

19691992
if (!info.hasPrefix())
19701993
return llvm::createStringError(
1971-
"DemangledInfo for '%s does not have suffix range.",
1994+
"The demangled name for '%s does not have a prefix range.",
19721995
demangled_name.data());
19731996

19741997
return demangled_name.slice(info.PrefixRange.first, info.PrefixRange.second);
@@ -1984,7 +2007,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
19842007

19852008
if (!info.hasSuffix())
19862009
return llvm::createStringError(
1987-
"DemangledInfo for '%s does not have suffix range.",
2010+
"The demangled name for '%s does not have a suffix range.",
19882011
demangled_name.data());
19892012

19902013
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
@@ -2039,6 +2062,24 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20392062

20402063
return true;
20412064
}
2065+
case FormatEntity::Entry::Type::FunctionNameQualifiers: {
2066+
auto qualifiers_or_err = GetDemangledNameQualifiers(sc);
2067+
if (!qualifiers_or_err) {
2068+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), qualifiers_or_err.takeError(),
2069+
"Failed to handle ${{function.name-qualifiers}} "
2070+
"frame-format variable: {0}");
2071+
return false;
2072+
}
2073+
2074+
s << *qualifiers_or_err;
2075+
2076+
return true;
2077+
}
2078+
case FormatEntity::Entry::Type::FunctionTemplateArguments: {
2079+
s << GetFunctionTemplateArguments(sc, exe_ctx);
2080+
2081+
return true;
2082+
}
20422083
case FormatEntity::Entry::Type::FunctionFormattedArguments: {
20432084
// This ensures we print the arguments even when no debug-info is available.
20442085
//
@@ -2047,9 +2088,7 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20472088
// once we have a "fallback operator" in the frame-format language.
20482089
if (!sc.function && sc.symbol)
20492090
return PrintDemangledArgumentList(s, sc);
2050-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
2051-
sc.function->GetMangled().GetMangledName().GetStringRef(),
2052-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
2091+
std::string display_name = GetDemangledFunctionName(sc, exe_ctx);
20532092
if (display_name.empty())
20542093
return false;
20552094

@@ -2089,7 +2128,6 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20892128
}
20902129

20912130
case FormatEntity::Entry::Type::FunctionScope:
2092-
case FormatEntity::Entry::Type::FunctionTemplateArguments:
20932131
case FormatEntity::Entry::Type::FunctionReturnRight:
20942132
case FormatEntity::Entry::Type::FunctionReturnLeft:
20952133
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
@@ -27,6 +27,7 @@ class TrackingNodePrinter : public NodePrinter {
2727
private:
2828
lldb_private::DemangledNameInfo info;
2929
std::optional<unsigned> parametersDepth;
30+
std::optional<unsigned> genericsSignatureDepth;
3031

3132
void startName() {
3233
if (!info.hasBasename())
@@ -38,6 +39,25 @@ class TrackingNodePrinter : public NodePrinter {
3839
info.BasenameRange.second = getStreamLength();
3940
}
4041

42+
void startGenericSignature(unsigned depth) {
43+
if (genericsSignatureDepth || !info.hasBasename() ||
44+
info.TemplateArgumentsRange.first <
45+
info.TemplateArgumentsRange.second) {
46+
return;
47+
}
48+
info.TemplateArgumentsRange.first = getStreamLength();
49+
genericsSignatureDepth = depth;
50+
}
51+
52+
void endGenericSignature(unsigned depth) {
53+
if (!genericsSignatureDepth || *genericsSignatureDepth != depth ||
54+
info.TemplateArgumentsRange.first <
55+
info.TemplateArgumentsRange.second) {
56+
return;
57+
}
58+
info.TemplateArgumentsRange.second = getStreamLength();
59+
}
60+
4161
void startParameters(unsigned depth) {
4262
if (parametersDepth || !info.hasBasename() ||
4363
info.ArgumentsRange.first < info.ArgumentsRange.second) {
@@ -79,6 +99,12 @@ class TrackingNodePrinter : public NodePrinter {
7999
endName();
80100
}
81101

102+
void printGenericSignature(NodePointer Node, unsigned depth) override {
103+
startGenericSignature(depth);
104+
NodePrinter::printGenericSignature(Node, depth);
105+
endGenericSignature(depth);
106+
}
107+
82108
void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType,
83109
unsigned depth, bool showTypes) override {
84110
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
@@ -33,6 +33,6 @@ def do_backtrace(self, arg):
3333
".sleep(",
3434
"`second() at main.swift:6",
3535
"`first() at main.swift:2",
36-
"`closure #1() at main.swift:12:19",
36+
"`closure #1 in static Main.main() at main.swift:12:19",
3737
],
3838
)

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

lldb/test/API/lang/swift/async/unwind/hidden_frames/TestSwiftAsyncHiddenFrames.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import lldbsuite.test.lldbutil as lldbutil
55

66

7-
@skipIf(bugnumber="rdar://156178892")
87
class TestSwiftAsyncHiddenFrames(lldbtest.TestBase):
98

109
NO_DEBUG_INFO_TESTCASE = True

0 commit comments

Comments
 (0)