Skip to content

Commit 9158498

Browse files
authored
Merge pull request #10710 from charles-zablit/charles-zablit/lldb/swift-mangling
[Syntax Highlighting] Add name and parameters syntax highlighting in Swift backtraces
2 parents dfc8ed9 + cf9b14c commit 9158498

File tree

10 files changed

+1590
-51
lines changed

10 files changed

+1590
-51
lines changed

lldb/include/lldb/Core/Mangled.h

Lines changed: 11 additions & 3 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,
@@ -127,7 +132,9 @@ class Mangled {
127132
///
128133
/// \return
129134
/// A const reference to the demangled name string object.
130-
ConstString GetDemangledName(const SymbolContext *sc = nullptr) const;
135+
ConstString
136+
GetDemangledName(const SymbolContext *sc = nullptr,
137+
NameFormatPreference preference = eFullName) const;
131138

132139
/// Display demangled name get accessor.
133140
///
@@ -291,8 +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,
295-
const SymbolContext *sc = nullptr) const;
301+
ConstString
302+
GetDemangledNameImpl(bool force, const SymbolContext *sc = nullptr,
303+
NameFormatPreference preference = eFullName) const;
296304

297305
/// The mangled version of the name.
298306
ConstString m_mangled;

lldb/source/Core/Mangled.cpp

Lines changed: 55 additions & 23 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(
@@ -293,10 +340,10 @@ bool Mangled::GetRichManglingInfo(RichManglingContext &context,
293340
}
294341

295342
ConstString Mangled::GetDemangledName( // BEGIN SWIFT
296-
const SymbolContext *sc
343+
const SymbolContext *sc, NameFormatPreference preference
297344
// END SWIFT
298345
) const {
299-
return GetDemangledNameImpl(/*force=*/false, sc);
346+
return GetDemangledNameImpl(/*force=*/false, sc, preference);
300347
}
301348

302349
std::optional<DemangledNameInfo> const &Mangled::GetDemangledInfo() const {
@@ -311,7 +358,8 @@ std::optional<DemangledNameInfo> const &Mangled::GetDemangledInfo() const {
311358
// name. The result is cached and will be kept until a new string value is
312359
// supplied to this object, or until the end of the object's lifetime.
313360
ConstString Mangled::GetDemangledNameImpl(bool force, // BEGIN SWIFT
314-
const SymbolContext *sc
361+
const SymbolContext *sc,
362+
NameFormatPreference preference
315363
// END SWIFT
316364
) const {
317365
if (!m_mangled)
@@ -350,26 +398,10 @@ ConstString Mangled::GetDemangledNameImpl(bool force, // BEGIN SWIFT
350398
// explicitly unsupported on llvm.org.
351399
#ifdef LLDB_ENABLE_SWIFT
352400
{
353-
const char *mangled_name = m_mangled.GetCString();
354-
Log *log = GetLog(LLDBLog::Demangle);
355-
LLDB_LOGF(log, "demangle swift: %s", mangled_name);
356-
std::string demangled(SwiftLanguageRuntime::DemangleSymbolAsString(
357-
mangled_name, SwiftLanguageRuntime::eTypeName, sc));
358-
// Don't cache the demangled name the function isn't available yet.
359-
if (!sc || !sc->function) {
360-
LLDB_LOGF(log, "demangle swift: %s -> \"%s\" (not cached)", mangled_name,
361-
demangled.c_str());
362-
return ConstString(demangled);
363-
}
364-
if (demangled.empty()) {
365-
LLDB_LOGF(log, "demangle swift: %s -> error: failed to demangle",
366-
mangled_name);
367-
} else {
368-
LLDB_LOGF(log, "demangle swift: %s -> \"%s\"", mangled_name,
369-
demangled.c_str());
370-
m_demangled.SetStringWithMangledCounterpart(demangled, m_mangled);
371-
}
372-
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;
373405
}
374406
#endif // LLDB_ENABLE_SWIFT
375407
break;

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

Lines changed: 102 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,23 +1906,96 @@ SwiftLanguage::GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
19061906
return mangled_name;
19071907
}
19081908

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

1914-
static std::optional<llvm::StringRef>
1948+
static llvm::Expected<llvm::StringRef>
19151949
GetDemangledFunctionPrefix(const SymbolContext &sc) {
1916-
return std::nullopt;
1950+
auto info_or_err = GetAndValidateInfo(sc);
1951+
if (!info_or_err)
1952+
return info_or_err.takeError();
1953+
1954+
auto [demangled_name, info] = *info_or_err;
1955+
1956+
if (!info.hasPrefix())
1957+
return llvm::createStringError(
1958+
"DemangledInfo for '%s does not have suffix range.",
1959+
demangled_name.data());
1960+
1961+
return demangled_name.slice(info.PrefixRange.first, info.PrefixRange.second);
19171962
}
19181963

1919-
static std::optional<llvm::StringRef>
1964+
static llvm::Expected<llvm::StringRef>
19201965
GetDemangledFunctionSuffix(const SymbolContext &sc) {
1921-
return std::nullopt;
1966+
auto info_or_err = GetAndValidateInfo(sc);
1967+
if (!info_or_err)
1968+
return info_or_err.takeError();
1969+
1970+
auto [demangled_name, info] = *info_or_err;
1971+
1972+
if (!info.hasSuffix())
1973+
return llvm::createStringError(
1974+
"DemangledInfo for '%s does not have suffix range.",
1975+
demangled_name.data());
1976+
1977+
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second);
19221978
}
19231979

19241980
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
1925-
return false;
1981+
assert(sc.symbol);
1982+
1983+
auto info_or_err = GetAndValidateInfo(sc);
1984+
if (!info_or_err) {
1985+
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), info_or_err.takeError(),
1986+
"Failed to handle ${{function.formatted-arguments}} "
1987+
"frame-format variable: {0}");
1988+
return false;
1989+
}
1990+
auto [demangled_name, info] = *info_or_err;
1991+
1992+
if (!info.hasArguments())
1993+
return false;
1994+
1995+
s << demangled_name.slice(info.ArgumentsRange.first,
1996+
info.ArgumentsRange.second);
1997+
1998+
return true;
19261999
}
19272000

19282001
static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
@@ -1941,11 +2014,15 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
19412014
Stream &s) {
19422015
switch (type) {
19432016
case FormatEntity::Entry::Type::FunctionBasename: {
1944-
std::optional<llvm::StringRef> name = GetDemangledBasename(sc);
1945-
if (!name)
2017+
auto name_or_err = GetDemangledBasename(sc);
2018+
if (!name_or_err) {
2019+
LLDB_LOG_ERROR(
2020+
GetLog(LLDBLog::Language), name_or_err.takeError(),
2021+
"Failed to handle ${{function.basename}} frame-format variable: {0}");
19462022
return false;
2023+
}
19472024

1948-
s << *name;
2025+
s << *name_or_err;
19492026

19502027
return true;
19512028
}
@@ -1972,20 +2049,28 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
19722049
return true;
19732050
}
19742051
case FormatEntity::Entry::Type::FunctionPrefix: {
1975-
std::optional<llvm::StringRef> prefix = GetDemangledFunctionPrefix(sc);
1976-
if (!prefix)
2052+
auto prefix_or_err = GetDemangledFunctionPrefix(sc);
2053+
if (!prefix_or_err) {
2054+
LLDB_LOG_ERROR(
2055+
GetLog(LLDBLog::Language), prefix_or_err.takeError(),
2056+
"Failed to handle ${{function.prefix}} frame-format variable: {0}");
19772057
return false;
2058+
}
19782059

1979-
s << *prefix;
2060+
s << *prefix_or_err;
19802061

19812062
return true;
19822063
}
19832064
case FormatEntity::Entry::Type::FunctionSuffix: {
1984-
std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc);
1985-
if (!suffix)
2065+
auto suffix_or_err = GetDemangledFunctionSuffix(sc);
2066+
if (!suffix_or_err) {
2067+
LLDB_LOG_ERROR(
2068+
GetLog(LLDBLog::Language), suffix_or_err.takeError(),
2069+
"Failed to handle ${{function.suffix}} frame-format variable: {0}");
19862070
return false;
2071+
}
19872072

1988-
s << *suffix;
2073+
s << *suffix_or_err;
19892074

19902075
return true;
19912076
}
@@ -2019,7 +2104,7 @@ class PluginProperties : public Properties {
20192104
}
20202105

20212106
FormatEntity::Entry GetFunctionNameFormat() const {
2022-
return GetPropertyAtIndexAs<const FormatEntity::Entry>(
2107+
return GetPropertyAtIndexAs<FormatEntity::Entry>(
20232108
ePropertyFunctionNameFormat, {});
20242109
}
20252110
};

0 commit comments

Comments
 (0)