Skip to content

Commit 95d0da6

Browse files
committed
[lldb] Update dwim-print to show expanded objc instances (llvm#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`. (cherry picked from commit 65e68a3)
1 parent adfb8ba commit 95d0da6

File tree

7 files changed

+73
-7
lines changed

7 files changed

+73
-7
lines changed

lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class DumpValueObjectOptions {
128128

129129
DumpValueObjectOptions &SetRevealEmptyAggregates(bool reveal = true);
130130

131+
DumpValueObjectOptions &SetExpandPointerTypeFlags(unsigned flags);
132+
131133
DumpValueObjectOptions &SetElementCount(uint32_t element_count = 0);
132134

133135
DumpValueObjectOptions &
@@ -145,6 +147,7 @@ class DumpValueObjectOptions {
145147
DeclPrintingHelper m_decl_printing_helper;
146148
ChildPrintingDecider m_child_printing_decider;
147149
PointerAsArraySettings m_pointer_as_array;
150+
unsigned m_expand_ptr_type_flags = 0;
148151
bool m_use_synthetic : 1;
149152
bool m_scope_already_checked : 1;
150153
bool m_flat_output : 1;

lldb/source/Commands/CommandObjectDWIMPrint.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
8989

9090
DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
9191
m_expr_options.m_verbosity, m_format_options.GetFormat());
92-
dump_options.SetHideRootName(suppress_result);
92+
dump_options.SetHideRootName(suppress_result)
93+
.SetExpandPointerTypeFlags(lldb::eTypeIsObjC);
9394

9495
bool is_po = m_varobj_options.use_objc;
9596

lldb/source/DataFormatters/DumpValueObjectOptions.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ DumpValueObjectOptions::SetRevealEmptyAggregates(bool reveal) {
201201
return *this;
202202
}
203203

204+
DumpValueObjectOptions &
205+
DumpValueObjectOptions::SetExpandPointerTypeFlags(unsigned flags) {
206+
m_expand_ptr_type_flags = flags;
207+
return *this;
208+
}
209+
204210
DumpValueObjectOptions &
205211
DumpValueObjectOptions::SetElementCount(uint32_t element_count) {
206212
m_pointer_as_array = PointerAsArraySettings(element_count);

lldb/source/DataFormatters/ValueObjectPrinter.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -575,12 +575,14 @@ bool ValueObjectPrinter::ShouldPrintChildren(
575575
return false;
576576

577577
const bool is_root_level = m_curr_depth == 0;
578-
579-
if (is_ref && is_root_level && print_children) {
580-
// If this is the root object (depth is zero) that we are showing and
581-
// it is a reference, and no pointer depth has been supplied print out
582-
// what it references. Don't do this at deeper depths otherwise we can
583-
// end up with infinite recursion...
578+
const bool is_expanded_ptr =
579+
is_ptr && m_type_flags.Test(m_options.m_expand_ptr_type_flags);
580+
581+
if ((is_ref || is_expanded_ptr) && is_root_level && print_children) {
582+
// If this is the root object (depth is zero) that we are showing and it
583+
// is either a reference or a preferred type of pointer, then print it.
584+
// Don't do this at deeper depths otherwise we can end up with infinite
585+
// recursion...
584586
return true;
585587
}
586588

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
OBJC_SOURCES := main.m
2+
LD_EXTRAS := -framework Foundation
3+
include Makefile.rules
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
Test dwim-print with objc instances.
3+
"""
4+
5+
import lldb
6+
from lldbsuite.test.lldbtest import *
7+
from lldbsuite.test.decorators import *
8+
import lldbsuite.test.lldbutil as lldbutil
9+
10+
11+
class TestCase(TestBase):
12+
@skipUnlessDarwin
13+
def test(self):
14+
self.build()
15+
lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
16+
self.expect("dwim-print parent", substrs=["_child = 0x"])
17+
self.expect(
18+
"dwim-print parent.child", patterns=[r'_name = 0x[0-9a-f]+ @"Seven"']
19+
)
20+
21+
@skipUnlessDarwin
22+
def test_with_summary(self):
23+
self.build()
24+
lldbutil.run_to_source_breakpoint(self, "break here", lldb.SBFileSpec("main.m"))
25+
self.runCmd("type summary add -s 'Parent of ${var._child._name}' 'Parent *'")
26+
self.expect("dwim-print parent", matching=False, substrs=["_child = 0x"])
27+
self.expect("dwim-print parent", substrs=['Parent of @"Seven"'])
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface Child : NSObject
4+
@property(nonatomic, copy) NSString *name;
5+
@end
6+
7+
@implementation Child
8+
@end
9+
10+
@interface Parent : NSObject
11+
@property(nonatomic, strong) Child *child;
12+
@end
13+
14+
@implementation Parent
15+
@end
16+
17+
int main(int argc, char **argv) {
18+
Child *child = [Child new];
19+
child.name = @"Seven";
20+
Parent *parent = [Parent new];
21+
parent.child = child;
22+
puts("break here");
23+
return 0;
24+
}

0 commit comments

Comments
 (0)