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