xref: /llvm-project/lldb/test/API/commands/expression/top-level/TestTopLevelExprs.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest top-level expressions.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprechtimport lldb
799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
999451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1099451b44SJordan Rupprecht
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtclass TopLevelExpressionsTestCase(TestBase):
1399451b44SJordan Rupprecht    def setUp(self):
1499451b44SJordan Rupprecht        # Call super's setUp().
1599451b44SJordan Rupprecht        TestBase.setUp(self)
1699451b44SJordan Rupprecht        # Find the line number to break for main.c.
17*2238dcc3SJonas Devlieghere        self.line = line_number("main.cpp", "// Set breakpoint here")
18*2238dcc3SJonas Devlieghere        self.dummy_line = line_number("dummy.cpp", "// Set breakpoint here")
1999451b44SJordan Rupprecht
2099451b44SJordan Rupprecht        # Disable confirmation prompt to avoid infinite wait
2199451b44SJordan Rupprecht        self.runCmd("settings set auto-confirm true")
22*2238dcc3SJonas Devlieghere        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
2399451b44SJordan Rupprecht
2499451b44SJordan Rupprecht    def build_and_run(self):
2599451b44SJordan Rupprecht        """Test top-level expressions."""
2699451b44SJordan Rupprecht        self.build()
2799451b44SJordan Rupprecht
2899451b44SJordan Rupprecht        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
2999451b44SJordan Rupprecht
3099451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
31*2238dcc3SJonas Devlieghere            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False
32*2238dcc3SJonas Devlieghere        )
3399451b44SJordan Rupprecht
3499451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
3599451b44SJordan Rupprecht
3699451b44SJordan Rupprecht    def run_dummy(self):
37*2238dcc3SJonas Devlieghere        self.runCmd("file " + self.getBuildArtifact("dummy"), CURRENT_EXECUTABLE_SET)
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
4099451b44SJordan Rupprecht            self,
4199451b44SJordan Rupprecht            "dummy.cpp",
4299451b44SJordan Rupprecht            self.dummy_line,
4399451b44SJordan Rupprecht            num_expected_locations=1,
44*2238dcc3SJonas Devlieghere            loc_exact=False,
45*2238dcc3SJonas Devlieghere        )
4699451b44SJordan Rupprecht
4799451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
4899451b44SJordan Rupprecht
49*2238dcc3SJonas Devlieghere    @add_test_categories(["pyapi"])
5099451b44SJordan Rupprecht    @skipIf(debug_info="gmodules")  # not relevant
5199451b44SJordan Rupprecht    @skipIf(oslist=["windows"])  # Error in record layout on Windows
5299451b44SJordan Rupprecht    def test_top_level_expressions(self):
5399451b44SJordan Rupprecht        self.build_and_run()
5499451b44SJordan Rupprecht
55*2238dcc3SJonas Devlieghere        resultFromCode = (
56*2238dcc3SJonas Devlieghere            self.frame().EvaluateExpression("doTest()").GetValueAsUnsigned()
57*2238dcc3SJonas Devlieghere        )
5899451b44SJordan Rupprecht
5999451b44SJordan Rupprecht        self.runCmd("kill")
6099451b44SJordan Rupprecht
6199451b44SJordan Rupprecht        self.run_dummy()
6299451b44SJordan Rupprecht
63*2238dcc3SJonas Devlieghere        codeFile = open("test.cpp", "r")
6499451b44SJordan Rupprecht
6599451b44SJordan Rupprecht        expressions = []
6699451b44SJordan Rupprecht        current_expression = ""
6799451b44SJordan Rupprecht
6899451b44SJordan Rupprecht        for line in codeFile:
6999451b44SJordan Rupprecht            if line.startswith("// --"):
7099451b44SJordan Rupprecht                expressions.append(current_expression)
7199451b44SJordan Rupprecht                current_expression = ""
7299451b44SJordan Rupprecht            else:
7399451b44SJordan Rupprecht                current_expression += line
7499451b44SJordan Rupprecht
7599451b44SJordan Rupprecht        options = lldb.SBExpressionOptions()
7699451b44SJordan Rupprecht        options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
7799451b44SJordan Rupprecht        options.SetTopLevel(True)
7899451b44SJordan Rupprecht
7999451b44SJordan Rupprecht        for expression in expressions:
8099451b44SJordan Rupprecht            self.frame().EvaluateExpression(expression, options)
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        resultFromTopLevel = self.frame().EvaluateExpression("doTest()")
8399451b44SJordan Rupprecht
8499451b44SJordan Rupprecht        self.assertTrue(resultFromTopLevel.IsValid())
85*2238dcc3SJonas Devlieghere        self.assertEqual(resultFromCode, resultFromTopLevel.GetValueAsUnsigned())
8671536fd0SRaphael Isemann
8769529286SJim Ingham        # Make sure the command line version works as well:
8869529286SJim Ingham        self.runCmd("expr --top-level -- int TopLevelFunction() { return 101; }")
8969529286SJim Ingham        resultFromTopLevel = self.frame().EvaluateExpression("TopLevelFunction()")
9069529286SJim Ingham        self.assertTrue(resultFromTopLevel.IsValid())
91*2238dcc3SJonas Devlieghere        self.assertEqual(
92*2238dcc3SJonas Devlieghere            101, resultFromTopLevel.GetValueAsUnsigned(), "Command line version works."
93*2238dcc3SJonas Devlieghere        )
9469529286SJim Ingham
9571536fd0SRaphael Isemann    def test_top_level_expression_without_target(self):
96*2238dcc3SJonas Devlieghere        self.expect(
97*2238dcc3SJonas Devlieghere            "expr --top-level -- void func() {}",
98*2238dcc3SJonas Devlieghere            error=True,
99*2238dcc3SJonas Devlieghere            substrs=["Top-level code needs to be inserted into a runnable target"],
100*2238dcc3SJonas Devlieghere        )
10171536fd0SRaphael Isemann
10271536fd0SRaphael Isemann        # FIXME: This doesn't actually generate any code, so LLDB should probably
10371536fd0SRaphael Isemann        # allow these expressions.
104*2238dcc3SJonas Devlieghere        self.expect(
105*2238dcc3SJonas Devlieghere            "expr --top-level -- template<typename T> struct StructT { T m; };",
106*2238dcc3SJonas Devlieghere            error=True,
107*2238dcc3SJonas Devlieghere            substrs=["Top-level code needs to be inserted into a runnable target"],
108*2238dcc3SJonas Devlieghere        )
109*2238dcc3SJonas Devlieghere        self.expect(
110*2238dcc3SJonas Devlieghere            "expr --top-level -- struct Struct { int i; };",
111*2238dcc3SJonas Devlieghere            error=True,
112*2238dcc3SJonas Devlieghere            substrs=["Top-level code needs to be inserted into a runnable target"],
113*2238dcc3SJonas Devlieghere        )
114