Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / test / API / functionalities / limit-debug-info / TestLimitDebugInfo.py
blobbf45202ac316e2aa44113c15d0ba239d1839f8c5
1 """
2 Test completing types using information from other shared libraries.
3 """
5 import os
6 import lldb
7 from lldbsuite.test.decorators import *
8 from lldbsuite.test.lldbtest import *
9 from lldbsuite.test import lldbutil
12 class LimitDebugInfoTestCase(TestBase):
13 def _check_type(self, target, name):
14 exe = target.FindModule(lldb.SBFileSpec("a.out"))
15 type_ = exe.FindFirstType(name)
16 self.trace("type_: %s" % type_)
17 self.assertTrue(type_)
18 self.assertTrue(type_.IsTypeComplete())
19 base = type_.GetDirectBaseClassAtIndex(0).GetType()
20 self.trace("base:%s" % base)
21 self.assertTrue(base)
22 self.assertEquals(base.GetNumberOfFields(), 0)
23 self.assertFalse(base.IsTypeComplete())
25 def _check_debug_info_is_limited(self, target):
26 # Without other shared libraries we should only see the member declared
27 # in the derived class. This serves as a sanity check that we are truly
28 # building with limited debug info.
29 self._check_type(target, "InheritsFromOne")
30 self._check_type(target, "InheritsFromTwo")
32 # Check that the statistics show that we had incomplete debug info.
33 stats = self.get_stats()
34 # Find the a.out module info in the stats and verify it has the
35 # "debugInfoHadIncompleteTypes" key value pair set to True
36 exe_module_found = False
37 for module in stats["modules"]:
38 if module["path"].endswith("a.out"):
39 self.assertTrue(module["debugInfoHadIncompleteTypes"])
40 exe_module_found = True
41 break
42 self.assertTrue(exe_module_found)
43 # Verify that "totalModuleCountWithIncompleteTypes" at the top level
44 # is greater than zero which shows we had incomplete debug info in a
45 # module
46 self.assertGreater(stats["totalModuleCountWithIncompleteTypes"], 0)
48 def _check_incomplete_frame_variable_output(self):
49 # Check that the display of the "frame variable" output identifies the
50 # incomplete types. Currently the expression parser will find the real
51 # definition for a type when running an expression for any forcefully
52 # completed types, but "frame variable" won't. I hope to fix this with
53 # a follow up patch, but if we don't find the actual definition we
54 # should clearly show this to the user by showing which types were
55 # incomplete. So this will test verifies the expected output for such
56 # types. We also need to verify the standard "frame variable" output
57 # which will inline all of the members on one line, versus the full
58 # output from "frame variable --raw" and a few other options.
59 # self.expect("frame variable two_as_member", error=True,
60 # substrs=["no member named 'one' in 'InheritsFromOne'"])
62 command_expect_pairs = [
63 # Test standard "frame variable" output for types to make sure
64 # "<incomplete type>" shows up where we expect it to
66 "var two_as_member",
68 "(TwoAsMember) ::two_as_member = (two = <incomplete type>, member = 47)"
72 "var inherits_from_one",
74 "(InheritsFromOne) ::inherits_from_one = (One = <incomplete type>, member = 47)"
78 "var inherits_from_two",
80 "(InheritsFromTwo) ::inherits_from_two = (Two = <incomplete type>, member = 47)"
84 "var one_as_member",
86 "(OneAsMember) ::one_as_member = (one = <incomplete type>, member = 47)"
90 "var two_as_member",
92 "(TwoAsMember) ::two_as_member = (two = <incomplete type>, member = 47)"
96 "var array_of_one",
98 "(array::One[3]) ::array_of_one = ([0] = <incomplete type>, [1] = <incomplete type>, [2] = <incomplete type>)"
102 "var array_of_two",
104 "(array::Two[3]) ::array_of_two = ([0] = <incomplete type>, [1] = <incomplete type>, [2] = <incomplete type>)"
108 "var shadowed_one",
110 "(ShadowedOne) ::shadowed_one = (func_shadow::One = <incomplete type>, member = 47)"
113 # Now test "frame variable --show-types output" which has multi-line
114 # output and should not always show classes that were forcefully
115 # completed to the user to let them know they have a type that should
116 # have been complete but wasn't.
118 "var --show-types inherits_from_one",
120 "(InheritsFromOne) ::inherits_from_one = {",
121 " (One) One = <incomplete type> {}",
122 " (int) member = 47",
123 "}",
127 "var --show-types inherits_from_two",
129 "(InheritsFromTwo) ::inherits_from_two = {",
130 " (Two) Two = <incomplete type> {}",
131 " (int) member = 47",
132 "}",
136 "var --show-types one_as_member",
138 "(OneAsMember) ::one_as_member = {",
139 " (member::One) one = <incomplete type> {}",
140 " (int) member = 47",
141 "}",
145 "var --show-types two_as_member",
147 "(TwoAsMember) ::two_as_member = {",
148 " (member::Two) two = <incomplete type> {}",
149 " (int) member = 47",
150 "}",
154 "var --show-types array_of_one",
156 "(array::One[3]) ::array_of_one = {",
157 " (array::One) [0] = <incomplete type> {}",
158 " (array::One) [1] = <incomplete type> {}",
159 " (array::One) [2] = <incomplete type> {}",
160 "}",
164 "var --show-types array_of_two",
166 "(array::Two[3]) ::array_of_two = {",
167 " (array::Two) [0] = <incomplete type> {}",
168 " (array::Two) [1] = <incomplete type> {}",
169 " (array::Two) [2] = <incomplete type> {}",
170 "}",
174 "var --show-types shadowed_one",
176 "(ShadowedOne) ::shadowed_one = {",
177 " (func_shadow::One) func_shadow::One = <incomplete type> {}",
178 " (int) member = 47",
179 "}",
183 for command, expect_items in command_expect_pairs:
184 self.expect(command, substrs=expect_items)
186 @skipIf(bugnumber="pr46284", debug_info="gmodules")
187 @skipIfWindows # Clang emits type info even with -flimit-debug-info
188 # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
189 # by-value functions.
190 @skipIf(compiler="clang", compiler_version=["<", "7.0"])
191 def test_one_and_two_debug(self):
192 self.build()
193 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
195 self._check_debug_info_is_limited(target)
197 lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"])
199 # But when other shared libraries are loaded, we should be able to see
200 # all members.
201 self.expect_expr("inherits_from_one.member", result_value="47")
202 self.expect_expr("inherits_from_one.one", result_value="142")
203 self.expect_expr("inherits_from_two.member", result_value="47")
204 self.expect_expr("inherits_from_two.one", result_value="142")
205 self.expect_expr("inherits_from_two.two", result_value="242")
207 self.expect_expr("one_as_member.member", result_value="47")
208 self.expect_expr("one_as_member.one.member", result_value="147")
209 self.expect_expr("two_as_member.member", result_value="47")
210 self.expect_expr("two_as_member.two.one.member", result_value="147")
211 self.expect_expr("two_as_member.two.member", result_value="247")
213 self.expect_expr("array_of_one[2].member", result_value="174")
214 self.expect_expr("array_of_two[2].one[2].member", result_value="174")
215 self.expect_expr("array_of_two[2].member", result_value="274")
217 self.expect_expr("get_one().member", result_value="124")
218 self.expect_expr("get_two().one().member", result_value="124")
219 self.expect_expr("get_two().member", result_value="224")
221 self.expect_expr("shadowed_one.member", result_value="47")
222 self.expect_expr("shadowed_one.one", result_value="142")
224 self._check_incomplete_frame_variable_output()
226 @skipIf(bugnumber="pr46284", debug_info="gmodules")
227 @skipIfWindows # Clang emits type info even with -flimit-debug-info
228 # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
229 # by-value functions.
230 @skipIf(compiler="clang", compiler_version=["<", "7.0"])
231 def test_two_debug(self):
232 self.build(dictionary=dict(STRIP_ONE="1"))
233 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
235 self._check_debug_info_is_limited(target)
237 lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"])
239 # This time, we should only see the members from the second library.
240 self.expect_expr("inherits_from_one.member", result_value="47")
241 self.expect(
242 "expr inherits_from_one.one",
243 error=True,
244 substrs=["no member named 'one' in 'InheritsFromOne'"],
246 self.expect_expr("inherits_from_two.member", result_value="47")
247 self.expect(
248 "expr inherits_from_two.one",
249 error=True,
250 substrs=["no member named 'one' in 'InheritsFromTwo'"],
252 self.expect_expr("inherits_from_two.two", result_value="242")
254 self.expect_expr("one_as_member.member", result_value="47")
255 self.expect(
256 "expr one_as_member.one.member",
257 error=True,
258 substrs=["no member named 'member' in 'member::One'"],
260 self.expect_expr("two_as_member.member", result_value="47")
261 self.expect(
262 "expr two_as_member.two.one.member",
263 error=True,
264 substrs=["no member named 'member' in 'member::One'"],
266 self.expect_expr("two_as_member.two.member", result_value="247")
268 self.expect(
269 "expr array_of_one[2].member",
270 error=True,
271 substrs=["no member named 'member' in 'array::One'"],
273 self.expect(
274 "expr array_of_two[2].one[2].member",
275 error=True,
276 substrs=["no member named 'member' in 'array::One'"],
278 self.expect_expr("array_of_two[2].member", result_value="274")
280 self.expect(
281 "expr get_one().member",
282 error=True,
283 substrs=["calling 'get_one' with incomplete return type 'result::One'"],
285 self.expect(
286 "expr get_two().one().member",
287 error=True,
288 substrs=["calling 'one' with incomplete return type 'result::One'"],
290 self.expect_expr("get_two().member", result_value="224")
292 self._check_incomplete_frame_variable_output()
294 @skipIf(bugnumber="pr46284", debug_info="gmodules")
295 @skipIfWindows # Clang emits type info even with -flimit-debug-info
296 # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
297 # by-value functions.
298 @skipIf(compiler="clang", compiler_version=["<", "7.0"])
299 def test_one_debug(self):
300 self.build(dictionary=dict(STRIP_TWO="1"))
301 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
303 self._check_debug_info_is_limited(target)
305 lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"])
307 # In this case we should only see the members from the second library.
308 # Note that we cannot see inherits_from_two.one because without debug
309 # info for "Two", we cannot determine that it in fact inherits from
310 # "One".
311 self.expect_expr("inherits_from_one.member", result_value="47")
312 self.expect_expr("inherits_from_one.one", result_value="142")
313 self.expect_expr("inherits_from_two.member", result_value="47")
314 self.expect(
315 "expr inherits_from_two.one",
316 error=True,
317 substrs=["no member named 'one' in 'InheritsFromTwo'"],
319 self.expect(
320 "expr inherits_from_two.two",
321 error=True,
322 substrs=["no member named 'two' in 'InheritsFromTwo'"],
325 self.expect_expr("one_as_member.member", result_value="47")
326 self.expect_expr("one_as_member.one.member", result_value="147")
327 self.expect_expr("two_as_member.member", result_value="47")
328 self.expect(
329 "expr two_as_member.two.one.member",
330 error=True,
331 substrs=["no member named 'one' in 'member::Two'"],
333 self.expect(
334 "expr two_as_member.two.member",
335 error=True,
336 substrs=["no member named 'member' in 'member::Two'"],
339 self.expect_expr("array_of_one[2].member", result_value="174")
340 self.expect(
341 "expr array_of_two[2].one[2].member",
342 error=True,
343 substrs=["no member named 'one' in 'array::Two'"],
345 self.expect(
346 "expr array_of_two[2].member",
347 error=True,
348 substrs=["no member named 'member' in 'array::Two'"],
351 self.expect_expr("get_one().member", result_value="124")
352 self.expect(
353 "expr get_two().one().member",
354 error=True,
355 substrs=["calling 'get_two' with incomplete return type 'result::Two'"],
357 self.expect(
358 "expr get_two().member",
359 error=True,
360 substrs=["calling 'get_two' with incomplete return type 'result::Two'"],
363 self._check_incomplete_frame_variable_output()