mirror of https://github.com/rust-lang/rust.git
Rollup merge of #77788 - ssomers:btree_cleanup_gdb, r=Mark-Simulacrum
BTreeMap: fix gdb provider on BTreeMap with ZST keys or values Avoid error when gdb is asked to inspect a BTreeMap or BTreeSet with a zero-sized type as key or value. And clean up. r? @Mark-Simulacrum
This commit is contained in:
commit
9c365a2561
|
@ -207,30 +207,46 @@ class StdRefCellProvider:
|
|||
yield "borrow", self.borrow
|
||||
|
||||
|
||||
# Yield each key (and optionally value) from a BoxedNode.
|
||||
def children_of_node(boxed_node, height, want_values):
|
||||
# Yields children (in a provider's sense of the word) for a tree headed by a BoxedNode.
|
||||
# In particular, yields each key/value pair in the node and in any child nodes.
|
||||
def children_of_node(boxed_node, height):
|
||||
def cast_to_internal(node):
|
||||
internal_type_name = str(node.type.target()).replace("LeafNode", "InternalNode", 1)
|
||||
internal_type_name = node.type.target().name.replace("LeafNode", "InternalNode", 1)
|
||||
internal_type = lookup_type(internal_type_name)
|
||||
return node.cast(internal_type.pointer())
|
||||
|
||||
node_ptr = unwrap_unique_or_non_null(boxed_node["ptr"])
|
||||
node_ptr = cast_to_internal(node_ptr) if height > 0 else node_ptr
|
||||
leaf = node_ptr["data"] if height > 0 else node_ptr.dereference()
|
||||
leaf = node_ptr.dereference()
|
||||
keys = leaf["keys"]
|
||||
values = leaf["vals"]
|
||||
vals = leaf["vals"]
|
||||
edges = cast_to_internal(node_ptr)["edges"] if height > 0 else None
|
||||
length = int(leaf["len"])
|
||||
|
||||
for i in xrange(0, length + 1):
|
||||
if height > 0:
|
||||
child_ptr = node_ptr["edges"][i]["value"]["value"]
|
||||
for child in children_of_node(child_ptr, height - 1, want_values):
|
||||
boxed_child_node = edges[i]["value"]["value"]
|
||||
for child in children_of_node(boxed_child_node, height - 1):
|
||||
yield child
|
||||
if i < length:
|
||||
if want_values:
|
||||
yield keys[i]["value"]["value"], values[i]["value"]["value"]
|
||||
else:
|
||||
yield keys[i]["value"]["value"]
|
||||
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
|
||||
key = keys[i]["value"]["value"] if keys.type.sizeof > 0 else None
|
||||
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else None
|
||||
yield key, val
|
||||
|
||||
|
||||
# Yields children for a BTreeMap.
|
||||
def children_of_map(map):
|
||||
if map["length"] > 0:
|
||||
root = map["root"]
|
||||
if root.type.name.startswith("core::option::Option<"):
|
||||
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
|
||||
boxed_root_node = root["node"]
|
||||
height = root["height"]
|
||||
for i, (key, val) in enumerate(children_of_node(boxed_root_node, height)):
|
||||
if key is not None:
|
||||
yield "key{}".format(i), key
|
||||
if val is not None:
|
||||
yield "val{}".format(i), val
|
||||
|
||||
|
||||
class StdBTreeSetProvider:
|
||||
|
@ -242,15 +258,8 @@ class StdBTreeSetProvider:
|
|||
|
||||
def children(self):
|
||||
inner_map = self.valobj["map"]
|
||||
if inner_map["length"] > 0:
|
||||
root = inner_map["root"]
|
||||
if "core::option::Option<" in root.type.name:
|
||||
type_name = str(root.type.name).replace("core::option::Option<", "", 1)[:-1]
|
||||
root = root.cast(gdb.lookup_type(type_name))
|
||||
|
||||
node_ptr = root["node"]
|
||||
for i, child in enumerate(children_of_node(node_ptr, root["height"], False)):
|
||||
yield "[{}]".format(i), child
|
||||
for child in children_of_map(inner_map):
|
||||
yield child
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
|
@ -265,16 +274,8 @@ class StdBTreeMapProvider:
|
|||
return "BTreeMap(size={})".format(self.valobj["length"])
|
||||
|
||||
def children(self):
|
||||
if self.valobj["length"] > 0:
|
||||
root = self.valobj["root"]
|
||||
if "core::option::Option<" in root.type.name:
|
||||
type_name = str(root.type.name).replace("core::option::Option<", "", 1)[:-1]
|
||||
root = root.cast(gdb.lookup_type(type_name))
|
||||
|
||||
node_ptr = root["node"]
|
||||
for i, child in enumerate(children_of_node(node_ptr, root["height"], True)):
|
||||
yield "key{}".format(i), child[0]
|
||||
yield "val{}".format(i), child[1]
|
||||
for child in children_of_map(self.valobj):
|
||||
yield child
|
||||
|
||||
@staticmethod
|
||||
def display_hint():
|
||||
|
|
|
@ -34,17 +34,20 @@
|
|||
// gdb-check:$6 = BTreeMap(size=15) = {[0] = pretty_std_collections::MyLeafNode (0), [...]}
|
||||
// (abbreviated because it's boring but we need enough elements to include internal nodes)
|
||||
|
||||
// gdb-command: print zst_btree_map
|
||||
// gdb-check:$7 = BTreeMap(size=1)
|
||||
|
||||
// gdb-command: print vec_deque
|
||||
// gdb-check:$7 = VecDeque(size=3) = {5, 3, 7}
|
||||
// gdb-check:$8 = VecDeque(size=3) = {5, 3, 7}
|
||||
|
||||
// gdb-command: print vec_deque2
|
||||
// gdb-check:$8 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
|
||||
// gdb-check:$9 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
// gdb-command: print hash_map
|
||||
// gdb-check:$9 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
|
||||
// gdb-check:$10 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
|
||||
|
||||
// gdb-command: print hash_set
|
||||
// gdb-check:$10 = HashSet(size=4) = {1, 2, 3, 4}
|
||||
// gdb-check:$11 = HashSet(size=4) = {1, 2, 3, 4}
|
||||
|
||||
// === LLDB TESTS ==================================================================================
|
||||
|
||||
|
@ -69,9 +72,9 @@
|
|||
#![allow(unused_variables)]
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::VecDeque;
|
||||
use std::hash::{BuildHasherDefault, Hasher};
|
||||
|
||||
struct MyLeafNode(i32); // helps to ensure we don't blindly replace substring "LeafNode"
|
||||
|
@ -111,6 +114,9 @@ fn main() {
|
|||
nasty_btree_map.insert(i, MyLeafNode(i));
|
||||
}
|
||||
|
||||
let mut zst_btree_map: BTreeMap<(), ()> = BTreeMap::new();
|
||||
zst_btree_map.insert((), ());
|
||||
|
||||
// VecDeque
|
||||
let mut vec_deque = VecDeque::new();
|
||||
vec_deque.push_back(5);
|
||||
|
|
Loading…
Reference in New Issue