Skip to content

Commit e287d31

Browse files
Merge pull request #11033 from charles-zablit/charles-zablit/lldb/swift-mangling-to-next
[lldb] add function name syntax highlighting in Swift backtraces This is a squash of the following commits: *- 1fa228c *- c9147b4 *- d8c0194 *- b10654b *- 315d438 *- d97d61a *- 715cfde *- 4b848aa *- bf50a87 *- 3a7d06c *- b392009 *- 9abe314 *- 5390223 *- 6e01f7e *- 7658032 *- 7ee1b24 *- cf9b14c
2 parents db3d7a7 + d9d5033 commit e287d31

File tree

10 files changed

+1593
-56
lines changed

10 files changed

+1593
-56
lines changed

lldb/include/lldb/Core/Mangled.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ class Mangled {
3939
ePreferDemangledWithoutArguments
4040
};
4141

42+
enum NameFormatPreference {
43+
eCompactName,
44+
eFullName,
45+
};
46+
4247
enum ManglingScheme {
4348
eManglingSchemeNone = 0,
4449
eManglingSchemeMSVC,
@@ -125,7 +130,9 @@ class Mangled {
125130
///
126131
/// \return
127132
/// A const reference to the demangled name string object.
128-
ConstString GetDemangledName(const SymbolContext *sc = nullptr) const;
133+
ConstString
134+
GetDemangledName(const SymbolContext *sc = nullptr,
135+
NameFormatPreference preference = eFullName) const;
129136

130137
/// Display demangled name get accessor.
131138
///
@@ -291,7 +298,9 @@ class Mangled {
291298
/// demangled name (if any). If \c force is \c true (or the mangled name
292299
/// on this object was not previously demangled), demangle and cache the
293300
/// name.
294-
ConstString GetDemangledNameImpl(bool force, const SymbolContext *sc = nullptr) const;
301+
ConstString
302+
GetDemangledNameImpl(bool force, const SymbolContext *sc = nullptr,
303+
NameFormatPreference preference = eFullName) const;
295304

296305
/// The mangled version of the name.
297306
ConstString m_mangled;

lldb/source/Core/Mangled.cpp

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,53 @@ void Mangled::SetValue(ConstString name) {
148148
}
149149
}
150150

151+
// BEGIN SWIFT
152+
#ifdef LLDB_ENABLE_SWIFT
153+
std::pair<ConstString, DemangledNameInfo>
154+
GetSwiftDemangledStr(ConstString m_mangled, const SymbolContext *sc,
155+
ConstString &m_demangled,
156+
Mangled::NameFormatPreference preference) {
157+
const char *mangled_name = m_mangled.AsCString("");
158+
Log *log = GetLog(LLDBLog::Demangle);
159+
LLDB_LOGF(log, "demangle swift: %s", mangled_name);
160+
SwiftLanguageRuntime::DemangleMode demangle_mode;
161+
switch (preference) {
162+
case Mangled::eFullName:
163+
demangle_mode = SwiftLanguageRuntime::DemangleMode::eTypeName;
164+
break;
165+
case Mangled::eCompactName:
166+
demangle_mode = SwiftLanguageRuntime::DemangleMode::eSimplified;
167+
break;
168+
}
169+
auto [demangled, info] = SwiftLanguageRuntime::TrackedDemangleSymbolAsString(
170+
mangled_name, demangle_mode, sc);
171+
info.PrefixRange.second =
172+
std::min(info.BasenameRange.first, info.ArgumentsRange.first);
173+
info.SuffixRange.first =
174+
std::max(info.BasenameRange.second, info.ArgumentsRange.second);
175+
info.SuffixRange.second = demangled.length();
176+
177+
// Don't cache the demangled name if the function isn't available yet.
178+
// Only cache eFullName demangled functions to keep the cache consistent.
179+
if (!sc || !sc->function ||
180+
preference == Mangled::NameFormatPreference::eCompactName) {
181+
LLDB_LOGF(log, "demangle swift: %s -> \"%s\" (not cached)", mangled_name,
182+
demangled.c_str());
183+
return std::make_pair(ConstString(demangled), info);
184+
}
185+
if (demangled.empty()) {
186+
LLDB_LOGF(log, "demangle swift: %s -> error: failed to demangle",
187+
mangled_name);
188+
} else {
189+
LLDB_LOGF(log, "demangle swift: %s -> \"%s\"", mangled_name,
190+
demangled.c_str());
191+
m_demangled.SetStringWithMangledCounterpart(demangled, m_mangled);
192+
}
193+
return std::make_pair(m_demangled, info);
194+
}
195+
#endif // LLDB_ENABLE_SWIFT
196+
// END SWIFT
197+
151198
// Local helpers for different demangling implementations.
152199
static char *GetMSVCDemangledStr(llvm::StringRef M) {
153200
char *demangled_cstr = llvm::microsoftDemangle(
@@ -292,12 +339,11 @@ bool Mangled::GetRichManglingInfo(RichManglingContext &context,
292339
llvm_unreachable("Fully covered switch above!");
293340
}
294341

295-
ConstString Mangled::GetDemangledName(
296-
// BEGIN SWIFT
297-
const SymbolContext *sc
342+
ConstString Mangled::GetDemangledName( // BEGIN SWIFT
343+
const SymbolContext *sc, NameFormatPreference preference
298344
// END SWIFT
299345
) const {
300-
return GetDemangledNameImpl(/*force=*/false, sc);
346+
return GetDemangledNameImpl(/*force=*/false, sc, preference);
301347
}
302348

303349
std::optional<DemangledNameInfo> const &Mangled::GetDemangledInfo() const {
@@ -311,11 +357,10 @@ std::optional<DemangledNameInfo> const &Mangled::GetDemangledInfo() const {
311357
// class will need to use this accessor if it wishes to decode the demangled
312358
// name. The result is cached and will be kept until a new string value is
313359
// supplied to this object, or until the end of the object's lifetime.
314-
ConstString Mangled::GetDemangledNameImpl(
315-
bool force
316-
// BEGIN SWIFT
317-
, const SymbolContext *sc
318-
// END SWIFT
360+
ConstString Mangled::GetDemangledNameImpl(bool force, // BEGIN SWIFT
361+
const SymbolContext *sc,
362+
NameFormatPreference preference
363+
// END SWIFT
319364
) const {
320365
if (!m_mangled)
321366
return m_demangled;
@@ -353,26 +398,10 @@ ConstString Mangled::GetDemangledNameImpl(
353398
// explicitly unsupported on llvm.org.
354399
#ifdef LLDB_ENABLE_SWIFT
355400
{
356-
const char *mangled_name = m_mangled.GetCString();
357-
Log *log = GetLog(LLDBLog::Demangle);
358-
LLDB_LOGF(log, "demangle swift: %s", mangled_name);
359-
std::string demangled(SwiftLanguageRuntime::DemangleSymbolAsString(
360-
mangled_name, SwiftLanguageRuntime::eTypeName, sc));
361-
// Don't cache the demangled name the function isn't available yet.
362-
if (!sc || !sc->function) {
363-
LLDB_LOGF(log, "demangle swift: %s -> \"%s\" (not cached)", mangled_name,
364-
demangled.c_str());
365-
return ConstString(demangled);
366-
}
367-
if (demangled.empty()) {
368-
LLDB_LOGF(log, "demangle swift: %s -> error: failed to demangle",
369-
mangled_name);
370-
} else {
371-
LLDB_LOGF(log, "demangle swift: %s -> \"%s\"", mangled_name,
372-
demangled.c_str());
373-
m_demangled.SetStringWithMangledCounterpart(demangled, m_mangled);
374-
}
375-
return m_demangled;
401+
auto demangled =
402+
GetSwiftDemangledStr(m_mangled, sc, m_demangled, preference);
403+
m_demangled_info.emplace(std::move(demangled.second));
404+
return demangled.first;
376405
}
377406
#endif // LLDB_ENABLE_SWIFT
378407
break;

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

Lines changed: 102 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,23 +1912,96 @@ SwiftLanguage::GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
19121912
return mangled_name;
19131913
}
19141914

1915-
static std::optional<llvm::StringRef>
1915+
static llvm::Expected<std::pair<llvm::StringRef, DemangledNameInfo>>
1916+
GetAndValidateInfo(const SymbolContext &sc) {
1917+
Mangled mangled = sc.GetPossiblyInlinedFunctionName();
1918+
if (!mangled)
1919+
return llvm::createStringError("Function does not have a mangled name.");
1920+
1921+
auto demangled_name =
1922+
mangled.GetDemangledName(nullptr, Mangled::eCompactName).GetStringRef();
1923+
if (demangled_name.empty())
1924+
return llvm::createStringError(
1925+
"Function '%s' does not have a demangled name.",
1926+
mangled.GetMangledName().AsCString(""));
1927+
1928+
const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
1929+
if (!info)
1930+
return llvm::createStringError(
1931+
"Function '%s' does not have demangled info.", demangled_name.data());
1932+
1933+
// Function without a basename is nonsense.
1934+
if (!info->hasBasename())
1935+
return llvm::createStringError(
1936+
"DemangledInfo for '%s does not have basename range.",
1937+
demangled_name.data());
1938+
1939+
return std::make_pair(demangled_name, *info);
1940+
}
1941+
1942+
static llvm::Expected<llvm::StringRef>
19161943
GetDemangledBasename(const SymbolContext &sc) {
1917-
return std::nullopt;
1944+
auto info_or_err = GetAndValidateInfo(sc);
1945+
if (!info_or_err)
1946+
return info_or_err.takeError();
1947+
1948+
auto [demangled_name, info] = *info_or_err;
1949+
1950+
return demangled_name.slice(info.BasenameRange.first,
1951+
info.BasenameRange.second);
19181952
}
19191953

1920-
static std::optional<llvm::StringRef>
1954+
static llvm::Expected<llvm::StringRef>
19211955
GetDemangledFunctionPrefix(const SymbolContext &sc) {
1922-
return std::nullopt;
1956+
auto info_or_err = GetAndValidateInfo(sc);
1957+
if (!info_or_err)
1958+
return info_or_err.takeError();
1959+
1960+
auto [demangled_name, info] = *info_or_err;
1961+
1962+
if (!info.hasPrefix())
1963+
return llvm::createStringError(
1964+
"DemangledInfo for '%s does not have suffix range.",
1965+
demangled_name.data());
1966+
1967+
return demangled_name.slice(info.PrefixRange.first, info.PrefixRange.second);
19231968
}
19241969

1925-
static std::optional<llvm::StringRef>
1970+
static llvm::Expected<llvm::StringRef>
19261971
GetDemangledFunctionSuffix(const SymbolContext &sc) {
1927-
return std::nullopt;
1972+
auto info_or_err = GetAndValidateInfo(sc);
1973+
if (!info_or_err)
1974+
return info_or_err.takeError();
1975+
1976+
auto [demangled_name, info] = *info_or_err;
1977+
1978+
if (!info.hasSuffix())
1979+
return llvm::createStringError(
1980+
"DemangledInfo for '%s does not have suffix range.",
1981+
demangled_name.data());
1982+
1983+
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
19281984
}
19291985

19301986
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
1931-
return false;
1987+
assert(sc.symbol);
1988+
1989+
auto info_or_err = GetAndValidateInfo(sc);
1990+
if (!info_or_err) {
1991+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), info_or_err.takeError(),
1992+
"Failed to handle ${{function.formatted-arguments}} "
1993+
"frame-format variable: {0}");
1994+
return false;
1995+
}
1996+
auto [demangled_name, info] = *info_or_err;
1997+
1998+
if (!info.hasArguments())
1999+
return false;
2000+
2001+
s << demangled_name.slice(info.ArgumentsRange.first,
2002+
info.ArgumentsRange.second);
2003+
2004+
return true;
19322005
}
19332006

19342007
static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
@@ -1947,11 +2020,15 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
19472020
Stream &s) {
19482021
switch (type) {
19492022
case FormatEntity::Entry::Type::FunctionBasename: {
1950-
std::optional<llvm::StringRef> name = GetDemangledBasename(sc);
1951-
if (!name)
2023+
auto name_or_err = GetDemangledBasename(sc);
2024+
if (!name_or_err) {
2025+
LLDB_LOG_ERROR(
2026+
GetLog(LLDBLog::Language), name_or_err.takeError(),
2027+
"Failed to handle ${{function.basename}} frame-format variable: {0}");
19522028
return false;
2029+
}
19532030

1954-
s << *name;
2031+
s << *name_or_err;
19552032

19562033
return true;
19572034
}
@@ -1978,20 +2055,28 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
19782055
return true;
19792056
}
19802057
case FormatEntity::Entry::Type::FunctionPrefix: {
1981-
std::optional<llvm::StringRef> prefix = GetDemangledFunctionPrefix(sc);
1982-
if (!prefix)
2058+
auto prefix_or_err = GetDemangledFunctionPrefix(sc);
2059+
if (!prefix_or_err) {
2060+
LLDB_LOG_ERROR(
2061+
GetLog(LLDBLog::Language), prefix_or_err.takeError(),
2062+
"Failed to handle ${{function.prefix}} frame-format variable: {0}");
19832063
return false;
2064+
}
19842065

1985-
s << *prefix;
2066+
s << *prefix_or_err;
19862067

19872068
return true;
19882069
}
19892070
case FormatEntity::Entry::Type::FunctionSuffix: {
1990-
std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc);
1991-
if (!suffix)
2071+
auto suffix_or_err = GetDemangledFunctionSuffix(sc);
2072+
if (!suffix_or_err) {
2073+
LLDB_LOG_ERROR(
2074+
GetLog(LLDBLog::Language), suffix_or_err.takeError(),
2075+
"Failed to handle ${{function.suffix}} frame-format variable: {0}");
19922076
return false;
2077+
}
19932078

1994-
s << *suffix;
2079+
s << *suffix_or_err;
19952080

19962081
return true;
19972082
}
@@ -2025,7 +2110,7 @@ class PluginProperties : public Properties {
20252110
}
20262111

20272112
FormatEntity::Entry GetFunctionNameFormat() const {
2028-
return GetPropertyAtIndexAs<const FormatEntity::Entry>(
2113+
return GetPropertyAtIndexAs<FormatEntity::Entry>(
20292114
ePropertyFunctionNameFormat, {});
20302115
}
20312116
};

0 commit comments

Comments
 (0)