| ... | @@ -4568,9 +4568,18 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc | ... | @@ -4568,9 +4568,18 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc |
| 4568 | else => .none, | 4568 | else => .none, |
| 4569 | }; | 4569 | }; |
| 4570 | | 4570 | |
| 4571 | const field_name: CValue = switch (struct_ty.tag()) { | 4571 | const FieldLoc = union(enum) { |
| | 4572 | begin: void, |
| | 4573 | field: CValue, |
| | 4574 | end: void, |
| | 4575 | }; |
| | 4576 | const field_loc = switch (struct_ty.tag()) { |
| 4572 | .@"struct" => switch (struct_ty.containerLayout()) { | 4577 | .@"struct" => switch (struct_ty.containerLayout()) { |
| 4573 | .Auto, .Extern => CValue{ .identifier = struct_ty.structFieldName(index) }, | 4578 | .Auto, .Extern => for (struct_ty.structFields().values()[index..]) |field, offset| { |
| | 4579 | if (field.ty.hasRuntimeBitsIgnoreComptime()) break FieldLoc{ .field = .{ |
| | 4580 | .identifier = struct_ty.structFieldName(index + offset), |
| | 4581 | } }; |
| | 4582 | } else @as(FieldLoc, .end), |
| 4574 | .Packed => if (field_ptr_info.data.host_size == 0) { | 4583 | .Packed => if (field_ptr_info.data.host_size == 0) { |
| 4575 | const target = f.object.dg.module.getTarget(); | 4584 | const target = f.object.dg.module.getTarget(); |
| 4576 | | 4585 | |
| ... | @@ -4595,40 +4604,43 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc | ... | @@ -4595,40 +4604,43 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc |
| 4595 | try f.writeCValue(writer, struct_ptr, .Other); | 4604 | try f.writeCValue(writer, struct_ptr, .Other); |
| 4596 | try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); | 4605 | try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); |
| 4597 | return local; | 4606 | return local; |
| 4598 | } else @as(CValue, CValue.none), // this @as is needed because of a stage1 bug | 4607 | } else @as(FieldLoc, .begin), |
| 4599 | }, | 4608 | }, |
| 4600 | .@"union", .union_safety_tagged, .union_tagged => if (struct_ty.containerLayout() == .Packed) { | 4609 | .@"union", .union_safety_tagged, .union_tagged => if (struct_ty.containerLayout() == .Packed) { |
| 4601 | try f.writeCValue(writer, struct_ptr, .Other); | 4610 | try f.writeCValue(writer, struct_ptr, .Other); |
| 4602 | try writer.writeAll(";\n"); | 4611 | try writer.writeAll(";\n"); |
| 4603 | return local; | 4612 | return local; |
| 4604 | } else .{ | 4613 | } else if (field_ty.hasRuntimeBitsIgnoreComptime()) FieldLoc{ .field = .{ |
| 4605 | .identifier = struct_ty.unionFields().keys()[index], | 4614 | .identifier = struct_ty.unionFields().keys()[index], |
| 4606 | }, | 4615 | } } else @as(FieldLoc, .end), |
| 4607 | .tuple, .anon_struct => field_name: { | 4616 | .tuple, .anon_struct => field_name: { |
| 4608 | const tuple = struct_ty.tupleFields(); | 4617 | const tuple = struct_ty.tupleFields(); |
| 4609 | if (tuple.values[index].tag() != .unreachable_value) return CValue.none; | 4618 | if (tuple.values[index].tag() != .unreachable_value) return CValue.none; |
| 4610 | | 4619 | |
| 4611 | var id: usize = 0; | 4620 | var id: usize = 0; |
| 4612 | for (tuple.values[0..index]) |value| | 4621 | break :field_name for (tuple.values) |value, i| { |
| 4613 | id += @boolToInt(value.tag() == .unreachable_value); | 4622 | if (value.tag() != .unreachable_value) continue; |
| 4614 | break :field_name .{ .field = id }; | 4623 | if (!tuple.types[i].hasRuntimeBitsIgnoreComptime()) continue; |
| | 4624 | if (i >= index) break FieldLoc{ .field = .{ .field = id } }; |
| | 4625 | id += 1; |
| | 4626 | } else @as(FieldLoc, .end); |
| 4615 | }, | 4627 | }, |
| 4616 | else => unreachable, | 4628 | else => unreachable, |
| 4617 | }; | 4629 | }; |
| 4618 | | 4630 | |
| 4619 | if (field_ty.hasRuntimeBitsIgnoreComptime()) { | 4631 | try writer.writeByte('&'); |
| 4620 | try writer.writeByte('&'); | 4632 | switch (field_loc) { |
| 4621 | if (extra_name != .none) { | 4633 | .begin, .end => { |
| | 4634 | try writer.writeByte('('); |
| | 4635 | try f.writeCValue(writer, struct_ptr, .Other); |
| | 4636 | try writer.print(")[{}]", .{@boolToInt(field_loc == .end)}); |
| | 4637 | }, |
| | 4638 | .field => |field| if (extra_name != .none) { |
| 4622 | try f.writeCValueDerefMember(writer, struct_ptr, extra_name); | 4639 | try f.writeCValueDerefMember(writer, struct_ptr, extra_name); |
| 4623 | if (field_name != .none) { | 4640 | try writer.writeByte('.'); |
| 4624 | try writer.writeByte('.'); | 4641 | try f.writeCValue(writer, field, .Other); |
| 4625 | try f.writeCValue(writer, field_name, .Other); | 4642 | } else try f.writeCValueDerefMember(writer, struct_ptr, field), |
| 4626 | } | 4643 | } |
| 4627 | } else if (field_name != .none) | | |
| 4628 | try f.writeCValueDerefMember(writer, struct_ptr, field_name) | | |
| 4629 | else | | |
| 4630 | try f.writeCValueDeref(writer, struct_ptr); | | |
| 4631 | } else try f.writeCValue(writer, struct_ptr, .Other); | | |
| 4632 | try writer.writeAll(";\n"); | 4644 | try writer.writeAll(";\n"); |
| 4633 | return local; | 4645 | return local; |
| 4634 | } | 4646 | } |