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) {...@@ -527,6 +527,11 @@ pub const Key = union(enum) {
527 return false;527 return false;
528 }528 }
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
530 pub fn setFullyResolved(s: @This(), ip: *InternPool) bool {535 pub fn setFullyResolved(s: @This(), ip: *InternPool) bool {
531 if (s.layout == .Packed) return true;536 if (s.layout == .Packed) return true;
532 const flags_ptr = s.flagsPtr(ip);537 const flags_ptr = s.flagsPtr(ip);
...@@ -612,6 +617,7 @@ pub const Key = union(enum) {...@@ -612,6 +617,7 @@ pub const Key = union(enum) {
612 };617 };
613618
614 /// Iterates over non-comptime fields in the order they are laid out in memory at runtime.619 /// 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.
615 /// Asserts the struct is not packed.621 /// Asserts the struct is not packed.
616 pub fn iterateRuntimeOrder(s: @This(), ip: *InternPool) RuntimeOrderIterator {622 pub fn iterateRuntimeOrder(s: @This(), ip: *InternPool) RuntimeOrderIterator {
617 assert(s.layout != .Packed);623 assert(s.layout != .Packed);
src/Sema.zig+6-1
...@@ -34293,6 +34293,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34293,6 +34293,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34293 );34293 );
34294 return sema.failWithOwnedErrorMsg(null, msg);34294 return sema.failWithOwnedErrorMsg(null, msg);
34295 }34295 }
34296 defer struct_type.clearLayoutWip(ip);
3429634297
34297 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);34298 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);
34298 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);34299 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);
...@@ -34300,6 +34301,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34300,6 +34301,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34300 for (aligns, sizes, 0..) |*field_align, *field_size, i| {34301 for (aligns, sizes, 0..) |*field_align, *field_size, i| {
34301 const field_ty = struct_type.field_types.get(ip)[i].toType();34302 const field_ty = struct_type.field_types.get(ip)[i].toType();
34302 if (struct_type.fieldIsComptime(ip, i) or !(try sema.typeHasRuntimeBits(field_ty))) {34303 if (struct_type.fieldIsComptime(ip, i) or !(try sema.typeHasRuntimeBits(field_ty))) {
34304 struct_type.offsets.get(ip)[i] = 0;
34303 field_size.* = 0;34305 field_size.* = 0;
34304 field_align.* = .none;34306 field_align.* = .none;
34305 continue;34307 continue;
...@@ -34379,6 +34381,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -34379,6 +34381,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34379 var offset: u64 = 0;34381 var offset: u64 = 0;
34380 var big_align: Alignment = .@"1";34382 var big_align: Alignment = .@"1";
34381 while (it.next()) |i| {34383 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;
34382 big_align = big_align.max(aligns[i]);34387 big_align = big_align.max(aligns[i]);
34383 offsets[i] = @intCast(aligns[i].forward(offset));34388 offsets[i] = @intCast(aligns[i].forward(offset));
34384 offset = offsets[i] + sizes[i];34389 offset = offsets[i] + sizes[i];
...@@ -34832,7 +34837,7 @@ fn resolveTypeFieldsStruct(...@@ -34832,7 +34837,7 @@ fn resolveTypeFieldsStruct(
34832 );34837 );
34833 return sema.failWithOwnedErrorMsg(null, msg);34838 return sema.failWithOwnedErrorMsg(null, msg);
34834 }34839 }
34835 errdefer struct_type.clearTypesWip(ip);34840 defer struct_type.clearTypesWip(ip);
3483634841
34837 try semaStructFields(mod, sema.arena, struct_type);34842 try semaStructFields(mod, sema.arena, struct_type);
34838}34843}
src/codegen/llvm.zig+6-3
...@@ -2504,6 +2504,7 @@ pub const Object = struct {...@@ -2504,6 +2504,7 @@ pub const Object = struct {
2504 var it = struct_type.iterateRuntimeOrder(ip);2504 var it = struct_type.iterateRuntimeOrder(ip);
2505 while (it.next()) |field_index| {2505 while (it.next()) |field_index| {
2506 const field_ty = field_types[field_index].toType();2506 const field_ty = field_types[field_index].toType();
2507 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
2507 const field_size = field_ty.abiSize(mod);2508 const field_size = field_ty.abiSize(mod);
2508 const field_align = mod.structFieldAlignment(2509 const field_align = mod.structFieldAlignment(
2509 struct_type.fieldAlign(ip, field_index),2510 struct_type.fieldAlign(ip, field_index),
...@@ -3306,6 +3307,7 @@ pub const Object = struct {...@@ -3306,6 +3307,7 @@ pub const Object = struct {
3306 var it = struct_type.iterateRuntimeOrder(ip);3307 var it = struct_type.iterateRuntimeOrder(ip);
3307 while (it.next()) |field_index| {3308 while (it.next()) |field_index| {
3308 const field_ty = struct_type.field_types.get(ip)[field_index].toType();3309 const field_ty = struct_type.field_types.get(ip)[field_index].toType();
3310 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
3309 const field_align = mod.structFieldAlignment(3311 const field_align = mod.structFieldAlignment(
3310 struct_type.fieldAlign(ip, field_index),3312 struct_type.fieldAlign(ip, field_index),
3311 field_ty,3313 field_ty,
...@@ -4016,10 +4018,11 @@ pub const Object = struct {...@@ -4016,10 +4018,11 @@ pub const Object = struct {
4016 var need_unnamed = false;4018 var need_unnamed = false;
4017 var field_it = struct_type.iterateRuntimeOrder(ip);4019 var field_it = struct_type.iterateRuntimeOrder(ip);
4018 while (field_it.next()) |field_index| {4020 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;
4020 const field_align = mod.structFieldAlignment(4023 const field_align = mod.structFieldAlignment(
4021 struct_type.fieldAlign(ip, field_index),4024 struct_type.fieldAlign(ip, field_index),
4022 field_ty.toType(),4025 field_ty,
4023 struct_type.layout,4026 struct_type.layout,
4024 );4027 );
4025 big_align = big_align.max(field_align);4028 big_align = big_align.max(field_align);
...@@ -4045,7 +4048,7 @@ pub const Object = struct {...@@ -4045,7 +4048,7 @@ pub const Object = struct {
4045 need_unnamed = true;4048 need_unnamed = true;
4046 llvm_index += 1;4049 llvm_index += 1;
40474050
4048 offset += field_ty.toType().abiSize(mod);4051 offset += field_ty.abiSize(mod);
4049 }4052 }
4050 {4053 {
4051 const prev_offset = offset;4054 const prev_offset = offset;
src/link/Dwarf.zig+35-19
...@@ -351,25 +351,41 @@ pub const DeclState = struct {...@@ -351,25 +351,41 @@ pub const DeclState = struct {
351 break :blk;351 break :blk;
352 }352 }
353353
354 for (354 if (struct_type.isTuple(ip)) {
355 struct_type.field_names.get(ip),355 for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {
356 struct_type.field_types.get(ip),356 if (!field_ty.toType().hasRuntimeBits(mod)) continue;
357 struct_type.offsets.get(ip),357 // DW.AT.member
358 ) |field_name_ip, field_ty, field_off| {358 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
359 if (!field_ty.toType().hasRuntimeBits(mod)) continue;359 // DW.AT.name, DW.FORM.string
360 const field_name = ip.stringToSlice(field_name_ip);360 try dbg_info_buffer.writer().print("{d}\x00", .{field_index});
361 // DW.AT.member361 // DW.AT.type, DW.FORM.ref4
362 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);362 var index = dbg_info_buffer.items.len;
363 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));363 try dbg_info_buffer.resize(index + 4);
364 // DW.AT.name, DW.FORM.string364 try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index)));
365 dbg_info_buffer.appendSliceAssumeCapacity(field_name);365 // DW.AT.data_member_location, DW.FORM.udata
366 dbg_info_buffer.appendAssumeCapacity(0);366 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
367 // DW.AT.type, DW.FORM.ref4367 }
368 var index = dbg_info_buffer.items.len;368 } else {
369 try dbg_info_buffer.resize(index + 4);369 for (
370 try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));370 struct_type.field_names.get(ip),
371 // DW.AT.data_member_location, DW.FORM.udata371 struct_type.field_types.get(ip),
372 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);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 }
373 }389 }
374 },390 },
375 else => unreachable,391 else => unreachable,