diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index cc18109270..b16fc76c01 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2153,7 +2153,7 @@ pub const Object = struct { )); } - const union_name = if (layout.tag_size == 0) "AnonUnion" else name.ptr; + const union_name = if (layout.tag_size == 0) name.ptr else "AnonUnion"; const union_di_ty = dib.createUnionType( compile_unit_scope, diff --git a/src/type.zig b/src/type.zig index 3b46546df0..5685d097b9 100644 --- a/src/type.zig +++ b/src/type.zig @@ -6062,7 +6062,7 @@ pub const Type = extern union { pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; pub fn Type(comptime t: Tag) type { - // Keep in sync with tools/zig-gdb.py + // Keep in sync with tools/stage2_pretty_printers_common.py return switch (t) { .u1, .u8, diff --git a/src/value.zig b/src/value.zig index 7a0636dda0..47f69b2099 100644 --- a/src/value.zig +++ b/src/value.zig @@ -22,7 +22,7 @@ pub const Value = extern union { tag_if_small_enough: Tag, ptr_otherwise: *Payload, - // Keep in sync with tools/zig-gdb.py + // Keep in sync with tools/stage2_pretty_printers_common.py pub const Tag = enum(usize) { // The first section of this enum are tags that require no payload. u1_type, diff --git a/tools/stage2_gdb_pretty_printers.py b/tools/stage2_gdb_pretty_printers.py index bd64916536..5eca2fdec2 100644 --- a/tools/stage2_gdb_pretty_printers.py +++ b/tools/stage2_gdb_pretty_printers.py @@ -2,56 +2,9 @@ # put "source /path/to/stage2_gdb_pretty_printers.py" in ~/.gdbinit to load it automatically. import re import gdb.printing +import stage2_pretty_printers_common as common class TypePrinter: - no_payload_count = 4096 - - # Keep in sync with src/type.zig - # Types which have no payload do not need to be entered here. - payload_type_names = { - 'array_u8': 'Type.Payload.Len', - 'array_u8_sentinel_0': 'Type.Payload.Len', - - 'single_const_pointer': 'Type.Payload.ElemType', - 'single_mut_pointer': 'Type.Payload.ElemType', - 'many_const_pointer': 'Type.Payload.ElemType', - 'many_mut_pointer': 'Type.Payload.ElemType', - 'c_const_pointer': 'Type.Payload.ElemType', - 'c_mut_pointer': 'Type.Payload.ElemType', - 'const_slice': 'Type.Payload.ElemType', - 'mut_slice': 'Type.Payload.ElemType', - 'optional': 'Type.Payload.ElemType', - 'optional_single_mut_pointer': 'Type.Payload.ElemType', - 'optional_single_const_pointer': 'Type.Payload.ElemType', - 'anyframe_T': 'Type.Payload.ElemType', - - 'int_signed': 'Type.Payload.Bits', - 'int_unsigned': 'Type.Payload.Bits', - - 'error_set': 'Type.Payload.ErrorSet', - 'error_set_inferred': 'Type.Payload.ErrorSetInferred', - 'error_set_merged': 'Type.Payload.ErrorSetMerged', - - 'array': 'Type.Payload.Array', - 'vector': 'Type.Payload.Array', - - 'array_sentinel': 'Type.Payload.ArraySentinel', - 'pointer': 'Type.Payload.Pointer', - 'function': 'Type.Payload.Function', - 'error_union': 'Type.Payload.ErrorUnion', - 'error_set_single': 'Type.Payload.Name', - 'opaque': 'Type.Payload.Opaque', - 'struct': 'Type.Payload.Struct', - 'union': 'Type.Payload.Union', - 'union_tagged': 'Type.Payload.Union', - 'enum_full, .enum_nonexhaustive': 'Type.Payload.EnumFull', - 'enum_simple': 'Type.Payload.EnumSimple', - 'enum_numbered': 'Type.Payload.EnumNumbered', - 'empty_struct': 'Type.Payload.ContainerScope', - 'tuple': 'Type.Payload.Tuple', - 'anon_struct': 'Type.Payload.AnonStruct', - } - def __init__(self, val): self.val = val @@ -59,7 +12,7 @@ class TypePrinter: tag_if_small_enough = self.val['tag_if_small_enough'] tag_type = tag_if_small_enough.type - if tag_if_small_enough < TypePrinter.no_payload_count: + if tag_if_small_enough < common.Type.no_payload_count: return tag_if_small_enough else: return self.val['ptr_otherwise'].dereference()['tag'] @@ -69,7 +22,7 @@ class TypePrinter: if tag is None: return None - type_name = TypePrinter.payload_type_names.get(str(tag)) + type_name = common.Type.payload_type_names.get(str(tag)) if type_name is None: return None return gdb.lookup_type('struct type.%s' % type_name) @@ -78,12 +31,12 @@ class TypePrinter: tag = self.tag() if tag is None: return '(invalid type)' - if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: + if self.val['tag_if_small_enough'] < common.Type.no_payload_count: return '.%s' % str(tag) return None def children(self): - if self.val['tag_if_small_enough'] < TypePrinter.no_payload_count: + if self.val['tag_if_small_enough'] < common.Type.no_payload_count: return yield ('tag', '.%s' % str(self.tag())) @@ -93,55 +46,6 @@ class TypePrinter: 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': 'Value.Payload.BigInt', - 'big_int_negative': 'Value.Payload.BigInt', - - 'extern_fn': 'Value.Payload.ExternFn', - - 'decl_ref': 'Value.Payload.Decl', - - 'repeated': 'Value.Payload.SubValue', - 'eu_payload': 'Value.Payload.SubValue', - 'opt_payload': 'Value.Payload.SubValue', - 'empty_array_sentinel': 'Value.Payload.SubValue', - - 'eu_payload_ptr': 'Value.Payload.PayloadPtr', - 'opt_payload_ptr': 'Value.Payload.PayloadPtr', - - 'bytes': 'Value.Payload.Bytes', - 'enum_literal': 'Value.Payload.Bytes', - - 'slice': 'Value.Payload.Slice', - - 'enum_field_index': 'Value.Payload.U32', - - 'ty': 'Value.Payload.Ty', - 'int_type': 'Value.Payload.IntType', - 'int_u64': 'Value.Payload.U64', - 'int_i64': 'Value.Payload.I64', - 'function': 'Value.Payload.Function', - 'variable': 'Value.Payload.Variable', - 'decl_ref_mut': 'Value.Payload.DeclRefMut', - 'elem_ptr': 'Value.Payload.ElemPtr', - 'field_ptr': 'Value.Payload.FieldPtr', - 'float_16': 'Value.Payload.Float_16', - 'float_32': 'Value.Payload.Float_32', - 'float_64': 'Value.Payload.Float_64', - 'float_80': 'Value.Payload.Float_80', - 'float_128': 'Value.Payload.Float_128', - 'error': 'Value.Payload.Error', - 'inferred_alloc': 'Value.Payload.InferredAlloc', - 'inferred_alloc_comptime': 'Value.Payload.InferredAllocComptime', - 'aggregate': 'Value.Payload.Aggregate', - 'union': 'Value.Payload.Union', - 'bound_fn': 'Value.Payload.BoundFn', - } - def __init__(self, val): self.val = val @@ -149,7 +53,7 @@ class ValuePrinter: 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: + if tag_if_small_enough < common.Value.no_payload_count: return tag_if_small_enough else: return self.val['ptr_otherwise'].dereference()['tag'] @@ -159,7 +63,7 @@ class ValuePrinter: if tag is None: return None - type_name = ValuePrinter.payload_type_names.get(str(tag)) + type_name = Comman.Value.payload_type_names.get(str(tag)) if type_name is None: return None return gdb.lookup_type('struct value.%s' % type_name) @@ -168,12 +72,12 @@ class ValuePrinter: tag = self.tag() if tag is None: return '(invalid value)' - if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count: + if self.val['tag_if_small_enough'] < common.Value.no_payload_count: return '.%s' % str(tag) return None def children(self): - if self.val['tag_if_small_enough'] < ValuePrinter.no_payload_count: + if self.val['tag_if_small_enough'] < common.Value.no_payload_count: return yield ('tag', '.%s' % str(self.tag())) diff --git a/tools/stage2_lldb_pretty_printers.py b/tools/stage2_lldb_pretty_printers.py new file mode 100644 index 0000000000..3dcb06f538 --- /dev/null +++ b/tools/stage2_lldb_pretty_printers.py @@ -0,0 +1,59 @@ +# pretty printing for stage 2. +# put "command script /path/to/stage2_lldb_pretty_printers.py" and "type category enable stage2" in ~/.lldbinit to load it automatically. +import lldb +import stage2_pretty_printers_common as common + +category = 'stage2' +module = category + '_lldb_pretty_printers' + +class type_Type_SynthProvider: + def __init__(self, type, _=None): + self.type = type + + def update(self): + self.tag = self.type.GetChildMemberWithName('tag_if_small_enough').Clone('tag') + self.payload = None + if self.tag.GetValueAsUnsigned() >= common.Type.no_payload_count: + ptr_otherwise = self.type.GetChildMemberWithName('ptr_otherwise') + self.tag = ptr_otherwise.Dereference().GetChildMemberWithName('tag') + payload_type = self.type.target.FindFirstType('type.' + common.Type.payload_type_names[self.tag.GetValue()]) + self.payload = ptr_otherwise.Cast(payload_type.GetPointerType()).Dereference().GetChildMemberWithName('data').Clone('payload') + + def num_children(self): + return 1 + (self.payload is not None) + + def get_child_index(self, name): + return ['tag', 'payload'].index(name) + + def get_child_at_index(self, index): + return [self.tag, self.payload][index] + +class value_Value_SynthProvider: + def __init__(self, value, _=None): + self.value = value + + def update(self): + self.tag = self.value.GetChildMemberWithName('tag_if_small_enough').Clone('tag') + self.payload = None + if self.tag.GetValueAsUnsigned() >= common.Value.no_payload_count: + ptr_otherwise = self.value.GetChildMemberWithName('ptr_otherwise') + self.tag = ptr_otherwise.Dereference().GetChildMemberWithName('tag') + payload_type = self.value.target.FindFirstType('value.' + common.Value.payload_type_names[self.tag.GetValue()]) + self.payload = ptr_otherwise.Cast(payload_type.GetPointerType()).Dereference().GetChildMemberWithName('data').Clone('payload') + + def num_children(self): + return 1 + (self.payload is not None) + + def get_child_index(self, name): + return ['tag', 'payload'].index(name) + + def get_child_at_index(self, index): + return [self.tag, self.payload][index] + +def add(debugger, type, summary=False, synth=False): + if summary: debugger.HandleCommand('type summary add --python-function ' + module + '.' + type.replace('.', '_') + '_SummaryProvider "' + type + '" --category ' + category) + if synth: debugger.HandleCommand('type synthetic add --python-class ' + module + '.' + type.replace('.', '_') + '_SynthProvider "' + type + '" --category ' + category) + +def __lldb_init_module(debugger, _=None): + add(debugger, 'type.Type', synth=True) + add(debugger, 'value.Value', synth=True) diff --git a/tools/stage2_pretty_printers_common.py b/tools/stage2_pretty_printers_common.py new file mode 100644 index 0000000000..eab369d3a8 --- /dev/null +++ b/tools/stage2_pretty_printers_common.py @@ -0,0 +1,98 @@ +class Type: + no_payload_count = 4096 + + # Keep in sync with src/type.zig + # Types which have no payload do not need to be entered here. + payload_type_names = { + 'array_u8': 'Type.Payload.Len', + 'array_u8_sentinel_0': 'Type.Payload.Len', + + 'single_const_pointer': 'Type.Payload.ElemType', + 'single_mut_pointer': 'Type.Payload.ElemType', + 'many_const_pointer': 'Type.Payload.ElemType', + 'many_mut_pointer': 'Type.Payload.ElemType', + 'c_const_pointer': 'Type.Payload.ElemType', + 'c_mut_pointer': 'Type.Payload.ElemType', + 'const_slice': 'Type.Payload.ElemType', + 'mut_slice': 'Type.Payload.ElemType', + 'optional': 'Type.Payload.ElemType', + 'optional_single_mut_pointer': 'Type.Payload.ElemType', + 'optional_single_const_pointer': 'Type.Payload.ElemType', + 'anyframe_T': 'Type.Payload.ElemType', + + 'int_signed': 'Type.Payload.Bits', + 'int_unsigned': 'Type.Payload.Bits', + + 'error_set': 'Type.Payload.ErrorSet', + 'error_set_inferred': 'Type.Payload.ErrorSetInferred', + 'error_set_merged': 'Type.Payload.ErrorSetMerged', + + 'array': 'Type.Payload.Array', + 'vector': 'Type.Payload.Array', + + 'array_sentinel': 'Type.Payload.ArraySentinel', + 'pointer': 'Type.Payload.Pointer', + 'function': 'Type.Payload.Function', + 'error_union': 'Type.Payload.ErrorUnion', + 'error_set_single': 'Type.Payload.Name', + 'opaque': 'Type.Payload.Opaque', + 'struct': 'Type.Payload.Struct', + 'union': 'Type.Payload.Union', + 'union_tagged': 'Type.Payload.Union', + 'enum_full, .enum_nonexhaustive': 'Type.Payload.EnumFull', + 'enum_simple': 'Type.Payload.EnumSimple', + 'enum_numbered': 'Type.Payload.EnumNumbered', + 'empty_struct': 'Type.Payload.ContainerScope', + 'tuple': 'Type.Payload.Tuple', + 'anon_struct': 'Type.Payload.AnonStruct', + } + +class Value: + 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': 'Value.Payload.BigInt', + 'big_int_negative': 'Value.Payload.BigInt', + + 'extern_fn': 'Value.Payload.ExternFn', + + 'decl_ref': 'Value.Payload.Decl', + + 'repeated': 'Value.Payload.SubValue', + 'eu_payload': 'Value.Payload.SubValue', + 'opt_payload': 'Value.Payload.SubValue', + 'empty_array_sentinel': 'Value.Payload.SubValue', + + 'eu_payload_ptr': 'Value.Payload.PayloadPtr', + 'opt_payload_ptr': 'Value.Payload.PayloadPtr', + + 'bytes': 'Value.Payload.Bytes', + 'enum_literal': 'Value.Payload.Bytes', + + 'slice': 'Value.Payload.Slice', + + 'enum_field_index': 'Value.Payload.U32', + + 'ty': 'Value.Payload.Ty', + 'int_type': 'Value.Payload.IntType', + 'int_u64': 'Value.Payload.U64', + 'int_i64': 'Value.Payload.I64', + 'function': 'Value.Payload.Function', + 'variable': 'Value.Payload.Variable', + 'decl_ref_mut': 'Value.Payload.DeclRefMut', + 'elem_ptr': 'Value.Payload.ElemPtr', + 'field_ptr': 'Value.Payload.FieldPtr', + 'float_16': 'Value.Payload.Float_16', + 'float_32': 'Value.Payload.Float_32', + 'float_64': 'Value.Payload.Float_64', + 'float_80': 'Value.Payload.Float_80', + 'float_128': 'Value.Payload.Float_128', + 'error': 'Value.Payload.Error', + 'inferred_alloc': 'Value.Payload.InferredAlloc', + 'inferred_alloc_comptime': 'Value.Payload.InferredAllocComptime', + 'aggregate': 'Value.Payload.Aggregate', + 'union': 'Value.Payload.Union', + 'bound_fn': 'Value.Payload.BoundFn', + }