11from sys import version_info
22
33import gdb
4- from gdb import lookup_type
54
65if version_info [0 ] >= 3 :
76 xrange = range
@@ -222,30 +221,43 @@ def to_string(self):
222221 return self .value
223222
224223
225- # Yield each key (and optionally value) from a BoxedNode.
226- def children_of_node (boxed_node , height , want_values ):
224+ # Yields children (in a provider's sense of the word) for a tree headed by a BoxedNode.
225+ # In particular, yields each key/value pair in the node and in any child nodes.
226+ def children_of_node (boxed_node , height ):
227227 def cast_to_internal (node ):
228- internal_type_name = str ( node .type .target ()). replace (' LeafNode' , ' InternalNode' )
229- internal_type = lookup_type (internal_type_name )
228+ internal_type_name = node .type .target (). name . replace (" LeafNode" , " InternalNode" , 1 )
229+ internal_type = gdb . lookup_type (internal_type_name )
230230 return node .cast (internal_type .pointer ())
231231
232- node_ptr = unwrap_unique_or_non_null (boxed_node [' ptr' ])
233- node_ptr = cast_to_internal ( node_ptr ) if height > 0 else node_ptr
234- leaf = node_ptr [ 'data' ] if height > 0 else node_ptr . dereference ()
235- keys = leaf ['keys' ]
236- values = leaf [ 'vals' ]
237- length = int (leaf [' len' ])
232+ node_ptr = unwrap_unique_or_non_null (boxed_node [" ptr" ])
233+ leaf = node_ptr . dereference ()
234+ keys = leaf [ "keys" ]
235+ vals = leaf ["vals" ]
236+ edges = cast_to_internal ( node_ptr )[ "edges" ] if height > 0 else None
237+ length = int (leaf [" len" ])
238238
239239 for i in xrange (0 , length + 1 ):
240240 if height > 0 :
241- child_ptr = node_ptr [ ' edges' ] [i ][' value' ][ ' value' ]
242- for child in children_of_node (child_ptr , height - 1 , want_values ):
241+ boxed_child_node = edges [i ][" value" ][ " value" ]
242+ for child in children_of_node (boxed_child_node , height - 1 ):
243243 yield child
244244 if i < length :
245- if want_values :
246- yield (keys [i ]['value' ]['value' ], values [i ]['value' ]['value' ])
247- else :
248- yield keys [i ]['value' ]['value' ]
245+ # Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
246+ key = keys [i ]["value" ]["value" ] if keys .type .sizeof > 0 else gdb .parse_and_eval ("()" )
247+ val = vals [i ]["value" ]["value" ] if vals .type .sizeof > 0 else gdb .parse_and_eval ("()" )
248+ yield key , val
249+
250+
251+ # Yields children for a BTreeMap.
252+ def children_of_map (map ):
253+ if map ["length" ] > 0 :
254+ root = map ["root" ]
255+ if root .type .name .startswith ("core::option::Option<" ):
256+ root = root .cast (gdb .lookup_type (root .type .name [21 :- 1 ]))
257+ boxed_root_node = root ["node" ]
258+ height = root ["height" ]
259+ for child in children_of_node (boxed_root_node , height ):
260+ yield child
249261
250262
251263class StdBTreeSetProvider :
@@ -256,9 +268,8 @@ def to_string(self):
256268 return "size={}" .format (self .valobj ["map" ]["length" ])
257269
258270 def children (self ):
259- root = self .valobj ["map" ]["root" ]
260- node_ptr = root ["node" ]
261- for i , child in enumerate (children_of_node (node_ptr , root ["height" ], want_values = False )):
271+ inner_map = self .valobj ["map" ]
272+ for i , (child , _ ) in enumerate (children_of_map (inner_map )):
262273 yield ("[{}]" .format (i ), child )
263274
264275 @staticmethod
@@ -274,13 +285,9 @@ def to_string(self):
274285 return "size={}" .format (self .valobj ["length" ])
275286
276287 def children (self ):
277- root = self .valobj ["root" ]
278- node_ptr = root ["node" ]
279- i = 0
280- for child in children_of_node (node_ptr , root ["height" ], want_values = True ):
281- yield ("key{}" .format (i ), child [0 ])
282- yield ("val{}" .format (i ), child [1 ])
283- i = i + 1
288+ for i , (key , val ) in enumerate (children_of_map (self .valobj )):
289+ yield ("key{}" .format (i ), key )
290+ yield ("val{}" .format (i ), val )
284291
285292 @staticmethod
286293 def display_hint ():
0 commit comments