authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-03-16 17:57:31+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-03-16 17:57:31+01:00
log0bd84e03b98a75806c47cb7f514a15de7e4d2b6e
treef81fcc9e6e08eac2dbf1f5b859e00d21fb22fdb3
parent6830bcbb0a887b146379f0d90b04b0ae5834dead

gdb: add printer for selfhosted Value


2 files changed, 94 insertions(+), 2 deletions(-)

src/value.zig+1
...@@ -20,6 +20,7 @@ pub const Value = extern union {...@@ -20,6 +20,7 @@ pub const Value = extern union {
20 tag_if_small_enough: Tag,20 tag_if_small_enough: Tag,
21 ptr_otherwise: *Payload,21 ptr_otherwise: *Payload,
2222
23 // Keep in sync with tools/zig-gdb.py
23 pub const Tag = enum(usize) {24 pub const Tag = enum(usize) {
24 // The first section of this enum are tags that require no payload.25 // The first section of this enum are tags that require no payload.
25 u1_type,26 u1_type,
tools/zig-gdb.py+93-2
...@@ -259,7 +259,7 @@ class TypePrinter:...@@ -259,7 +259,7 @@ class TypePrinter:
259 def to_string(self):259 def to_string(self):
260 tag = self.tag()260 tag = self.tag()
261 if tag is None:261 if tag is None:
262 return 'Type.(invalid type)'262 return '(invalid type)'
263 if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count:263 if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count:
264 return '.%s' % str(tag)264 return '.%s' % str(tag)
265 return None265 return None
...@@ -274,6 +274,96 @@ class TypePrinter:...@@ -274,6 +274,96 @@ class TypePrinter:
274 if payload_type is not None:274 if payload_type is not None:
275 yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data'])275 yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data'])
276276
277class ValuePrinter:
278 no_payload_count = 4096
279
280 # Keep in sync with src/value.zig
281 # Values which have no payload do not need to be entered here.
282 payload_type_names = {
283 'big_int_positive': 'BigInt',
284 'big_int_negative': 'BigInt',
285
286 'extern_fn': 'ExternFn',
287
288 'decl_ref': 'Decl',
289
290 'repeated': 'SubValue',
291 'eu_payload': 'SubValue',
292 'opt_payload': 'SubValue',
293 'empty_array_sentinel': 'SubValue',
294
295 'eu_payload_ptr': 'PayloadPtr',
296 'opt_payload_ptr': 'PayloadPtr',
297
298 'bytes': 'Bytes',
299 'enum_literal': 'Bytes',
300
301 'slice': 'Slice',
302
303 'enum_field_index': 'U32',
304
305 'ty': 'Ty',
306 'int_type': 'IntType',
307 'int_u64': 'U64',
308 'int_i64': 'I64',
309 'function': 'Function',
310 'variable': 'Variable',
311 'decl_ref_mut': 'DeclRefMut',
312 'elem_ptr': 'ElemPtr',
313 'field_ptr': 'FieldPtr',
314 'float_16': 'Float_16',
315 'float_32': 'Float_32',
316 'float_64': 'Float_64',
317 'float_80': 'Float_80',
318 'float_128': 'Float_128',
319 'error': 'Error',
320 'inferred_alloc': 'InferredAlloc',
321 'inferred_alloc_comptime': 'InferredAllocComptime',
322 'aggregate': 'Aggregate',
323 'union': 'Union',
324 'bound_fn': 'BoundFn',
325 }
326
327 def __init__(self, val):
328 self.val = val
329
330 def tag(self):
331 tag_if_small_enough = self.val['tag_if_small_enough']
332 tag_type = tag_if_small_enough.type
333
334 if tag_if_small_enough < ValuePrinter.no_payload_count:
335 return tag_if_small_enough
336 else:
337 return self.val['ptr_otherwise'].dereference()['tag']
338
339 def payload_type(self):
340 tag = self.tag()
341 if tag is None:
342 return None
343
344 type_name = ValuePrinter.payload_type_names.get(str(tag))
345 if type_name is None:
346 return None
347 return gdb.lookup_type('struct value.%s' % type_name)
348
349 def to_string(self):
350 tag = self.tag()
351 if tag is None:
352 return '(invalid value)'
353 if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count:
354 return '.%s' % str(tag)
355 return None
356
357 def children(self):
358 if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count:
359 return
360
361 yield ('tag', '.%s' % str(self.tag()))
362
363 payload_type = self.payload_type()
364 if payload_type is not None:
365 yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data'])
366
277pp1 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler')367pp1 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler')
278pp1.add_printer('Buf', '^Buf$', BufPrinter)368pp1.add_printer('Buf', '^Buf$', BufPrinter)
279pp1.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter)369pp1.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter)
...@@ -293,6 +383,7 @@ ppstd.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged...@@ -293,6 +383,7 @@ ppstd.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged
293gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd)383gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd)
294384
295pp2 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage2 compiler')385pp2 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage2 compiler')
296ppstd.add_printer('Type', r'^type\.Type$', TypePrinter)386pp2.add_printer('Type', r'^type\.Type$', TypePrinter)
387pp2.add_printer('Value', r'^value\.Value$', ValuePrinter)
297gdb.printing.register_pretty_printer(gdb.current_objfile(), pp2)388gdb.printing.register_pretty_printer(gdb.current_objfile(), pp2)
298389