╭ compiler_gdb_pretty_printers.py ──────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 # pretty printing for stage 2. 2 # put "source /path/to/stage2_gdb_pretty_printers.py" in ~/.gdbinit to load it automatically. 3 import re 4 import gdb.printing 5 6 class TypePrinter: 7 no_payload_count = 4096 8 9 # Keep in sync with src/type.zig 10 # Types which have no payload do not need to be entered here. 11 payload_type_names = { 12 'array_u8': 'Type.Payload.Len', 13 'array_u8_sentinel_0': 'Type.Payload.Len', 14 15 'single_const_pointer': 'Type.Payload.ElemType', 16 'single_mut_pointer': 'Type.Payload.ElemType', 17 'many_const_pointer': 'Type.Payload.ElemType', 18 'many_mut_pointer': 'Type.Payload.ElemType', 19 'c_const_pointer': 'Type.Payload.ElemType', 20 'c_mut_pointer': 'Type.Payload.ElemType', 21 'slice_const': 'Type.Payload.ElemType', 22 'mut_slice': 'Type.Payload.ElemType', 23 'optional': 'Type.Payload.ElemType', 24 'optional_single_mut_pointer': 'Type.Payload.ElemType', 25 'optional_single_const_pointer': 'Type.Payload.ElemType', 26 'anyframe_T': 'Type.Payload.ElemType', 27 28 'int_signed': 'Type.Payload.Bits', 29 'int_unsigned': 'Type.Payload.Bits', 30 31 'error_set': 'Type.Payload.ErrorSet', 32 'error_set_inferred': 'Type.Payload.ErrorSetInferred', 33 'error_set_merged': 'Type.Payload.ErrorSetMerged', 34 35 'array': 'Type.Payload.Array', 36 'vector': 'Type.Payload.Array', 37 38 'array_sentinel': 'Type.Payload.ArraySentinel', 39 'pointer': 'Type.Payload.Pointer', 40 'function': 'Type.Payload.Function', 41 'error_union': 'Type.Payload.ErrorUnion', 42 'error_set_single': 'Type.Payload.Name', 43 'opaque': 'Type.Payload.Opaque', 44 'struct': 'Type.Payload.Struct', 45 'union': 'Type.Payload.Union', 46 'union_tagged': 'Type.Payload.Union', 47 'enum_full, .enum_nonexhaustive': 'Type.Payload.EnumFull', 48 'enum_simple': 'Type.Payload.EnumSimple', 49 'enum_numbered': 'Type.Payload.EnumNumbered', 50 'empty_struct': 'Type.Payload.ContainerScope', 51 'tuple': 'Type.Payload.Tuple', 52 'anon_struct': 'Type.Payload.AnonStruct', 53 } 54 55 def __init__(self, val): 56 self.val = val 57 58 def tag(self): 59 tag_if_small_enough = self.val['tag_if_small_enough'] 60 tag_type = tag_if_small_enough.type 61 62 if tag_if_small_enough < TypePrinter.no_payload_count: 63 return tag_if_small_enough 64 else: 65 return self.val['ptr_otherwise'].dereference()['tag'] 66 67 def payload_type(self): 68 tag = self.tag() 69 if tag is None: 70 return None 71 72 type_name = TypePrinter.payload_type_names.get(str(tag)) 73 if type_name is None: 74 return None 75 return gdb.lookup_type('struct type.%s' % type_name) 76 77 def to_string(self): 78 tag = self.tag() 79 if tag is None: 80 return '(invalid type)' 81 if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: 82 return '.%s' % str(tag) 83 return None 84 85 def children(self): 86 if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: 87 return 88 89 yield ('tag', '.%s' % str(self.tag())) 90 91 payload_type = self.payload_type() 92 if payload_type is not None: 93 yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data']) 94 95 class ValuePrinter: 96 no_payload_count = 4096 97 98 # Keep in sync with src/value.zig 99 # Values which have no payload do not need to be entered here. 100 payload_type_names = { 101 'big_int_positive': 'Value.Payload.BigInt', 102 'big_int_negative': 'Value.Payload.BigInt', 103 104 'extern_fn': 'Value.Payload.ExternFn', 105 106 'decl_ref': 'Value.Payload.Decl', 107 108 'repeated': 'Value.Payload.SubValue', 109 'eu_payload': 'Value.Payload.SubValue', 110 'opt_payload': 'Value.Payload.SubValue', 111 'empty_array_sentinel': 'Value.Payload.SubValue', 112 113 'eu_payload_ptr': 'Value.Payload.PayloadPtr', 114 'opt_payload_ptr': 'Value.Payload.PayloadPtr', 115 116 'bytes': 'Value.Payload.Bytes', 117 'enum_literal': 'Value.Payload.Bytes', 118 119 'slice': 'Value.Payload.Slice', 120 121 'enum_field_index': 'Value.Payload.U32', 122 123 'ty': 'Value.Payload.Ty', 124 'int_type': 'Value.Payload.IntType', 125 'int_u64': 'Value.Payload.U64', 126 'int_i64': 'Value.Payload.I64', 127 'function': 'Value.Payload.Function', 128 'variable': 'Value.Payload.Variable', 129 'decl_ref_mut': 'Value.Payload.DeclRefMut', 130 'elem_ptr': 'Value.Payload.ElemPtr', 131 'field_ptr': 'Value.Payload.FieldPtr', 132 'float_16': 'Value.Payload.Float_16', 133 'float_32': 'Value.Payload.Float_32', 134 'float_64': 'Value.Payload.Float_64', 135 'float_80': 'Value.Payload.Float_80', 136 'float_128': 'Value.Payload.Float_128', 137 'error': 'Value.Payload.Error', 138 'inferred_alloc': 'Value.Payload.InferredAlloc', 139 'inferred_alloc_comptime': 'Value.Payload.InferredAllocComptime', 140 'aggregate': 'Value.Payload.Aggregate', 141 'union': 'Value.Payload.Union', 142 'bound_fn': 'Value.Payload.BoundFn', 143 } 144 145 def __init__(self, val): 146 self.val = val 147 148 def tag(self): 149 tag_if_small_enough = self.val['tag_if_small_enough'] 150 tag_type = tag_if_small_enough.type 151 152 if tag_if_small_enough < ValuePrinter.no_payload_count: 153 return tag_if_small_enough 154 else: 155 return self.val['ptr_otherwise'].dereference()['tag'] 156 157 def payload_type(self): 158 tag = self.tag() 159 if tag is None: 160 return None 161 162 type_name = ValuePrinter.payload_type_names.get(str(tag)) 163 if type_name is None: 164 return None 165 return gdb.lookup_type('struct value.%s' % type_name) 166 167 def to_string(self): 168 tag = self.tag() 169 if tag is None: 170 return '(invalid value)' 171 if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count: 172 return '.%s' % str(tag) 173 return None 174 175 def children(self): 176 if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count: 177 return 178 179 yield ('tag', '.%s' % str(self.tag())) 180 181 payload_type = self.payload_type() 182 if payload_type is not None: 183 yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data']) 184 185 pp = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage2 compiler') 186 pp.add_printer('Type', r'^type\.Type$', TypePrinter) 187 pp.add_printer('Value', r'^value\.Value$', ValuePrinter) 188 gdb.printing.register_pretty_printer(gdb.current_objfile(), pp) 189 190