[Lldb-commits] [lldb] [lldb] Update dwim-print to show expanded objc instances (PR #117500)

Dave Lee via lldb-commits lldb-commits at lists.llvm.org
Wed Mar 12 16:50:47 PDT 2025


https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/117500

>From 3199d3ee3817a8551cda1f5fce6083fef1c079d9 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 23 Nov 2024 18:25:22 -0800
Subject: [PATCH 1/4] [lldb] Update dwim-print to show expanded objc instances

When printing an ObjC object, which is a pointer, lldb has handled it like it treats any
other pointer, printing only pointer address and class name. The object is not expanded,
and its children are not shown.

This change updates the dwim-print to print expanded objc pointers - it is assumed
that's what the user meant.

Note that this is currently possible using the `--ptr-depth`/`-P` flag, but the default
is 0. With this change, when dwim-print prints objc objects, the default is effectively
changed to 1.
---
 .../lldb/DataFormatters/DumpValueObjectOptions.h |  3 +++
 lldb/source/Commands/CommandObjectDWIMPrint.cpp  |  3 ++-
 .../DataFormatters/DumpValueObjectOptions.cpp    |  6 ++++++
 .../source/DataFormatters/ValueObjectPrinter.cpp | 14 ++++++++------
 lldb/test/API/commands/dwim-print/objc/Makefile  |  3 +++
 .../dwim-print/objc/TestDWIMPrintObjC.py         | 16 ++++++++++++++++
 lldb/test/API/commands/dwim-print/objc/main.m    | 15 +++++++++++++++
 7 files changed, 53 insertions(+), 7 deletions(-)
 create mode 100644 lldb/test/API/commands/dwim-print/objc/Makefile
 create mode 100644 lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
 create mode 100644 lldb/test/API/commands/dwim-print/objc/main.m

diff --git a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
index c7f8cccc116c4..7e213f29b3bc0 100644
--- a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
+++ b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
@@ -125,6 +125,8 @@ class DumpValueObjectOptions {
 
   DumpValueObjectOptions &SetRevealEmptyAggregates(bool reveal = true);
 
+  DumpValueObjectOptions &SetExpandPointerTypeFlags(unsigned flags);
+
   DumpValueObjectOptions &SetElementCount(uint32_t element_count = 0);
 
   DumpValueObjectOptions &
@@ -142,6 +144,7 @@ class DumpValueObjectOptions {
   DeclPrintingHelper m_decl_printing_helper;
   ChildPrintingDecider m_child_printing_decider;
   PointerAsArraySettings m_pointer_as_array;
+  unsigned m_expand_ptr_type_flags = 0;
   bool m_use_synthetic : 1;
   bool m_scope_already_checked : 1;
   bool m_flat_output : 1;
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 62c4e74d853ad..8bfef15036cc7 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -87,7 +87,8 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
 
   DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
       m_expr_options.m_verbosity, m_format_options.GetFormat());
-  dump_options.SetHideRootName(suppress_result);
+  dump_options.SetHideRootName(suppress_result)
+      .SetExpandPointerTypeFlags(lldb::eTypeIsObjC);
 
   bool is_po = m_varobj_options.use_objc;
 
diff --git a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
index 18d590d47d9a0..a4db0d3cb240f 100644
--- a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
+++ b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
@@ -201,6 +201,12 @@ DumpValueObjectOptions::SetRevealEmptyAggregates(bool reveal) {
   return *this;
 }
 
+DumpValueObjectOptions &
+DumpValueObjectOptions::SetExpandPointerTypeFlags(unsigned flags) {
+  m_expand_ptr_type_flags = flags;
+  return *this;
+}
+
 DumpValueObjectOptions &
 DumpValueObjectOptions::SetElementCount(uint32_t element_count) {
   m_pointer_as_array = PointerAsArraySettings(element_count);
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index face38253efab..83db9292c5e76 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -554,12 +554,14 @@ bool ValueObjectPrinter::ShouldPrintChildren(
       return false;
 
     const bool is_root_level = m_curr_depth == 0;
-
-    if (is_ref && is_root_level && print_children) {
-      // If this is the root object (depth is zero) that we are showing and
-      // it is a reference, and no pointer depth has been supplied print out
-      // what it references. Don't do this at deeper depths otherwise we can
-      // end up with infinite recursion...
+    const bool is_expanded_ptr =
+        is_ptr && m_type_flags.Test(m_options.m_expand_ptr_type_flags);
+
+    if ((is_ref || is_expanded_ptr) && is_root_level && print_children) {
+      // If this is the root object (depth is zero) that we are showing and it
+      // is either a reference or a preferred type of pointer, then print it.
+      // Don't do this at deeper depths otherwise we can end up with infinite
+      // recursion...
       return true;
     }
 
diff --git a/lldb/test/API/commands/dwim-print/objc/Makefile b/lldb/test/API/commands/dwim-print/objc/Makefile
new file mode 100644
index 0000000000000..845553d5e3f2f
--- /dev/null
+++ b/lldb/test/API/commands/dwim-print/objc/Makefile
@@ -0,0 +1,3 @@
+OBJC_SOURCES := main.m
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
new file mode 100644
index 0000000000000..a642c40aeb7e4
--- /dev/null
+++ b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
@@ -0,0 +1,16 @@
+"""
+Test dwim-print with objc instances.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+class TestCase(TestBase):
+
+    def test(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
+        self.expect("dwim-print obj", substrs=["_number = 15"])
diff --git a/lldb/test/API/commands/dwim-print/objc/main.m b/lldb/test/API/commands/dwim-print/objc/main.m
new file mode 100644
index 0000000000000..5fdeb00323801
--- /dev/null
+++ b/lldb/test/API/commands/dwim-print/objc/main.m
@@ -0,0 +1,15 @@
+#import <Foundation/Foundation.h>
+
+ at interface Object : NSObject
+ at property(nonatomic) int number;
+ at end
+
+ at implementation Object
+ at end
+
+int main(int argc, char **argv) {
+  Object *obj = [Object new];
+  obj.number = 15;
+  puts("break here");
+  return 0;
+}

>From 1890aaa2e8791fa643a07c4a6b4fb8bd6dc25526 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 2 Dec 2024 16:27:59 -0800
Subject: [PATCH 2/4] python formatting

---
 lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
index a642c40aeb7e4..ec5a40c6c3cf0 100644
--- a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
+++ b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
@@ -9,7 +9,6 @@
 
 
 class TestCase(TestBase):
-
     def test(self):
         self.build()
         lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))

>From 40aadada9852fc9481b475c61a696115ebb1b0ca Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 2 Dec 2024 16:45:02 -0800
Subject: [PATCH 3/4] Apply skipUnlessDarwin decorator

---
 lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
index ec5a40c6c3cf0..67a66bcfe687e 100644
--- a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
+++ b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
@@ -9,6 +9,7 @@
 
 
 class TestCase(TestBase):
+    @skipUnlessDarwin
     def test(self):
         self.build()
         lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))

>From 668e91d8caed3db546a9908def5b72a3c6fb5f03 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Wed, 12 Mar 2025 16:50:21 -0700
Subject: [PATCH 4/4] Test expansion of nested objc objects

---
 .../API/commands/dwim-print/objc/Makefile     |  2 +-
 .../dwim-print/objc/TestDWIMPrintObjC.py      |  5 ++++-
 lldb/test/API/commands/dwim-print/objc/main.m | 19 ++++++++++++++-----
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lldb/test/API/commands/dwim-print/objc/Makefile b/lldb/test/API/commands/dwim-print/objc/Makefile
index 845553d5e3f2f..a3198db9e8e88 100644
--- a/lldb/test/API/commands/dwim-print/objc/Makefile
+++ b/lldb/test/API/commands/dwim-print/objc/Makefile
@@ -1,3 +1,3 @@
 OBJC_SOURCES := main.m
-
+LD_EXTRAS := -framework Foundation
 include Makefile.rules
diff --git a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
index 67a66bcfe687e..7b9f3672a4a7c 100644
--- a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
+++ b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
@@ -13,4 +13,7 @@ class TestCase(TestBase):
     def test(self):
         self.build()
         lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
-        self.expect("dwim-print obj", substrs=["_number = 15"])
+        self.expect("dwim-print parent", substrs=["_child = 0x"])
+        self.expect(
+            "dwim-print parent.child", patterns=[r'_name = 0x[0-9a-f]+ @"Seven"']
+        )
diff --git a/lldb/test/API/commands/dwim-print/objc/main.m b/lldb/test/API/commands/dwim-print/objc/main.m
index 5fdeb00323801..ac7efcf0f07ab 100644
--- a/lldb/test/API/commands/dwim-print/objc/main.m
+++ b/lldb/test/API/commands/dwim-print/objc/main.m
@@ -1,15 +1,24 @@
 #import <Foundation/Foundation.h>
 
- at interface Object : NSObject
- at property(nonatomic) int number;
+ at interface Child : NSObject
+ at property(nonatomic, copy) NSString *name;
 @end
 
- at implementation Object
+ at implementation Child
+ at end
+
+ at interface Parent : NSObject
+ at property(nonatomic, strong) Child *child;
+ at end
+
+ at implementation Parent
 @end
 
 int main(int argc, char **argv) {
-  Object *obj = [Object new];
-  obj.number = 15;
+  Child *child = [Child new];
+  child.name = @"Seven";
+  Parent *parent = [Parent new];
+  parent.child = child;
   puts("break here");
   return 0;
 }



More information about the lldb-commits mailing list