| author | |
| committer | |
| log | ada83fa55773c8f8ff1bc2643c6525c3dfe871bf |
| tree | de2c912fbe4f95d331b69b9c184e998b2d85ed08 |
| parent | 0182b7242e216ea6eabf465e32b7da60ad32ee2d |
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 | } |
| 529 | 529 | ||
| 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 | }; |
| 613 | 618 | ||
| 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); | ||
| 34296 | 34297 | ||
| 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); |
| 34836 | 34841 | ||
| 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; |
| 4047 | 4050 | ||
| 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 | } |
| 353 | 353 | ||
| 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.member | 361 | // 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.string | 364 | 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.ref4 | 367 | } |
| 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.udata | 371 | 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, |