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    def test_one_and_two_debug(self):
36        self.build()
37        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
38
39        self._check_debug_info_is_limited(target)
40
41        self.registerSharedLibrariesWithTarget(target, ["one", "two"])
42
43        # But when other shared libraries are loaded, we should be able to see
44        # all members.
45        self.expect_expr("inherits_from_one.member", result_value="47")
46        self.expect_expr("inherits_from_one.one", result_value="142")
47        self.expect_expr("inherits_from_two.member", result_value="47")
48        self.expect_expr("inherits_from_two.one", result_value="142")
49        self.expect_expr("inherits_from_two.two", result_value="242")
50
51        self.expect_expr("one_as_member.member", result_value="47")
52        self.expect_expr("one_as_member.one.member", result_value="147")
53        self.expect_expr("two_as_member.member", result_value="47")
54        self.expect_expr("two_as_member.two.one.member", result_value="147")
55        self.expect_expr("two_as_member.two.member", result_value="247")
56
57        self.expect_expr("array_of_one[2].member", result_value="174")
58        self.expect_expr("array_of_two[2].one[2].member", result_value="174")
59        self.expect_expr("array_of_two[2].member", result_value="274")
60
61    @skipIf(bugnumber="pr46284", debug_info="gmodules")
62    @skipIfWindows # Clang emits type info even with -flimit-debug-info
63    def test_two_debug(self):
64        self.build(dictionary=dict(STRIP_ONE="1"))
65        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
66
67        self._check_debug_info_is_limited(target)
68
69        self.registerSharedLibrariesWithTarget(target, ["one", "two"])
70
71        # This time, we should only see the members from the second library.
72        self.expect_expr("inherits_from_one.member", result_value="47")
73        self.expect("expr inherits_from_one.one", error=True,
74            substrs=["no member named 'one' in 'InheritsFromOne'"])
75        self.expect_expr("inherits_from_two.member", result_value="47")
76        self.expect("expr inherits_from_two.one", error=True,
77            substrs=["no member named 'one' in 'InheritsFromTwo'"])
78        self.expect_expr("inherits_from_two.two", result_value="242")
79
80        self.expect_expr("one_as_member.member", result_value="47")
81        self.expect("expr one_as_member.one.member", error=True,
82                substrs=["no member named 'member' in 'member::One'"])
83        self.expect_expr("two_as_member.member", result_value="47")
84        self.expect("expr two_as_member.two.one.member", error=True,
85                substrs=["no member named 'member' in 'member::One'"])
86        self.expect_expr("two_as_member.two.member", result_value="247")
87
88        self.expect("expr array_of_one[2].member", error=True,
89                substrs=["no member named 'member' in 'array::One'"])
90        self.expect("expr array_of_two[2].one[2].member", error=True,
91                substrs=["no member named 'member' in 'array::One'"])
92        self.expect_expr("array_of_two[2].member", result_value="274")
93
94    @skipIf(bugnumber="pr46284", debug_info="gmodules")
95    @skipIfWindows # Clang emits type info even with -flimit-debug-info
96    def test_one_debug(self):
97        self.build(dictionary=dict(STRIP_TWO="1"))
98        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
99
100        self._check_debug_info_is_limited(target)
101
102        self.registerSharedLibrariesWithTarget(target, ["one", "two"])
103
104        # In this case we should only see the members from the second library.
105        # Note that we cannot see inherits_from_two.one because without debug
106        # info for "Two", we cannot determine that it in fact inherits from
107        # "One".
108        self.expect_expr("inherits_from_one.member", result_value="47")
109        self.expect_expr("inherits_from_one.one", result_value="142")
110        self.expect_expr("inherits_from_two.member", result_value="47")
111        self.expect("expr inherits_from_two.one", error=True,
112            substrs=["no member named 'one' in 'InheritsFromTwo'"])
113        self.expect("expr inherits_from_two.two", error=True,
114            substrs=["no member named 'two' in 'InheritsFromTwo'"])
115
116        self.expect_expr("one_as_member.member", result_value="47")
117        self.expect_expr("one_as_member.one.member", result_value="147")
118        self.expect_expr("two_as_member.member", result_value="47")
119        self.expect("expr two_as_member.two.one.member", error=True,
120                substrs=["no member named 'one' in 'member::Two'"])
121        self.expect("expr two_as_member.two.member", error=True,
122                substrs=["no member named 'member' in 'member::Two'"])
123
124        self.expect_expr("array_of_one[2].member", result_value="174")
125        self.expect("expr array_of_two[2].one[2].member", error=True,
126                substrs=["no member named 'one' in 'array::Two'"])
127        self.expect("expr array_of_two[2].member", error=True,
128                substrs=["no member named 'member' in 'array::Two'"])
129