https://github.com/kuilpd created 
https://github.com/llvm/llvm-project/pull/187680

* Correctly return the result when used from the console, so that it can
  use `DiagnosticsRendering` to output the error.
* Add location pointer to `DILDiagnosticError` internal formatting to show
  diagnostics when called from the API.

>From c864791ebf1c27fd3695b31bfede693a487b8cac Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Thu, 19 Mar 2026 19:38:35 +0500
Subject: [PATCH 1/2] [lldb] Fix DIL error diagnostics output

---
 lldb/source/Commands/CommandObjectFrame.cpp | 17 +++++++++++++++--
 lldb/source/Target/StackFrame.cpp           |  8 +++++---
 lldb/source/ValueObject/DILParser.cpp       | 16 ++++++++++++----
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectFrame.cpp 
b/lldb/source/Commands/CommandObjectFrame.cpp
index 9133359fbf537..47ad6c164f5b9 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -637,8 +637,21 @@ may even involve JITing and running code in the target 
program.)");
               Stream &output_stream = result.GetOutputStream();
               options.SetRootValueObjectName(
                   valobj_sp->GetParent() ? entry.c_str() : nullptr);
-              if (llvm::Error error = valobj_sp->Dump(output_stream, options))
-                result.AppendError(toString(std::move(error)));
+              // Check only the `error` argument, because doing
+              // `valobj_sp->GetError()` will update the value and potentially
+              // return a new error that happens during the update, even if
+              // `GetValueForVariableExpressionPath` reported no errors.
+              if (error.Fail()) {
+                result.SetStatus(eReturnStatusFailed);
+                result.SetError(error.takeError());
+              } else {
+                // If there is an error while updating the value, it will be
+                // printed here as the contents of the value, e.g.
+                // `(int) *((int*)0) = <parent is NULL>`
+                if (llvm::Error error = valobj_sp->Dump(output_stream, 
options))
+                  result.AppendError(toString(std::move(error)));
+              }
+
             } else {
               if (auto error_cstr = error.AsCString(nullptr))
                 result.AppendError(error_cstr);
diff --git a/lldb/source/Target/StackFrame.cpp 
b/lldb/source/Target/StackFrame.cpp
index 9fb26176e43c0..0b4ced1cd67ba 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -552,7 +552,9 @@ ValueObjectSP 
StackFrame::DILGetValueForVariableExpressionPath(
   auto lex_or_err = dil::DILLexer::Create(var_expr, mode);
   if (!lex_or_err) {
     error = Status::FromError(lex_or_err.takeError());
-    return ValueObjectConstResult::Create(nullptr, std::move(error));
+    // Duplicate the error so that it can be accessed from both
+    // the return result and the `&error` argument.
+    return ValueObjectConstResult::Create(nullptr, error.Clone());
   }
 
   // Parse the expression.
@@ -561,7 +563,7 @@ ValueObjectSP 
StackFrame::DILGetValueForVariableExpressionPath(
       !no_synth_child, !no_fragile_ivar, check_ptr_vs_member);
   if (!tree_or_error) {
     error = Status::FromError(tree_or_error.takeError());
-    return ValueObjectConstResult::Create(nullptr, std::move(error));
+    return ValueObjectConstResult::Create(nullptr, error.Clone());
   }
 
   // Evaluate the parsed expression.
@@ -573,7 +575,7 @@ ValueObjectSP 
StackFrame::DILGetValueForVariableExpressionPath(
   auto valobj_or_error = interpreter.Evaluate(**tree_or_error);
   if (!valobj_or_error) {
     error = Status::FromError(valobj_or_error.takeError());
-    return ValueObjectConstResult::Create(nullptr, std::move(error));
+    return ValueObjectConstResult::Create(nullptr, error.Clone());
   }
 
   var_sp = (*valobj_or_error)->GetVariable();
diff --git a/lldb/source/ValueObject/DILParser.cpp 
b/lldb/source/ValueObject/DILParser.cpp
index bb5a86bc7168b..4fd3d52bc9f0a 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -36,13 +36,21 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
   DiagnosticDetail::SourceLocation sloc = {
       FileSpec{}, /*line=*/1, static_cast<uint16_t>(loc + 1),
       err_len,    false,      /*in_user_input=*/true};
-  std::string rendered_msg =
-      llvm::formatv("<user expression 0>:1:{0}: {1}\n   1 | {2}\n     | ^",
-                    loc + 1, message, expr);
+  StreamString rendered_msg(false);
+  auto msg = llvm::formatv("<user expression>:1:{0}: {1}\n    1 | {2}\n      
|",
+                           loc + 1, message, expr);
+  rendered_msg << msg.str();
+  for (uint32_t i = 0; i <= loc; i++)
+    rendered_msg << " ";
+  rendered_msg << "^";
+  for (uint32_t i = 1; i < err_len; i++)
+    rendered_msg << "~";
+  std::string rendered_str = rendered_msg.GetString().str();
+
   m_detail.source_location = sloc;
   m_detail.severity = lldb::eSeverityError;
   m_detail.message = message;
-  m_detail.rendered = std::move(rendered_msg);
+  m_detail.rendered = std::move(rendered_str);
 }
 
 llvm::Expected<lldb::TypeSystemSP>

>From 3dfc0855900d009243b1a517b5359796ec31ea82 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <[email protected]>
Date: Fri, 20 Mar 2026 00:44:10 +0500
Subject: [PATCH 2/2] Add a test

---
 lldb/test/Shell/Commands/Inputs/main.c        |  1 +
 .../Commands/command-dil-diagnostics.test     | 22 +++++++++++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 lldb/test/Shell/Commands/command-dil-diagnostics.test

diff --git a/lldb/test/Shell/Commands/Inputs/main.c 
b/lldb/test/Shell/Commands/Inputs/main.c
index c029ddd96cd52..284605e5db11d 100644
--- a/lldb/test/Shell/Commands/Inputs/main.c
+++ b/lldb/test/Shell/Commands/Inputs/main.c
@@ -1,2 +1,3 @@
 int foo() { return 0; }
 int main() { return foo(); }
+int a = 1;
diff --git a/lldb/test/Shell/Commands/command-dil-diagnostics.test 
b/lldb/test/Shell/Commands/command-dil-diagnostics.test
new file mode 100644
index 0000000000000..ee056e6bb3f51
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-dil-diagnostics.test
@@ -0,0 +1,22 @@
+## Check DIL error diagnostics output.
+# XFAIL: target-windows
+# RUN: %clang_host -g -O0 %S/Inputs/main.c -o %t
+# RUN: %lldb %t -o "command source -e 0 %s" -o exit 2>&1 | FileCheck %s 
--strict-whitespace
+settings set target.experimental.use-DIL true
+b main
+run
+
+## Check console diagnostincs pointing to an error in user input.
+frame var a+b
+# CHECK:      {{^                   (\^|˄)}}
+# CHECK-NEXT: {{^                   (╰─ )?}}error: use of undeclared 
identifier 'b'
+
+## Check diagnostics when called from API.
+script lldb.frame.GetValueForVariablePath("++foo")
+# CHECK: error: <user expression>:1:3: use of undeclared identifier 'foo'
+# CHECK-NEXT: {{^    }}1 | ++foo
+# CHECK-NEXT: {{^    }}  |   ^~~
+
+## Check that a result that fails to retrieve data is displaying an error.
+frame var *((int*)0)
+# CHECK: (int) *((int*)0) = <parent is NULL>

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to