Skip to content

Commit 43f85c3

Browse files
[lldb] add Template Arguments format entity
1 parent be916fe commit 43f85c3

File tree

9 files changed

+1004
-472
lines changed

9 files changed

+1004
-472
lines changed

lldb/include/lldb/Core/DemangledNameInfo.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ struct DemangledNameInfo {
3030
/// \endcode
3131
std::pair<size_t, size_t> BasenameRange;
3232

33+
/// A [start, end) pair for the function template arguments.
34+
/// The basename is the name without scope qualifiers
35+
/// and without template parameters. E.g.,
36+
/// \code{.cpp}
37+
/// void foo::bar<int>::someFunc<float>(int) const &&
38+
/// ^ ^
39+
/// start end
40+
/// \endcode
41+
std::pair<size_t, size_t> TemplateRange;
42+
3343
/// A [start, end) pair for the function scope qualifiers.
3444
/// E.g., for
3545
/// \code{.cpp}
@@ -80,6 +90,11 @@ struct DemangledNameInfo {
8090
return BasenameRange.second > BasenameRange.first;
8191
}
8292

93+
/// Returns \c true if this object holds a valid template range.
94+
bool hasTemplate() const {
95+
return TemplateRange.second >= TemplateRange.first;
96+
}
97+
8398
/// Returns \c true if this object holds a valid scope range.
8499
bool hasScope() const { return ScopeRange.second >= ScopeRange.first; }
85100

lldb/source/Core/Mangled.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,15 @@ GetSwiftDemangledStr(ConstString m_mangled, const SymbolContext *sc,
173173
info.SuffixRange.first =
174174
std::max(info.BasenameRange.second, info.ArgumentsRange.second);
175175
info.SuffixRange.second = demangled.length();
176+
if (info.hasBasename() && info.hasArguments()) {
177+
if (info.hasTemplate()) {
178+
info.NameQualifiersRange.second =
179+
std::min(info.ArgumentsRange.first, info.TemplateRange.first);
180+
} else {
181+
info.NameQualifiersRange.second = info.ArgumentsRange.first;
182+
}
183+
info.NameQualifiersRange.first = info.BasenameRange.second;
184+
}
176185

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

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,6 +1953,20 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
19531953
return true;
19541954
}
19551955

1956+
case FormatEntity::Entry::Type::FunctionNameQualifiers: {
1957+
auto name_or_err = GetDemangledBasename(sc);
1958+
if (!name_or_err) {
1959+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), name_or_err.takeError(),
1960+
"Failed to handle ${{function.name-qualifiers}} "
1961+
"frame-format variable: {0}");
1962+
return false;
1963+
}
1964+
1965+
s << *name_or_err;
1966+
1967+
return true;
1968+
}
1969+
19561970
case FormatEntity::Entry::Type::FunctionTemplateArguments: {
19571971
auto template_args_or_err = GetDemangledTemplateArguments(sc);
19581972
if (!template_args_or_err) {

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 & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,13 +1718,7 @@ bool SwiftLanguage::GetFunctionDisplayName(
17181718
// No need to customize this.
17191719
return false;
17201720
case Language::FunctionNameRepresentation::eNameWithNoArgs: {
1721-
if (!sc.function)
1722-
return false;
1723-
if (sc.function->GetLanguage() != eLanguageTypeSwift)
1724-
return false;
1725-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
1726-
sc.function->GetMangled().GetMangledName().GetStringRef(),
1727-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1721+
std::string display_name = GetDemangledFunctionName(sc, exe_ctx);
17281722
if (display_name.empty())
17291723
return false;
17301724
s << display_name;
@@ -1759,69 +1753,82 @@ bool SwiftLanguage::GetFunctionDisplayName(
17591753
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
17601754
args);
17611755

1756+
s << GetFunctionTemplateArguments(sc, exe_ctx);
17621757
s << GetFunctionDisplayArgs(sc, args, exe_ctx);
17631758
return true;
17641759
}
17651760
}
17661761
return false;
17671762
}
17681763

1769-
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1770-
const ExecutionContext *exe_ctx) {
1764+
std::string
1765+
SwiftLanguage::GetDemangledFunctionName(const SymbolContext &sc,
1766+
const ExecutionContext *exe_ctx) {
17711767
if (!sc.function)
17721768
return {};
17731769
if (sc.function->GetLanguage() != eLanguageTypeSwift)
17741770
return {};
1775-
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1771+
return SwiftLanguageRuntime::DemangleSymbolAsString(
17761772
sc.GetPossiblyInlinedFunctionName().GetMangledName(),
17771773
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1778-
if (name.empty())
1774+
}
1775+
1776+
std::string SwiftLanguage::GetFunctionName(const SymbolContext &sc,
1777+
const ExecutionContext *exe_ctx) {
1778+
std::string demangled_name = GetDemangledFunctionName(sc, exe_ctx);
1779+
if (demangled_name.empty())
17791780
return {};
1780-
size_t open_paren = name.find('(');
1781-
size_t generic = name.find('<');
1781+
size_t open_paren = demangled_name.find('(');
1782+
size_t generic = demangled_name.find('<');
17821783
size_t name_end = std::min(open_paren, generic);
17831784
if (name_end == std::string::npos)
1784-
return name;
1785-
return name.substr(0, name_end);
1785+
return demangled_name;
1786+
return demangled_name.substr(0, name_end);
1787+
}
1788+
1789+
std::string
1790+
SwiftLanguage::GetFunctionTemplateArguments(const SymbolContext &sc,
1791+
const ExecutionContext *exe_ctx) {
1792+
std::string demangled_name = GetDemangledFunctionName(sc, exe_ctx);
1793+
if (demangled_name.empty())
1794+
return {};
1795+
size_t open_paren = demangled_name.find('(');
1796+
size_t generic_start = demangled_name.find('<');
1797+
if (generic_start == std::string::npos || generic_start > open_paren)
1798+
return {};
1799+
1800+
int generic_depth = 1;
1801+
size_t generic_end = generic_start + 1;
1802+
1803+
while (generic_end < demangled_name.size() && generic_depth > 0) {
1804+
if (demangled_name[generic_end] == '<') {
1805+
generic_depth++;
1806+
} else if (demangled_name[generic_end] == '>') {
1807+
generic_depth--;
1808+
}
1809+
generic_end++;
1810+
}
1811+
1812+
if (generic_depth != 0)
1813+
return {};
1814+
1815+
return demangled_name.substr(generic_start, generic_end - generic_start);
17861816
}
17871817

17881818
std::string SwiftLanguage::GetFunctionDisplayArgs(
17891819
const SymbolContext &sc, VariableList &args,
17901820
const lldb_private::ExecutionContext *exe_ctx) {
17911821
ExecutionContextScope *exe_scope =
17921822
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
1793-
std::string name = SwiftLanguageRuntime::DemangleSymbolAsString(
1794-
sc.function->GetMangled().GetMangledName().GetStringRef(),
1795-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1823+
std::string name = GetDemangledFunctionName(sc, exe_ctx);
17961824
lldb_private::StreamString s;
17971825
const char *cstr = name.data();
17981826
const char *open_paren = strchr(cstr, '(');
17991827
const char *close_paren = nullptr;
1800-
const char *generic = strchr(cstr, '<');
1801-
// If before the arguments list begins there is a template sign
1802-
// then scan to the end of the generic args before you try to find
1803-
// the arguments list.
1804-
const char *generic_start = generic;
1805-
if (generic && open_paren && generic < open_paren) {
1806-
int generic_depth = 1;
1807-
++generic;
1808-
for (; *generic && generic_depth > 0; generic++) {
1809-
if (*generic == '<')
1810-
generic_depth++;
1811-
if (*generic == '>')
1812-
generic_depth--;
1813-
}
1814-
if (*generic)
1815-
open_paren = strchr(generic, '(');
1816-
else
1817-
open_paren = nullptr;
1818-
}
18191828
if (open_paren) {
18201829
close_paren = strchr(open_paren, ')');
18211830
}
18221831

1823-
if (generic_start && generic_start < open_paren)
1824-
s.Write(generic_start, open_paren - generic_start);
18251832
s.PutChar('(');
18261833

18271834
const size_t num_args = args.GetSize();
@@ -1945,6 +1952,23 @@ GetDemangledBasename(const SymbolContext &sc) {
19451952
info.BasenameRange.second);
19461953
}
19471954

1955+
static llvm::Expected<llvm::StringRef>
1956+
GetDemangledNameQualifiers(const SymbolContext &sc) {
1957+
auto info_or_err = GetAndValidateInfo(sc);
1958+
if (!info_or_err)
1959+
return info_or_err.takeError();
1960+
1961+
auto [demangled_name, info] = *info_or_err;
1962+
1963+
if (!info.hasPrefix())
1964+
return llvm::createStringError(
1965+
"DemangledInfo for '%s does not have a name qualifiers range.",
1966+
demangled_name.data());
1967+
1968+
return demangled_name.slice(info.NameQualifiersRange.first,
1969+
info.NameQualifiersRange.second);
1970+
}
1971+
19481972
static llvm::Expected<llvm::StringRef>
19491973
GetDemangledFunctionPrefix(const SymbolContext &sc) {
19501974
auto info_or_err = GetAndValidateInfo(sc);
@@ -1955,7 +1979,7 @@ GetDemangledFunctionPrefix(const SymbolContext &sc) {
19551979

19561980
if (!info.hasPrefix())
19571981
return llvm::createStringError(
1958-
"DemangledInfo for '%s does not have suffix range.",
1982+
"DemangledInfo for '%s does not have a prefix range.",
19591983
demangled_name.data());
19601984

19611985
return demangled_name.slice(info.PrefixRange.first, info.PrefixRange.second);
@@ -1971,7 +1995,7 @@ GetDemangledFunctionSuffix(const SymbolContext &sc) {
19711995

19721996
if (!info.hasSuffix())
19731997
return llvm::createStringError(
1974-
"DemangledInfo for '%s does not have suffix range.",
1998+
"DemangledInfo for '%s does not have a suffix range.",
19751999
demangled_name.data());
19762000

19772001
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
@@ -2026,6 +2050,24 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20262050

20272051
return true;
20282052
}
2053+
case FormatEntity::Entry::Type::FunctionNameQualifiers: {
2054+
auto qualifiers_or_err = GetDemangledNameQualifiers(sc);
2055+
if (!qualifiers_or_err) {
2056+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), qualifiers_or_err.takeError(),
2057+
"Failed to handle ${{function.name-qualifiers}} "
2058+
"frame-format variable: {0}");
2059+
return false;
2060+
}
2061+
2062+
s << *qualifiers_or_err;
2063+
2064+
return true;
2065+
}
2066+
case FormatEntity::Entry::Type::FunctionTemplateArguments: {
2067+
s << GetFunctionTemplateArguments(sc, exe_ctx);
2068+
2069+
return true;
2070+
}
20292071
case FormatEntity::Entry::Type::FunctionFormattedArguments: {
20302072
// This ensures we print the arguments even when no debug-info is available.
20312073
//
@@ -2034,9 +2076,7 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20342076
// once we have a "fallback operator" in the frame-format language.
20352077
if (!sc.function && sc.symbol)
20362078
return PrintDemangledArgumentList(s, sc);
2037-
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
2038-
sc.function->GetMangled().GetMangledName().GetStringRef(),
2039-
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
2079+
std::string display_name = GetDemangledFunctionName(sc, exe_ctx);
20402080
if (display_name.empty())
20412081
return false;
20422082

@@ -2076,7 +2116,6 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
20762116
}
20772117

20782118
case FormatEntity::Entry::Type::FunctionScope:
2079-
case FormatEntity::Entry::Type::FunctionTemplateArguments:
20802119
case FormatEntity::Entry::Type::FunctionReturnRight:
20812120
case FormatEntity::Entry::Type::FunctionReturnLeft:
20822121
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: 24 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,23 @@ class TrackingNodePrinter : public NodePrinter {
4344
info.BasenameRange.second = getStreamLength();
4445
}
4546

47+
void startGenericSignature(unsigned depth) {
48+
if (genericsSignatureDepth || !info.hasBasename() ||
49+
info.TemplateRange.first < info.TemplateRange.second) {
50+
return;
51+
}
52+
info.TemplateRange.first = getStreamLength();
53+
genericsSignatureDepth = depth;
54+
}
55+
56+
void endGenericSignature(unsigned depth) {
57+
if (!genericsSignatureDepth || *genericsSignatureDepth != depth ||
58+
info.TemplateRange.first < info.TemplateRange.second) {
59+
return;
60+
}
61+
info.TemplateRange.second = getStreamLength();
62+
}
63+
4664
void startParameters(unsigned depth) {
4765
if (parametersDepth || !info.hasBasename() ||
4866
info.ArgumentsRange.first < info.ArgumentsRange.second) {
@@ -85,6 +103,12 @@ class TrackingNodePrinter : public NodePrinter {
85103
endName();
86104
}
87105

106+
void printGenericSignature(NodePointer Node, unsigned depth) override {
107+
startGenericSignature(depth);
108+
NodePrinter::printGenericSignature(Node, depth);
109+
endGenericSignature(depth);
110+
}
111+
88112
void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType,
89113
unsigned depth, bool showTypes) override {
90114
startParameters(depth);

0 commit comments

Comments
 (0)