Skip to content

Commit 6e96ad5

Browse files
committed
Fix & enable irept pretty-printer
1 parent bb6baff commit 6e96ad5

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

scripts/pretty-printers/gdb/pretty_printers.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ def find_type(type, name):
7070

7171

7272
class IrepPrettyPrinter:
73-
"Print an irept"
73+
"""
74+
Print an irept.
75+
76+
This is an array GDB type as everything in the tree is key->value, so it
77+
works better than doing a map type with individual key/value entries.
78+
"""
7479

7580
def __init__(self, val):
7681
self.val = val["data"].referenced_value()
@@ -82,31 +87,42 @@ def to_string(self):
8287
return "Exception pretty printing irept"
8388

8489
def children(self):
90+
"""
91+
This method tells the pretty-printer what children this object can
92+
return. Because we've stated this is a array then we've also stated that
93+
irept is a container that holds other values.
94+
95+
This makes things awkward because some ireps are not actually containers
96+
of children but values themselves. It's hard to represent that, so instead
97+
we return a single child with the value of the node.
98+
"""
99+
85100
sub = self.val["sub"]
86-
count = 0
101+
sub_count = 0
87102
item = sub["_M_impl"]["_M_start"]
88103
finish = sub["_M_impl"]["_M_finish"]
89104
while item != finish:
90-
yield "sub %d key" % count, "sub[%d]" % count
91-
yield "sub %d value" % count, item.dereference()
92-
count += 1
105+
# The name is just the index, as that's all we have.
106+
yield "%d" % sub_count, item.dereference()
107+
sub_count += 1
93108
item += 1
94109

95110
named_sub = self.val["named_sub"]
96111
size = named_sub["_M_t"]["_M_impl"]["_M_node_count"]
97112
node = named_sub["_M_t"]["_M_impl"]["_M_header"]["_M_left"]
98-
count = 0
99-
while count != size:
113+
named_sub_count = 0
114+
while named_sub_count != size:
100115
rep_type = find_type(named_sub.type, "_Rep_type")
101116
link_type = find_type(rep_type, "_Link_type")
102117
node_type = link_type.strip_typedefs()
103118
current = node.cast(node_type).dereference()
104119
addr_type = current.type.template_argument(0).pointer()
105120
result = current["_M_storage"]["_M_storage"].address.cast(addr_type).dereference()
106-
yield "named_sub %d key" % count, "named_sub[\"%s\"]" % deconstruct_dstring(result["first"])[1].replace("\"", "\\\"")
107-
yield "named_sub %d value" % count, result["second"]
108-
count += 1
109-
if count < size:
121+
122+
# Return (name_of_named_sub, value)
123+
yield "%s" % deconstruct_dstring(result["first"])[1].replace("\"", "\\\""), result["second"]
124+
named_sub_count += 1
125+
if named_sub_count < size:
110126
# Get the next node
111127
right = node.dereference()["_M_right"]
112128
if right:
@@ -125,8 +141,14 @@ def children(self):
125141
if node.dereference()["_M_right"] != parent:
126142
node = parent
127143

144+
# If we have no children it means we're actually a value node, so
145+
# return the value of the node and a throw-away second value.
146+
if sub_count == 0 and named_sub_count == 0:
147+
yield (self.to_string(), self.val)
148+
149+
128150
def display_hint(self):
129-
return "map"
151+
return "array"
130152

131153

132154
class InstructionPrettyPrinter:
@@ -154,5 +176,7 @@ def load_cbmc_printers():
154176
# it should be applied too, third is the class that should be called to pretty-print that type.
155177
printers.add_printer("dstringt", "^(?:dstringt|irep_idt)", DStringPrettyPrinter)
156178
printers.add_printer("instructiont", "^goto_programt::instructiont", InstructionPrettyPrinter)
179+
printers.add_printer("irept", "^irept", IrepPrettyPrinter)
180+
157181
# We aren't associating with a particular object file, so pass in None instead of gdb.current_objfile()
158182
gdb.printing.register_pretty_printer(None, printers, replace=True)

0 commit comments

Comments
 (0)