@@ -1152,16 +1152,22 @@ def has_children(self) -> bool:
1152
1152
1153
1153
1154
1154
def children_of_node (node_ptr : SBValue , height : int ):
1155
- def cast_to_internal (node : SBValue ) -> SBValue :
1155
+ def get_edges (node : SBValue ) -> SBValue :
1156
1156
# BTreeMap implementation does ad-hoc polymorphism between LeafNode and InternalNode
1157
1157
# with raw pointers.
1158
1158
# 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 )
1165
1171
1166
1172
def unwrap_item_from_array_of_maybe_uninit (arr : SBValue , index : int ) -> SBValue :
1167
1173
element = arr .GetChildAtIndex (index )
@@ -1170,20 +1176,21 @@ def unwrap_item_from_array_of_maybe_uninit(arr: SBValue, index: int) -> SBValue:
1170
1176
if node_ptr .type .name .startswith ("alloc::collections::btree::node::BoxedNode<" ):
1171
1177
# BACKCOMPAT: rust 1.49
1172
1178
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
+
1174
1185
leaf = node_ptr .Dereference ()
1175
1186
keys = leaf .GetChildMemberWithName ("keys" )
1176
1187
vals = leaf .GetChildMemberWithName ("vals" )
1177
1188
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
1183
1190
1184
1191
for i in range (length + 1 ):
1185
1192
if height > 0 :
1186
- child_ptr = unwrap_item_from_array_of_maybe_uninit ( edges , i )
1193
+ child_ptr = edges . GetChildAtIndex ( i )
1187
1194
yield from children_of_node (child_ptr , height - 1 )
1188
1195
if i < length :
1189
1196
# 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:
1202
1209
yield key , val
1203
1210
1204
1211
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
-
1213
1212
class StdBTreeMapSyntheticProvider :
1214
1213
def __init__ (self , valobj : SBValue , _dict : LLDBOpaque , show_values : bool = True ):
1215
1214
self .valobj = valobj
1216
1215
self ._dict = _dict
1217
- self .show_values = True
1216
+ self .show_values = show_values
1218
1217
1219
1218
def num_children (self ) -> int :
1220
1219
return self .size
@@ -1244,20 +1243,22 @@ def update(self) -> bool:
1244
1243
# - Type lookup after get_template_args helper fails with codelldb for unclear reasons
1245
1244
# - Native `template_args[0]` from LLDB fails with codelldb and just says `T` if printed
1246
1245
# 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 ( )
1251
1250
1252
1251
if self .size == 0 :
1253
1252
return
1254
1253
1255
1254
root = self .valobj .GetChildMemberWithName ("root" )
1256
1255
1257
1256
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" )
1261
1262
1262
1263
height = root .GetChildMemberWithName ("height" )
1263
1264
node_ptr = root .GetChildMemberWithName ("node" )
0 commit comments