aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectExpression.cpp
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2024-09-27 16:32:35 -0700
committerAdrian Prantl <aprantl@apple.com>2024-09-27 18:09:52 -0700
commitd33fa70dddcb29d5fd85188e119f034e585ccccf (patch)
tree77285a9be170a11e3885dcf4bdb02959457ced16 /lldb/source/Commands/CommandObjectExpression.cpp
parentdf4d7d3b29b073e24a5ebb8302e7a1ac873a5cde (diff)
downloadllvm-d33fa70dddcb29d5fd85188e119f034e585ccccf.zip
llvm-d33fa70dddcb29d5fd85188e119f034e585ccccf.tar.gz
llvm-d33fa70dddcb29d5fd85188e119f034e585ccccf.tar.bz2
[lldb] Inline expression evaluator error visualization (#106470)
This patch is a reworking of Pete Lawrence's (@PortalPete) proposal for better expression evaluator error messages: https://github.com/llvm/llvm-project/pull/80938 Before: ``` $ lldb -o "expr a+b" (lldb) expr a+b error: <user expression 0>:1:1: use of undeclared identifier 'a' a+b ^ error: <user expression 0>:1:3: use of undeclared identifier 'b' a+b ^ ``` After: ``` (lldb) expr a+b ^ ^ │ ╰─ error: use of undeclared identifier 'b' ╰─ error: use of undeclared identifier 'a' ``` This eliminates the confusing `<user expression 0>:1:3` source location and avoids echoing the expression to the console again, which results in a cleaner presentation that makes it easier to grasp what's going on. You can't see it here, bug the word "error" is now also in color, if so desired. Depends on https://github.com/llvm/llvm-project/pull/106442.
Diffstat (limited to 'lldb/source/Commands/CommandObjectExpression.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp41
1 files changed, 28 insertions, 13 deletions
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 7711946..9722c85 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -6,10 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringRef.h"
-
#include "CommandObjectExpression.h"
+#include "DiagnosticRendering.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/REPL.h"
#include "lldb/Expression/UserExpression.h"
@@ -486,19 +486,34 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
- const char *error_cstr = result_valobj_sp->GetError().AsCString();
- if (error_cstr && error_cstr[0]) {
- const size_t error_cstr_len = strlen(error_cstr);
- const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
- if (strstr(error_cstr, "error:") != error_cstr)
- error_stream.PutCString("error: ");
- error_stream.Write(error_cstr, error_cstr_len);
- if (!ends_with_newline)
- error_stream.EOL();
+ // Retrieve the diagnostics.
+ std::vector<DiagnosticDetail> details;
+ llvm::consumeError(llvm::handleErrors(
+ result_valobj_sp->GetError().ToError(),
+ [&](ExpressionError &error) { details = error.GetDetails(); }));
+ // Find the position of the expression in the command.
+ std::optional<uint16_t> expr_pos;
+ size_t nchar = m_original_command.find(expr);
+ if (nchar != std::string::npos)
+ expr_pos = nchar + GetDebugger().GetPrompt().size();
+
+ if (!details.empty()) {
+ bool show_inline =
+ GetDebugger().GetShowInlineDiagnostics() && !expr.contains('\n');
+ RenderDiagnosticDetails(error_stream, expr_pos, show_inline, details);
} else {
- error_stream.PutCString("error: unknown error\n");
+ const char *error_cstr = result_valobj_sp->GetError().AsCString();
+ llvm::StringRef error(error_cstr);
+ if (!error.empty()) {
+ if (!error.starts_with("error:"))
+ error_stream << "error: ";
+ error_stream << error;
+ if (!error.ends_with('\n'))
+ error_stream.EOL();
+ } else {
+ error_stream << "error: unknown error\n";
+ }
}
-
result.SetStatus(eReturnStatusFailed);
}
}