[Lldb-commits] [lldb] [lldb] Store the return ValueObject in the CommandReturnObject (PR #127566)

via lldb-commits lldb-commits at lists.llvm.org
Mon Feb 17 20:50:38 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

<details>
<summary>Changes</summary>

There are a lot of lldb commands whose result is really a ValueObject that we then print with the ValueObjectPrinter. Now that we have the ability to access the SBCommandReturnObject through a callback (#<!-- -->125006), we can store the resultant ValueObject in the return object, allowing an IDE  to access the SBValue and do its own rich formatting.

rdar://143965453

---
Full diff: https://github.com/llvm/llvm-project/pull/127566.diff


8 Files Affected:

- (modified) lldb/include/lldb/API/SBCommandReturnObject.h (+2) 
- (modified) lldb/include/lldb/API/SBValue.h (+1) 
- (modified) lldb/include/lldb/Interpreter/CommandReturnObject.h (+10) 
- (modified) lldb/source/API/SBCommandReturnObject.cpp (+12-2) 
- (modified) lldb/source/Commands/CommandObjectDWIMPrint.cpp (+3) 
- (modified) lldb/source/Commands/CommandObjectExpression.cpp (+2) 
- (modified) lldb/source/Commands/CommandObjectFrame.cpp (+3-2) 
- (modified) lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py (+13) 


``````````diff
diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h
index 9a63c1f96aa70..96dda239d3c97 100644
--- a/lldb/include/lldb/API/SBCommandReturnObject.h
+++ b/lldb/include/lldb/API/SBCommandReturnObject.h
@@ -136,6 +136,8 @@ class LLDB_API SBCommandReturnObject {
 
   void SetError(const char *error_cstr);
 
+  lldb::SBValue GetReturnValue(lldb::DynamicValueType use_dynamic);
+
 protected:
   friend class SBCommandInterpreter;
   friend class SBOptions;
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index 46ef6daa95264..75d20a4378f09 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -442,6 +442,7 @@ class LLDB_API SBValue {
 
 protected:
   friend class SBBlock;
+  friend class SBCommandReturnObject;
   friend class SBFrame;
   friend class SBModule;
   friend class SBTarget;
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index 803bcd76995ed..20600ff667bb6 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -14,6 +14,7 @@
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/StreamTee.h"
 #include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-forward.h"
 #include "lldb/lldb-private.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -165,6 +166,12 @@ class CommandReturnObject {
     return m_diagnostic_indent;
   }
 
+  lldb::ValueObjectSP GetValueObjectSP() const { return m_value_object_sp; }
+
+  void SetValueObjectSP(lldb::ValueObjectSP value_object_sp) {
+    m_value_object_sp = value_object_sp;
+  }
+
   lldb::ReturnStatus GetStatus() const;
 
   void SetStatus(lldb::ReturnStatus status);
@@ -197,6 +204,9 @@ class CommandReturnObject {
 
   lldb::ReturnStatus m_status = lldb::eReturnStatusStarted;
 
+  /// An optional ValueObjectSP if the command created one.
+  lldb::ValueObjectSP m_value_object_sp;
+
   bool m_did_change_process_state = false;
   bool m_suppress_immediate_output = false;
 
diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp
index 6f54581e64ef4..b0de4adc6e241 100644
--- a/lldb/source/API/SBCommandReturnObject.cpp
+++ b/lldb/source/API/SBCommandReturnObject.cpp
@@ -12,6 +12,7 @@
 #include "lldb/API/SBFile.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStructuredData.h"
+#include "lldb/API/SBValue.h"
 #include "lldb/Core/StructuredDataImpl.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Utility/ConstString.h"
@@ -62,8 +63,8 @@ SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) {
   m_opaque_up = clone(rhs.m_opaque_up);
 }
 
-SBCommandReturnObject &SBCommandReturnObject::
-operator=(const SBCommandReturnObject &rhs) {
+SBCommandReturnObject &
+SBCommandReturnObject::operator=(const SBCommandReturnObject &rhs) {
   LLDB_INSTRUMENT_VA(this, rhs);
 
   if (this != &rhs)
@@ -356,3 +357,12 @@ void SBCommandReturnObject::SetError(const char *error_cstr) {
   if (error_cstr)
     ref().AppendError(error_cstr);
 }
+
+SBValue
+SBCommandReturnObject::GetReturnValue(lldb::DynamicValueType use_dynamic) {
+  LLDB_INSTRUMENT_VA(this, use_dynamic);
+
+  SBValue sb_value;
+  sb_value.SetSP(ref().GetValueObjectSP(), use_dynamic);
+  return sb_value;
+}
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index d4d038d28f675..aab99441c63a3 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -205,6 +205,9 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
     ExpressionResults expr_result = target.EvaluateExpression(
         expr, exe_scope, valobj_sp, eval_options, &fixed_expression);
 
+    if (valobj_sp)
+      result.SetValueObjectSP(valobj_sp);
+
     // Record the position of the expression in the command.
     std::optional<uint16_t> indent;
     if (fixed_expression.empty()) {
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 7e26381c92405..b0c92d9391b13 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -434,6 +434,8 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
   }
 
   if (result_valobj_sp) {
+    result.SetValueObjectSP(result_valobj_sp);
+
     Format format = m_format_options.GetFormat();
 
     if (result_valobj_sp->GetError().Success()) {
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index a5709b36f52ee..69bce205ddccc 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -152,6 +152,7 @@ class CommandObjectFrameDiagnose : public CommandObjectParsed {
       return;
     }
 
+    result.SetValueObjectSP(valobj_sp);
     DumpValueObjectOptions::DeclPrintingHelper helper =
         [&valobj_sp](ConstString type, ConstString var,
                      const DumpValueObjectOptions &opts,
@@ -317,9 +318,9 @@ class CommandObjectFrameSelect : public CommandObjectParsed {
       } else if (*m_options.relative_frame_offset > 0) {
         // I don't want "up 20" where "20" takes you past the top of the stack
         // to produce an error, but rather to just go to the top.  OTOH, start
-        // by seeing if the requested frame exists, in which case we can avoid 
+        // by seeing if the requested frame exists, in which case we can avoid
         // counting the stack here...
-        const uint32_t frame_requested = frame_idx 
+        const uint32_t frame_requested = frame_idx
             + *m_options.relative_frame_offset;
         StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_requested);
         if (frame_sp)
diff --git a/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py b/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py
index 2193b7270d0b4..0fee54eb5fe1d 100644
--- a/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py
+++ b/lldb/test/API/api/command-return-object/TestSBCommandReturnObject.py
@@ -33,3 +33,16 @@ def test_get_command(self):
         ci.HandleCommand("help help", res)
         self.assertTrue(res.Succeeded())
         self.assertEqual(res.GetCommand(), "help help")
+
+        value = res.GetReturnValue(lldb.eNoDynamicValues)
+        self.assertFalse(value)
+
+    def test_get_value(self):
+        res = lldb.SBCommandReturnObject()
+        ci = self.dbg.GetCommandInterpreter()
+        ci.HandleCommand("p 1 + 1", res)
+        self.assertTrue(res.Succeeded())
+
+        value = res.GetReturnValue(lldb.eNoDynamicValues)
+        self.assertTrue(value)
+        self.assertEqual(value.GetValue(), "2")

``````````

</details>


https://github.com/llvm/llvm-project/pull/127566


More information about the lldb-commits mailing list