authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-09-20 21:19:29+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-21 14:48:40-07:00
logada83fa55773c8f8ff1bc2643c6525c3dfe871bf
treede2c912fbe4f95d331b69b9c184e998b2d85ed08
parent0182b7242e216ea6eabf465e32b7da60ad32ee2d

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

We're hitting false compile errors, but this is progress!

4 files changed, 53 insertions(+), 23 deletions(-)

src/InternPool.zig+6
......@@ -527,6 +527,11 @@ pub const Key = union(enum) {
527527 return false;
528528 }
529529
530 pub fn clearLayoutWip(s: @This(), ip: *InternPool) void {
531 if (s.layout == .Packed) return;
532 s.flagsPtr(ip).layout_wip = false;
533 }
534
530535 pub fn setFullyResolved(s: @This(), ip: *InternPool) bool {
531536 if (s.layout == .Packed) return true;
532537 const flags_ptr = s.flagsPtr(ip);
......@@ -612,6 +617,7 @@ pub const Key = union(enum) {
612617 };
613618
614619 /// Iterates over non-comptime fields in the order they are laid out in memory at runtime.
620 /// May or may not include zero-bit fields.
615621 /// Asserts the struct is not packed.
616622 pub fn iterateRuntimeOrder(s: @This(), ip: *InternPool) RuntimeOrderIterator {
617623 assert(s.layout != .Packed);
src/Sema.zig+6-1
......@@ -34293,6 +34293,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3429334293 );
3429434294 return sema.failWithOwnedErrorMsg(null, msg);
3429534295 }
34296 defer struct_type.clearLayoutWip(ip);
3429634297
3429734298 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);
3429834299 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);
......@@ -34300,6 +34301,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3430034301 for (aligns, sizes, 0..) |*field_align, *field_size, i| {
3430134302 const field_ty = struct_type.field_types.get(ip)[i].toType();
3430234303 if (struct_type.fieldIsComptime(ip, i) or !(try sema.typeHasRuntimeBits(field_ty))) {
34304 struct_type.offsets.get(ip)[i] = 0;
3430334305 field_size.* = 0;
3430434306 field_align.* = .none;
3430534307 continue;
......@@ -34379,6 +34381,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3437934381 var offset: u64 = 0;
3438034382 var big_align: Alignment = .@"1";
3438134383 while (it.next()) |i| {
34384 const field_ty = struct_type.field_types.get(ip)[i].toType();
34385 // Type query definitely valid as we performed it earlier
34386 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
3438234387 big_align = big_align.max(aligns[i]);
3438334388 offsets[i] = @intCast(aligns[i].forward(offset));
3438434389 offset = offsets[i] + sizes[i];
......@@ -34832,7 +34837,7 @@ fn resolveTypeFieldsStruct(
3483234837 );
3483334838 return sema.failWithOwnedErrorMsg(null, msg);
3483434839 }
34835 errdefer struct_type.clearTypesWip(ip);
34840 defer struct_type.clearTypesWip(ip);
3483634841
3483734842 try semaStructFields(mod, sema.arena, struct_type);
3483834843}
src/codegen/llvm.zig+6-3
......@@ -2504,6 +2504,7 @@ pub const Object = struct {
25042504 var it = struct_type.iterateRuntimeOrder(ip);
25052505 while (it.next()) |field_index| {
25062506 const field_ty = field_types[field_index].toType();
2507 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
25072508 const field_size = field_ty.abiSize(mod);
25082509 const field_align = mod.structFieldAlignment(
25092510 struct_type.fieldAlign(ip, field_index),
......@@ -3306,6 +3307,7 @@ pub const Object = struct {
33063307 var it = struct_type.iterateRuntimeOrder(ip);
33073308 while (it.next()) |field_index| {
33083309 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
3310 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
33093311 const field_align = mod.structFieldAlignment(
33103312 struct_type.fieldAlign(ip, field_index),
33113313 field_ty,
......@@ -4016,10 +4018,11 @@ pub const Object = struct {
40164018 var need_unnamed = false;
40174019 var field_it = struct_type.iterateRuntimeOrder(ip);
40184020 while (field_it.next()) |field_index| {
4019 const field_ty = struct_type.field_types.get(ip)[field_index];
4021 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
4022 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
40204023 const field_align = mod.structFieldAlignment(
40214024 struct_type.fieldAlign(ip, field_index),
4022 field_ty.toType(),
4025 field_ty,
40234026 struct_type.layout,
40244027 );
40254028 big_align = big_align.max(field_align);
......@@ -4045,7 +4048,7 @@ pub const Object = struct {
40454048 need_unnamed = true;
40464049 llvm_index += 1;
40474050
4048 offset += field_ty.toType().abiSize(mod);
4051 offset += field_ty.abiSize(mod);
40494052 }
40504053 {
40514054 const prev_offset = offset;
src/link/Dwarf.zig+35-19
......@@ -351,25 +351,41 @@ pub const DeclState = struct {
351351 break :blk;
352352 }
353353
354 for (
355 struct_type.field_names.get(ip),
356 struct_type.field_types.get(ip),
357 struct_type.offsets.get(ip),
358 ) |field_name_ip, field_ty, field_off| {
359 if (!field_ty.toType().hasRuntimeBits(mod)) continue;
360 const field_name = ip.stringToSlice(field_name_ip);
361 // DW.AT.member
362 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
363 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));
364 // DW.AT.name, DW.FORM.string
365 dbg_info_buffer.appendSliceAssumeCapacity(field_name);
366 dbg_info_buffer.appendAssumeCapacity(0);
367 // DW.AT.type, DW.FORM.ref4
368 var index = dbg_info_buffer.items.len;
369 try dbg_info_buffer.resize(index + 4);
370 try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));
371 // DW.AT.data_member_location, DW.FORM.udata
372 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
354 if (struct_type.isTuple(ip)) {
355 for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {
356 if (!field_ty.toType().hasRuntimeBits(mod)) continue;
357 // DW.AT.member
358 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
359 // DW.AT.name, DW.FORM.string
360 try dbg_info_buffer.writer().print("{d}\x00", .{field_index});
361 // DW.AT.type, DW.FORM.ref4
362 var index = dbg_info_buffer.items.len;
363 try dbg_info_buffer.resize(index + 4);
364 try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index)));
365 // DW.AT.data_member_location, DW.FORM.udata
366 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
367 }
368 } else {
369 for (
370 struct_type.field_names.get(ip),
371 struct_type.field_types.get(ip),
372 struct_type.offsets.get(ip),
373 ) |field_name_ip, field_ty, field_off| {
374 if (!field_ty.toType().hasRuntimeBits(mod)) continue;
375 const field_name = ip.stringToSlice(field_name_ip);
376 // DW.AT.member
377 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
378 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));
379 // DW.AT.name, DW.FORM.string
380 dbg_info_buffer.appendSliceAssumeCapacity(field_name);
381 dbg_info_buffer.appendAssumeCapacity(0);
382 // DW.AT.type, DW.FORM.ref4
383 var index = dbg_info_buffer.items.len;
384 try dbg_info_buffer.resize(index + 4);
385 try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));
386 // DW.AT.data_member_location, DW.FORM.udata
387 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
388 }
373389 }
374390 },
375391 else => unreachable,