xref: /llvm-project/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py (revision 31e55d461693df035049e09cbeeb8886ca2cb6d3)
1"""Show bitfields and check that they display correctly."""
2
3import lldb
4from lldbsuite.test.decorators import *
5from lldbsuite.test.lldbtest import *
6from lldbsuite.test import lldbutil
7
8
9class CppBitfieldsTestCase(TestBase):
10    @no_debug_info_test
11    @skipIf(oslist=["windows"], bugnumber="github.com/llvm/llvm-project/issues/105019")
12    def test_bitfields(self):
13        self.build()
14        lldbutil.run_to_source_breakpoint(
15            self, "// break here", lldb.SBFileSpec("main.cpp", False)
16        )
17
18        # Accessing LargeBitsA.
19        self.expect_expr(
20            "lba",
21            result_children=[
22                ValueCheck(name="", type="int:32"),
23                ValueCheck(name="a", type="unsigned int:20", value="2"),
24            ],
25        )
26        self.expect_expr("lba.a", result_type="unsigned int", result_value="2")
27
28        # Accessing LargeBitsB.
29        self.expect_expr(
30            "lbb",
31            result_children=[
32                ValueCheck(name="a", type="unsigned int:1", value="1"),
33                ValueCheck(name="", type="int:31"),
34                ValueCheck(name="b", type="unsigned int:20", value="3"),
35            ],
36        )
37        self.expect_expr("lbb.b", result_type="unsigned int", result_value="3")
38
39        # Accessing LargeBitsC.
40        self.expect_expr(
41            "lbc",
42            result_children=[
43                ValueCheck(name="", type="int:22"),
44                ValueCheck(name="a", type="unsigned int:1", value="1"),
45                ValueCheck(name="b", type="unsigned int:1", value="0"),
46                ValueCheck(name="c", type="unsigned int:5", value="4"),
47                ValueCheck(name="d", type="unsigned int:1", value="1"),
48                ValueCheck(name="", type="int:2"),
49                ValueCheck(name="e", type="unsigned int:20", value="20"),
50            ],
51        )
52        self.expect_expr("lbc.c", result_type="unsigned int", result_value="4")
53
54        # Accessing LargeBitsD.
55        self.expect_expr(
56            "lbd",
57            result_children=[
58                ValueCheck(name="arr", type="char[3]", summary='"ab"'),
59                ValueCheck(name="", type="int:32"),
60                ValueCheck(name="a", type="unsigned int:20", value="5"),
61            ],
62        )
63        self.expect_expr("lbd.a", result_type="unsigned int", result_value="5")
64
65        # Test BitfieldsInStructInUnion.
66        # FIXME: This needs some more explanation for what it's actually testing.
67        nested_struct_children = [
68            ValueCheck(name="", type="int:22"),
69            ValueCheck(name="a", type="uint64_t:1", value="1"),
70            ValueCheck(name="b", type="uint64_t:1", value="0"),
71            ValueCheck(name="c", type="uint64_t:1", value="1"),
72            ValueCheck(name="d", type="uint64_t:1", value="0"),
73            ValueCheck(name="e", type="uint64_t:1", value="1"),
74            ValueCheck(name="f", type="uint64_t:1", value="0"),
75            ValueCheck(name="g", type="uint64_t:1", value="1"),
76            ValueCheck(name="h", type="uint64_t:1", value="0"),
77            ValueCheck(name="i", type="uint64_t:1", value="1"),
78            ValueCheck(name="j", type="uint64_t:1", value="0"),
79            ValueCheck(name="k", type="uint64_t:1", value="1"),
80        ]
81        self.expect_expr(
82            "bitfields_in_struct_in_union",
83            result_type="BitfieldsInStructInUnion",
84            result_children=[
85                ValueCheck(
86                    name="",
87                    children=[ValueCheck(name="f", children=nested_struct_children)],
88                )
89            ],
90        )
91        self.expect_expr(
92            "bitfields_in_struct_in_union.f.a", result_type="uint64_t", result_value="1"
93        )
94
95        # Unions with bitfields.
96        self.expect_expr(
97            "uwbf",
98            result_type="UnionWithBitfields",
99            result_children=[
100                ValueCheck(name="a", value="255"),
101                ValueCheck(name="b", value="65535"),
102                ValueCheck(name="c", value="4294967295"),
103                ValueCheck(name="x", value="4294967295"),
104            ],
105        )
106        self.expect_expr(
107            "uwubf",
108            result_type="UnionWithUnnamedBitfield",
109            result_children=[
110                ValueCheck(name="a", value="16777215"),
111                ValueCheck(name="x", value="4294967295"),
112            ],
113        )
114
115        # Class with a base class and a bitfield.
116        self.expect_expr(
117            "derived",
118            result_type="Derived",
119            result_children=[
120                ValueCheck(
121                    name="Base",
122                    children=[ValueCheck(name="b_a", value="2", type="uint32_t")],
123                ),
124                ValueCheck(name="d_a", value="1", type="uint32_t:1"),
125            ],
126        )
127
128        # Struct with bool bitfields.
129        self.expect_expr(
130            "bb",
131            result_type="",
132            result_children=[
133                ValueCheck(name="a", value="true", type="bool:1"),
134                ValueCheck(name="b", value="false", type="bool:1"),
135                ValueCheck(name="c", value="true", type="bool:2"),
136                ValueCheck(name="d", value="true", type="bool:2"),
137            ],
138        )
139
140        bb = self.frame().FindVariable("bb")
141        self.assertSuccess(bb.GetError())
142
143        bb_a = bb.GetChildAtIndex(0)
144        self.assertSuccess(bb_a.GetError())
145        self.assertEqual(bb_a.GetValueAsUnsigned(), 1)
146        self.assertEqual(bb_a.GetValueAsSigned(), 1)
147
148        bb_b = bb.GetChildAtIndex(1)
149        self.assertSuccess(bb_b.GetError())
150        self.assertEqual(bb_b.GetValueAsUnsigned(), 0)
151        self.assertEqual(bb_b.GetValueAsSigned(), 0)
152
153        bb_c = bb.GetChildAtIndex(2)
154        self.assertSuccess(bb_c.GetError())
155        self.assertEqual(bb_c.GetValueAsUnsigned(), 1)
156        self.assertEqual(bb_c.GetValueAsSigned(), 1)
157
158        bb_d = bb.GetChildAtIndex(3)
159        self.assertSuccess(bb_d.GetError())
160        self.assertEqual(bb_d.GetValueAsUnsigned(), 1)
161        self.assertEqual(bb_d.GetValueAsSigned(), 1)
162
163        # Test a class with a base class that has a vtable ptr. The derived
164        # class has bitfields.
165        base_with_vtable_children = [
166            ValueCheck(name="a", type="unsigned int:4", value="5"),
167            ValueCheck(name="b", type="unsigned int:4", value="0"),
168            ValueCheck(name="c", type="unsigned int:4", value="5"),
169        ]
170        self.expect_expr("base_with_vtable", result_children=base_with_vtable_children)
171        self.expect_var_path("base_with_vtable", children=base_with_vtable_children)
172
173    @no_debug_info_test
174    def test_bitfield_behind_vtable_ptr(self):
175        self.build()
176        lldbutil.run_to_source_breakpoint(
177            self, "// break here", lldb.SBFileSpec("main.cpp", False)
178        )
179
180        # Test a class with a vtable ptr and bitfields.
181        with_vtable_children = [
182            ValueCheck(name="a", type="unsigned int:4", value="5"),
183            ValueCheck(name="b", type="unsigned int:4", value="0"),
184            ValueCheck(name="c", type="unsigned int:4", value="5"),
185        ]
186        self.expect_expr("with_vtable", result_children=with_vtable_children)
187        self.expect_var_path("with_vtable", children=with_vtable_children)
188
189        # Test a class with a vtable ptr and unnamed bitfield directly after.
190        with_vtable_and_unnamed_children = [
191            ValueCheck(name="", type="int:4", value="0"),
192            ValueCheck(name="b", type="unsigned int:4", value="0"),
193            ValueCheck(name="c", type="unsigned int:4", value="5"),
194        ]
195        self.expect_expr(
196            "with_vtable_and_unnamed", result_children=with_vtable_and_unnamed_children
197        )
198        self.expect_var_path(
199            "with_vtable_and_unnamed", children=with_vtable_and_unnamed_children
200        )
201
202        derived_with_vtable_children = [
203            ValueCheck(
204                name="Base",
205                children=[ValueCheck(name="b_a", value="2", type="uint32_t")],
206            ),
207            ValueCheck(name="a", value="1", type="unsigned int:1"),
208        ]
209        self.expect_expr(
210            "derived_with_vtable", result_children=derived_with_vtable_children
211        )
212        self.expect_var_path(
213            "derived_with_vtable", children=derived_with_vtable_children
214        )
215