@@ -1152,16 +1152,22 @@ def has_children(self) -> bool:
11521152
11531153
11541154def children_of_node (node_ptr : SBValue , height : int ):
1155- def cast_to_internal (node : SBValue ) -> SBValue :
1155+ def get_edges (node : SBValue ) -> SBValue :
11561156 # BTreeMap implementation does ad-hoc polymorphism between LeafNode and InternalNode
11571157 # with raw pointers.
11581158 # https://github.com/rust-lang/rust/issues/90520#issuecomment-2211103129
1159- internal_type_name = node .type .GetPointeeType ().name .replace (
1160- "LeafNode" , "InternalNode" , 1
1161- )
1162- target = node .GetTarget ()
1163- internal_type = target .FindFirstType (internal_type_name )
1164- return node .Cast (internal_type .GetPointerType ())
1159+ # Implementing this the same way as the GDB provider with type casting fails
1160+ # because LLDB does not find the target type for some reason.
1161+ # Therefore, we manually do the pointer arithmetic to get the edges array
1162+ # and handle it as raw pointers later instead of MaybeUninit<NonNull<LeafNode<K,V>>>.
1163+ # We can do that because InternalNode is repr(C).
1164+ leaf_ptr_type = node .GetType ()
1165+ # Array has a constant length of 2 * B
1166+ edges_arr_type = leaf_ptr_type .GetArrayType (12 )
1167+ node_addr = node .unsigned
1168+ leaf_size = leaf_ptr_type .GetPointeeType ().size
1169+ edges_addr = node_addr + leaf_size
1170+ return node .CreateValueFromAddress ("edges" , edges_addr , edges_arr_type )
11651171
11661172 def unwrap_item_from_array_of_maybe_uninit (arr : SBValue , index : int ) -> SBValue :
11671173 element = arr .GetChildAtIndex (index )
@@ -1170,20 +1176,21 @@ def unwrap_item_from_array_of_maybe_uninit(arr: SBValue, index: int) -> SBValue:
11701176 if node_ptr .type .name .startswith ("alloc::collections::btree::node::BoxedNode<" ):
11711177 # BACKCOMPAT: rust 1.49
11721178 node_ptr = node_ptr .GetChildMemberWithName ("ptr" )
1173- node_ptr = unwrap_unique_or_non_null (node_ptr )
1179+
1180+ if not node_ptr .type .IsPointerType ():
1181+ # After the first recursion, this method is called with a raw pointer type directly
1182+ # instead of NonNull<T>
1183+ node_ptr = unwrap_unique_or_non_null (node_ptr )
1184+
11741185 leaf = node_ptr .Dereference ()
11751186 keys = leaf .GetChildMemberWithName ("keys" )
11761187 vals = leaf .GetChildMemberWithName ("vals" )
11771188 length = leaf .GetChildMemberWithName ("len" ).unsigned
1178- edges = (
1179- cast_to_internal (node_ptr ).GetChildMemberWithName ("edges" )
1180- if height > 0
1181- else None
1182- )
1189+ edges = get_edges (node_ptr ) if height > 0 else None
11831190
11841191 for i in range (length + 1 ):
11851192 if height > 0 :
1186- child_ptr = unwrap_item_from_array_of_maybe_uninit ( edges , i )
1193+ child_ptr = edges . GetChildAtIndex ( i )
11871194 yield from children_of_node (child_ptr , height - 1 )
11881195 if i < length :
11891196 # Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
@@ -1202,19 +1209,11 @@ def unwrap_item_from_array_of_maybe_uninit(arr: SBValue, index: int) -> SBValue:
12021209 yield key , val
12031210
12041211
1205- def strip_till_parentheses (text : str ) -> str :
1206- start = text .find ("(" )
1207- end = text .find (")" )
1208- if start == - 1 or end == - 1 :
1209- return text
1210- return text [start : end + 1 ]
1211-
1212-
12131212class StdBTreeMapSyntheticProvider :
12141213 def __init__ (self , valobj : SBValue , _dict : LLDBOpaque , show_values : bool = True ):
12151214 self .valobj = valobj
12161215 self ._dict = _dict
1217- self .show_values = True
1216+ self .show_values = show_values
12181217
12191218 def num_children (self ) -> int :
12201219 return self .size
@@ -1244,20 +1243,22 @@ def update(self) -> bool:
12441243 # - Type lookup after get_template_args helper fails with codelldb for unclear reasons
12451244 # - Native `template_args[0]` from LLDB fails with codelldb and just says `T` if printed
12461245 # on console
1247- marker_type_name = self .valobj .GetChildMemberWithName ("_marker" ). GetTypeName ( )
1248- pair_type_name = strip_till_parentheses ( marker_type_name )
1249- target = self . valobj . GetTarget ( )
1250- self .pair_type = target . FindFirstType ( pair_type_name )
1246+ marker = self .valobj .GetChildMemberWithName ("_marker" )
1247+ marker_type = marker . GetType ( )
1248+ box = marker_type . GetTemplateArgumentType ( 0 )
1249+ self .pair_type = box . GetPointeeType ( )
12511250
12521251 if self .size == 0 :
12531252 return
12541253
12551254 root = self .valobj .GetChildMemberWithName ("root" )
12561255
12571256 if root .type .name .startswith ("core::option::Option<" ):
1258- target = self .valobj .GetTarget ()
1259- type_some = target .FindFirstType (get_template_args (root .GetTypeName ())[0 ])
1260- root = root .Cast (type_some )
1257+ synthetic_children = root .children [0 ]
1258+ current_variant = synthetic_children .GetChildMemberWithName ("$variant$" )
1259+ root = current_variant .GetChildMemberWithName (
1260+ "value"
1261+ ).GetChildMemberWithName ("__0" )
12611262
12621263 height = root .GetChildMemberWithName ("height" )
12631264 node_ptr = root .GetChildMemberWithName ("node" )
0 commit comments