xref: /llvm-project/lldb/test/API/lang/c/blocks/TestBlocks.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""Test that lldb can invoke blocks and access variables inside them"""
2
3
4import lldb
5from lldbsuite.test.lldbtest import *
6from lldbsuite.test.decorators import *
7import lldbsuite.test.lldbutil as lldbutil
8
9
10class BlocksTestCase(TestBase):
11    lines = []
12
13    def setUp(self):
14        # Call super's setUp().
15        TestBase.setUp(self)
16        # Find the line numbers to break at.
17        self.lines.append(line_number("main.c", "// Set breakpoint 0 here."))
18        self.lines.append(line_number("main.c", "// Set breakpoint 1 here."))
19        self.lines.append(line_number("main.c", "// Set breakpoint 2 here."))
20
21    def launch_common(self):
22        self.build()
23        exe = self.getBuildArtifact("a.out")
24        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
25
26        self.is_started = False
27
28        # Break inside the foo function which takes a bar_ptr argument.
29        for line in self.lines:
30            lldbutil.run_break_set_by_file_and_line(
31                self, "main.c", line, num_expected_locations=1, loc_exact=True
32            )
33
34        self.wait_for_breakpoint()
35
36    @skipUnlessDarwin
37    def test_expr(self):
38        self.launch_common()
39
40        self.expect("expression a + b", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 7"])
41
42        self.expect("expression c", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 1"])
43
44        self.wait_for_breakpoint()
45
46        # This should display correctly.
47        self.expect(
48            "expression (int)neg (-12)", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 12"]
49        )
50
51        self.wait_for_breakpoint()
52
53        self.expect_expr("h(cg)", result_type="int", result_value="42")
54
55    @skipUnlessDarwin
56    def test_define(self):
57        self.launch_common()
58
59        self.runCmd(
60            "expression int (^$add)(int, int) = ^int(int a, int b) { return a + b; };"
61        )
62        self.expect(
63            "expression $add(2,3)", VARIABLES_DISPLAYED_CORRECTLY, substrs=[" = 5"]
64        )
65
66        self.runCmd("expression int $a = 3")
67        self.expect(
68            "expression int (^$addA)(int) = ^int(int b) { return $a + b; };",
69            "Proper error is reported on capture",
70            error=True,
71        )
72
73    def wait_for_breakpoint(self):
74        if not self.is_started:
75            self.is_started = True
76            self.runCmd("process launch", RUN_SUCCEEDED)
77        else:
78            self.runCmd("process continue", RUN_SUCCEEDED)
79
80        # The stop reason of the thread should be breakpoint.
81        self.expect(
82            "thread list",
83            STOPPED_DUE_TO_BREAKPOINT,
84            substrs=["stopped", "stop reason = breakpoint"],
85        )
86