compiler: get codegen of behavior tests working on at least one backend

We're hitting false compile errors, but this is progress!
This commit is contained in:
mlugg 2023-09-20 21:19:29 +01:00 committed by Andrew Kelley
parent 0182b7242e
commit ada83fa557
4 changed files with 53 additions and 23 deletions

View File

@ -527,6 +527,11 @@ pub const Key = union(enum) {
return false;
}
pub fn clearLayoutWip(s: @This(), ip: *InternPool) void {
if (s.layout == .Packed) return;
s.flagsPtr(ip).layout_wip = false;
}
pub fn setFullyResolved(s: @This(), ip: *InternPool) bool {
if (s.layout == .Packed) return true;
const flags_ptr = s.flagsPtr(ip);
@ -612,6 +617,7 @@ pub const Key = union(enum) {
};
/// Iterates over non-comptime fields in the order they are laid out in memory at runtime.
/// May or may not include zero-bit fields.
/// Asserts the struct is not packed.
pub fn iterateRuntimeOrder(s: @This(), ip: *InternPool) RuntimeOrderIterator {
assert(s.layout != .Packed);

View File

@ -34293,6 +34293,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
);
return sema.failWithOwnedErrorMsg(null, msg);
}
defer struct_type.clearLayoutWip(ip);
const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);
const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);
@ -34300,6 +34301,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
for (aligns, sizes, 0..) |*field_align, *field_size, i| {
const field_ty = struct_type.field_types.get(ip)[i].toType();
if (struct_type.fieldIsComptime(ip, i) or !(try sema.typeHasRuntimeBits(field_ty))) {
struct_type.offsets.get(ip)[i] = 0;
field_size.* = 0;
field_align.* = .none;
continue;
@ -34379,6 +34381,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
var offset: u64 = 0;
var big_align: Alignment = .@"1";
while (it.next()) |i| {
const field_ty = struct_type.field_types.get(ip)[i].toType();
// Type query definitely valid as we performed it earlier
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
big_align = big_align.max(aligns[i]);
offsets[i] = @intCast(aligns[i].forward(offset));
offset = offsets[i] + sizes[i];
@ -34832,7 +34837,7 @@ fn resolveTypeFieldsStruct(
);
return sema.failWithOwnedErrorMsg(null, msg);
}
errdefer struct_type.clearTypesWip(ip);
defer struct_type.clearTypesWip(ip);
try semaStructFields(mod, sema.arena, struct_type);
}

View File

@ -2504,6 +2504,7 @@ pub const Object = struct {
var it = struct_type.iterateRuntimeOrder(ip);
while (it.next()) |field_index| {
const field_ty = field_types[field_index].toType();
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_size = field_ty.abiSize(mod);
const field_align = mod.structFieldAlignment(
struct_type.fieldAlign(ip, field_index),
@ -3306,6 +3307,7 @@ pub const Object = struct {
var it = struct_type.iterateRuntimeOrder(ip);
while (it.next()) |field_index| {
const field_ty = struct_type.field_types.get(ip)[field_index].toType();
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_align = mod.structFieldAlignment(
struct_type.fieldAlign(ip, field_index),
field_ty,
@ -4016,10 +4018,11 @@ pub const Object = struct {
var need_unnamed = false;
var field_it = struct_type.iterateRuntimeOrder(ip);
while (field_it.next()) |field_index| {
const field_ty = struct_type.field_types.get(ip)[field_index];
const field_ty = struct_type.field_types.get(ip)[field_index].toType();
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_align = mod.structFieldAlignment(
struct_type.fieldAlign(ip, field_index),
field_ty.toType(),
field_ty,
struct_type.layout,
);
big_align = big_align.max(field_align);
@ -4045,7 +4048,7 @@ pub const Object = struct {
need_unnamed = true;
llvm_index += 1;
offset += field_ty.toType().abiSize(mod);
offset += field_ty.abiSize(mod);
}
{
const prev_offset = offset;

View File

@ -351,25 +351,41 @@ pub const DeclState = struct {
break :blk;
}
for (
struct_type.field_names.get(ip),
struct_type.field_types.get(ip),
struct_type.offsets.get(ip),
) |field_name_ip, field_ty, field_off| {
if (!field_ty.toType().hasRuntimeBits(mod)) continue;
const field_name = ip.stringToSlice(field_name_ip);
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity(field_name);
dbg_info_buffer.appendAssumeCapacity(0);
// DW.AT.type, DW.FORM.ref4
var index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));
// DW.AT.data_member_location, DW.FORM.udata
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
if (struct_type.isTuple(ip)) {
for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {
if (!field_ty.toType().hasRuntimeBits(mod)) continue;
// DW.AT.member
try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
try dbg_info_buffer.writer().print("{d}\x00", .{field_index});
// DW.AT.type, DW.FORM.ref4
var index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index)));
// DW.AT.data_member_location, DW.FORM.udata
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
}
} else {
for (
struct_type.field_names.get(ip),
struct_type.field_types.get(ip),
struct_type.offsets.get(ip),
) |field_name_ip, field_ty, field_off| {
if (!field_ty.toType().hasRuntimeBits(mod)) continue;
const field_name = ip.stringToSlice(field_name_ip);
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity(field_name);
dbg_info_buffer.appendAssumeCapacity(0);
// DW.AT.type, DW.FORM.ref4
var index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));
// DW.AT.data_member_location, DW.FORM.udata
try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
}
}
},
else => unreachable,