xref: /llvm-project/lldb/test/API/commands/expression/formatters/TestFormatters.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest using LLDB data formatters with frozen objects coming from the expression parser.
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 ExprFormattersTestCase(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.cpp.
17*2238dcc3SJonas Devlieghere        self.line = line_number("main.cpp", "// Stop here")
1899451b44SJordan Rupprecht
1999451b44SJordan Rupprecht    @skipIfTargetAndroid()  # skipping to avoid crashing the test runner
20*2238dcc3SJonas Devlieghere    @expectedFailureAndroid("llvm.org/pr24691")  # we hit an assertion in clang
2199451b44SJordan Rupprecht    def test(self):
2299451b44SJordan Rupprecht        """Test expr + formatters for good interoperability."""
2399451b44SJordan Rupprecht        self.build()
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprecht        # This is the function to remove the custom formats in order to have a
2699451b44SJordan Rupprecht        # clean slate for the next test case.
2799451b44SJordan Rupprecht        def cleanup():
28*2238dcc3SJonas Devlieghere            self.runCmd("type summary clear", check=False)
29*2238dcc3SJonas Devlieghere            self.runCmd("type synthetic clear", check=False)
3099451b44SJordan Rupprecht
3199451b44SJordan Rupprecht        # Execute the cleanup function during test case tear down.
3299451b44SJordan Rupprecht        self.addTearDownHook(cleanup)
3399451b44SJordan Rupprecht
3499451b44SJordan Rupprecht        """Test expr + formatters for good interoperability."""
3599451b44SJordan Rupprecht        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
38*2238dcc3SJonas Devlieghere            self, "main.cpp", self.line, loc_exact=True
39*2238dcc3SJonas Devlieghere        )
4099451b44SJordan Rupprecht
4199451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
4299451b44SJordan Rupprecht        self.runCmd("command script import formatters.py")
4399451b44SJordan Rupprecht        self.runCmd("command script import foosynth.py")
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht        if self.TraceOn():
4699451b44SJordan Rupprecht            self.runCmd("frame variable foo1 --show-types")
4799451b44SJordan Rupprecht            self.runCmd("frame variable foo1.b --show-types")
4899451b44SJordan Rupprecht            self.runCmd("frame variable foo1.b.b_ref --show-types")
4999451b44SJordan Rupprecht
50*2238dcc3SJonas Devlieghere        self.filecheck(
51*2238dcc3SJonas Devlieghere            "expression --show-types -- *(new_foo(47))",
52*2238dcc3SJonas Devlieghere            __file__,
53*2238dcc3SJonas Devlieghere            "-check-prefix=EXPR-TYPES-NEW-FOO",
54*2238dcc3SJonas Devlieghere        )
5599451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO: (foo) ${{.*}} = {
5699451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:   (int) a = 47
5799451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:   (int *) a_ptr = 0x
5899451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:   (bar) b = {
5999451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:     (int) i = 94
6099451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:     (int *) i_ptr = 0x
6199451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:     (baz) b = {
6299451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:       (int) h = 97
6399451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:       (int) k = 99
6499451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:     }
6599451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:     (baz &) b_ref = 0x
6699451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT:   }
6799451b44SJordan Rupprecht        # EXPR-TYPES-NEW-FOO-NEXT: }
6899451b44SJordan Rupprecht
6999451b44SJordan Rupprecht        self.runCmd("type summary add -F formatters.foo_SummaryProvider3 foo")
70*2238dcc3SJonas Devlieghere        self.filecheck("expression foo1", __file__, "-check-prefix=EXPR-FOO1opts")
7199451b44SJordan Rupprecht        # EXPR-FOO1opts: (foo) $
7299451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: a = 12
7399451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: a_ptr = {{[0-9]+}} -> 13
7499451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: i = 24
7599451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: i_ptr = {{[0-9]+}} -> 25
7699451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: b_ref = {{[0-9]+}}
7799451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: h = 27
7899451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: k = 29
7999451b44SJordan Rupprecht        # EXPR-FOO1opts-SAME: WITH_OPTS
8099451b44SJordan Rupprecht
8199451b44SJordan Rupprecht        self.runCmd("type summary delete foo")
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
8499451b44SJordan Rupprecht
85*2238dcc3SJonas Devlieghere        self.expect("expression new_int(12)", substrs=["(int *) $", " = 0x"])
8699451b44SJordan Rupprecht
87*2238dcc3SJonas Devlieghere        self.runCmd('type summary add -s "${var%pointer} -> ${*var%decimal}" "int *"')
8899451b44SJordan Rupprecht
89*2238dcc3SJonas Devlieghere        self.expect("expression new_int(12)", substrs=["(int *) $", "= 0x", " -> 12"])
9099451b44SJordan Rupprecht
91*2238dcc3SJonas Devlieghere        self.expect("expression foo1.a_ptr", substrs=["(int *) $", "= 0x", " -> 13"])
9299451b44SJordan Rupprecht
93*2238dcc3SJonas Devlieghere        self.filecheck("expression foo1", __file__, "-check-prefix=EXPR-FOO1")
9499451b44SJordan Rupprecht        # EXPR-FOO1: (foo) $
9599451b44SJordan Rupprecht        # EXPR-FOO1-SAME: a = 12
9699451b44SJordan Rupprecht        # EXPR-FOO1-SAME: a_ptr = {{[0-9]+}} -> 13
9799451b44SJordan Rupprecht        # EXPR-FOO1-SAME: i = 24
9899451b44SJordan Rupprecht        # EXPR-FOO1-SAME: i_ptr = {{[0-9]+}} -> 25
9999451b44SJordan Rupprecht        # EXPR-FOO1-SAME: b_ref = {{[0-9]+}}
10099451b44SJordan Rupprecht        # EXPR-FOO1-SAME: h = 27
10199451b44SJordan Rupprecht        # EXPR-FOO1-SAME: k = 29
10299451b44SJordan Rupprecht
103*2238dcc3SJonas Devlieghere        self.filecheck(
104*2238dcc3SJonas Devlieghere            "expression --ptr-depth=1 -- new_foo(47)",
105*2238dcc3SJonas Devlieghere            __file__,
106*2238dcc3SJonas Devlieghere            "-check-prefix=EXPR-PTR-DEPTH1",
107*2238dcc3SJonas Devlieghere        )
10899451b44SJordan Rupprecht        # EXPR-PTR-DEPTH1: (foo *) $
10999451b44SJordan Rupprecht        # EXPR-PTR-DEPTH1-SAME: a = 47
11099451b44SJordan Rupprecht        # EXPR-PTR-DEPTH1-SAME: a_ptr = {{[0-9]+}} -> 48
11199451b44SJordan Rupprecht        # EXPR-PTR-DEPTH1-SAME: i = 94
11299451b44SJordan Rupprecht        # EXPR-PTR-DEPTH1-SAME: i_ptr = {{[0-9]+}} -> 95
11399451b44SJordan Rupprecht
114*2238dcc3SJonas Devlieghere        self.filecheck("expression foo2", __file__, "-check-prefix=EXPR-FOO2")
11599451b44SJordan Rupprecht        # EXPR-FOO2: (foo) $
11699451b44SJordan Rupprecht        # EXPR-FOO2-SAME: a = 121
11799451b44SJordan Rupprecht        # EXPR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122
11899451b44SJordan Rupprecht        # EXPR-FOO2-SAME: i = 242
11999451b44SJordan Rupprecht        # EXPR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243
12099451b44SJordan Rupprecht        # EXPR-FOO2-SAME: h = 245
12199451b44SJordan Rupprecht        # EXPR-FOO2-SAME: k = 247
12299451b44SJordan Rupprecht
12399451b44SJordan Rupprecht        object_name = self.res.GetOutput()
12499451b44SJordan Rupprecht        object_name = object_name[7:]
125*2238dcc3SJonas Devlieghere        object_name = object_name[0 : object_name.find(" =")]
12699451b44SJordan Rupprecht
127*2238dcc3SJonas Devlieghere        self.filecheck("frame variable foo2", __file__, "-check-prefix=VAR-FOO2")
12899451b44SJordan Rupprecht        # VAR-FOO2: (foo) foo2
12999451b44SJordan Rupprecht        # VAR-FOO2-SAME: a = 121
13099451b44SJordan Rupprecht        # VAR-FOO2-SAME: a_ptr = {{[0-9]+}} -> 122
13199451b44SJordan Rupprecht        # VAR-FOO2-SAME: i = 242
13299451b44SJordan Rupprecht        # VAR-FOO2-SAME: i_ptr = {{[0-9]+}} -> 243
13399451b44SJordan Rupprecht        # VAR-FOO2-SAME: h = 245
13499451b44SJordan Rupprecht        # VAR-FOO2-SAME: k = 247
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht        # The object is the same as foo2, so use the EXPR-FOO2 checks.
137*2238dcc3SJonas Devlieghere        self.filecheck(
138*2238dcc3SJonas Devlieghere            "expression $" + object_name, __file__, "-check-prefix=EXPR-FOO2"
139*2238dcc3SJonas Devlieghere        )
14099451b44SJordan Rupprecht
14199451b44SJordan Rupprecht        self.runCmd("type summary delete foo")
14299451b44SJordan Rupprecht        self.runCmd(
143*2238dcc3SJonas Devlieghere            "type synthetic add --python-class foosynth.FooSyntheticProvider foo"
144*2238dcc3SJonas Devlieghere        )
14599451b44SJordan Rupprecht
146*2238dcc3SJonas Devlieghere        self.expect(
147*2238dcc3SJonas Devlieghere            "expression --show-types -- $" + object_name,
148*2238dcc3SJonas Devlieghere            substrs=["(foo) $", " = {", "(int) *i_ptr = 243"],
149*2238dcc3SJonas Devlieghere        )
15099451b44SJordan Rupprecht
15199451b44SJordan Rupprecht        self.runCmd("n")
15299451b44SJordan Rupprecht        self.runCmd("n")
15399451b44SJordan Rupprecht
15499451b44SJordan Rupprecht        self.runCmd("type synthetic delete foo")
15599451b44SJordan Rupprecht        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
15699451b44SJordan Rupprecht
15799451b44SJordan Rupprecht        self.expect(
15899451b44SJordan Rupprecht            "expression foo2",
15999451b44SJordan Rupprecht            substrs=[
160*2238dcc3SJonas Devlieghere                "(foo) $",
161*2238dcc3SJonas Devlieghere                "a = 7777",
162*2238dcc3SJonas Devlieghere                "a_ptr = ",
163*2238dcc3SJonas Devlieghere                " -> 122",
164*2238dcc3SJonas Devlieghere                "i = 242",
165*2238dcc3SJonas Devlieghere                "i_ptr = ",
166*2238dcc3SJonas Devlieghere                " -> 8888",
167*2238dcc3SJonas Devlieghere            ],
168*2238dcc3SJonas Devlieghere        )
16999451b44SJordan Rupprecht
170*2238dcc3SJonas Devlieghere        self.expect("expression $" + object_name + ".a", substrs=["7777"])
17199451b44SJordan Rupprecht
172*2238dcc3SJonas Devlieghere        self.expect("expression *$" + object_name + ".b.i_ptr", substrs=["8888"])
17399451b44SJordan Rupprecht
17499451b44SJordan Rupprecht        self.expect(
175*2238dcc3SJonas Devlieghere            "expression $" + object_name,
17699451b44SJordan Rupprecht            substrs=[
177*2238dcc3SJonas Devlieghere                "(foo) $",
178*2238dcc3SJonas Devlieghere                "a = 121",
179*2238dcc3SJonas Devlieghere                "a_ptr = ",
180*2238dcc3SJonas Devlieghere                " -> 122",
181*2238dcc3SJonas Devlieghere                "i = 242",
182*2238dcc3SJonas Devlieghere                "i_ptr = ",
183*2238dcc3SJonas Devlieghere                " -> 8888",
184*2238dcc3SJonas Devlieghere                "h = 245",
185*2238dcc3SJonas Devlieghere                "k = 247",
186*2238dcc3SJonas Devlieghere            ],
187*2238dcc3SJonas Devlieghere        )
18899451b44SJordan Rupprecht
18999451b44SJordan Rupprecht        self.runCmd("type summary delete foo")
19099451b44SJordan Rupprecht        self.runCmd(
191*2238dcc3SJonas Devlieghere            "type synthetic add --python-class foosynth.FooSyntheticProvider foo"
192*2238dcc3SJonas Devlieghere        )
19399451b44SJordan Rupprecht
194*2238dcc3SJonas Devlieghere        self.expect(
195*2238dcc3SJonas Devlieghere            "expression --show-types -- $" + object_name,
196*2238dcc3SJonas Devlieghere            substrs=["(foo) $", " = {", "(int) *i_ptr = 8888"],
197*2238dcc3SJonas Devlieghere        )
19899451b44SJordan Rupprecht
19999451b44SJordan Rupprecht        self.runCmd("n")
20099451b44SJordan Rupprecht
20199451b44SJordan Rupprecht        self.runCmd("type synthetic delete foo")
20299451b44SJordan Rupprecht        self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
20399451b44SJordan Rupprecht
20499451b44SJordan Rupprecht        self.expect(
205*2238dcc3SJonas Devlieghere            "expression $" + object_name,
20699451b44SJordan Rupprecht            substrs=[
207*2238dcc3SJonas Devlieghere                "(foo) $",
208*2238dcc3SJonas Devlieghere                "a = 121",
209*2238dcc3SJonas Devlieghere                "a_ptr = ",
210*2238dcc3SJonas Devlieghere                " -> 122",
211*2238dcc3SJonas Devlieghere                "i = 242",
212*2238dcc3SJonas Devlieghere                "i_ptr = ",
213*2238dcc3SJonas Devlieghere                " -> 8888",
214*2238dcc3SJonas Devlieghere                "k = 247",
215*2238dcc3SJonas Devlieghere            ],
216*2238dcc3SJonas Devlieghere        )
21799451b44SJordan Rupprecht
21899451b44SJordan Rupprecht        process = self.dbg.GetSelectedTarget().GetProcess()
21999451b44SJordan Rupprecht        thread = process.GetThreadAtIndex(0)
22099451b44SJordan Rupprecht        frame = thread.GetSelectedFrame()
22199451b44SJordan Rupprecht
22299451b44SJordan Rupprecht        frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr")
22399451b44SJordan Rupprecht
22499451b44SJordan Rupprecht        a_data = frozen.GetPointeeData()
22599451b44SJordan Rupprecht
22699451b44SJordan Rupprecht        error = lldb.SBError()
227*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 0), 122, "*a_ptr = 122")
22899451b44SJordan Rupprecht
22999451b44SJordan Rupprecht        ret = line_number("main.cpp", "Done initializing")
23099451b44SJordan Rupprecht        self.runCmd("thread until " + str(ret))
23199451b44SJordan Rupprecht
232*2238dcc3SJonas Devlieghere        self.expect("frame variable numbers", substrs=["1", "2", "3", "4", "5"])
23399451b44SJordan Rupprecht
234*2238dcc3SJonas Devlieghere        self.expect("expression numbers", substrs=["1", "2", "3", "4", "5"])
23599451b44SJordan Rupprecht
23699451b44SJordan Rupprecht        frozen = frame.EvaluateExpression("&numbers")
23799451b44SJordan Rupprecht
23899451b44SJordan Rupprecht        a_data = frozen.GetPointeeData(0, 1)
23999451b44SJordan Rupprecht
240*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 0), 1, "numbers[0] == 1")
241*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 4), 2, "numbers[1] == 2")
242*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 8), 3, "numbers[2] == 3")
243*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 12), 4, "numbers[3] == 4")
244*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 16), 5, "numbers[4] == 5")
24599451b44SJordan Rupprecht
24699451b44SJordan Rupprecht        frozen = frame.EvaluateExpression("numbers")
24799451b44SJordan Rupprecht
24899451b44SJordan Rupprecht        a_data = frozen.GetData()
24999451b44SJordan Rupprecht
250*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 0), 1, "numbers[0] == 1")
251*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 4), 2, "numbers[1] == 2")
252*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 8), 3, "numbers[2] == 3")
253*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 12), 4, "numbers[3] == 4")
254*2238dcc3SJonas Devlieghere        self.assertEqual(a_data.GetUnsignedInt32(error, 16), 5, "numbers[4] == 5")
255