xref: /llvm-project/lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Test top-level expressions.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class TopLevelExpressionsTestCase(TestBase):
13    def setUp(self):
14        # Call super's setUp().
15        TestBase.setUp(self)
16        # Find the line number to break for main.c.
17        self.line = line_number("main.cpp", "// Set breakpoint here")
18        self.dummy_line = line_number("dummy.cpp", "// Set breakpoint here")
19
20        # Disable confirmation prompt to avoid infinite wait
21        self.runCmd("settings set auto-confirm true")
22        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
23
24    def build_and_run(self):
25        """Test top-level expressions."""
26        self.build()
27
28        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
29
30        lldbutil.run_break_set_by_file_and_line(
31            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False
32        )
33
34        self.runCmd("run", RUN_SUCCEEDED)
35
36    def run_dummy(self):
37        self.runCmd("file " + self.getBuildArtifact("dummy"), CURRENT_EXECUTABLE_SET)
38
39        lldbutil.run_break_set_by_file_and_line(
40            self,
41            "dummy.cpp",
42            self.dummy_line,
43            num_expected_locations=1,
44            loc_exact=False,
45        )
46
47        self.runCmd("run", RUN_SUCCEEDED)
48
49    @add_test_categories(["pyapi"])
50    @skipIf(debug_info="gmodules")  # not relevant
51    @skipIf(oslist=["windows"])  # Error in record layout on Windows
52    def test_top_level_expressions(self):
53        self.build_and_run()
54
55        resultFromCode = (
56            self.frame().EvaluateExpression("doTest()").GetValueAsUnsigned()
57        )
58
59        self.runCmd("kill")
60
61        self.run_dummy()
62
63        codeFile = open("test.cpp", "r")
64
65        expressions = []
66        current_expression = ""
67
68        for line in codeFile:
69            if line.startswith("// --"):
70                expressions.append(current_expression)
71                current_expression = ""
72            else:
73                current_expression += line
74
75        options = lldb.SBExpressionOptions()
76        options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
77        options.SetTopLevel(True)
78
79        for expression in expressions:
80            self.frame().EvaluateExpression(expression, options)
81
82        resultFromTopLevel = self.frame().EvaluateExpression("doTest()")
83
84        self.assertTrue(resultFromTopLevel.IsValid())
85        self.assertEqual(resultFromCode, resultFromTopLevel.GetValueAsUnsigned())
86
87        # Make sure the command line version works as well:
88        self.runCmd("expr --top-level -- int TopLevelFunction() { return 101; }")
89        resultFromTopLevel = self.frame().EvaluateExpression("TopLevelFunction()")
90        self.assertTrue(resultFromTopLevel.IsValid())
91        self.assertEqual(
92            101, resultFromTopLevel.GetValueAsUnsigned(), "Command line version works."
93        )
94
95    def test_top_level_expression_without_target(self):
96        self.expect(
97            "expr --top-level -- void func() {}",
98            error=True,
99            substrs=["Top-level code needs to be inserted into a runnable target"],
100        )
101
102        # FIXME: This doesn't actually generate any code, so LLDB should probably
103        # allow these expressions.
104        self.expect(
105            "expr --top-level -- template<typename T> struct StructT { T m; };",
106            error=True,
107            substrs=["Top-level code needs to be inserted into a runnable target"],
108        )
109        self.expect(
110            "expr --top-level -- struct Struct { int i; };",
111            error=True,
112            substrs=["Top-level code needs to be inserted into a runnable target"],
113        )
114