mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
distribute the lldb pretty printers
rather than having them only in the source tree in tools/, distribute them to zig users. gdb ones are too outdated, delete them. stage1 also is useless now.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
# pretty printing for the zig language, zig standard library, and zig stage 2 compiler.
|
||||
# pretty printing for the zig language, zig standard library, and zig compiler.
|
||||
# put commands in ~/.lldbinit to run them automatically when starting lldb
|
||||
# `command script import /path/to/zig/tools/lldb_pretty_printers.py` to import this file
|
||||
# `command script import /path/to/zig/lib/lldb/pretty_printers.py` to import this file
|
||||
# `type category enable zig.lang` to enable pretty printing for the zig language
|
||||
# `type category enable zig.std` to enable pretty printing for the zig standard library
|
||||
# `type category enable zig.stage2` to enable pretty printing for the zig stage 2 compiler
|
||||
# `type category enable zig.compiler` to enable pretty printing for the zig compiler
|
||||
import lldb
|
||||
import re
|
||||
|
||||
@@ -331,7 +331,7 @@ class std_Entry_SynthProvider:
|
||||
def get_child_index(self, name): return self.indices.get(name)
|
||||
def get_child_at_index(self, index): return self.children[index].deref if index in range(len(self.children)) else None
|
||||
|
||||
# Define Zig Stage2 Compiler
|
||||
# Define Zig Compiler
|
||||
|
||||
class TagAndPayload_SynthProvider:
|
||||
def __init__(self, value, _=None): self.value = value
|
||||
@@ -680,7 +680,7 @@ value_tag_handlers = {
|
||||
'lazy_size': lambda payload: '@sizeOf(%s)' % type_Type_SummaryProvider(payload),
|
||||
}
|
||||
|
||||
# Define Zig Stage2 Compiler (compiled with the self-hosted backend)
|
||||
# Define Zig Compiler (compiled with the self-hosted backend)
|
||||
|
||||
class root_InternPool_Local_List_SynthProvider:
|
||||
def __init__(self, value, _=None): self.value = value
|
||||
@@ -915,31 +915,31 @@ def __lldb_init_module(debugger, _=None):
|
||||
add(debugger, category='zig.std', regex=True, type='^hash_map\\.HashMapUnmanaged\\(.*\\)$', identifier='std_HashMapUnmanaged', synth=True, expand=True, summary=True)
|
||||
add(debugger, category='zig.std', regex=True, type='^hash_map\\.HashMapUnmanaged\\(.*\\)\\.Entry$', identifier = 'std_Entry', synth=True, inline_children=True, summary=True)
|
||||
|
||||
# Initialize Zig Stage2 Compiler
|
||||
add(debugger, category='zig.stage2', type='Zir.Inst', identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Zir\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type='^Zir\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', type='Zir.Inst::Zir.Inst.Ref', identifier='InstRef', summary=True)
|
||||
add(debugger, category='zig.stage2', type='Zir.Inst::Zir.Inst.Index', identifier='InstIndex', summary=True)
|
||||
add(debugger, category='zig.stage2', type='Air.Inst', identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', type='Air.Inst::Air.Inst.Ref', identifier='InstRef', summary=True)
|
||||
add(debugger, category='zig.stage2', type='Air.Inst::Air.Inst.Index', identifier='InstIndex', summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
|
||||
add(debugger, category='zig.stage2', type='zig.DeclIndex', synth=True)
|
||||
add(debugger, category='zig.stage2', type='Module.Namespace::Module.Namespace.Index', synth=True)
|
||||
add(debugger, category='zig.stage2', type='Module.LazySrcLoc', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Index', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.NullTerminatedString', summary=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Key.ErrorUnion.Value', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Key.Float.Storage', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Key.Ptr.Addr', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='InternPool.Key.Aggregate.Storage', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.stage2', type='arch.x86_64.CodeGen.MCValue', identifier='zig_TaggedUnion', synth=True, inline_children=True, summary=True)
|
||||
# Initialize Zig Compiler
|
||||
add(debugger, category='zig.compiler', type='Zir.Inst', identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.compiler', regex=True, type=MultiArrayList_Entry('Zir\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.compiler', regex=True, type='^Zir\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
|
||||
add(debugger, category='zig.compiler', type='Zir.Inst::Zir.Inst.Ref', identifier='InstRef', summary=True)
|
||||
add(debugger, category='zig.compiler', type='Zir.Inst::Zir.Inst.Index', identifier='InstIndex', summary=True)
|
||||
add(debugger, category='zig.compiler', type='Air.Inst', identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.compiler', type='Air.Inst::Air.Inst.Ref', identifier='InstRef', summary=True)
|
||||
add(debugger, category='zig.compiler', type='Air.Inst::Air.Inst.Index', identifier='InstIndex', summary=True)
|
||||
add(debugger, category='zig.compiler', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
|
||||
add(debugger, category='zig.compiler', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
|
||||
add(debugger, category='zig.compiler', type='zig.DeclIndex', synth=True)
|
||||
add(debugger, category='zig.compiler', type='Module.Namespace::Module.Namespace.Index', synth=True)
|
||||
add(debugger, category='zig.compiler', type='Module.LazySrcLoc', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Index', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.NullTerminatedString', summary=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Key.ErrorUnion.Value', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Key.Float.Storage', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Key.Ptr.Addr', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='InternPool.Key.Aggregate.Storage', identifier='zig_TaggedUnion', synth=True)
|
||||
add(debugger, category='zig.compiler', type='arch.x86_64.CodeGen.MCValue', identifier='zig_TaggedUnion', synth=True, inline_children=True, summary=True)
|
||||
|
||||
# Initialize Zig Stage2 Compiler (compiled with the self-hosted backend)
|
||||
# Initialize Zig Compiler (compiled with the self-hosted backend)
|
||||
add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.Local\.List\(.*\)$', identifier='root_InternPool_Local_List', synth=True, expand=True, summary='capacity=${var%#}')
|
||||
add(debugger, category='zig', type='root.InternPool.Index', synth=True, summary=True)
|
||||
add(debugger, category='zig', type='root.InternPool.Index.Unwrapped', synth=True)
|
||||
@@ -1,142 +0,0 @@
|
||||
# pretty printing for the standard library.
|
||||
# put "source /path/to/std_gdb_pretty_printers.py" in ~/.gdbinit to load it automatically.
|
||||
import re
|
||||
import gdb.printing
|
||||
|
||||
# Handles both ArrayList and ArrayListUnmanaged.
|
||||
class ArrayListPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
type = self.val.type.name[len('std.array_list.'):]
|
||||
type = re.sub(r'^ArrayListAligned(Unmanaged)?\((.*),null\)$', r'ArrayList\1(\2)', type)
|
||||
return '%s of length %s, capacity %s' % (type, self.val['items']['len'], self.val['capacity'])
|
||||
|
||||
def children(self):
|
||||
for i in range(self.val['items']['len']):
|
||||
item = self.val['items']['ptr'] + i
|
||||
yield ('[%d]' % i, item.dereference())
|
||||
|
||||
def display_hint(self):
|
||||
return 'array'
|
||||
|
||||
class MultiArrayListPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def child_type(self):
|
||||
(helper_fn, _) = gdb.lookup_symbol('%s.dbHelper' % self.val.type.name)
|
||||
return helper_fn.type.fields()[1].type.target()
|
||||
|
||||
def to_string(self):
|
||||
type = self.val.type.name[len('std.multi_array_list.'):]
|
||||
return '%s of length %s, capacity %s' % (type, self.val['len'], self.val['capacity'])
|
||||
|
||||
def slice(self):
|
||||
fields = self.child_type().fields()
|
||||
base = self.val['bytes']
|
||||
cap = self.val['capacity']
|
||||
len = self.val['len']
|
||||
|
||||
if len == 0:
|
||||
return
|
||||
|
||||
fields = sorted(fields, key=lambda field: field.type.alignof, reverse=True)
|
||||
|
||||
for field in fields:
|
||||
ptr = base.cast(field.type.pointer()).dereference().cast(field.type.array(len - 1))
|
||||
base += field.type.sizeof * cap
|
||||
yield (field.name, ptr)
|
||||
|
||||
def children(self):
|
||||
for i, (name, ptr) in enumerate(self.slice()):
|
||||
yield ('[%d]' % i, name)
|
||||
yield ('[%d]' % i, ptr)
|
||||
|
||||
def display_hint(self):
|
||||
return 'map'
|
||||
|
||||
# Handles both HashMap and HashMapUnmanaged.
|
||||
class HashMapPrinter:
|
||||
def __init__(self, val):
|
||||
self.type = val.type
|
||||
is_managed = re.search(r'^std\.hash_map\.HashMap\(', self.type.name)
|
||||
self.val = val['unmanaged'] if is_managed else val
|
||||
|
||||
def header_ptr_type(self):
|
||||
(helper_fn, _) = gdb.lookup_symbol('%s.dbHelper' % self.val.type.name)
|
||||
return helper_fn.type.fields()[1].type
|
||||
|
||||
def header(self):
|
||||
if self.val['metadata'] == 0:
|
||||
return None
|
||||
return (self.val['metadata'].cast(self.header_ptr_type()) - 1).dereference()
|
||||
|
||||
def to_string(self):
|
||||
type = self.type.name[len('std.hash_map.'):]
|
||||
type = re.sub(r'^HashMap(Unmanaged)?\((.*),std.hash_map.AutoContext\(.*$', r'AutoHashMap\1(\2)', type)
|
||||
hdr = self.header()
|
||||
if hdr is not None:
|
||||
cap = hdr['capacity']
|
||||
else:
|
||||
cap = 0
|
||||
return '%s of length %s, capacity %s' % (type, self.val['size'], cap)
|
||||
|
||||
def children(self):
|
||||
hdr = self.header()
|
||||
if hdr is None:
|
||||
return
|
||||
is_map = self.display_hint() == 'map'
|
||||
for i in range(hdr['capacity']):
|
||||
metadata = self.val['metadata'] + i
|
||||
if metadata.dereference()['used'] == 1:
|
||||
yield ('[%d]' % i, (hdr['keys'] + i).dereference())
|
||||
if is_map:
|
||||
yield ('[%d]' % i, (hdr['values'] + i).dereference())
|
||||
|
||||
def display_hint(self):
|
||||
for field in self.header_ptr_type().target().fields():
|
||||
if field.name == 'values':
|
||||
return 'map'
|
||||
return 'array'
|
||||
|
||||
# Handles both ArrayHashMap and ArrayHashMapUnmanaged.
|
||||
class ArrayHashMapPrinter:
|
||||
def __init__(self, val):
|
||||
self.type = val.type
|
||||
is_managed = re.search(r'^std\.array_hash_map\.ArrayHashMap\(', self.type.name)
|
||||
self.val = val['unmanaged'] if is_managed else val
|
||||
|
||||
def to_string(self):
|
||||
type = self.type.name[len('std.array_hash_map.'):]
|
||||
type = re.sub(r'^ArrayHashMap(Unmanaged)?\((.*),std.array_hash_map.AutoContext\(.*$', r'AutoArrayHashMap\1(\2)', type)
|
||||
return '%s of length %s' % (type, self.val['entries']['len'])
|
||||
|
||||
def children(self):
|
||||
entries = MultiArrayListPrinter(self.val['entries'])
|
||||
len = self.val['entries']['len']
|
||||
fields = {}
|
||||
for name, ptr in entries.slice():
|
||||
fields[str(name)] = ptr
|
||||
|
||||
for i in range(len):
|
||||
if 'key' in fields:
|
||||
yield ('[%d]' % i, fields['key'][i])
|
||||
else:
|
||||
yield ('[%d]' % i, '{}')
|
||||
if 'value' in fields:
|
||||
yield ('[%d]' % i, fields['value'][i])
|
||||
|
||||
def display_hint(self):
|
||||
for name, ptr in MultiArrayListPrinter(self.val['entries']).slice():
|
||||
if name == 'value':
|
||||
return 'map'
|
||||
return 'array'
|
||||
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter('Zig standard library')
|
||||
pp.add_printer('ArrayList', r'^std\.array_list\.ArrayListAligned(Unmanaged)?\(.*\)$', ArrayListPrinter)
|
||||
pp.add_printer('MultiArrayList', r'^std\.multi_array_list\.MultiArrayList\(.*\)$', MultiArrayListPrinter)
|
||||
pp.add_printer('HashMap', r'^std\.hash_map\.HashMap(Unmanaged)?\(.*\)$', HashMapPrinter)
|
||||
pp.add_printer('ArrayHashMap', r'^std\.array_hash_map\.ArrayHashMap(Unmanaged)?\(.*\)$', ArrayHashMapPrinter)
|
||||
gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
|
||||
@@ -1,63 +0,0 @@
|
||||
# pretty printing for the language.
|
||||
# put "source /path/to/zig_gdb_pretty_printers.py" in ~/.gdbinit to load it automatically.
|
||||
import gdb.printing
|
||||
|
||||
|
||||
class ZigPrettyPrinter(gdb.printing.PrettyPrinter):
|
||||
def __init__(self):
|
||||
super().__init__('Zig')
|
||||
|
||||
def __call__(self, val):
|
||||
tag = val.type.tag
|
||||
if tag is None:
|
||||
return None
|
||||
if tag == '[]u8':
|
||||
return StringPrinter(val)
|
||||
if tag.startswith('[]'):
|
||||
return SlicePrinter(val)
|
||||
if tag.startswith('?'):
|
||||
return OptionalPrinter(val)
|
||||
return None
|
||||
|
||||
|
||||
class SlicePrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return f"{self.val['len']} items at {self.val['ptr']}"
|
||||
|
||||
def children(self):
|
||||
def it(val):
|
||||
for i in range(int(val['len'])):
|
||||
item = val['ptr'] + i
|
||||
yield (f'[{i}]', item.dereference())
|
||||
return it(self.val)
|
||||
|
||||
def display_hint(self):
|
||||
return 'array'
|
||||
|
||||
|
||||
class StringPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
return self.val['ptr'].string(length=int(self.val['len']))
|
||||
|
||||
def display_hint(self):
|
||||
return 'string'
|
||||
|
||||
|
||||
class OptionalPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
if self.val['some']:
|
||||
return self.val['data']
|
||||
else:
|
||||
return 'null'
|
||||
|
||||
|
||||
gdb.printing.register_pretty_printer(gdb.current_objfile(), ZigPrettyPrinter())
|
||||
Reference in New Issue
Block a user