xref: /llvm-project/lldb/test/API/lang/rust/enum-structs/TestRustEnumStructs.py (revision a4c18137d84bc48df49ee0101bef465a955e62ac)
1e84751a2SVladimir Makaev"""Test that lldb recognizes enum structs emitted by Rust compiler """
2e84751a2SVladimir Makaevimport logging
3e84751a2SVladimir Makaev
4e84751a2SVladimir Makaevimport lldb
5e84751a2SVladimir Makaevfrom lldbsuite.test.decorators import *
6e84751a2SVladimir Makaevfrom lldbsuite.test.lldbtest import *
7e84751a2SVladimir Makaevfrom RustEnumValue import RustEnumValue
8e84751a2SVladimir Makaev
9e84751a2SVladimir Makaev
10e84751a2SVladimir Makaevclass TestRustEnumStructs(TestBase):
11e84751a2SVladimir Makaev    def setUp(self):
12e84751a2SVladimir Makaev        TestBase.setUp(self)
13e84751a2SVladimir Makaev        src_dir = self.getSourceDir()
14e84751a2SVladimir Makaev        yaml_path = os.path.join(src_dir, "main.yaml")
15e84751a2SVladimir Makaev        obj_path = self.getBuildArtifact("main.o")
16e84751a2SVladimir Makaev        self.yaml2obj(yaml_path, obj_path)
17e84751a2SVladimir Makaev        self.dbg.CreateTarget(obj_path)
18e84751a2SVladimir Makaev
19e84751a2SVladimir Makaev    def getFromGlobal(self, name):
20e84751a2SVladimir Makaev        values = self.target().FindGlobalVariables(name, 1)
21e84751a2SVladimir Makaev        self.assertEqual(values.GetSize(), 1)
22e84751a2SVladimir Makaev        return RustEnumValue(values[0])
23e84751a2SVladimir Makaev
24e84751a2SVladimir Makaev    def test_clike_enums_are_represented_correctly(self):
25e84751a2SVladimir Makaev        # these type of enums are not using DW_TAG_variant_part.
26e84751a2SVladimir Makaev        all_values = [
27e84751a2SVladimir Makaev            self.target().FindFirstGlobalVariable("CLIKE_DEFAULT_A").GetValue(),
28e84751a2SVladimir Makaev            self.target().FindFirstGlobalVariable("CLIKE_DEFAULT_B").GetValue(),
29e84751a2SVladimir Makaev            self.target().FindFirstGlobalVariable("CLIKE_U8_A").GetValue(),
30e84751a2SVladimir Makaev            self.target().FindFirstGlobalVariable("CLIKE_U8_C").GetValue(),
31e84751a2SVladimir Makaev            self.target().FindFirstGlobalVariable("CLIKE_U32_A").GetValue(),
32e84751a2SVladimir Makaev            self.target().FindFirstGlobalVariable("CLIKE_U32_B").GetValue(),
33e84751a2SVladimir Makaev        ]
346bf923d5SDavid Spickett        self.assertEqual(
356bf923d5SDavid Spickett            all_values, ["A", "B", "VariantA", "VariantC", "VariantA", "VariantB"]
366bf923d5SDavid Spickett        )
37e84751a2SVladimir Makaev
38e84751a2SVladimir Makaev    def test_enum_with_tuples_has_all_variants(self):
396bf923d5SDavid Spickett        self.assertEqual(
406bf923d5SDavid Spickett            self.getFromGlobal("ENUM_WITH_TUPLES_A").getAllVariantTypes(),
416bf923d5SDavid Spickett            [
426bf923d5SDavid Spickett                "main::EnumWithTuples::A:8",
436bf923d5SDavid Spickett                "main::EnumWithTuples::B:8",
446bf923d5SDavid Spickett                "main::EnumWithTuples::C:8",
456bf923d5SDavid Spickett                "main::EnumWithTuples::D:8",
466bf923d5SDavid Spickett                "main::EnumWithTuples::AA:8",
476bf923d5SDavid Spickett                "main::EnumWithTuples::BB:8",
486bf923d5SDavid Spickett                "main::EnumWithTuples::BC:8",
496bf923d5SDavid Spickett                "main::EnumWithTuples::CC:8",
506bf923d5SDavid Spickett            ],
516bf923d5SDavid Spickett        )
52e84751a2SVladimir Makaev
53e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_a(self):
54e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_A: EnumWithTuples = EnumWithTuples::A(13);
55e84751a2SVladimir Makaev        self.assertEqual(
566bf923d5SDavid Spickett            self.getFromGlobal("ENUM_WITH_TUPLES_A")
576bf923d5SDavid Spickett            .getCurrentValue()
586bf923d5SDavid Spickett            .GetChildAtIndex(0)
596bf923d5SDavid Spickett            .GetData()
606bf923d5SDavid Spickett            .GetUnsignedInt8(lldb.SBError(), 0),
616bf923d5SDavid Spickett            13,
626bf923d5SDavid Spickett        )
63e84751a2SVladimir Makaev
64e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_aa(self):
65e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_AA: EnumWithTuples = EnumWithTuples::AA(13, 37);
66e84751a2SVladimir Makaev        value = self.getFromGlobal("ENUM_WITH_TUPLES_AA").getCurrentValue()
67e84751a2SVladimir Makaev        self.assertEqual(
686bf923d5SDavid Spickett            (
696bf923d5SDavid Spickett                value.GetChildAtIndex(0).GetData().GetUnsignedInt8(lldb.SBError(), 0),
706bf923d5SDavid Spickett                value.GetChildAtIndex(1).GetData().GetUnsignedInt8(lldb.SBError(), 0),
716bf923d5SDavid Spickett            ),
726bf923d5SDavid Spickett            (13, 37),
736bf923d5SDavid Spickett        )
74e84751a2SVladimir Makaev
75e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_b(self):
76e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_B: EnumWithTuples = EnumWithTuples::B(37);
77e84751a2SVladimir Makaev        self.assertEqual(
786bf923d5SDavid Spickett            self.getFromGlobal("ENUM_WITH_TUPLES_B")
796bf923d5SDavid Spickett            .getCurrentValue()
806bf923d5SDavid Spickett            .GetChildAtIndex(0)
816bf923d5SDavid Spickett            .GetData()
826bf923d5SDavid Spickett            .GetUnsignedInt16(lldb.SBError(), 0),
836bf923d5SDavid Spickett            37,
846bf923d5SDavid Spickett        )
85e84751a2SVladimir Makaev
86e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_bb(self):
87e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_BB: EnumWithTuples = EnumWithTuples::BB(37, 5535);
88e84751a2SVladimir Makaev        value = self.getFromGlobal("ENUM_WITH_TUPLES_BB").getCurrentValue()
89e84751a2SVladimir Makaev        self.assertEqual(
906bf923d5SDavid Spickett            (
916bf923d5SDavid Spickett                value.GetChildAtIndex(0).GetData().GetUnsignedInt16(lldb.SBError(), 0),
926bf923d5SDavid Spickett                value.GetChildAtIndex(1).GetData().GetUnsignedInt16(lldb.SBError(), 0),
936bf923d5SDavid Spickett            ),
946bf923d5SDavid Spickett            (37, 5535),
956bf923d5SDavid Spickett        )
96e84751a2SVladimir Makaev
97e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_bc(self):
98e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_BC: EnumWithTuples = EnumWithTuples::BC(65000, 165000);
99e84751a2SVladimir Makaev        value = self.getFromGlobal("ENUM_WITH_TUPLES_BC").getCurrentValue()
100e84751a2SVladimir Makaev        self.assertEqual(
1016bf923d5SDavid Spickett            (
1026bf923d5SDavid Spickett                value.GetChildAtIndex(0).GetData().GetUnsignedInt16(lldb.SBError(), 0),
1036bf923d5SDavid Spickett                value.GetChildAtIndex(1).GetData().GetUnsignedInt32(lldb.SBError(), 0),
1046bf923d5SDavid Spickett            ),
1056bf923d5SDavid Spickett            (65000, 165000),
1066bf923d5SDavid Spickett        )
107e84751a2SVladimir Makaev
108e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_c(self):
109e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_C: EnumWithTuples = EnumWithTuples::C(31337);
110e84751a2SVladimir Makaev        self.assertEqual(
1116bf923d5SDavid Spickett            self.getFromGlobal("ENUM_WITH_TUPLES_C")
1126bf923d5SDavid Spickett            .getCurrentValue()
1136bf923d5SDavid Spickett            .GetChildAtIndex(0)
1146bf923d5SDavid Spickett            .GetData()
1156bf923d5SDavid Spickett            .GetUnsignedInt32(lldb.SBError(), 0),
1166bf923d5SDavid Spickett            31337,
1176bf923d5SDavid Spickett        )
118e84751a2SVladimir Makaev
119e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_cc(self):
120e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_CC: EnumWithTuples = EnumWithTuples::CC(31337, 87236);
121e84751a2SVladimir Makaev        value = self.getFromGlobal("ENUM_WITH_TUPLES_CC").getCurrentValue()
122e84751a2SVladimir Makaev        self.assertEqual(
1236bf923d5SDavid Spickett            (
1246bf923d5SDavid Spickett                value.GetChildAtIndex(0).GetData().GetUnsignedInt32(lldb.SBError(), 0),
1256bf923d5SDavid Spickett                value.GetChildAtIndex(1).GetData().GetUnsignedInt32(lldb.SBError(), 0),
1266bf923d5SDavid Spickett            ),
1276bf923d5SDavid Spickett            (31337, 87236),
1286bf923d5SDavid Spickett        )
129e84751a2SVladimir Makaev
130e84751a2SVladimir Makaev    def test_enum_with_tuples_values_are_correct_d(self):
131e84751a2SVladimir Makaev        # static ENUM_WITH_TUPLES_D: EnumWithTuples = EnumWithTuples::D(123456789012345678);
132e84751a2SVladimir Makaev        self.assertEqual(
1336bf923d5SDavid Spickett            self.getFromGlobal("ENUM_WITH_TUPLES_D")
1346bf923d5SDavid Spickett            .getCurrentValue()
1356bf923d5SDavid Spickett            .GetChildAtIndex(0)
1366bf923d5SDavid Spickett            .GetData()
1376bf923d5SDavid Spickett            .GetUnsignedInt64(lldb.SBError(), 0),
1386bf923d5SDavid Spickett            123456789012345678,
1396bf923d5SDavid Spickett        )
140e84751a2SVladimir Makaev
141e84751a2SVladimir Makaev    def test_mixed_enum_variants(self):
142e84751a2SVladimir Makaev        # static MIXED_ENUM_A: MixedEnum1 = MixedEnum1::A;
1436bf923d5SDavid Spickett        self.assertEqual(
1446bf923d5SDavid Spickett            self.getFromGlobal("MIXED_ENUM_A").getAllVariantTypes(),
1456bf923d5SDavid Spickett            [
1466bf923d5SDavid Spickett                "main::MixedEnum::A:64",
1476bf923d5SDavid Spickett                "main::MixedEnum::B:64",
1486bf923d5SDavid Spickett                "main::MixedEnum::C:64",
1496bf923d5SDavid Spickett                "main::MixedEnum::D:64",
1506bf923d5SDavid Spickett                "main::MixedEnum::E:64",
1516bf923d5SDavid Spickett            ],
1526bf923d5SDavid Spickett        )
153e84751a2SVladimir Makaev
154e84751a2SVladimir Makaev    def test_mixed_enum_a(self):
155e84751a2SVladimir Makaev        # static MIXED_ENUM_A: MixedEnum = MixedEnum::A;
156e84751a2SVladimir Makaev        value = self.getFromGlobal("MIXED_ENUM_A").getCurrentValue()
157e84751a2SVladimir Makaev        self.assertEqual(value.GetType().GetDisplayTypeName(), "main::MixedEnum::A")
158e84751a2SVladimir Makaev        self.assertEqual(value.GetValue(), None)
159e84751a2SVladimir Makaev
160e84751a2SVladimir Makaev    def test_mixed_enum_c(self):
161e84751a2SVladimir Makaev        # static MIXED_ENUM_C: MixedEnum = MixedEnum::C(254, -254);
162e84751a2SVladimir Makaev        value = self.getFromGlobal("MIXED_ENUM_C").getCurrentValue()
163e84751a2SVladimir Makaev        self.assertEqual(
1646bf923d5SDavid Spickett            (
1656bf923d5SDavid Spickett                value.GetChildAtIndex(0).GetData().GetUnsignedInt8(lldb.SBError(), 0),
1666bf923d5SDavid Spickett                value.GetChildAtIndex(1).GetData().GetSignedInt32(lldb.SBError(), 0),
1676bf923d5SDavid Spickett            ),
1686bf923d5SDavid Spickett            (254, -254),
1696bf923d5SDavid Spickett        )
170e84751a2SVladimir Makaev
171e84751a2SVladimir Makaev    def test_mixed_enum_d_none(self):
172e84751a2SVladimir Makaev        # static MIXED_ENUM_D_NONE: MixedEnum = MixedEnum::D(None);
1736bf923d5SDavid Spickett        value = RustEnumValue(
1746bf923d5SDavid Spickett            self.getFromGlobal("MIXED_ENUM_D_NONE").getCurrentValue().GetChildAtIndex(0)
1756bf923d5SDavid Spickett        )
1766bf923d5SDavid Spickett        self.assertEqual(
1776bf923d5SDavid Spickett            value.getAllVariantTypes(),
1786bf923d5SDavid Spickett            [
1796bf923d5SDavid Spickett                "core::option::Option<main::Struct2>::None<main::Struct2>:32",
1806bf923d5SDavid Spickett                "core::option::Option<main::Struct2>::Some<main::Struct2>:32",
1816bf923d5SDavid Spickett            ],
1826bf923d5SDavid Spickett        )
183e84751a2SVladimir Makaev        self.assertEqual(value.getCurrentValue().GetValue(), None)
1846bf923d5SDavid Spickett        self.assertEqual(
1856bf923d5SDavid Spickett            value.getCurrentValue().GetType().GetDisplayTypeName(),
1866bf923d5SDavid Spickett            "core::option::Option<main::Struct2>::None<main::Struct2>",
1876bf923d5SDavid Spickett        )
188e84751a2SVladimir Makaev
189e84751a2SVladimir Makaev    def test_mixed_enum_d_some(self):
190e84751a2SVladimir Makaev        # static MIXED_ENUM_D_SOME: MixedEnum = MixedEnum::D(Some(Struct2 {
191e84751a2SVladimir Makaev        #     field: 123456,
192e84751a2SVladimir Makaev        #     inner: Struct1 { field: 123 },
193e84751a2SVladimir Makaev        # }));
194e84751a2SVladimir Makaev        variant_with_option = RustEnumValue(
1956bf923d5SDavid Spickett            self.getFromGlobal("MIXED_ENUM_D_SOME").getCurrentValue().GetChildAtIndex(0)
1966bf923d5SDavid Spickett        )
197e84751a2SVladimir Makaev
198e84751a2SVladimir Makaev        value_inside_option = variant_with_option.getCurrentValue().GetChildAtIndex(0)
199e84751a2SVladimir Makaev        self.assertEqual(
2006bf923d5SDavid Spickett            value_inside_option.GetChildMemberWithName("field")
2016bf923d5SDavid Spickett            .GetData()
2026bf923d5SDavid Spickett            .GetUnsignedInt32(lldb.SBError(), 0),
2036bf923d5SDavid Spickett            123456,
2046bf923d5SDavid Spickett        )
205e84751a2SVladimir Makaev
206e84751a2SVladimir Makaev        self.assertEqual(
2076bf923d5SDavid Spickett            value_inside_option.GetChildMemberWithName("inner")
2086bf923d5SDavid Spickett            .GetChildMemberWithName("field")
2096bf923d5SDavid Spickett            .GetData()
2106bf923d5SDavid Spickett            .GetSignedInt32(lldb.SBError(), 0),
2116bf923d5SDavid Spickett            123,
2126bf923d5SDavid Spickett        )
2136bf923d5SDavid Spickett        self.assertEqual(
2146bf923d5SDavid Spickett            value_inside_option.GetType().GetDisplayTypeName(), "main::Struct2"
2156bf923d5SDavid Spickett        )
216e84751a2SVladimir Makaev
217e84751a2SVladimir Makaev    def test_option_non_null_some_pointer(self):
2186bf923d5SDavid Spickett        type = self.target().FindFirstType(
2196bf923d5SDavid Spickett            "core::option::Option<core::ptr::non_null::NonNull<u64>>"
2206bf923d5SDavid Spickett        )
221e84751a2SVladimir Makaev        # this type is "optimized" by rust compiler so the discriminant isn't present on Some variant of option
222e84751a2SVladimir Makaev        data = [1337]
223e84751a2SVladimir Makaev        pointer_size = self.target().GetAddressByteSize()
224e84751a2SVladimir Makaev        byte_order = self.target().GetByteOrder()
2256bf923d5SDavid Spickett        value = RustEnumValue(
2266bf923d5SDavid Spickett            self.target().CreateValueFromData(
2276bf923d5SDavid Spickett                "adhoc_value",
2286bf923d5SDavid Spickett                lldb.SBData.CreateDataFromUInt64Array(byte_order, pointer_size, data),
2296bf923d5SDavid Spickett                type,
2306bf923d5SDavid Spickett            )
2316bf923d5SDavid Spickett        )
232e84751a2SVladimir Makaev        self.assertEqual(value.getFields(), ["$variant$0", "$variant$"])
233e84751a2SVladimir Makaev        self.assertEqual(
2346bf923d5SDavid Spickett            value.getCurrentValue()
2356bf923d5SDavid Spickett            .GetChildAtIndex(0)
2366bf923d5SDavid Spickett            .GetChildMemberWithName("pointer")
2376bf923d5SDavid Spickett            .GetValueAsUnsigned(),
2386bf923d5SDavid Spickett            1337,
2396bf923d5SDavid Spickett        )
240e84751a2SVladimir Makaev
241e84751a2SVladimir Makaev    def test_option_non_null_none(self):
2426bf923d5SDavid Spickett        type = self.target().FindFirstType(
2436bf923d5SDavid Spickett            "core::option::Option<core::ptr::non_null::NonNull<u64>>"
2446bf923d5SDavid Spickett        )
245e84751a2SVladimir Makaev        # this type is "optimized" by rust compiler so the discriminant isn't present on Some variant of option
246e84751a2SVladimir Makaev        # in this test case 0 is used to represent 'None'
247e84751a2SVladimir Makaev        data = [0]
248e84751a2SVladimir Makaev        pointer_size = self.target().GetAddressByteSize()
249e84751a2SVladimir Makaev        byte_order = self.target().GetByteOrder()
2506bf923d5SDavid Spickett        value = RustEnumValue(
2516bf923d5SDavid Spickett            self.target().CreateValueFromData(
2526bf923d5SDavid Spickett                "adhoc_value",
2536bf923d5SDavid Spickett                lldb.SBData.CreateDataFromUInt64Array(byte_order, pointer_size, data),
2546bf923d5SDavid Spickett                type,
2556bf923d5SDavid Spickett            )
2566bf923d5SDavid Spickett        )
257e84751a2SVladimir Makaev        self.assertEqual(value.getFields(), ["$variant$0", "$variant$"])
258e84751a2SVladimir Makaev        self.assertEqual(value.getCurrentValue().GetValue(), None)
2596bf923d5SDavid Spickett        self.assertEqual(
2606bf923d5SDavid Spickett            value.getCurrentValue().GetType().GetDisplayTypeName(),
2616bf923d5SDavid Spickett            "core::option::Option<core::ptr::non_null::NonNull<u64>>::None<core::ptr::non_null::NonNull<unsigned long> >",
2626bf923d5SDavid Spickett        )
263e84751a2SVladimir Makaev
264e84751a2SVladimir Makaev    def test_niche_layout_with_fields_2(self):
265e84751a2SVladimir Makaev        # static NICHE_W_FIELDS_2_A: NicheLayoutWithFields2 =
266e84751a2SVladimir Makaev        #           NicheLayoutWithFields2::A(NonZeroU32::new(800).unwrap(), 900);
267e84751a2SVladimir Makaev        value = self.getFromGlobal("NICHE_W_FIELDS_2_A").getCurrentValue()
268e84751a2SVladimir Makaev        self.assertEqual(
269e84751a2SVladimir Makaev            (
2706bf923d5SDavid Spickett                value.GetChildAtIndex(0)
2716bf923d5SDavid Spickett                .GetChildAtIndex(0)
2726bf923d5SDavid Spickett                .GetData()
2736bf923d5SDavid Spickett                .GetUnsignedInt32(lldb.SBError(), 0),
2746bf923d5SDavid Spickett                value.GetChildAtIndex(1).GetData().GetUnsignedInt32(lldb.SBError(), 0),
275e84751a2SVladimir Makaev            ),
2766bf923d5SDavid Spickett            (800, 900),
277e84751a2SVladimir Makaev        )
278e84751a2SVladimir Makaev
279e84751a2SVladimir Makaev    def test_niche_layout_with_fields_3_a(self):
280e84751a2SVladimir Makaev        # static NICHE_W_FIELDS_3_A: NicheLayoutWithFields3 = NicheLayoutWithFields3::A(137, true);
281e84751a2SVladimir Makaev        value = self.getFromGlobal("NICHE_W_FIELDS_3_A").getCurrentValue()
282e84751a2SVladimir Makaev        self.assertEqual(
283e84751a2SVladimir Makaev            (
284e84751a2SVladimir Makaev                value.GetChildAtIndex(0).GetData().GetUnsignedInt8(lldb.SBError(), 0),
285e84751a2SVladimir Makaev                value.GetChildAtIndex(1).GetData().GetUnsignedInt8(lldb.SBError(), 0),
286e84751a2SVladimir Makaev            ),
2876bf923d5SDavid Spickett            (137, 1),
288e84751a2SVladimir Makaev        )
289e84751a2SVladimir Makaev
290*a4c18137SMichael Buch    def test_niche_layout_with_fields_3_c(self):
291e84751a2SVladimir Makaev        # static NICHE_W_FIELDS_3_C: NicheLayoutWithFields3 = NicheLayoutWithFields3::C(false);
292e84751a2SVladimir Makaev        value = self.getFromGlobal("NICHE_W_FIELDS_3_C").getCurrentValue()
293e84751a2SVladimir Makaev        self.assertEqual(
2946bf923d5SDavid Spickett            value.GetChildAtIndex(0).GetData().GetUnsignedInt8(lldb.SBError(), 0), 0
295e84751a2SVladimir Makaev        )
296