aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2022-03-16 17:57:31 +0100
committerRobin Voetter <robin@voetter.nl>2022-03-16 17:57:31 +0100
commit0bd84e03b98a75806c47cb7f514a15de7e4d2b6e (patch)
treef81fcc9e6e08eac2dbf1f5b859e00d21fb22fdb3 /tools
parent6830bcbb0a887b146379f0d90b04b0ae5834dead (diff)
downloadzig-0bd84e03b98a75806c47cb7f514a15de7e4d2b6e.tar.gz
zig-0bd84e03b98a75806c47cb7f514a15de7e4d2b6e.zip
gdb: add printer for selfhosted Value
Diffstat (limited to 'tools')
-rw-r--r--tools/zig-gdb.py95
1 files changed, 93 insertions, 2 deletions
diff --git a/tools/zig-gdb.py b/tools/zig-gdb.py
index ff1b20bb74..001211267c 100644
--- a/tools/zig-gdb.py
+++ b/tools/zig-gdb.py
@@ -259,7 +259,7 @@ class TypePrinter:
def to_string(self):
tag = self.tag()
if tag is None:
- return 'Type.(invalid type)'
+ return '(invalid type)'
if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count:
return '.%s' % str(tag)
return None
@@ -274,6 +274,96 @@ class TypePrinter:
if payload_type is not None:
yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data'])
+class ValuePrinter:
+ no_payload_count = 4096
+
+ # Keep in sync with src/value.zig
+ # Values which have no payload do not need to be entered here.
+ payload_type_names = {
+ 'big_int_positive': 'BigInt',
+ 'big_int_negative': 'BigInt',
+
+ 'extern_fn': 'ExternFn',
+
+ 'decl_ref': 'Decl',
+
+ 'repeated': 'SubValue',
+ 'eu_payload': 'SubValue',
+ 'opt_payload': 'SubValue',
+ 'empty_array_sentinel': 'SubValue',
+
+ 'eu_payload_ptr': 'PayloadPtr',
+ 'opt_payload_ptr': 'PayloadPtr',
+
+ 'bytes': 'Bytes',
+ 'enum_literal': 'Bytes',
+
+ 'slice': 'Slice',
+
+ 'enum_field_index': 'U32',
+
+ 'ty': 'Ty',
+ 'int_type': 'IntType',
+ 'int_u64': 'U64',
+ 'int_i64': 'I64',
+ 'function': 'Function',
+ 'variable': 'Variable',
+ 'decl_ref_mut': 'DeclRefMut',
+ 'elem_ptr': 'ElemPtr',
+ 'field_ptr': 'FieldPtr',
+ 'float_16': 'Float_16',
+ 'float_32': 'Float_32',
+ 'float_64': 'Float_64',
+ 'float_80': 'Float_80',
+ 'float_128': 'Float_128',
+ 'error': 'Error',
+ 'inferred_alloc': 'InferredAlloc',
+ 'inferred_alloc_comptime': 'InferredAllocComptime',
+ 'aggregate': 'Aggregate',
+ 'union': 'Union',
+ 'bound_fn': 'BoundFn',
+ }
+
+ def __init__(self, val):
+ self.val = val
+
+ def tag(self):
+ tag_if_small_enough = self.val['tag_if_small_enough']
+ tag_type = tag_if_small_enough.type
+
+ if tag_if_small_enough < ValuePrinter.no_payload_count:
+ return tag_if_small_enough
+ else:
+ return self.val['ptr_otherwise'].dereference()['tag']
+
+ def payload_type(self):
+ tag = self.tag()
+ if tag is None:
+ return None
+
+ type_name = ValuePrinter.payload_type_names.get(str(tag))
+ if type_name is None:
+ return None
+ return gdb.lookup_type('struct value.%s' % type_name)
+
+ def to_string(self):
+ tag = self.tag()
+ if tag is None:
+ return '(invalid value)'
+ if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count:
+ return '.%s' % str(tag)
+ return None
+
+ def children(self):
+ if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count:
+ return
+
+ yield ('tag', '.%s' % str(self.tag()))
+
+ payload_type = self.payload_type()
+ if payload_type is not None:
+ yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data'])
+
pp1 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler')
pp1.add_printer('Buf', '^Buf$', BufPrinter)
pp1.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter)
@@ -293,6 +383,7 @@ ppstd.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged
gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd)
pp2 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage2 compiler')
-ppstd.add_printer('Type', r'^type\.Type$', TypePrinter)
+pp2.add_printer('Type', r'^type\.Type$', TypePrinter)
+pp2.add_printer('Value', r'^value\.Value$', ValuePrinter)
gdb.printing.register_pretty_printer(gdb.current_objfile(), pp2)