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

via lldb-commits lldb-commits at lists.llvm.org
Sat Mar 15 08:57:54 PDT 2025


Author: Dave Lee
Date: 2025-03-15T08:57:51-07:00
New Revision: 65e68a30787d7ce2bf5a9e695dd03944137c5287

URL: https://github.com/llvm/llvm-project/commit/65e68a30787d7ce2bf5a9e695dd03944137c5287
DIFF: https://github.com/llvm/llvm-project/commit/65e68a30787d7ce2bf5a9e695dd03944137c5287.diff

LOG: [lldb] Update dwim-print to show expanded objc instances (#117500)

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

This change updates `dwim-print` to print objc pointers by expanding (ie
dereferencing), with the assumption that it's what the user wants.

Note that this is currently possible using the `--ptr-depth`/`-P` flag.
With this change, when `dwim-print` prints root level objc objects, it's
the same effect as using `--ptr-depth 1`.

Added: 
    lldb/test/API/commands/dwim-print/objc/Makefile
    lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
    lldb/test/API/commands/dwim-print/objc/main.m

Modified: 
    lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
    lldb/source/Commands/CommandObjectDWIMPrint.cpp
    lldb/source/DataFormatters/DumpValueObjectOptions.cpp
    lldb/source/DataFormatters/ValueObjectPrinter.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
index ce15963ab5662..cdb620e2148de 100644
--- a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
+++ b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
@@ -123,6 +123,8 @@ class DumpValueObjectOptions {
 
   DumpValueObjectOptions &SetRevealEmptyAggregates(bool reveal = true);
 
+  DumpValueObjectOptions &SetExpandPointerTypeFlags(unsigned flags);
+
   DumpValueObjectOptions &SetElementCount(uint32_t element_count = 0);
 
   DumpValueObjectOptions &
@@ -140,6 +142,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 17c60297a521e..a110eececf4d6 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 b952fb643f13e..c343e6083df19 100644
--- a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
+++ b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
@@ -199,6 +199,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 01e604e019f25..5e04a621bbda8 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -547,12 +547,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..a3198db9e8e88
--- /dev/null
+++ b/lldb/test/API/commands/dwim-print/objc/Makefile
@@ -0,0 +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
new file mode 100644
index 0000000000000..616d049459ab9
--- /dev/null
+++ b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
@@ -0,0 +1,27 @@
+"""
+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):
+    @skipUnlessDarwin
+    def test(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
+        self.expect("dwim-print parent", substrs=["_child = 0x"])
+        self.expect(
+            "dwim-print parent.child", patterns=[r'_name = 0x[0-9a-f]+ @"Seven"']
+        )
+
+    @skipUnlessDarwin
+    def test_with_summary(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
+        self.runCmd("type summary add -s 'Parent of ${var._child._name}' 'Parent *'")
+        self.expect("dwim-print parent", matching=False, substrs=["_child = 0x"])
+        self.expect("dwim-print parent", substrs=['Parent of @"Seven"'])

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..ac7efcf0f07ab
--- /dev/null
+++ b/lldb/test/API/commands/dwim-print/objc/main.m
@@ -0,0 +1,24 @@
+#import <Foundation/Foundation.h>
+
+ at interface Child : NSObject
+ at property(nonatomic, copy) NSString *name;
+ at end
+
+ at implementation Child
+ at end
+
+ at interface Parent : NSObject
+ at property(nonatomic, strong) Child *child;
+ at end
+
+ at implementation Parent
+ at end
+
+int main(int argc, char **argv) {
+  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