| ... | ... | @@ -1,8 +1,9 @@ |
| 1 | 1 | # pretty printing for stage1, stage2 and the standard library |
| 2 | 2 | # put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically |
| 3 | 3 | |
| 4 | | import gdb.printing |
| 5 | 4 | import re |
| 5 | import gdb.printing |
| 6 | import gdb.types |
| 6 | 7 | |
| 7 | 8 | class ZigListPrinter: |
| 8 | 9 | def __init__(self, val): |
| ... | ... | @@ -184,6 +185,95 @@ class ArrayHashMapPrinter: |
| 184 | 185 | return 'map' |
| 185 | 186 | return 'array' |
| 186 | 187 | |
| 188 | class TypePrinter: |
| 189 | no_payload_count = 4096 |
| 190 | |
| 191 | # Keep in sync with src/type.zig |
| 192 | # Types which have no payload do not need to be entered here. |
| 193 | payload_type_names = { |
| 194 | 'array_u8': 'type.Len', |
| 195 | 'array_u8_sentinel_0': 'Len', |
| 196 | |
| 197 | 'single_const_pointer': 'ElemType', |
| 198 | 'single_mut_pointer': 'ElemType', |
| 199 | 'many_const_pointer': 'ElemType', |
| 200 | 'many_mut_pointer': 'ElemType', |
| 201 | 'c_const_pointer': 'ElemType', |
| 202 | 'c_mut_pointer': 'ElemType', |
| 203 | 'const_slice': 'ElemType', |
| 204 | 'mut_slice': 'ElemType', |
| 205 | 'optional': 'ElemType', |
| 206 | 'optional_single_mut_pointer': 'ElemType', |
| 207 | 'optional_single_const_pointer': 'ElemType', |
| 208 | 'anyframe_T': 'ElemType', |
| 209 | |
| 210 | 'int_signed': 'Bits', |
| 211 | 'int_unsigned': 'Bits', |
| 212 | |
| 213 | 'error_set': 'ErrorSet', |
| 214 | 'error_set_inferred': 'ErrorSetInferred', |
| 215 | 'error_set_merged': 'ErrorSetMerged', |
| 216 | |
| 217 | 'array': 'Array', |
| 218 | 'vector': 'Array', |
| 219 | |
| 220 | 'array_sentinel': 'ArraySentinel', |
| 221 | 'pointer': 'Pointer', |
| 222 | 'function': 'Function', |
| 223 | 'error_union': 'ErrorUnion', |
| 224 | 'error_set_single': 'Name', |
| 225 | 'opaque': 'Opaque', |
| 226 | 'struct': 'Struct', |
| 227 | 'union': 'Union', |
| 228 | 'union_tagged': 'Union', |
| 229 | 'enum_full, .enum_nonexhaustive': 'EnumFull', |
| 230 | 'enum_simple': 'EnumSimple', |
| 231 | 'enum_numbered': 'EnumNumbered', |
| 232 | 'empty_struct': 'ContainerScope', |
| 233 | 'tuple': 'Tuple', |
| 234 | 'anon_struct': 'AnonStruct', |
| 235 | } |
| 236 | |
| 237 | def __init__(self, val): |
| 238 | self.val = val |
| 239 | |
| 240 | def tag(self): |
| 241 | tag_if_small_enough = self.val['tag_if_small_enough'] |
| 242 | tag_type = tag_if_small_enough.type |
| 243 | |
| 244 | if tag_if_small_enough < TypePrinter.no_payload_count: |
| 245 | return tag_if_small_enough |
| 246 | else: |
| 247 | return self.val['ptr_otherwise'].dereference()['tag'] |
| 248 | |
| 249 | def payload_type(self): |
| 250 | tag = self.tag() |
| 251 | if tag is None: |
| 252 | return None |
| 253 | |
| 254 | type_name = TypePrinter.payload_type_names.get(str(tag)) |
| 255 | if type_name is None: |
| 256 | return None |
| 257 | return gdb.lookup_type('struct type.%s' % type_name) |
| 258 | |
| 259 | def to_string(self): |
| 260 | tag = self.tag() |
| 261 | if tag is None: |
| 262 | return 'Type.(invalid type)' |
| 263 | if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: |
| 264 | return '.%s' % str(tag) |
| 265 | return None |
| 266 | |
| 267 | def children(self): |
| 268 | if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: |
| 269 | return |
| 270 | |
| 271 | yield ('tag', '.%s' % str(self.tag())) |
| 272 | |
| 273 | payload_type = self.payload_type() |
| 274 | if payload_type is not None: |
| 275 | yield ('payload', self.val['ptr_otherwise'].cast(payload_type.pointer()).dereference()['data']) |
| 276 | |
| 187 | 277 | pp1 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage1 compiler') |
| 188 | 278 | pp1.add_printer('Buf', '^Buf$', BufPrinter) |
| 189 | 279 | pp1.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter) |
| ... | ... | @@ -193,6 +283,7 @@ gdb.printing.register_pretty_printer(gdb.current_objfile(), pp1) |
| 193 | 283 | pplang = gdb.printing.RegexpCollectionPrettyPrinter('Zig language') |
| 194 | 284 | pplang.add_printer('Slice', '^\[\]u8', SliceStringPrinter) |
| 195 | 285 | pplang.add_printer('Slice', '^\[\]', SlicePrinter) |
| 286 | gdb.printing.register_pretty_printer(gdb.current_objfile(), pplang) |
| 196 | 287 | |
| 197 | 288 | ppstd = gdb.printing.RegexpCollectionPrettyPrinter('Zig standard library') |
| 198 | 289 | ppstd.add_printer('ArrayList', r'^std\.array_list\.ArrayListAligned(Unmanaged)?\(.*\)$', ArrayListPrinter) |
| ... | ... | @@ -200,3 +291,8 @@ ppstd.add_printer('MultiArrayList', r'^std\.multi_array_list\.MultiArrayList\(.* |
| 200 | 291 | ppstd.add_printer('HashMap', r'^std\.hash_map\.HashMap(Unmanaged)?\(.*\)$', HashMapPrinter) |
| 201 | 292 | ppstd.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged)?\(.*\)$', ArrayHashMapPrinter) |
| 202 | 293 | gdb.printing.register_pretty_printer(gdb.current_objfile(), ppstd) |
| 294 | |
| 295 | pp2 = gdb.printing.RegexpCollectionPrettyPrinter('Zig stage2 compiler') |
| 296 | ppstd.add_printer('Type', r'^type\.Type$', TypePrinter) |
| 297 | gdb.printing.register_pretty_printer(gdb.current_objfile(), pp2) |
| 298 | |