xref: /llvm-project/lldb/test/API/lang/objc/real-definition/TestRealDefinition.py (revision 9f0b5f9a39ea6e70c98c69a720d7e4f5d3800bf6)
1"""Test that types defined in shared libraries work correctly."""
2
3
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class TestRealDefinition(TestBase):
12
13    mydir = TestBase.compute_mydir(__file__)
14
15    def test_frame_var_after_stop_at_interface(self):
16        """Test that we can find the implementation for an objective C type"""
17        if self.getArchitecture() == 'i386':
18            self.skipTest("requires modern objc runtime")
19        self.build()
20        self.common_setup()
21
22        line = line_number(
23            'Foo.m', '// Set breakpoint where Bar is an interface')
24        lldbutil.run_break_set_by_file_and_line(
25            self, 'Foo.m', line, num_expected_locations=1, loc_exact=True)
26
27        self.runCmd("run", RUN_SUCCEEDED)
28
29        # The stop reason of the thread should be breakpoint.
30        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
31                    substrs=['stopped',
32                             'stop reason = breakpoint'])
33
34        # Run and stop at Foo
35        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1)
36
37        self.runCmd("continue", RUN_SUCCEEDED)
38
39        # Run at stop at main
40        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1)
41
42        # This should display correctly.
43        self.expect(
44            "frame variable foo->_bar->_hidden_ivar",
45            VARIABLES_DISPLAYED_CORRECTLY,
46            substrs=[
47                "(NSString *)",
48                "foo->_bar->_hidden_ivar = 0x"])
49
50    def test_frame_var_after_stop_at_implementation(self):
51        """Test that we can find the implementation for an objective C type"""
52        if self.getArchitecture() == 'i386':
53            self.skipTest("requires modern objc runtime")
54        self.build()
55        self.common_setup()
56
57        line = line_number(
58            'Bar.m', '// Set breakpoint where Bar is an implementation')
59        lldbutil.run_break_set_by_file_and_line(
60            self, 'Bar.m', line, num_expected_locations=1, loc_exact=True)
61
62        self.runCmd("run", RUN_SUCCEEDED)
63
64        # The stop reason of the thread should be breakpoint.
65        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
66                    substrs=['stopped',
67                             'stop reason = breakpoint'])
68
69        # Run and stop at Foo
70        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1)
71
72        self.runCmd("continue", RUN_SUCCEEDED)
73
74        # Run at stop at main
75        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1)
76
77        # This should display correctly.
78        self.expect(
79            "frame variable foo->_bar->_hidden_ivar",
80            VARIABLES_DISPLAYED_CORRECTLY,
81            substrs=[
82                "(NSString *)",
83                "foo->_bar->_hidden_ivar = 0x"])
84
85    def common_setup(self):
86        exe = self.getBuildArtifact("a.out")
87        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
88
89        # Break inside the foo function which takes a bar_ptr argument.
90        line = line_number('main.m', '// Set breakpoint in main')
91        lldbutil.run_break_set_by_file_and_line(
92            self, "main.m", line, num_expected_locations=1, loc_exact=True)
93