From 94cf4d2d8193efb0ae642d475fb8437eb4c7e8c1 Mon Sep 17 00:00:00 2001 From: Tau Date: Sat, 29 Jun 2024 16:19:55 +0200 Subject: llvm: add pass-by-reference info to debug types Without this data, debugger expressions try to pass structs by-value, which mostly just crashes. Also: mark enums as enum classes to prevent the enumerators from shadowing other identifiers. --- src/codegen/llvm.zig | 10 ++++++++++ src/codegen/llvm/Builder.zig | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8cbd08a62d..19b6e0e070 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2068,6 +2068,7 @@ pub const Object = struct { debug_ptr_type, debug_len_type, }), + isByRef(ty, pt), ); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_slice_type); @@ -2237,6 +2238,7 @@ pub const Object = struct { debug_data_type, debug_some_type, }), + isByRef(ty, pt), ); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); @@ -2313,6 +2315,7 @@ pub const Object = struct { ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&fields), + isByRef(ty, pt), ); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_error_union_type); @@ -2542,6 +2545,7 @@ pub const Object = struct { 0, // Size 0, // Align .none, // Fields + false, // ByRef ); break :res debug_opaque_type; }, @@ -2601,6 +2605,7 @@ pub const Object = struct { ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(fields.items), + isByRef(ty, pt), ); break :res debug_struct_type; @@ -2656,6 +2661,7 @@ pub const Object = struct { ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(fields.items), + isByRef(ty, pt), ); break :res debug_struct_type; @@ -2683,6 +2689,7 @@ pub const Object = struct { try o.builder.debugTuple( &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty), required_by_runtime)}, ), + isByRef(ty, pt), ); break :res debug_union_type; @@ -2736,6 +2743,7 @@ pub const Object = struct { ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(fields.items), + isByRef(ty, pt), ); if (layout.tag_size == 0) { @@ -2791,6 +2799,7 @@ pub const Object = struct { ty.abiSize(pt) * 8, (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&full_fields), + isByRef(ty, pt), ); break :res debug_tagged_union_type; @@ -2824,6 +2833,7 @@ pub const Object = struct { 0, 0, if (fields.len == 0) .none else try o.builder.debugTuple(fields), + false, // is_byref ); } diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index ce001ca45b..7fc0fbdfc0 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -7911,6 +7911,10 @@ pub const Metadata = enum(u32) { align_in_bits_lo: u32, align_in_bits_hi: u32, fields_tuple: Metadata, + flags: packed struct(u32) { + is_byref: bool, + pad: u31 = 0, + }, pub fn bitSize(self: CompositeType) u64 { return @as(u64, self.size_in_bits_hi) << 32 | self.size_in_bits_lo; @@ -11638,7 +11642,17 @@ fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item. u32 => value, MetadataString, Metadata, Variable.Index, Value => @intFromEnum(value), Metadata.DIFlags => @bitCast(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => blk: { + switch (@typeInfo(field.type)) { + .Struct => |s| { + if (s.backing_integer == u32) + break :blk @bitCast(value); + @compileLog(s.layout, s.backing_integer); + }, + else => {}, + } + @compileError("bad field type: " ++ @typeName(field.type)); + }, }); } return result; @@ -11677,7 +11691,7 @@ fn metadataExtraDataTrail( u32 => value, MetadataString, Metadata, Variable.Index, Value => @enumFromInt(value), Metadata.DIFlags => @bitCast(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @bitCast(value), }; return .{ .data = result, @@ -11844,6 +11858,7 @@ pub fn debugStructType( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, + is_byref: bool, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugStructTypeAssumeCapacity( @@ -11855,6 +11870,7 @@ pub fn debugStructType( size_in_bits, align_in_bits, fields_tuple, + is_byref, ); } @@ -11868,6 +11884,7 @@ pub fn debugUnionType( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, + is_byref: bool, ) Allocator.Error!Metadata { try self.ensureUnusedMetadataCapacity(1, Metadata.CompositeType, 0); return self.debugUnionTypeAssumeCapacity( @@ -11879,6 +11896,7 @@ pub fn debugUnionType( size_in_bits, align_in_bits, fields_tuple, + is_byref, ); } @@ -12400,6 +12418,7 @@ fn debugStructTypeAssumeCapacity( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, + is_byref: bool, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12412,6 +12431,7 @@ fn debugStructTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, + is_byref, ); } @@ -12425,6 +12445,7 @@ fn debugUnionTypeAssumeCapacity( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, + is_byref: bool, ) Metadata { assert(!self.strip); return self.debugCompositeTypeAssumeCapacity( @@ -12437,6 +12458,7 @@ fn debugUnionTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, + is_byref, ); } @@ -12462,6 +12484,7 @@ fn debugEnumerationTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, + false, // is_byref ); } @@ -12487,6 +12510,7 @@ fn debugArrayTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, + size_in_bits > 0, // is_byref ); } @@ -12512,6 +12536,7 @@ fn debugVectorTypeAssumeCapacity( size_in_bits, align_in_bits, fields_tuple, + false, ); } @@ -12526,6 +12551,7 @@ fn debugCompositeTypeAssumeCapacity( size_in_bits: u64, align_in_bits: u64, fields_tuple: Metadata, + is_byref: bool, ) Metadata { assert(!self.strip); return self.metadataSimpleAssumeCapacity(tag, Metadata.CompositeType{ @@ -12539,6 +12565,7 @@ fn debugCompositeTypeAssumeCapacity( .align_in_bits_lo = @truncate(align_in_bits), .align_in_bits_hi = @truncate(align_in_bits >> 32), .fields_tuple = fields_tuple, + .flags = .{ .is_byref = is_byref }, }); } @@ -13973,7 +14000,11 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .underlying_type = extra.underlying_type, .size_in_bits = extra.bitSize(), .align_in_bits = extra.bitAlign(), - .flags = if (kind == .composite_vector_type) .{ .Vector = true } else .{}, + .flags = .{ + .Vector = kind == .composite_vector_type, + .EnumClass = kind == .composite_enumeration_type, + .TypePassbyReference = extra.flags.is_byref, + }, .elements = extra.fields_tuple, }, metadata_adapter); }, -- cgit v1.2.3