@@ -70,7 +70,12 @@ def find_type(type, name):
70
70
71
71
72
72
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
+ """
74
79
75
80
def __init__ (self , val ):
76
81
self .val = val ["data" ].referenced_value ()
@@ -82,31 +87,42 @@ def to_string(self):
82
87
return "Exception pretty printing irept"
83
88
84
89
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
+
85
100
sub = self .val ["sub" ]
86
- count = 0
101
+ sub_count = 0
87
102
item = sub ["_M_impl" ]["_M_start" ]
88
103
finish = sub ["_M_impl" ]["_M_finish" ]
89
104
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
93
108
item += 1
94
109
95
110
named_sub = self .val ["named_sub" ]
96
111
size = named_sub ["_M_t" ]["_M_impl" ]["_M_node_count" ]
97
112
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 :
100
115
rep_type = find_type (named_sub .type , "_Rep_type" )
101
116
link_type = find_type (rep_type , "_Link_type" )
102
117
node_type = link_type .strip_typedefs ()
103
118
current = node .cast (node_type ).dereference ()
104
119
addr_type = current .type .template_argument (0 ).pointer ()
105
120
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 :
110
126
# Get the next node
111
127
right = node .dereference ()["_M_right" ]
112
128
if right :
@@ -125,8 +141,14 @@ def children(self):
125
141
if node .dereference ()["_M_right" ] != parent :
126
142
node = parent
127
143
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
+
128
150
def display_hint (self ):
129
- return "map "
151
+ return "array "
130
152
131
153
132
154
class InstructionPrettyPrinter :
@@ -154,5 +176,7 @@ def load_cbmc_printers():
154
176
# it should be applied too, third is the class that should be called to pretty-print that type.
155
177
printers .add_printer ("dstringt" , "^(?:dstringt|irep_idt)" , DStringPrettyPrinter )
156
178
printers .add_printer ("instructiont" , "^goto_programt::instructiont" , InstructionPrettyPrinter )
179
+ printers .add_printer ("irept" , "^irept" , IrepPrettyPrinter )
180
+
157
181
# We aren't associating with a particular object file, so pass in None instead of gdb.current_objfile()
158
182
gdb .printing .register_pretty_printer (None , printers , replace = True )
0 commit comments