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.
This commit is contained in:
Tau 2024-06-29 16:19:55 +02:00
parent 177b3359a1
commit 94cf4d2d81
2 changed files with 44 additions and 3 deletions

View File

@ -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
);
}

View File

@ -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);
},