1"""
2Test completing types using information from other shared libraries.
3"""
4
5import os
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class LimitDebugInfoTestCase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15
16    def _check_type(self, target, name):
17        exe = target.FindModule(lldb.SBFileSpec("a.out"))
18        type_ = exe.FindFirstType(name)
19        self.trace("type_: %s"%type_)
20        self.assertTrue(type_)
21        base = type_.GetDirectBaseClassAtIndex(0).GetType()
22        self.trace("base:%s"%base)
23        self.assertTrue(base)
24        self.assertEquals(base.GetNumberOfFields(), 0)
25
26    def _check_debug_info_is_limited(self, target):
27        # Without other shared libraries we should only see the member declared
28        # in the derived class. This serves as a sanity check that we are truly
29        # building with limited debug info.
30        self._check_type(target, "InheritsFromOne")
31        self._check_type(target, "InheritsFromTwo")
32
33    @skipIf(bugnumber="pr46284", debug_info="gmodules")
34    @skipIfWindows # Clang emits type info even with -flimit-debug-info
35    # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
36    # by-value functions.
37    @skipIf(compiler="clang", compiler_version=['<', '7.0'])
38    def test_one_and_two_debug(self):
39        self.build()
40        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
41
42        self._check_debug_info_is_limited(target)
43
44        lldbutil.run_to_name_breakpoint(self, "main",
45                extra_images=["one", "two"])
46
47        # But when other shared libraries are loaded, we should be able to see
48        # all members.
49        self.expect_expr("inherits_from_one.member", result_value="47")
50        self.expect_expr("inherits_from_one.one", result_value="142")
51        self.expect_expr("inherits_from_two.member", result_value="47")
52        self.expect_expr("inherits_from_two.one", result_value="142")
53        self.expect_expr("inherits_from_two.two", result_value="242")
54
55        self.expect_expr("one_as_member.member", result_value="47")
56        self.expect_expr("one_as_member.one.member", result_value="147")
57        self.expect_expr("two_as_member.member", result_value="47")
58        self.expect_expr("two_as_member.two.one.member", result_value="147")
59        self.expect_expr("two_as_member.two.member", result_value="247")
60
61        self.expect_expr("array_of_one[2].member", result_value="174")
62        self.expect_expr("array_of_two[2].one[2].member", result_value="174")
63        self.expect_expr("array_of_two[2].member", result_value="274")
64
65        self.expect_expr("get_one().member", result_value="124")
66        self.expect_expr("get_two().one().member", result_value="124")
67        self.expect_expr("get_two().member", result_value="224")
68
69        self.expect_expr("shadowed_one.member", result_value="47")
70        self.expect_expr("shadowed_one.one", result_value="142")
71
72    @skipIf(bugnumber="pr46284", debug_info="gmodules")
73    @skipIfWindows # Clang emits type info even with -flimit-debug-info
74    # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
75    # by-value functions.
76    @skipIf(compiler="clang", compiler_version=['<', '7.0'])
77    def test_two_debug(self):
78        self.build(dictionary=dict(STRIP_ONE="1"))
79        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
80
81        self._check_debug_info_is_limited(target)
82
83        lldbutil.run_to_name_breakpoint(self, "main",
84                extra_images=["one", "two"])
85
86        # This time, we should only see the members from the second library.
87        self.expect_expr("inherits_from_one.member", result_value="47")
88        self.expect("expr inherits_from_one.one", error=True,
89            substrs=["no member named 'one' in 'InheritsFromOne'"])
90        self.expect_expr("inherits_from_two.member", result_value="47")
91        self.expect("expr inherits_from_two.one", error=True,
92            substrs=["no member named 'one' in 'InheritsFromTwo'"])
93        self.expect_expr("inherits_from_two.two", result_value="242")
94
95        self.expect_expr("one_as_member.member", result_value="47")
96        self.expect("expr one_as_member.one.member", error=True,
97                substrs=["no member named 'member' in 'member::One'"])
98        self.expect_expr("two_as_member.member", result_value="47")
99        self.expect("expr two_as_member.two.one.member", error=True,
100                substrs=["no member named 'member' in 'member::One'"])
101        self.expect_expr("two_as_member.two.member", result_value="247")
102
103        self.expect("expr array_of_one[2].member", error=True,
104                substrs=["no member named 'member' in 'array::One'"])
105        self.expect("expr array_of_two[2].one[2].member", error=True,
106                substrs=["no member named 'member' in 'array::One'"])
107        self.expect_expr("array_of_two[2].member", result_value="274")
108
109        self.expect("expr get_one().member", error=True,
110                substrs=["calling 'get_one' with incomplete return type 'result::One'"])
111        self.expect("expr get_two().one().member", error=True,
112                substrs=["calling 'one' with incomplete return type 'result::One'"])
113        self.expect_expr("get_two().member", result_value="224")
114
115    @skipIf(bugnumber="pr46284", debug_info="gmodules")
116    @skipIfWindows # Clang emits type info even with -flimit-debug-info
117    # Requires DW_CC_pass_by_* attributes from Clang 7 to correctly call
118    # by-value functions.
119    @skipIf(compiler="clang", compiler_version=['<', '7.0'])
120    def test_one_debug(self):
121        self.build(dictionary=dict(STRIP_TWO="1"))
122        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
123
124        self._check_debug_info_is_limited(target)
125
126        lldbutil.run_to_name_breakpoint(self, "main",
127                extra_images=["one", "two"])
128
129        # In this case we should only see the members from the second library.
130        # Note that we cannot see inherits_from_two.one because without debug
131        # info for "Two", we cannot determine that it in fact inherits from
132        # "One".
133        self.expect_expr("inherits_from_one.member", result_value="47")
134        self.expect_expr("inherits_from_one.one", result_value="142")
135        self.expect_expr("inherits_from_two.member", result_value="47")
136        self.expect("expr inherits_from_two.one", error=True,
137            substrs=["no member named 'one' in 'InheritsFromTwo'"])
138        self.expect("expr inherits_from_two.two", error=True,
139            substrs=["no member named 'two' in 'InheritsFromTwo'"])
140
141        self.expect_expr("one_as_member.member", result_value="47")
142        self.expect_expr("one_as_member.one.member", result_value="147")
143        self.expect_expr("two_as_member.member", result_value="47")
144        self.expect("expr two_as_member.two.one.member", error=True,
145                substrs=["no member named 'one' in 'member::Two'"])
146        self.expect("expr two_as_member.two.member", error=True,
147                substrs=["no member named 'member' in 'member::Two'"])
148
149        self.expect_expr("array_of_one[2].member", result_value="174")
150        self.expect("expr array_of_two[2].one[2].member", error=True,
151                substrs=["no member named 'one' in 'array::Two'"])
152        self.expect("expr array_of_two[2].member", error=True,
153                substrs=["no member named 'member' in 'array::Two'"])
154
155        self.expect_expr("get_one().member", result_value="124")
156        self.expect("expr get_two().one().member", error=True,
157                substrs=["calling 'get_two' with incomplete return type 'result::Two'"])
158        self.expect("expr get_two().member", error=True,
159                substrs=["calling 'get_two' with incomplete return type 'result::Two'"])
160