1"""
2Test lldb data formatter subsystem.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class LibcxxMapDataFormatterTestCase(TestBase):
14
15    def setUp(self):
16        TestBase.setUp(self)
17        ns = 'ndk' if lldbplatformutil.target_is_android() else ''
18        self.namespace = 'std'
19
20    def check_pair(self, first_value, second_value):
21        pair_children = [ValueCheck(name="first", value=first_value),
22                         ValueCheck(name="second", value=second_value)]
23        return ValueCheck(children=pair_children)
24
25    @add_test_categories(["libc++"])
26    def test_with_run_command(self):
27        """Test that that file and class static variables display correctly."""
28        self.build()
29        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
30
31        bkpt = self.target().FindBreakpointByID(
32            lldbutil.run_break_set_by_source_regexp(
33                self, "Set break point at this line."))
34
35        self.runCmd("run", RUN_SUCCEEDED)
36
37        # The stop reason of the thread should be breakpoint.
38        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
39                    substrs=['stopped',
40                             'stop reason = breakpoint'])
41
42        # This is the function to remove the custom formats in order to have a
43        # clean slate for the next test case.
44        def cleanup():
45            self.runCmd('type format clear', check=False)
46            self.runCmd('type summary clear', check=False)
47            self.runCmd('type filter clear', check=False)
48            self.runCmd('type synth clear', check=False)
49            self.runCmd(
50                "settings set target.max-children-count 256",
51                check=False)
52
53        # Execute the cleanup function during test case tear down.
54        self.addTearDownHook(cleanup)
55
56        ns = self.namespace
57        self.expect_expr("ii", result_summary="size=0", result_children=[])
58
59        self.expect('frame var ii',
60                    substrs=['%s::map' % ns,
61                             'size=0',
62                             '{}'])
63
64        lldbutil.continue_to_breakpoint(self.process(), bkpt)
65
66        self.expect_expr("ii", result_summary="size=2", result_children=[
67            self.check_pair("0", "0"),
68            self.check_pair("1", "1")
69        ])
70
71        self.expect('frame variable ii',
72                    substrs=['%s::map' % ns, 'size=2',
73                             '[0] = ',
74                             'first = 0',
75                             'second = 0',
76                             '[1] = ',
77                             'first = 1',
78                             'second = 1'])
79
80        lldbutil.continue_to_breakpoint(self.process(), bkpt)
81
82        self.expect('frame variable ii',
83                    substrs=['%s::map' % ns, 'size=4',
84                             '[2] = ',
85                             'first = 2',
86                             'second = 0',
87                             '[3] = ',
88                             'first = 3',
89                             'second = 1'])
90
91        lldbutil.continue_to_breakpoint(self.process(), bkpt)
92
93        self.expect("p ii",
94                    substrs=['%s::map' % ns, 'size=8',
95                             '[5] = ',
96                             'first = 5',
97                             'second = 0',
98                             '[7] = ',
99                             'first = 7',
100                             'second = 1'])
101
102        self.expect("frame var ii",
103                    substrs=['%s::map' % ns, 'size=8',
104                             '[5] = ',
105                             'first = 5',
106                             'second = 0',
107                             '[7] = ',
108                             'first = 7',
109                             'second = 1'])
110
111        # check access-by-index
112        self.expect("frame variable ii[0]",
113                    substrs=['first = 0',
114                             'second = 0'])
115        self.expect("frame variable ii[3]",
116                    substrs=['first =',
117                             'second ='])
118
119        # (Non-)const key/val iterators
120        self.expect_expr("it", result_children=[
121            ValueCheck(name="first", value="0"),
122            ValueCheck(name="second", value="0")
123        ])
124        self.expect_expr("const_it", result_children=[
125            ValueCheck(name="first", value="0"),
126            ValueCheck(name="second", value="0")
127        ])
128
129        # check that MightHaveChildren() gets it right
130        self.assertTrue(
131            self.frame().FindVariable("ii").MightHaveChildren(),
132            "ii.MightHaveChildren() says False for non empty!")
133
134        # check that the expression parser does not make use of
135        # synthetic children instead of running code
136        # TOT clang has a fix for this, which makes the expression command here succeed
137        # since this would make the test fail or succeed depending on clang version in use
138        # this is safer commented for the time being
139        # self.expect("expression ii[8]", matching=False, error=True,
140        #            substrs = ['1234567'])
141
142        self.runCmd("continue")
143
144        self.expect('frame variable ii',
145                    substrs=['%s::map' % ns, 'size=0',
146                             '{}'])
147
148        self.expect('frame variable si',
149                    substrs=['%s::map' % ns, 'size=0',
150                             '{}'])
151
152        self.runCmd("continue")
153
154        self.expect('frame variable si',
155                    substrs=['%s::map' % ns, 'size=1',
156                             '[0] = ',
157                             'first = \"zero\"',
158                             'second = 0'])
159
160        lldbutil.continue_to_breakpoint(self.process(), bkpt)
161
162        self.expect(
163            "frame variable si",
164            substrs=[
165                '%s::map' % ns,
166                'size=4',
167                '[0] = (first = "one", second = 1)',
168                '[1] = (first = "three", second = 3)',
169                '[2] = (first = "two", second = 2)',
170                '[3] = (first = "zero", second = 0)',
171            ])
172
173        self.expect(
174            "p si",
175            substrs=[
176                '%s::map' % ns,
177                'size=4',
178                '[0] = (first = "one", second = 1)',
179                '[1] = (first = "three", second = 3)',
180                '[2] = (first = "two", second = 2)',
181                '[3] = (first = "zero", second = 0)',
182            ])
183
184        # check that MightHaveChildren() gets it right
185        self.assertTrue(
186            self.frame().FindVariable("si").MightHaveChildren(),
187            "si.MightHaveChildren() says False for non empty!")
188
189        # check access-by-index
190        self.expect("frame variable si[0]",
191                    substrs=['first = ', 'one',
192                             'second = 1'])
193
194        # check that the expression parser does not make use of
195        # synthetic children instead of running code
196        # TOT clang has a fix for this, which makes the expression command here succeed
197        # since this would make the test fail or succeed depending on clang version in use
198        # this is safer commented for the time being
199        # self.expect("expression si[0]", matching=False, error=True,
200        #            substrs = ['first = ', 'zero'])
201
202        lldbutil.continue_to_breakpoint(self.process(), bkpt)
203
204        self.expect('frame variable si',
205                    substrs=['%s::map' % ns, 'size=0',
206                             '{}'])
207
208        lldbutil.continue_to_breakpoint(self.process(), bkpt)
209
210        self.expect('frame variable is',
211                    substrs=['%s::map' % ns, 'size=0',
212                             '{}'])
213
214        lldbutil.continue_to_breakpoint(self.process(), bkpt)
215
216        self.expect(
217            "frame variable is",
218            substrs=[
219                '%s::map' % ns,
220                'size=4',
221                '[0] = (first = 1, second = "is")',
222                '[1] = (first = 2, second = "smart")',
223                '[2] = (first = 3, second = "!!!")',
224                '[3] = (first = 85, second = "goofy")',
225            ])
226
227        self.expect(
228            "p is",
229            substrs=[
230                '%s::map' % ns,
231                'size=4',
232                '[0] = (first = 1, second = "is")',
233                '[1] = (first = 2, second = "smart")',
234                '[2] = (first = 3, second = "!!!")',
235                '[3] = (first = 85, second = "goofy")',
236            ])
237
238        # check that MightHaveChildren() gets it right
239        self.assertTrue(
240            self.frame().FindVariable("is").MightHaveChildren(),
241            "is.MightHaveChildren() says False for non empty!")
242
243        # check access-by-index
244        self.expect("frame variable is[0]",
245                    substrs=['first = ',
246                             'second ='])
247
248        # check that the expression parser does not make use of
249        # synthetic children instead of running code
250        # TOT clang has a fix for this, which makes the expression command here succeed
251        # since this would make the test fail or succeed depending on clang version in use
252        # this is safer commented for the time being
253        # self.expect("expression is[0]", matching=False, error=True,
254        #            substrs = ['first = ', 'goofy'])
255
256        lldbutil.continue_to_breakpoint(self.process(), bkpt)
257
258        self.expect('frame variable is',
259                    substrs=['%s::map' % ns, 'size=0',
260                             '{}'])
261
262        lldbutil.continue_to_breakpoint(self.process(), bkpt)
263
264        self.expect('frame variable ss',
265                    substrs=['%s::map' % ns, 'size=0',
266                             '{}'])
267
268        lldbutil.continue_to_breakpoint(self.process(), bkpt)
269
270        self.expect(
271            "frame variable ss",
272            substrs=[
273                '%s::map' % ns,
274                'size=3',
275                '[0] = (first = "casa", second = "house")',
276                '[1] = (first = "ciao", second = "hello")',
277                '[2] = (first = "gatto", second = "cat")',
278            ])
279
280        self.expect(
281            "p ss",
282            substrs=[
283                '%s::map' % ns,
284                'size=3',
285                '[0] = (first = "casa", second = "house")',
286                '[1] = (first = "ciao", second = "hello")',
287                '[2] = (first = "gatto", second = "cat")',
288            ])
289
290        # check that MightHaveChildren() gets it right
291        self.assertTrue(
292            self.frame().FindVariable("ss").MightHaveChildren(),
293            "ss.MightHaveChildren() says False for non empty!")
294
295        # check access-by-index
296        self.expect("frame variable ss[2]",
297                    substrs=['gatto', 'cat'])
298
299        # check that the expression parser does not make use of
300        # synthetic children instead of running code
301        # TOT clang has a fix for this, which makes the expression command here succeed
302        # since this would make the test fail or succeed depending on clang version in use
303        # this is safer commented for the time being
304        # self.expect("expression ss[3]", matching=False, error=True,
305        #            substrs = ['gatto'])
306
307        lldbutil.continue_to_breakpoint(self.process(), bkpt)
308
309        self.expect('frame variable ss',
310                    substrs=['%s::map' % ns, 'size=0',
311                             '{}'])
312