-
Notifications
You must be signed in to change notification settings - Fork 344
[Syntax Highlighting] Add name and parameters syntax highlighting in Swift backtraces #10710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1fa228c
c9147b4
d8c0194
b10654b
315d438
d97d61a
715cfde
4b848aa
bf50a87
3a7d06c
b392009
9abe314
5390223
6e01f7e
7658032
7ee1b24
cf9b14c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1906,23 +1906,96 @@ SwiftLanguage::GetDemangledFunctionNameWithoutArguments(Mangled mangled) const { | |
return mangled_name; | ||
} | ||
|
||
static std::optional<llvm::StringRef> | ||
static llvm::Expected<std::pair<llvm::StringRef, DemangledNameInfo>> | ||
GetAndValidateInfo(const SymbolContext &sc) { | ||
Mangled mangled = sc.GetPossiblyInlinedFunctionName(); | ||
if (!mangled) | ||
return llvm::createStringError("Function does not have a mangled name."); | ||
|
||
auto demangled_name = | ||
mangled.GetDemangledName(nullptr, Mangled::eCompactName).GetStringRef(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I asked this before but why do we need to use Or was it because the backtrace previously always used the compact mode, but in other places around LLDB we use full mode? So to avoid changing the backtrace too much you used compact here too? I think it seems reasonable to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I re-ran the tests just to make sure I got the information right: The backtrace was using Some other parts of LLDB used However, with the highlighting changes, the backtrace now uses
This changes the behavior of the python I think at some point some other APIs broke, but rerunning the tests with the latest changes and forcing |
||
if (demangled_name.empty()) | ||
return llvm::createStringError( | ||
"Function '%s' does not have a demangled name.", | ||
mangled.GetMangledName().AsCString("")); | ||
|
||
const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo(); | ||
if (!info) | ||
return llvm::createStringError( | ||
"Function '%s' does not have demangled info.", demangled_name.data()); | ||
|
||
// Function without a basename is nonsense. | ||
if (!info->hasBasename()) | ||
return llvm::createStringError( | ||
"DemangledInfo for '%s does not have basename range.", | ||
demangled_name.data()); | ||
|
||
return std::make_pair(demangled_name, *info); | ||
} | ||
|
||
static llvm::Expected<llvm::StringRef> | ||
GetDemangledBasename(const SymbolContext &sc) { | ||
return std::nullopt; | ||
auto info_or_err = GetAndValidateInfo(sc); | ||
if (!info_or_err) | ||
return info_or_err.takeError(); | ||
|
||
auto [demangled_name, info] = *info_or_err; | ||
|
||
return demangled_name.slice(info.BasenameRange.first, | ||
info.BasenameRange.second); | ||
} | ||
|
||
static std::optional<llvm::StringRef> | ||
static llvm::Expected<llvm::StringRef> | ||
GetDemangledFunctionPrefix(const SymbolContext &sc) { | ||
return std::nullopt; | ||
auto info_or_err = GetAndValidateInfo(sc); | ||
if (!info_or_err) | ||
return info_or_err.takeError(); | ||
|
||
auto [demangled_name, info] = *info_or_err; | ||
|
||
Michael137 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!info.hasPrefix()) | ||
return llvm::createStringError( | ||
"DemangledInfo for '%s does not have suffix range.", | ||
demangled_name.data()); | ||
|
||
return demangled_name.slice(info.PrefixRange.first, info.PrefixRange.second); | ||
} | ||
|
||
static std::optional<llvm::StringRef> | ||
static llvm::Expected<llvm::StringRef> | ||
GetDemangledFunctionSuffix(const SymbolContext &sc) { | ||
return std::nullopt; | ||
auto info_or_err = GetAndValidateInfo(sc); | ||
if (!info_or_err) | ||
return info_or_err.takeError(); | ||
|
||
auto [demangled_name, info] = *info_or_err; | ||
Michael137 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (!info.hasSuffix()) | ||
return llvm::createStringError( | ||
"DemangledInfo for '%s does not have suffix range.", | ||
demangled_name.data()); | ||
|
||
return demangled_name.slice(info.SuffixRange.first, info.SuffixRange.second); | ||
} | ||
|
||
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) { | ||
return false; | ||
assert(sc.symbol); | ||
|
||
auto info_or_err = GetAndValidateInfo(sc); | ||
if (!info_or_err) { | ||
LLDB_LOG_ERROR(GetLog(LLDBLog::Language), info_or_err.takeError(), | ||
"Failed to handle ${{function.formatted-arguments}} " | ||
"frame-format variable: {0}"); | ||
return false; | ||
} | ||
auto [demangled_name, info] = *info_or_err; | ||
|
||
if (!info.hasArguments()) | ||
return false; | ||
Michael137 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
s << demangled_name.slice(info.ArgumentsRange.first, | ||
info.ArgumentsRange.second); | ||
|
||
return true; | ||
} | ||
|
||
static VariableListSP GetFunctionVariableList(const SymbolContext &sc) { | ||
|
@@ -1941,11 +2014,15 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc, | |
Stream &s) { | ||
switch (type) { | ||
case FormatEntity::Entry::Type::FunctionBasename: { | ||
std::optional<llvm::StringRef> name = GetDemangledBasename(sc); | ||
if (!name) | ||
auto name_or_err = GetDemangledBasename(sc); | ||
if (!name_or_err) { | ||
LLDB_LOG_ERROR( | ||
GetLog(LLDBLog::Language), name_or_err.takeError(), | ||
"Failed to handle ${{function.basename}} frame-format variable: {0}"); | ||
return false; | ||
} | ||
|
||
s << *name; | ||
s << *name_or_err; | ||
|
||
return true; | ||
} | ||
|
@@ -1972,20 +2049,28 @@ bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc, | |
return true; | ||
} | ||
case FormatEntity::Entry::Type::FunctionPrefix: { | ||
std::optional<llvm::StringRef> prefix = GetDemangledFunctionPrefix(sc); | ||
if (!prefix) | ||
auto prefix_or_err = GetDemangledFunctionPrefix(sc); | ||
if (!prefix_or_err) { | ||
LLDB_LOG_ERROR( | ||
GetLog(LLDBLog::Language), prefix_or_err.takeError(), | ||
"Failed to handle ${{function.prefix}} frame-format variable: {0}"); | ||
return false; | ||
} | ||
|
||
s << *prefix; | ||
s << *prefix_or_err; | ||
|
||
return true; | ||
} | ||
case FormatEntity::Entry::Type::FunctionSuffix: { | ||
std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc); | ||
if (!suffix) | ||
auto suffix_or_err = GetDemangledFunctionSuffix(sc); | ||
if (!suffix_or_err) { | ||
LLDB_LOG_ERROR( | ||
GetLog(LLDBLog::Language), suffix_or_err.takeError(), | ||
"Failed to handle ${{function.suffix}} frame-format variable: {0}"); | ||
return false; | ||
} | ||
|
||
s << *suffix; | ||
s << *suffix_or_err; | ||
|
||
return true; | ||
} | ||
|
@@ -2019,7 +2104,7 @@ class PluginProperties : public Properties { | |
} | ||
|
||
FormatEntity::Entry GetFunctionNameFormat() const { | ||
return GetPropertyAtIndexAs<const FormatEntity::Entry>( | ||
return GetPropertyAtIndexAs<FormatEntity::Entry>( | ||
ePropertyFunctionNameFormat, {}); | ||
} | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because otherwise this will crash on a nullptr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks 👍