| ... | @@ -39,7 +39,7 @@ pub const CValue = union(enum) { | ... | @@ -39,7 +39,7 @@ pub const CValue = union(enum) { |
| 39 | constant: Air.Inst.Ref, | 39 | constant: Air.Inst.Ref, |
| 40 | /// Index into the parameters | 40 | /// Index into the parameters |
| 41 | arg: usize, | 41 | arg: usize, |
| 42 | /// The payload field of a parameter | 42 | /// The array field of a parameter |
| 43 | arg_array: usize, | 43 | arg_array: usize, |
| 44 | /// Index into a tuple's fields | 44 | /// Index into a tuple's fields |
| 45 | field: usize, | 45 | field: usize, |
| ... | @@ -50,6 +50,8 @@ pub const CValue = union(enum) { | ... | @@ -50,6 +50,8 @@ pub const CValue = union(enum) { |
| 50 | undef: Type, | 50 | undef: Type, |
| 51 | /// Render the slice as an identifier (using fmtIdent) | 51 | /// Render the slice as an identifier (using fmtIdent) |
| 52 | identifier: []const u8, | 52 | identifier: []const u8, |
| | 53 | /// Render the slice as an payload.identifier (using fmtIdent) |
| | 54 | payload_identifier: []const u8, |
| 53 | /// Render these bytes literally. | 55 | /// Render these bytes literally. |
| 54 | /// TODO make this a [*:0]const u8 to save memory | 56 | /// TODO make this a [*:0]const u8 to save memory |
| 55 | bytes: []const u8, | 57 | bytes: []const u8, |
| ... | @@ -416,12 +418,20 @@ pub const Function = struct { | ... | @@ -416,12 +418,20 @@ pub const Function = struct { |
| 416 | return f.object.dg.fail(format, args); | 418 | return f.object.dg.fail(format, args); |
| 417 | } | 419 | } |
| 418 | | 420 | |
| 419 | fn renderType(f: *Function, w: anytype, t: Type) !void { | 421 | fn indexToCType(f: *Function, idx: CType.Index) CType { |
| 420 | return f.object.dg.renderType(w, t, .Complete); | 422 | return f.object.dg.indexToCType(idx); |
| | 423 | } |
| | 424 | |
| | 425 | fn typeToIndex(f: *Function, ty: Type, kind: CType.Kind) !CType.Index { |
| | 426 | return f.object.dg.typeToIndex(ty, kind); |
| | 427 | } |
| | 428 | |
| | 429 | fn typeToCType(f: *Function, ty: Type, kind: CType.Kind) !CType { |
| | 430 | return f.object.dg.typeToCType(ty, kind); |
| 421 | } | 431 | } |
| 422 | | 432 | |
| 423 | fn renderTypecast(f: *Function, w: anytype, t: Type) !void { | 433 | fn renderType(f: *Function, w: anytype, t: Type) !void { |
| 424 | return f.object.dg.renderTypecast(w, t); | 434 | return f.object.dg.renderType(w, t); |
| 425 | } | 435 | } |
| 426 | | 436 | |
| 427 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, src_ty: Type, location: ValueRenderLocation) !void { | 437 | fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, src_ty: Type, location: ValueRenderLocation) !void { |
| ... | @@ -532,7 +542,7 @@ pub const DeclGen = struct { | ... | @@ -532,7 +542,7 @@ pub const DeclGen = struct { |
| 532 | try writer.writeByte('{'); | 542 | try writer.writeByte('{'); |
| 533 | } else { | 543 | } else { |
| 534 | try writer.writeByte('('); | 544 | try writer.writeByte('('); |
| 535 | try dg.renderTypecast(writer, ty); | 545 | try dg.renderType(writer, ty); |
| 536 | try writer.writeAll("){ .ptr = "); | 546 | try writer.writeAll("){ .ptr = "); |
| 537 | } | 547 | } |
| 538 | | 548 | |
| ... | @@ -559,7 +569,7 @@ pub const DeclGen = struct { | ... | @@ -559,7 +569,7 @@ pub const DeclGen = struct { |
| 559 | const need_typecast = if (ty.castPtrToFn()) |_| false else !ty.eql(decl.ty, dg.module); | 569 | const need_typecast = if (ty.castPtrToFn()) |_| false else !ty.eql(decl.ty, dg.module); |
| 560 | if (need_typecast) { | 570 | if (need_typecast) { |
| 561 | try writer.writeAll("(("); | 571 | try writer.writeAll("(("); |
| 562 | try dg.renderTypecast(writer, ty); | 572 | try dg.renderType(writer, ty); |
| 563 | try writer.writeByte(')'); | 573 | try writer.writeByte(')'); |
| 564 | } | 574 | } |
| 565 | try writer.writeByte('&'); | 575 | try writer.writeByte('&'); |
| ... | @@ -574,7 +584,7 @@ pub const DeclGen = struct { | ... | @@ -574,7 +584,7 @@ pub const DeclGen = struct { |
| 574 | fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void { | 584 | fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void { |
| 575 | if (!ptr_ty.isSlice()) { | 585 | if (!ptr_ty.isSlice()) { |
| 576 | try writer.writeByte('('); | 586 | try writer.writeByte('('); |
| 577 | try dg.renderTypecast(writer, ptr_ty); | 587 | try dg.renderType(writer, ptr_ty); |
| 578 | try writer.writeByte(')'); | 588 | try writer.writeByte(')'); |
| 579 | } | 589 | } |
| 580 | switch (ptr_val.tag()) { | 590 | switch (ptr_val.tag()) { |
| ... | @@ -589,90 +599,71 @@ pub const DeclGen = struct { | ... | @@ -589,90 +599,71 @@ pub const DeclGen = struct { |
| 589 | try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index, location); | 599 | try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index, location); |
| 590 | }, | 600 | }, |
| 591 | .field_ptr => { | 601 | .field_ptr => { |
| 592 | const ptr_info = ptr_ty.ptrInfo(); | 602 | const target = dg.module.getTarget(); |
| 593 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; | 603 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 594 | const container_ty = field_ptr.container_ty; | | |
| 595 | const index = field_ptr.field_index; | | |
| 596 | | | |
| 597 | var container_ptr_ty_pl: Type.Payload.ElemType = .{ | | |
| 598 | .base = .{ .tag = .c_mut_pointer }, | | |
| 599 | .data = field_ptr.container_ty, | | |
| 600 | }; | | |
| 601 | const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base); | | |
| 602 | | | |
| 603 | const FieldInfo = struct { name: []const u8, ty: Type }; | | |
| 604 | const field_info: FieldInfo = switch (container_ty.zigTypeTag()) { | | |
| 605 | .Struct => switch (container_ty.containerLayout()) { | | |
| 606 | .Auto, .Extern => FieldInfo{ | | |
| 607 | .name = container_ty.structFields().keys()[index], | | |
| 608 | .ty = container_ty.structFields().values()[index].ty, | | |
| 609 | }, | | |
| 610 | .Packed => if (ptr_info.data.host_size == 0) { | | |
| 611 | const target = dg.module.getTarget(); | | |
| 612 | | | |
| 613 | const byte_offset = container_ty.packedStructFieldByteOffset(index, target); | | |
| 614 | var byte_offset_pl = Value.Payload.U64{ | | |
| 615 | .base = .{ .tag = .int_u64 }, | | |
| 616 | .data = byte_offset, | | |
| 617 | }; | | |
| 618 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); | | |
| 619 | | | |
| 620 | var u8_ptr_pl = ptr_info; | | |
| 621 | u8_ptr_pl.data.pointee_type = Type.u8; | | |
| 622 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | | |
| 623 | | | |
| 624 | try writer.writeAll("&(("); | | |
| 625 | try dg.renderTypecast(writer, u8_ptr_ty); | | |
| 626 | try writer.writeByte(')'); | | |
| 627 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty, location); | | |
| 628 | return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)}); | | |
| 629 | } else { | | |
| 630 | var host_pl = Type.Payload.Bits{ | | |
| 631 | .base = .{ .tag = .int_unsigned }, | | |
| 632 | .data = ptr_info.data.host_size * 8, | | |
| 633 | }; | | |
| 634 | const host_ty = Type.initPayload(&host_pl.base); | | |
| 635 | | 604 | |
| 636 | try writer.writeByte('('); | 605 | // Ensure complete type definition is visible before accessing fields. |
| 637 | try dg.renderTypecast(writer, ptr_ty); | 606 | _ = try dg.typeToIndex(field_ptr.container_ty, .complete); |
| 638 | try writer.writeByte(')'); | 607 | |
| 639 | return dg.renderParentPtr(writer, field_ptr.container_ptr, host_ty, location); | 608 | var container_ptr_pl = ptr_ty.ptrInfo(); |
| 640 | }, | 609 | container_ptr_pl.data.pointee_type = field_ptr.container_ty; |
| 641 | }, | 610 | const container_ptr_ty = Type.initPayload(&container_ptr_pl.base); |
| 642 | .Union => switch (container_ty.containerLayout()) { | 611 | |
| 643 | .Auto, .Extern => FieldInfo{ | 612 | switch (fieldLocation( |
| 644 | .name = container_ty.unionFields().keys()[index], | 613 | field_ptr.container_ty, |
| 645 | .ty = container_ty.unionFields().values()[index].ty, | 614 | ptr_ty, |
| 646 | }, | 615 | @intCast(u32, field_ptr.field_index), |
| 647 | .Packed => { | 616 | target, |
| 648 | return dg.renderParentPtr(writer, field_ptr.container_ptr, ptr_ty, location); | 617 | )) { |
| 649 | }, | 618 | .begin => try dg.renderParentPtr( |
| | 619 | writer, |
| | 620 | field_ptr.container_ptr, |
| | 621 | container_ptr_ty, |
| | 622 | location, |
| | 623 | ), |
| | 624 | .field => |field| { |
| | 625 | try writer.writeAll("&("); |
| | 626 | try dg.renderParentPtr( |
| | 627 | writer, |
| | 628 | field_ptr.container_ptr, |
| | 629 | container_ptr_ty, |
| | 630 | location, |
| | 631 | ); |
| | 632 | try writer.writeAll(")->"); |
| | 633 | try dg.writeCValue(writer, field); |
| 650 | }, | 634 | }, |
| 651 | .Pointer => field_info: { | 635 | .byte_offset => |byte_offset| { |
| 652 | assert(container_ty.isSlice()); | 636 | var u8_ptr_pl = ptr_ty.ptrInfo(); |
| 653 | break :field_info switch (index) { | 637 | u8_ptr_pl.data.pointee_type = Type.u8; |
| 654 | 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() }, | 638 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); |
| 655 | 1 => FieldInfo{ .name = "len", .ty = Type.usize }, | 639 | |
| 656 | else => unreachable, | 640 | var byte_offset_pl = Value.Payload.U64{ |
| | 641 | .base = .{ .tag = .int_u64 }, |
| | 642 | .data = byte_offset, |
| 657 | }; | 643 | }; |
| 658 | }, | 644 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); |
| 659 | else => unreachable, | | |
| 660 | }; | | |
| 661 | | | |
| 662 | if (field_info.ty.hasRuntimeBitsIgnoreComptime()) { | | |
| 663 | // Ensure complete type definition is visible before accessing fields. | | |
| 664 | try dg.renderType(std.io.null_writer, field_ptr.container_ty, .Complete); | | |
| 665 | | 645 | |
| 666 | try writer.writeAll("&("); | 646 | try writer.writeAll("(("); |
| 667 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty, location); | 647 | try dg.renderType(writer, u8_ptr_ty); |
| 668 | try writer.writeAll(")->"); | 648 | try writer.writeByte(')'); |
| 669 | switch (field_ptr.container_ty.tag()) { | 649 | try dg.renderParentPtr( |
| 670 | .union_tagged, .union_safety_tagged => try writer.writeAll("payload."), | 650 | writer, |
| 671 | else => {}, | 651 | field_ptr.container_ptr, |
| 672 | } | 652 | container_ptr_ty, |
| 673 | try writer.print("{ }", .{fmtIdent(field_info.name)}); | 653 | location, |
| 674 | } else { | 654 | ); |
| 675 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty, location); | 655 | try writer.print(" + {})", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)}); |
| | 656 | }, |
| | 657 | .end => { |
| | 658 | try writer.writeAll("(("); |
| | 659 | try dg.renderParentPtr( |
| | 660 | writer, |
| | 661 | field_ptr.container_ptr, |
| | 662 | container_ptr_ty, |
| | 663 | location, |
| | 664 | ); |
| | 665 | try writer.print(") + {})", .{try dg.fmtIntLiteral(Type.usize, Value.one)}); |
| | 666 | }, |
| 676 | } | 667 | } |
| 677 | }, | 668 | }, |
| 678 | .elem_ptr => { | 669 | .elem_ptr => { |
| ... | @@ -696,7 +687,7 @@ pub const DeclGen = struct { | ... | @@ -696,7 +687,7 @@ pub const DeclGen = struct { |
| 696 | const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base); | 687 | const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base); |
| 697 | | 688 | |
| 698 | // Ensure complete type definition is visible before accessing fields. | 689 | // Ensure complete type definition is visible before accessing fields. |
| 699 | try dg.renderType(std.io.null_writer, payload_ptr.container_ty, .Complete); | 690 | _ = try dg.typeToIndex(payload_ptr.container_ty, .complete); |
| 700 | | 691 | |
| 701 | try writer.writeAll("&("); | 692 | try writer.writeAll("&("); |
| 702 | try dg.renderParentPtr(writer, payload_ptr.container_ptr, container_ptr_ty, location); | 693 | try dg.renderParentPtr(writer, payload_ptr.container_ptr, container_ptr_ty, location); |
| ... | @@ -763,18 +754,18 @@ pub const DeclGen = struct { | ... | @@ -763,18 +754,18 @@ pub const DeclGen = struct { |
| 763 | .Pointer => if (ty.isSlice()) { | 754 | .Pointer => if (ty.isSlice()) { |
| 764 | if (!location.isInitializer()) { | 755 | if (!location.isInitializer()) { |
| 765 | try writer.writeByte('('); | 756 | try writer.writeByte('('); |
| 766 | try dg.renderTypecast(writer, ty); | 757 | try dg.renderType(writer, ty); |
| 767 | try writer.writeByte(')'); | 758 | try writer.writeByte(')'); |
| 768 | } | 759 | } |
| 769 | | 760 | |
| 770 | try writer.writeAll("{("); | 761 | try writer.writeAll("{("); |
| 771 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 762 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 772 | const ptr_ty = ty.slicePtrFieldType(&buf); | 763 | const ptr_ty = ty.slicePtrFieldType(&buf); |
| 773 | try dg.renderTypecast(writer, ptr_ty); | 764 | try dg.renderType(writer, ptr_ty); |
| 774 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)}); | 765 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)}); |
| 775 | } else { | 766 | } else { |
| 776 | try writer.writeAll("(("); | 767 | try writer.writeAll("(("); |
| 777 | try dg.renderTypecast(writer, ty); | 768 | try dg.renderType(writer, ty); |
| 778 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); | 769 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); |
| 779 | }, | 770 | }, |
| 780 | .Optional => { | 771 | .Optional => { |
| ... | @@ -791,7 +782,7 @@ pub const DeclGen = struct { | ... | @@ -791,7 +782,7 @@ pub const DeclGen = struct { |
| 791 | | 782 | |
| 792 | if (!location.isInitializer()) { | 783 | if (!location.isInitializer()) { |
| 793 | try writer.writeByte('('); | 784 | try writer.writeByte('('); |
| 794 | try dg.renderTypecast(writer, ty); | 785 | try dg.renderType(writer, ty); |
| 795 | try writer.writeByte(')'); | 786 | try writer.writeByte(')'); |
| 796 | } | 787 | } |
| 797 | | 788 | |
| ... | @@ -805,7 +796,7 @@ pub const DeclGen = struct { | ... | @@ -805,7 +796,7 @@ pub const DeclGen = struct { |
| 805 | .Auto, .Extern => { | 796 | .Auto, .Extern => { |
| 806 | if (!location.isInitializer()) { | 797 | if (!location.isInitializer()) { |
| 807 | try writer.writeByte('('); | 798 | try writer.writeByte('('); |
| 808 | try dg.renderTypecast(writer, ty); | 799 | try dg.renderType(writer, ty); |
| 809 | try writer.writeByte(')'); | 800 | try writer.writeByte(')'); |
| 810 | } | 801 | } |
| 811 | | 802 | |
| ... | @@ -827,7 +818,7 @@ pub const DeclGen = struct { | ... | @@ -827,7 +818,7 @@ pub const DeclGen = struct { |
| 827 | .Union => { | 818 | .Union => { |
| 828 | if (!location.isInitializer()) { | 819 | if (!location.isInitializer()) { |
| 829 | try writer.writeByte('('); | 820 | try writer.writeByte('('); |
| 830 | try dg.renderTypecast(writer, ty); | 821 | try dg.renderType(writer, ty); |
| 831 | try writer.writeByte(')'); | 822 | try writer.writeByte(')'); |
| 832 | } | 823 | } |
| 833 | | 824 | |
| ... | @@ -852,7 +843,7 @@ pub const DeclGen = struct { | ... | @@ -852,7 +843,7 @@ pub const DeclGen = struct { |
| 852 | .ErrorUnion => { | 843 | .ErrorUnion => { |
| 853 | if (!location.isInitializer()) { | 844 | if (!location.isInitializer()) { |
| 854 | try writer.writeByte('('); | 845 | try writer.writeByte('('); |
| 855 | try dg.renderTypecast(writer, ty); | 846 | try dg.renderType(writer, ty); |
| 856 | try writer.writeByte(')'); | 847 | try writer.writeByte(')'); |
| 857 | } | 848 | } |
| 858 | | 849 | |
| ... | @@ -865,7 +856,7 @@ pub const DeclGen = struct { | ... | @@ -865,7 +856,7 @@ pub const DeclGen = struct { |
| 865 | .Array, .Vector => { | 856 | .Array, .Vector => { |
| 866 | if (!location.isInitializer()) { | 857 | if (!location.isInitializer()) { |
| 867 | try writer.writeByte('('); | 858 | try writer.writeByte('('); |
| 868 | try dg.renderTypecast(writer, ty); | 859 | try dg.renderType(writer, ty); |
| 869 | try writer.writeByte(')'); | 860 | try writer.writeByte(')'); |
| 870 | } | 861 | } |
| 871 | | 862 | |
| ... | @@ -1026,7 +1017,7 @@ pub const DeclGen = struct { | ... | @@ -1026,7 +1017,7 @@ pub const DeclGen = struct { |
| 1026 | return dg.renderValue(writer, ty, slice_val, location); | 1017 | return dg.renderValue(writer, ty, slice_val, location); |
| 1027 | } else { | 1018 | } else { |
| 1028 | try writer.writeAll("(("); | 1019 | try writer.writeAll("(("); |
| 1029 | try dg.renderTypecast(writer, ty); | 1020 | try dg.renderType(writer, ty); |
| 1030 | try writer.writeAll(")NULL)"); | 1021 | try writer.writeAll(")NULL)"); |
| 1031 | }, | 1022 | }, |
| 1032 | .variable => { | 1023 | .variable => { |
| ... | @@ -1036,7 +1027,7 @@ pub const DeclGen = struct { | ... | @@ -1036,7 +1027,7 @@ pub const DeclGen = struct { |
| 1036 | .slice => { | 1027 | .slice => { |
| 1037 | if (!location.isInitializer()) { | 1028 | if (!location.isInitializer()) { |
| 1038 | try writer.writeByte('('); | 1029 | try writer.writeByte('('); |
| 1039 | try dg.renderTypecast(writer, ty); | 1030 | try dg.renderType(writer, ty); |
| 1040 | try writer.writeByte(')'); | 1031 | try writer.writeByte(')'); |
| 1041 | } | 1032 | } |
| 1042 | | 1033 | |
| ... | @@ -1059,7 +1050,7 @@ pub const DeclGen = struct { | ... | @@ -1059,7 +1050,7 @@ pub const DeclGen = struct { |
| 1059 | }, | 1050 | }, |
| 1060 | .int_u64, .one => { | 1051 | .int_u64, .one => { |
| 1061 | try writer.writeAll("(("); | 1052 | try writer.writeAll("(("); |
| 1062 | try dg.renderTypecast(writer, ty); | 1053 | try dg.renderType(writer, ty); |
| 1063 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); | 1054 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); |
| 1064 | }, | 1055 | }, |
| 1065 | .field_ptr, | 1056 | .field_ptr, |
| ... | @@ -1074,7 +1065,7 @@ pub const DeclGen = struct { | ... | @@ -1074,7 +1065,7 @@ pub const DeclGen = struct { |
| 1074 | .Array, .Vector => { | 1065 | .Array, .Vector => { |
| 1075 | if (location == .FunctionArgument) { | 1066 | if (location == .FunctionArgument) { |
| 1076 | try writer.writeByte('('); | 1067 | try writer.writeByte('('); |
| 1077 | try dg.renderTypecast(writer, ty); | 1068 | try dg.renderType(writer, ty); |
| 1078 | try writer.writeByte(')'); | 1069 | try writer.writeByte(')'); |
| 1079 | } | 1070 | } |
| 1080 | | 1071 | |
| ... | @@ -1177,7 +1168,7 @@ pub const DeclGen = struct { | ... | @@ -1177,7 +1168,7 @@ pub const DeclGen = struct { |
| 1177 | | 1168 | |
| 1178 | if (!location.isInitializer()) { | 1169 | if (!location.isInitializer()) { |
| 1179 | try writer.writeByte('('); | 1170 | try writer.writeByte('('); |
| 1180 | try dg.renderTypecast(writer, ty); | 1171 | try dg.renderType(writer, ty); |
| 1181 | try writer.writeByte(')'); | 1172 | try writer.writeByte(')'); |
| 1182 | } | 1173 | } |
| 1183 | | 1174 | |
| ... | @@ -1211,7 +1202,7 @@ pub const DeclGen = struct { | ... | @@ -1211,7 +1202,7 @@ pub const DeclGen = struct { |
| 1211 | | 1202 | |
| 1212 | if (!location.isInitializer()) { | 1203 | if (!location.isInitializer()) { |
| 1213 | try writer.writeByte('('); | 1204 | try writer.writeByte('('); |
| 1214 | try dg.renderTypecast(writer, ty); | 1205 | try dg.renderType(writer, ty); |
| 1215 | try writer.writeByte(')'); | 1206 | try writer.writeByte(')'); |
| 1216 | } | 1207 | } |
| 1217 | | 1208 | |
| ... | @@ -1275,7 +1266,7 @@ pub const DeclGen = struct { | ... | @@ -1275,7 +1266,7 @@ pub const DeclGen = struct { |
| 1275 | | 1266 | |
| 1276 | if (!location.isInitializer()) { | 1267 | if (!location.isInitializer()) { |
| 1277 | try writer.writeByte('('); | 1268 | try writer.writeByte('('); |
| 1278 | try dg.renderTypecast(writer, ty); | 1269 | try dg.renderType(writer, ty); |
| 1279 | try writer.writeByte(')'); | 1270 | try writer.writeByte(')'); |
| 1280 | } | 1271 | } |
| 1281 | | 1272 | |
| ... | @@ -1362,7 +1353,7 @@ pub const DeclGen = struct { | ... | @@ -1362,7 +1353,7 @@ pub const DeclGen = struct { |
| 1362 | | 1353 | |
| 1363 | if (!empty) try writer.writeAll(" | "); | 1354 | if (!empty) try writer.writeAll(" | "); |
| 1364 | try writer.writeByte('('); | 1355 | try writer.writeByte('('); |
| 1365 | try dg.renderTypecast(writer, ty); | 1356 | try dg.renderType(writer, ty); |
| 1366 | try writer.writeByte(')'); | 1357 | try writer.writeByte(')'); |
| 1367 | | 1358 | |
| 1368 | if (bit_offset_val_pl.data != 0) { | 1359 | if (bit_offset_val_pl.data != 0) { |
| ... | @@ -1385,7 +1376,7 @@ pub const DeclGen = struct { | ... | @@ -1385,7 +1376,7 @@ pub const DeclGen = struct { |
| 1385 | | 1376 | |
| 1386 | if (!location.isInitializer()) { | 1377 | if (!location.isInitializer()) { |
| 1387 | try writer.writeByte('('); | 1378 | try writer.writeByte('('); |
| 1388 | try dg.renderTypecast(writer, ty); | 1379 | try dg.renderType(writer, ty); |
| 1389 | try writer.writeByte(')'); | 1380 | try writer.writeByte(')'); |
| 1390 | } | 1381 | } |
| 1391 | | 1382 | |
| ... | @@ -1396,11 +1387,11 @@ pub const DeclGen = struct { | ... | @@ -1396,11 +1387,11 @@ pub const DeclGen = struct { |
| 1396 | if (field_ty.hasRuntimeBits()) { | 1387 | if (field_ty.hasRuntimeBits()) { |
| 1397 | if (field_ty.isPtrAtRuntime()) { | 1388 | if (field_ty.isPtrAtRuntime()) { |
| 1398 | try writer.writeByte('('); | 1389 | try writer.writeByte('('); |
| 1399 | try dg.renderTypecast(writer, ty); | 1390 | try dg.renderType(writer, ty); |
| 1400 | try writer.writeByte(')'); | 1391 | try writer.writeByte(')'); |
| 1401 | } else if (field_ty.zigTypeTag() == .Float) { | 1392 | } else if (field_ty.zigTypeTag() == .Float) { |
| 1402 | try writer.writeByte('('); | 1393 | try writer.writeByte('('); |
| 1403 | try dg.renderTypecast(writer, ty); | 1394 | try dg.renderType(writer, ty); |
| 1404 | try writer.writeByte(')'); | 1395 | try writer.writeByte(')'); |
| 1405 | } | 1396 | } |
| 1406 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); | 1397 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); |
| ... | @@ -1509,9 +1500,11 @@ pub const DeclGen = struct { | ... | @@ -1509,9 +1500,11 @@ pub const DeclGen = struct { |
| 1509 | fn indexToCType(dg: *DeclGen, idx: CType.Index) CType { | 1500 | fn indexToCType(dg: *DeclGen, idx: CType.Index) CType { |
| 1510 | return dg.ctypes.indexToCType(idx); | 1501 | return dg.ctypes.indexToCType(idx); |
| 1511 | } | 1502 | } |
| | 1503 | |
| 1512 | fn typeToIndex(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType.Index { | 1504 | fn typeToIndex(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType.Index { |
| 1513 | return dg.ctypes.typeToIndex(dg.gpa, ty, dg.module, kind); | 1505 | return dg.ctypes.typeToIndex(dg.gpa, ty, dg.module, kind); |
| 1514 | } | 1506 | } |
| | 1507 | |
| 1515 | fn typeToCType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType { | 1508 | fn typeToCType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType { |
| 1516 | return dg.ctypes.typeToCType(dg.gpa, ty, dg.module, kind); | 1509 | return dg.ctypes.typeToCType(dg.gpa, ty, dg.module, kind); |
| 1517 | } | 1510 | } |
| ... | @@ -1524,16 +1517,10 @@ pub const DeclGen = struct { | ... | @@ -1524,16 +1517,10 @@ pub const DeclGen = struct { |
| 1524 | /// There are three type formats in total that we support rendering: | 1517 | /// There are three type formats in total that we support rendering: |
| 1525 | /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) | | 1518 | /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) | |
| 1526 | /// |---------------------|-----------------|---------------------| | 1519 | /// |---------------------|-----------------|---------------------| |
| 1527 | /// | `renderTypecast` | "uint8_t *" | "uint8_t *[10]" | | | |
| 1528 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | | 1520 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | |
| 1529 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | | 1521 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | |
| 1530 | /// | 1522 | /// |
| 1531 | fn renderType( | 1523 | fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void { |
| 1532 | dg: *DeclGen, | | |
| 1533 | w: anytype, | | |
| 1534 | t: Type, | | |
| 1535 | _: TypedefKind, | | |
| 1536 | ) error{ OutOfMemory, AnalysisFail }!void { | | |
| 1537 | const store = &dg.ctypes.set; | 1524 | const store = &dg.ctypes.set; |
| 1538 | const module = dg.module; | 1525 | const module = dg.module; |
| 1539 | const idx = try dg.typeToIndex(t, .complete); | 1526 | const idx = try dg.typeToIndex(t, .complete); |
| ... | @@ -1603,12 +1590,12 @@ pub const DeclGen = struct { | ... | @@ -1603,12 +1590,12 @@ pub const DeclGen = struct { |
| 1603 | | 1590 | |
| 1604 | if (needs_cast) { | 1591 | if (needs_cast) { |
| 1605 | try w.writeByte('('); | 1592 | try w.writeByte('('); |
| 1606 | try dg.renderTypecast(w, dest_ty); | 1593 | try dg.renderType(w, dest_ty); |
| 1607 | try w.writeByte(')'); | 1594 | try w.writeByte(')'); |
| 1608 | } | 1595 | } |
| 1609 | if (src_is_ptr) { | 1596 | if (src_is_ptr) { |
| 1610 | try w.writeByte('('); | 1597 | try w.writeByte('('); |
| 1611 | try dg.renderTypecast(w, src_eff_ty); | 1598 | try dg.renderType(w, src_eff_ty); |
| 1612 | try w.writeByte(')'); | 1599 | try w.writeByte(')'); |
| 1613 | } | 1600 | } |
| 1614 | try context.writeValue(dg, w, src_ty, location); | 1601 | try context.writeValue(dg, w, src_ty, location); |
| ... | @@ -1625,7 +1612,7 @@ pub const DeclGen = struct { | ... | @@ -1625,7 +1612,7 @@ pub const DeclGen = struct { |
| 1625 | try w.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral? | 1612 | try w.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral? |
| 1626 | if (src_is_ptr) { | 1613 | if (src_is_ptr) { |
| 1627 | try w.writeByte('('); | 1614 | try w.writeByte('('); |
| 1628 | try dg.renderTypecast(w, src_eff_ty); | 1615 | try dg.renderType(w, src_eff_ty); |
| 1629 | try w.writeByte(')'); | 1616 | try w.writeByte(')'); |
| 1630 | } | 1617 | } |
| 1631 | try context.writeValue(dg, w, src_ty, .FunctionArgument); | 1618 | try context.writeValue(dg, w, src_ty, .FunctionArgument); |
| ... | @@ -1646,28 +1633,11 @@ pub const DeclGen = struct { | ... | @@ -1646,28 +1633,11 @@ pub const DeclGen = struct { |
| 1646 | } | 1633 | } |
| 1647 | } | 1634 | } |
| 1648 | | 1635 | |
| 1649 | /// Renders a type in C typecast format. | | |
| 1650 | /// | | |
| 1651 | /// This is guaranteed to be valid in a typecast expression, but not | | |
| 1652 | /// necessarily in a variable/field declaration. | | |
| 1653 | /// | | |
| 1654 | /// There are three type formats in total that we support rendering: | | |
| 1655 | /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) | | | |
| 1656 | /// |---------------------|-----------------|---------------------| | | |
| 1657 | /// | `renderTypecast` | "uint8_t *" | "uint8_t *[10]" | | | |
| 1658 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | | | |
| 1659 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | | | |
| 1660 | /// | | |
| 1661 | fn renderTypecast(dg: *DeclGen, w: anytype, ty: Type) error{ OutOfMemory, AnalysisFail }!void { | | |
| 1662 | try dg.renderType(w, ty, undefined); | | |
| 1663 | } | | |
| 1664 | | | |
| 1665 | /// Renders a type and name in field declaration/definition format. | 1636 | /// Renders a type and name in field declaration/definition format. |
| 1666 | /// | 1637 | /// |
| 1667 | /// There are three type formats in total that we support rendering: | 1638 | /// There are three type formats in total that we support rendering: |
| 1668 | /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) | | 1639 | /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) | |
| 1669 | /// |---------------------|-----------------|---------------------| | 1640 | /// |---------------------|-----------------|---------------------| |
| 1670 | /// | `renderTypecast` | "uint8_t *" | "uint8_t *[10]" | | | |
| 1671 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | | 1641 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | |
| 1672 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | | 1642 | /// | `renderType` | "uint8_t *" | "uint8_t *[10]" | |
| 1673 | /// | 1643 | /// |
| ... | @@ -1708,7 +1678,7 @@ pub const DeclGen = struct { | ... | @@ -1708,7 +1678,7 @@ pub const DeclGen = struct { |
| 1708 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); | 1678 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| 1709 | | 1679 | |
| 1710 | try w.writeAll("static "); | 1680 | try w.writeAll("static "); |
| 1711 | try dg.renderType(w, name_slice_ty, .Complete); | 1681 | try dg.renderType(w, name_slice_ty); |
| 1712 | try w.writeByte(' '); | 1682 | try w.writeByte(' '); |
| 1713 | try w.writeAll(fn_name); | 1683 | try w.writeAll(fn_name); |
| 1714 | try w.writeByte('('); | 1684 | try w.writeByte('('); |
| ... | @@ -1742,7 +1712,7 @@ pub const DeclGen = struct { | ... | @@ -1742,7 +1712,7 @@ pub const DeclGen = struct { |
| 1742 | try w.writeAll(" = "); | 1712 | try w.writeAll(" = "); |
| 1743 | try dg.renderValue(w, name_ty, name_val, .Initializer); | 1713 | try dg.renderValue(w, name_ty, name_val, .Initializer); |
| 1744 | try w.writeAll(";\n return ("); | 1714 | try w.writeAll(";\n return ("); |
| 1745 | try dg.renderTypecast(w, name_slice_ty); | 1715 | try dg.renderType(w, name_slice_ty); |
| 1746 | try w.print("){{{}, {}}};\n", .{ | 1716 | try w.print("){{{}, {}}};\n", .{ |
| 1747 | fmtIdent("name"), try dg.fmtIntLiteral(Type.usize, len_val), | 1717 | fmtIdent("name"), try dg.fmtIntLiteral(Type.usize, len_val), |
| 1748 | }); | 1718 | }); |
| ... | @@ -1787,6 +1757,10 @@ pub const DeclGen = struct { | ... | @@ -1787,6 +1757,10 @@ pub const DeclGen = struct { |
| 1787 | }, | 1757 | }, |
| 1788 | .undef => |ty| return dg.renderValue(w, ty, Value.undef, .Other), | 1758 | .undef => |ty| return dg.renderValue(w, ty, Value.undef, .Other), |
| 1789 | .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}), | 1759 | .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}), |
| | 1760 | .payload_identifier => |ident| return w.print("{ }.{ }", .{ |
| | 1761 | fmtIdent("payload"), |
| | 1762 | fmtIdent(ident), |
| | 1763 | }), |
| 1790 | .bytes => |bytes| return w.writeAll(bytes), | 1764 | .bytes => |bytes| return w.writeAll(bytes), |
| 1791 | } | 1765 | } |
| 1792 | } | 1766 | } |
| ... | @@ -1812,6 +1786,10 @@ pub const DeclGen = struct { | ... | @@ -1812,6 +1786,10 @@ pub const DeclGen = struct { |
| 1812 | .decl_ref => |decl| return dg.renderDeclName(w, decl, 0), | 1786 | .decl_ref => |decl| return dg.renderDeclName(w, decl, 0), |
| 1813 | .undef => unreachable, | 1787 | .undef => unreachable, |
| 1814 | .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}), | 1788 | .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}), |
| | 1789 | .payload_identifier => |ident| return w.print("(*{ }.{ })", .{ |
| | 1790 | fmtIdent("payload"), |
| | 1791 | fmtIdent(ident), |
| | 1792 | }), |
| 1815 | .bytes => |bytes| { | 1793 | .bytes => |bytes| { |
| 1816 | try w.writeAll("(*"); | 1794 | try w.writeAll("(*"); |
| 1817 | try w.writeAll(bytes); | 1795 | try w.writeAll(bytes); |
| ... | @@ -1829,7 +1807,7 @@ pub const DeclGen = struct { | ... | @@ -1829,7 +1807,7 @@ pub const DeclGen = struct { |
| 1829 | fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void { | 1807 | fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void { |
| 1830 | switch (c_value) { | 1808 | switch (c_value) { |
| 1831 | .none, .constant, .field, .undef => unreachable, | 1809 | .none, .constant, .field, .undef => unreachable, |
| 1832 | .new_local, .local, .arg, .arg_array, .decl, .identifier, .bytes => { | 1810 | .new_local, .local, .arg, .arg_array, .decl, .identifier, .payload_identifier, .bytes => { |
| 1833 | try dg.writeCValue(writer, c_value); | 1811 | try dg.writeCValue(writer, c_value); |
| 1834 | try writer.writeAll("->"); | 1812 | try writer.writeAll("->"); |
| 1835 | }, | 1813 | }, |
| ... | @@ -3048,7 +3026,7 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3048,7 +3026,7 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3048 | try writer.writeByte(']'); | 3026 | try writer.writeByte(']'); |
| 3049 | if (is_array) { | 3027 | if (is_array) { |
| 3050 | try writer.writeAll(", sizeof("); | 3028 | try writer.writeAll(", sizeof("); |
| 3051 | try f.renderTypecast(writer, inst_ty); | 3029 | try f.renderType(writer, inst_ty); |
| 3052 | try writer.writeAll("))"); | 3030 | try writer.writeAll("))"); |
| 3053 | } | 3031 | } |
| 3054 | try writer.writeAll(";\n"); | 3032 | try writer.writeAll(";\n"); |
| ... | @@ -3080,7 +3058,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3080,7 +3058,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3080 | const local = try f.allocLocal(inst, f.air.typeOfIndex(inst)); | 3058 | const local = try f.allocLocal(inst, f.air.typeOfIndex(inst)); |
| 3081 | try f.writeCValue(writer, local, .Other); | 3059 | try f.writeCValue(writer, local, .Other); |
| 3082 | try writer.writeAll(" = ("); | 3060 | try writer.writeAll(" = ("); |
| 3083 | try f.renderTypecast(writer, inst_ty); | 3061 | try f.renderType(writer, inst_ty); |
| 3084 | try writer.writeAll(")&("); | 3062 | try writer.writeAll(")&("); |
| 3085 | if (ptr_ty.ptrSize() == .One) { | 3063 | if (ptr_ty.ptrSize() == .One) { |
| 3086 | // It's a pointer to an array, so we need to de-reference. | 3064 | // It's a pointer to an array, so we need to de-reference. |
| ... | @@ -3128,7 +3106,7 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3128,7 +3106,7 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3128 | try writer.writeByte(']'); | 3106 | try writer.writeByte(']'); |
| 3129 | if (is_array) { | 3107 | if (is_array) { |
| 3130 | try writer.writeAll(", sizeof("); | 3108 | try writer.writeAll(", sizeof("); |
| 3131 | try f.renderTypecast(writer, inst_ty); | 3109 | try f.renderType(writer, inst_ty); |
| 3132 | try writer.writeAll("))"); | 3110 | try writer.writeAll("))"); |
| 3133 | } | 3111 | } |
| 3134 | try writer.writeAll(";\n"); | 3112 | try writer.writeAll(";\n"); |
| ... | @@ -3197,7 +3175,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3197,7 +3175,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3197 | try writer.writeByte(']'); | 3175 | try writer.writeByte(']'); |
| 3198 | if (is_array) { | 3176 | if (is_array) { |
| 3199 | try writer.writeAll(", sizeof("); | 3177 | try writer.writeAll(", sizeof("); |
| 3200 | try f.renderTypecast(writer, inst_ty); | 3178 | try f.renderType(writer, inst_ty); |
| 3201 | try writer.writeAll("))"); | 3179 | try writer.writeAll("))"); |
| 3202 | } | 3180 | } |
| 3203 | try writer.writeAll(";\n"); | 3181 | try writer.writeAll(";\n"); |
| ... | @@ -3240,11 +3218,11 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3240,11 +3218,11 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3240 | | 3218 | |
| 3241 | fn airArg(f: *Function, inst: Air.Inst.Index) !CValue { | 3219 | fn airArg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3242 | const inst_ty = f.air.typeOfIndex(inst); | 3220 | const inst_ty = f.air.typeOfIndex(inst); |
| 3243 | const inst_cty = try f.object.dg.typeToIndex(inst_ty, .parameter); | 3221 | const inst_cty = try f.typeToIndex(inst_ty, .parameter); |
| 3244 | | 3222 | |
| 3245 | const i = f.next_arg_index; | 3223 | const i = f.next_arg_index; |
| 3246 | f.next_arg_index += 1; | 3224 | f.next_arg_index += 1; |
| 3247 | return if (inst_cty != try f.object.dg.typeToIndex(inst_ty, .complete)) | 3225 | return if (inst_cty != try f.typeToIndex(inst_ty, .complete)) |
| 3248 | .{ .arg_array = i } | 3226 | .{ .arg_array = i } |
| 3249 | else | 3227 | else |
| 3250 | .{ .arg = i }; | 3228 | .{ .arg = i }; |
| ... | @@ -3281,7 +3259,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3281,7 +3259,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3281 | try writer.writeAll(", (const char *)"); | 3259 | try writer.writeAll(", (const char *)"); |
| 3282 | try f.writeCValue(writer, operand, .Other); | 3260 | try f.writeCValue(writer, operand, .Other); |
| 3283 | try writer.writeAll(", sizeof("); | 3261 | try writer.writeAll(", sizeof("); |
| 3284 | try f.renderTypecast(writer, src_ty); | 3262 | try f.renderType(writer, src_ty); |
| 3285 | try writer.writeAll("))"); | 3263 | try writer.writeAll("))"); |
| 3286 | } else if (ptr_info.host_size != 0) { | 3264 | } else if (ptr_info.host_size != 0) { |
| 3287 | var host_pl = Type.Payload.Bits{ | 3265 | var host_pl = Type.Payload.Bits{ |
| ... | @@ -3310,11 +3288,11 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3310,11 +3288,11 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3310 | | 3288 | |
| 3311 | try f.writeCValue(writer, local, .Other); | 3289 | try f.writeCValue(writer, local, .Other); |
| 3312 | try writer.writeAll(" = ("); | 3290 | try writer.writeAll(" = ("); |
| 3313 | try f.renderTypecast(writer, src_ty); | 3291 | try f.renderType(writer, src_ty); |
| 3314 | try writer.writeAll(")zig_wrap_"); | 3292 | try writer.writeAll(")zig_wrap_"); |
| 3315 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty); | 3293 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty); |
| 3316 | try writer.writeAll("(("); | 3294 | try writer.writeAll("(("); |
| 3317 | try f.renderTypecast(writer, field_ty); | 3295 | try f.renderType(writer, field_ty); |
| 3318 | try writer.writeByte(')'); | 3296 | try writer.writeByte(')'); |
| 3319 | const cant_cast = host_ty.isInt() and host_ty.bitSize(target) > 64; | 3297 | const cant_cast = host_ty.isInt() and host_ty.bitSize(target) > 64; |
| 3320 | if (cant_cast) { | 3298 | if (cant_cast) { |
| ... | @@ -3365,7 +3343,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3365,7 +3343,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3365 | try f.writeCValue(writer, operand, .FunctionArgument); | 3343 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3366 | deref = false; | 3344 | deref = false; |
| 3367 | try writer.writeAll(", sizeof("); | 3345 | try writer.writeAll(", sizeof("); |
| 3368 | try f.renderTypecast(writer, ret_ty); | 3346 | try f.renderType(writer, ret_ty); |
| 3369 | try writer.writeAll("));\n"); | 3347 | try writer.writeAll("));\n"); |
| 3370 | break :ret_val array_local; | 3348 | break :ret_val array_local; |
| 3371 | } else operand; | 3349 | } else operand; |
| ... | @@ -3440,7 +3418,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3440,7 +3418,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3440 | try writer.writeByte('('); | 3418 | try writer.writeByte('('); |
| 3441 | } else if (dest_c_bits <= 64) { | 3419 | } else if (dest_c_bits <= 64) { |
| 3442 | try writer.writeByte('('); | 3420 | try writer.writeByte('('); |
| 3443 | try f.renderTypecast(writer, inst_ty); | 3421 | try f.renderType(writer, inst_ty); |
| 3444 | try writer.writeByte(')'); | 3422 | try writer.writeByte(')'); |
| 3445 | } | 3423 | } |
| 3446 | | 3424 | |
| ... | @@ -3521,7 +3499,7 @@ fn storeUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue { | ... | @@ -3521,7 +3499,7 @@ fn storeUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue { |
| 3521 | try writer.writeAll("memset("); | 3499 | try writer.writeAll("memset("); |
| 3522 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); | 3500 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); |
| 3523 | try writer.print(", {x}, sizeof(", .{try f.fmtIntLiteral(Type.u8, Value.undef)}); | 3501 | try writer.print(", {x}, sizeof(", .{try f.fmtIntLiteral(Type.u8, Value.undef)}); |
| 3524 | try f.renderTypecast(writer, lhs_child_ty); | 3502 | try f.renderType(writer, lhs_child_ty); |
| 3525 | try writer.writeAll("));\n"); | 3503 | try writer.writeAll("));\n"); |
| 3526 | } | 3504 | } |
| 3527 | return CValue.none; | 3505 | return CValue.none; |
| ... | @@ -3582,7 +3560,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3582,7 +3560,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3582 | if (!is_array) try writer.writeByte('&'); | 3560 | if (!is_array) try writer.writeByte('&'); |
| 3583 | try f.writeCValue(writer, array_src, .FunctionArgument); | 3561 | try f.writeCValue(writer, array_src, .FunctionArgument); |
| 3584 | try writer.writeAll(", sizeof("); | 3562 | try writer.writeAll(", sizeof("); |
| 3585 | try f.renderTypecast(writer, src_ty); | 3563 | try f.renderType(writer, src_ty); |
| 3586 | try writer.writeAll("))"); | 3564 | try writer.writeAll("))"); |
| 3587 | if (src_val == .constant) { | 3565 | if (src_val == .constant) { |
| 3588 | try freeLocal(f, inst, array_src.new_local, 0); | 3566 | try freeLocal(f, inst, array_src.new_local, 0); |
| ... | @@ -3641,13 +3619,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3641,13 +3619,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3641 | try writer.writeAll("(0, "); | 3619 | try writer.writeAll("(0, "); |
| 3642 | } else { | 3620 | } else { |
| 3643 | try writer.writeByte('('); | 3621 | try writer.writeByte('('); |
| 3644 | try f.renderTypecast(writer, host_ty); | 3622 | try f.renderType(writer, host_ty); |
| 3645 | try writer.writeByte(')'); | 3623 | try writer.writeByte(')'); |
| 3646 | } | 3624 | } |
| 3647 | | 3625 | |
| 3648 | if (src_ty.isPtrAtRuntime()) { | 3626 | if (src_ty.isPtrAtRuntime()) { |
| 3649 | try writer.writeByte('('); | 3627 | try writer.writeByte('('); |
| 3650 | try f.renderTypecast(writer, Type.usize); | 3628 | try f.renderType(writer, Type.usize); |
| 3651 | try writer.writeByte(')'); | 3629 | try writer.writeByte(')'); |
| 3652 | } | 3630 | } |
| 3653 | try f.writeCValue(writer, src_val, .Other); | 3631 | try f.writeCValue(writer, src_val, .Other); |
| ... | @@ -3919,7 +3897,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | ... | @@ -3919,7 +3897,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3919 | // results in a NULL pointer, or if LHS is NULL. The operation is only UB | 3897 | // results in a NULL pointer, or if LHS is NULL. The operation is only UB |
| 3920 | // if the result is NULL and then dereferenced. | 3898 | // if the result is NULL and then dereferenced. |
| 3921 | try writer.writeByte('('); | 3899 | try writer.writeByte('('); |
| 3922 | try f.renderTypecast(writer, inst_ty); | 3900 | try f.renderType(writer, inst_ty); |
| 3923 | try writer.writeAll(")(((uintptr_t)"); | 3901 | try writer.writeAll(")(((uintptr_t)"); |
| 3924 | try f.writeCValue(writer, lhs, .Other); | 3902 | try f.writeCValue(writer, lhs, .Other); |
| 3925 | try writer.writeAll(") "); | 3903 | try writer.writeAll(") "); |
| ... | @@ -3927,7 +3905,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | ... | @@ -3927,7 +3905,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 3927 | try writer.writeAll(" ("); | 3905 | try writer.writeAll(" ("); |
| 3928 | try f.writeCValue(writer, rhs, .Other); | 3906 | try f.writeCValue(writer, rhs, .Other); |
| 3929 | try writer.writeAll("*sizeof("); | 3907 | try writer.writeAll("*sizeof("); |
| 3930 | try f.renderTypecast(writer, elem_ty); | 3908 | try f.renderType(writer, elem_ty); |
| 3931 | try writer.writeAll(")))"); | 3909 | try writer.writeAll(")))"); |
| 3932 | } else try f.writeCValue(writer, lhs, .Initializer); | 3910 | } else try f.writeCValue(writer, lhs, .Initializer); |
| 3933 | | 3911 | |
| ... | @@ -3992,7 +3970,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3992,7 +3970,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3992 | try f.writeCValue(writer, local, .Other); | 3970 | try f.writeCValue(writer, local, .Other); |
| 3993 | try writer.writeAll(".ptr = ("); | 3971 | try writer.writeAll(".ptr = ("); |
| 3994 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 3972 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 3995 | try f.renderTypecast(writer, inst_ty.slicePtrFieldType(&buf)); | 3973 | try f.renderType(writer, inst_ty.slicePtrFieldType(&buf)); |
| 3996 | try writer.writeByte(')'); | 3974 | try writer.writeByte(')'); |
| 3997 | try f.writeCValue(writer, ptr, .Other); | 3975 | try f.writeCValue(writer, ptr, .Other); |
| 3998 | try writer.writeAll("; "); | 3976 | try writer.writeAll("; "); |
| ... | @@ -4032,13 +4010,13 @@ fn airCall( | ... | @@ -4032,13 +4010,13 @@ fn airCall( |
| 4032 | defer gpa.free(resolved_args); | 4010 | defer gpa.free(resolved_args); |
| 4033 | for (resolved_args, args) |*resolved_arg, arg| { | 4011 | for (resolved_args, args) |*resolved_arg, arg| { |
| 4034 | const arg_ty = f.air.typeOf(arg); | 4012 | const arg_ty = f.air.typeOf(arg); |
| 4035 | const arg_cty = try f.object.dg.typeToIndex(arg_ty, .parameter); | 4013 | const arg_cty = try f.typeToIndex(arg_ty, .parameter); |
| 4036 | if (f.object.dg.indexToCType(arg_cty).tag() == .void) { | 4014 | if (f.indexToCType(arg_cty).tag() == .void) { |
| 4037 | resolved_arg.* = .none; | 4015 | resolved_arg.* = .none; |
| 4038 | continue; | 4016 | continue; |
| 4039 | } | 4017 | } |
| 4040 | resolved_arg.* = try f.resolveInst(arg); | 4018 | resolved_arg.* = try f.resolveInst(arg); |
| 4041 | if (arg_cty != try f.object.dg.typeToIndex(arg_ty, .complete)) { | 4019 | if (arg_cty != try f.typeToIndex(arg_ty, .complete)) { |
| 4042 | var lowered_arg_buf: LowerFnRetTyBuffer = undefined; | 4020 | var lowered_arg_buf: LowerFnRetTyBuffer = undefined; |
| 4043 | const lowered_arg_ty = lowerFnRetTy(arg_ty, &lowered_arg_buf, target); | 4021 | const lowered_arg_ty = lowerFnRetTy(arg_ty, &lowered_arg_buf, target); |
| 4044 | | 4022 | |
| ... | @@ -4048,7 +4026,7 @@ fn airCall( | ... | @@ -4048,7 +4026,7 @@ fn airCall( |
| 4048 | try writer.writeAll(", "); | 4026 | try writer.writeAll(", "); |
| 4049 | try f.writeCValue(writer, resolved_arg.*, .FunctionArgument); | 4027 | try f.writeCValue(writer, resolved_arg.*, .FunctionArgument); |
| 4050 | try writer.writeAll(", sizeof("); | 4028 | try writer.writeAll(", sizeof("); |
| 4051 | try f.renderTypecast(writer, lowered_arg_ty); | 4029 | try f.renderType(writer, lowered_arg_ty); |
| 4052 | try writer.writeAll("));\n"); | 4030 | try writer.writeAll("));\n"); |
| 4053 | resolved_arg.* = array_local; | 4031 | resolved_arg.* = array_local; |
| 4054 | } | 4032 | } |
| ... | @@ -4077,7 +4055,7 @@ fn airCall( | ... | @@ -4077,7 +4055,7 @@ fn airCall( |
| 4077 | .none | 4055 | .none |
| 4078 | else if (f.liveness.isUnused(inst)) r: { | 4056 | else if (f.liveness.isUnused(inst)) r: { |
| 4079 | try writer.writeByte('('); | 4057 | try writer.writeByte('('); |
| 4080 | try f.renderTypecast(writer, Type.void); | 4058 | try f.renderType(writer, Type.void); |
| 4081 | try writer.writeByte(')'); | 4059 | try writer.writeByte(')'); |
| 4082 | break :r .none; | 4060 | break :r .none; |
| 4083 | } else r: { | 4061 | } else r: { |
| ... | @@ -4132,7 +4110,7 @@ fn airCall( | ... | @@ -4132,7 +4110,7 @@ fn airCall( |
| 4132 | try writer.writeAll(", "); | 4110 | try writer.writeAll(", "); |
| 4133 | try f.writeCValueMember(writer, result_local, .{ .identifier = "array" }); | 4111 | try f.writeCValueMember(writer, result_local, .{ .identifier = "array" }); |
| 4134 | try writer.writeAll(", sizeof("); | 4112 | try writer.writeAll(", sizeof("); |
| 4135 | try f.renderTypecast(writer, ret_ty); | 4113 | try f.renderType(writer, ret_ty); |
| 4136 | try writer.writeAll("));\n"); | 4114 | try writer.writeAll("));\n"); |
| 4137 | try freeLocal(f, inst, result_local.new_local, 0); | 4115 | try freeLocal(f, inst, result_local.new_local, 0); |
| 4138 | break :r array_local; | 4116 | break :r array_local; |
| ... | @@ -4280,7 +4258,7 @@ fn lowerTry( | ... | @@ -4280,7 +4258,7 @@ fn lowerTry( |
| 4280 | try writer.writeAll(", "); | 4258 | try writer.writeAll(", "); |
| 4281 | try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); | 4259 | try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); |
| 4282 | try writer.writeAll(", sizeof("); | 4260 | try writer.writeAll(", sizeof("); |
| 4283 | try f.renderTypecast(writer, payload_ty); | 4261 | try f.renderType(writer, payload_ty); |
| 4284 | try writer.writeAll("));\n"); | 4262 | try writer.writeAll("));\n"); |
| 4285 | } else { | 4263 | } else { |
| 4286 | try f.writeCValue(writer, local, .Other); | 4264 | try f.writeCValue(writer, local, .Other); |
| ... | @@ -4313,7 +4291,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4313,7 +4291,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4313 | try writer.writeAll(", "); | 4291 | try writer.writeAll(", "); |
| 4314 | try f.writeCValue(writer, operand, .FunctionArgument); | 4292 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 4315 | try writer.writeAll(", sizeof("); | 4293 | try writer.writeAll(", sizeof("); |
| 4316 | try f.renderTypecast(writer, operand_ty); | 4294 | try f.renderType(writer, operand_ty); |
| 4317 | try writer.writeAll("))"); | 4295 | try writer.writeAll("))"); |
| 4318 | } else { | 4296 | } else { |
| 4319 | try f.writeCValue(writer, result, .Other); | 4297 | try f.writeCValue(writer, result, .Other); |
| ... | @@ -4362,7 +4340,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4362,7 +4340,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4362 | if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { | 4340 | if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { |
| 4363 | try f.writeCValue(writer, local, .Other); | 4341 | try f.writeCValue(writer, local, .Other); |
| 4364 | try writer.writeAll(" = ("); | 4342 | try writer.writeAll(" = ("); |
| 4365 | try f.renderTypecast(writer, dest_ty); | 4343 | try f.renderType(writer, dest_ty); |
| 4366 | try writer.writeByte(')'); | 4344 | try writer.writeByte(')'); |
| 4367 | try f.writeCValue(writer, operand, .Other); | 4345 | try f.writeCValue(writer, operand, .Other); |
| 4368 | try writer.writeAll(";\n"); | 4346 | try writer.writeAll(";\n"); |
| ... | @@ -4383,7 +4361,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4383,7 +4361,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4383 | try writer.writeAll(", &"); | 4361 | try writer.writeAll(", &"); |
| 4384 | try f.writeCValue(writer, operand_lval, .Other); | 4362 | try f.writeCValue(writer, operand_lval, .Other); |
| 4385 | try writer.writeAll(", sizeof("); | 4363 | try writer.writeAll(", sizeof("); |
| 4386 | try f.renderTypecast(writer, dest_ty); | 4364 | try f.renderType(writer, dest_ty); |
| 4387 | try writer.writeAll("));\n"); | 4365 | try writer.writeAll("));\n"); |
| 4388 | | 4366 | |
| 4389 | // Ensure padding bits have the expected value. | 4367 | // Ensure padding bits have the expected value. |
| ... | @@ -4415,7 +4393,7 @@ fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4415,7 +4393,7 @@ fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4415 | const local = try f.allocLocal(inst, Type.usize); | 4393 | const local = try f.allocLocal(inst, Type.usize); |
| 4416 | try f.writeCValue(writer, local, .Other); | 4394 | try f.writeCValue(writer, local, .Other); |
| 4417 | try writer.writeAll(" = ("); | 4395 | try writer.writeAll(" = ("); |
| 4418 | try f.renderTypecast(writer, Type.usize); | 4396 | try f.renderType(writer, Type.usize); |
| 4419 | try writer.writeAll(")zig_return_address();\n"); | 4397 | try writer.writeAll(")zig_return_address();\n"); |
| 4420 | return local; | 4398 | return local; |
| 4421 | } | 4399 | } |
| ... | @@ -4426,7 +4404,7 @@ fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4426,7 +4404,7 @@ fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4426 | const local = try f.allocLocal(inst, Type.usize); | 4404 | const local = try f.allocLocal(inst, Type.usize); |
| 4427 | try f.writeCValue(writer, local, .Other); | 4405 | try f.writeCValue(writer, local, .Other); |
| 4428 | try writer.writeAll(" = ("); | 4406 | try writer.writeAll(" = ("); |
| 4429 | try f.renderTypecast(writer, Type.usize); | 4407 | try f.renderType(writer, Type.usize); |
| 4430 | try writer.writeAll(")zig_frame_address();\n"); | 4408 | try writer.writeAll(")zig_frame_address();\n"); |
| 4431 | return local; | 4409 | return local; |
| 4432 | } | 4410 | } |
| ... | @@ -4558,11 +4536,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4558,11 +4536,11 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4558 | try writer.writeAll("switch ("); | 4536 | try writer.writeAll("switch ("); |
| 4559 | if (condition_ty.zigTypeTag() == .Bool) { | 4537 | if (condition_ty.zigTypeTag() == .Bool) { |
| 4560 | try writer.writeByte('('); | 4538 | try writer.writeByte('('); |
| 4561 | try f.renderTypecast(writer, Type.u1); | 4539 | try f.renderType(writer, Type.u1); |
| 4562 | try writer.writeByte(')'); | 4540 | try writer.writeByte(')'); |
| 4563 | } else if (condition_ty.isPtrAtRuntime()) { | 4541 | } else if (condition_ty.isPtrAtRuntime()) { |
| 4564 | try writer.writeByte('('); | 4542 | try writer.writeByte('('); |
| 4565 | try f.renderTypecast(writer, Type.usize); | 4543 | try f.renderType(writer, Type.usize); |
| 4566 | try writer.writeByte(')'); | 4544 | try writer.writeByte(')'); |
| 4567 | } | 4545 | } |
| 4568 | try f.writeCValue(writer, condition, .Other); | 4546 | try f.writeCValue(writer, condition, .Other); |
| ... | @@ -4591,7 +4569,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4591,7 +4569,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4591 | try writer.writeAll("case "); | 4569 | try writer.writeAll("case "); |
| 4592 | if (condition_ty.isPtrAtRuntime()) { | 4570 | if (condition_ty.isPtrAtRuntime()) { |
| 4593 | try writer.writeByte('('); | 4571 | try writer.writeByte('('); |
| 4594 | try f.renderTypecast(writer, Type.usize); | 4572 | try f.renderType(writer, Type.usize); |
| 4595 | try writer.writeByte(')'); | 4573 | try writer.writeByte(')'); |
| 4596 | } | 4574 | } |
| 4597 | try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other); | 4575 | try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other); |
| ... | @@ -5043,7 +5021,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5043,7 +5021,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5043 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); | 5021 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 5044 | if (is_array) { | 5022 | if (is_array) { |
| 5045 | try writer.writeAll(", sizeof("); | 5023 | try writer.writeAll(", sizeof("); |
| 5046 | try f.renderTypecast(writer, inst_ty); | 5024 | try f.renderType(writer, inst_ty); |
| 5047 | try writer.writeAll("))"); | 5025 | try writer.writeAll("))"); |
| 5048 | } | 5026 | } |
| 5049 | try writer.writeAll(";\n"); | 5027 | try writer.writeAll(";\n"); |
| ... | @@ -5127,6 +5105,62 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5127,6 +5105,62 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5127 | } | 5105 | } |
| 5128 | } | 5106 | } |
| 5129 | | 5107 | |
| | 5108 | fn fieldLocation( |
| | 5109 | container_ty: Type, |
| | 5110 | field_ptr_ty: Type, |
| | 5111 | field_index: u32, |
| | 5112 | target: std.Target, |
| | 5113 | ) union(enum) { |
| | 5114 | begin: void, |
| | 5115 | field: CValue, |
| | 5116 | byte_offset: u32, |
| | 5117 | end: void, |
| | 5118 | } { |
| | 5119 | return switch (container_ty.zigTypeTag()) { |
| | 5120 | .Struct => switch (container_ty.containerLayout()) { |
| | 5121 | .Auto, .Extern => for (field_index..container_ty.structFieldCount()) |next_field_index| { |
| | 5122 | if (container_ty.structFieldIsComptime(next_field_index)) continue; |
| | 5123 | const field_ty = container_ty.structFieldType(next_field_index); |
| | 5124 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; |
| | 5125 | break .{ .field = if (container_ty.isSimpleTuple()) |
| | 5126 | .{ .field = next_field_index } |
| | 5127 | else |
| | 5128 | .{ .identifier = container_ty.structFieldName(next_field_index) } }; |
| | 5129 | } else if (container_ty.hasRuntimeBitsIgnoreComptime()) .end else .begin, |
| | 5130 | .Packed => if (field_ptr_ty.ptrInfo().data.host_size == 0) |
| | 5131 | .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, target) } |
| | 5132 | else |
| | 5133 | .begin, |
| | 5134 | }, |
| | 5135 | .Union => switch (container_ty.containerLayout()) { |
| | 5136 | .Auto, .Extern => { |
| | 5137 | const field_ty = container_ty.structFieldType(field_index); |
| | 5138 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) |
| | 5139 | return if (container_ty.unionTagTypeSafety() != null and |
| | 5140 | !container_ty.unionHasAllZeroBitFieldTypes()) |
| | 5141 | .{ .field = .{ .identifier = "payload" } } |
| | 5142 | else |
| | 5143 | .begin; |
| | 5144 | const field_name = container_ty.unionFields().keys()[field_index]; |
| | 5145 | return .{ .field = if (container_ty.unionTagTypeSafety()) |_| |
| | 5146 | .{ .payload_identifier = field_name } |
| | 5147 | else |
| | 5148 | .{ .identifier = field_name } }; |
| | 5149 | }, |
| | 5150 | .Packed => .begin, |
| | 5151 | }, |
| | 5152 | .Pointer => switch (container_ty.ptrSize()) { |
| | 5153 | .Slice => switch (field_index) { |
| | 5154 | 0 => .{ .field = .{ .identifier = "ptr" } }, |
| | 5155 | 1 => .{ .field = .{ .identifier = "len" } }, |
| | 5156 | else => unreachable, |
| | 5157 | }, |
| | 5158 | .One, .Many, .C => unreachable, |
| | 5159 | }, |
| | 5160 | else => unreachable, |
| | 5161 | }; |
| | 5162 | } |
| | 5163 | |
| 5130 | fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 5164 | fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5131 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 5165 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 5132 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; | 5166 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; |
| ... | @@ -5136,10 +5170,10 @@ fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5136,10 +5170,10 @@ fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5136 | return .none; | 5170 | return .none; |
| 5137 | } | 5171 | } |
| 5138 | | 5172 | |
| 5139 | const struct_ptr = try f.resolveInst(extra.struct_operand); | 5173 | const container_ptr_val = try f.resolveInst(extra.struct_operand); |
| 5140 | try reap(f, inst, &.{extra.struct_operand}); | 5174 | try reap(f, inst, &.{extra.struct_operand}); |
| 5141 | const struct_ptr_ty = f.air.typeOf(extra.struct_operand); | 5175 | const container_ptr_ty = f.air.typeOf(extra.struct_operand); |
| 5142 | return structFieldPtr(f, inst, struct_ptr_ty, struct_ptr, extra.field_index); | 5176 | return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, extra.field_index); |
| 5143 | } | 5177 | } |
| 5144 | | 5178 | |
| 5145 | fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue { | 5179 | fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue { |
| ... | @@ -5150,10 +5184,10 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue | ... | @@ -5150,10 +5184,10 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue |
| 5150 | return .none; | 5184 | return .none; |
| 5151 | } | 5185 | } |
| 5152 | | 5186 | |
| 5153 | const struct_ptr = try f.resolveInst(ty_op.operand); | 5187 | const container_ptr_val = try f.resolveInst(ty_op.operand); |
| 5154 | try reap(f, inst, &.{ty_op.operand}); | 5188 | try reap(f, inst, &.{ty_op.operand}); |
| 5155 | const struct_ptr_ty = f.air.typeOf(ty_op.operand); | 5189 | const container_ptr_ty = f.air.typeOf(ty_op.operand); |
| 5156 | return structFieldPtr(f, inst, struct_ptr_ty, struct_ptr, index); | 5190 | return fieldPtr(f, inst, container_ptr_ty, container_ptr_val, index); |
| 5157 | } | 5191 | } |
| 5158 | | 5192 | |
| 5159 | fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 5193 | fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -5165,130 +5199,115 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5165,130 +5199,115 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5165 | return CValue.none; | 5199 | return CValue.none; |
| 5166 | } | 5200 | } |
| 5167 | | 5201 | |
| 5168 | const struct_ptr_ty = f.air.typeOfIndex(inst); | 5202 | const target = f.object.dg.module.getTarget(); |
| | 5203 | const container_ptr_ty = f.air.typeOfIndex(inst); |
| | 5204 | const container_ty = container_ptr_ty.childType(); |
| 5169 | | 5205 | |
| 5170 | const field_ptr_ty = f.air.typeOf(extra.field_ptr); | 5206 | const field_ptr_ty = f.air.typeOf(extra.field_ptr); |
| 5171 | const field_ptr_val = try f.resolveInst(extra.field_ptr); | 5207 | const field_ptr_val = try f.resolveInst(extra.field_ptr); |
| 5172 | try reap(f, inst, &.{extra.field_ptr}); | 5208 | try reap(f, inst, &.{extra.field_ptr}); |
| 5173 | | 5209 | |
| 5174 | const target = f.object.dg.module.getTarget(); | 5210 | const writer = f.object.writer(); |
| 5175 | const struct_ty = struct_ptr_ty.childType(); | 5211 | const local = try f.allocLocal(inst, container_ptr_ty); |
| | 5212 | try f.writeCValue(writer, local, .Other); |
| | 5213 | try writer.writeAll(" = ("); |
| | 5214 | try f.renderType(writer, container_ptr_ty); |
| | 5215 | try writer.writeByte(')'); |
| 5176 | | 5216 | |
| 5177 | if (struct_ty.zigTypeTag() == .Union) { | 5217 | switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, target)) { |
| 5178 | return f.fail("TODO: CBE: @fieldParentPtr for unions", .{}); | 5218 | .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), |
| 5179 | } | 5219 | .field => |field| { |
| | 5220 | var u8_ptr_pl = field_ptr_ty.ptrInfo(); |
| | 5221 | u8_ptr_pl.data.pointee_type = Type.u8; |
| | 5222 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); |
| 5180 | | 5223 | |
| 5181 | const field_offset = struct_ty.structFieldOffset(extra.field_index, target); | 5224 | try writer.writeAll("(("); |
| | 5225 | try f.renderType(writer, u8_ptr_ty); |
| | 5226 | try writer.writeByte(')'); |
| | 5227 | try f.writeCValue(writer, field_ptr_val, .Other); |
| | 5228 | try writer.writeAll(" - offsetof("); |
| | 5229 | try f.renderType(writer, container_ty); |
| | 5230 | try writer.writeAll(", "); |
| | 5231 | try f.writeCValue(writer, field, .Other); |
| | 5232 | try writer.writeAll("))"); |
| | 5233 | }, |
| | 5234 | .byte_offset => |byte_offset| { |
| | 5235 | var u8_ptr_pl = field_ptr_ty.ptrInfo(); |
| | 5236 | u8_ptr_pl.data.pointee_type = Type.u8; |
| | 5237 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); |
| 5182 | | 5238 | |
| 5183 | var field_offset_pl = Value.Payload.I64{ | 5239 | var byte_offset_pl = Value.Payload.U64{ |
| 5184 | .base = .{ .tag = .int_i64 }, | 5240 | .base = .{ .tag = .int_u64 }, |
| 5185 | .data = -@intCast(i64, field_offset), | 5241 | .data = byte_offset, |
| 5186 | }; | 5242 | }; |
| 5187 | const field_offset_val = Value.initPayload(&field_offset_pl.base); | 5243 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); |
| 5188 | | 5244 | |
| 5189 | var u8_ptr_pl = field_ptr_ty.ptrInfo(); | 5245 | try writer.writeAll("(("); |
| 5190 | u8_ptr_pl.data.pointee_type = Type.u8; | 5246 | try f.renderType(writer, u8_ptr_ty); |
| 5191 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | 5247 | try writer.writeByte(')'); |
| | 5248 | try f.writeCValue(writer, field_ptr_val, .Other); |
| | 5249 | try writer.print(" - {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); |
| | 5250 | }, |
| | 5251 | .end => { |
| | 5252 | try f.writeCValue(writer, field_ptr_val, .Other); |
| | 5253 | try writer.print(" - {}", .{try f.fmtIntLiteral(Type.usize, Value.one)}); |
| | 5254 | }, |
| | 5255 | } |
| 5192 | | 5256 | |
| 5193 | const writer = f.object.writer(); | 5257 | try writer.writeAll(";\n"); |
| 5194 | const local = try f.allocLocal(inst, struct_ptr_ty); | | |
| 5195 | try f.writeCValue(writer, local, .Other); | | |
| 5196 | try writer.writeAll(" = ("); | | |
| 5197 | try f.renderTypecast(writer, struct_ptr_ty); | | |
| 5198 | try writer.writeAll(")&(("); | | |
| 5199 | try f.renderTypecast(writer, u8_ptr_ty); | | |
| 5200 | try writer.writeByte(')'); | | |
| 5201 | try f.writeCValue(writer, field_ptr_val, .Other); | | |
| 5202 | try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.isize, field_offset_val)}); | | |
| 5203 | return local; | 5258 | return local; |
| 5204 | } | 5259 | } |
| 5205 | | 5260 | |
| 5206 | fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue { | 5261 | fn fieldPtr( |
| 5207 | const writer = f.object.writer(); | 5262 | f: *Function, |
| | 5263 | inst: Air.Inst.Index, |
| | 5264 | container_ptr_ty: Type, |
| | 5265 | container_ptr_val: CValue, |
| | 5266 | field_index: u32, |
| | 5267 | ) !CValue { |
| | 5268 | const target = f.object.dg.module.getTarget(); |
| | 5269 | const container_ty = container_ptr_ty.elemType(); |
| 5208 | const field_ptr_ty = f.air.typeOfIndex(inst); | 5270 | const field_ptr_ty = f.air.typeOfIndex(inst); |
| 5209 | const field_ptr_info = field_ptr_ty.ptrInfo(); | | |
| 5210 | const struct_ty = struct_ptr_ty.elemType(); | | |
| 5211 | const field_ty = struct_ty.structFieldType(index); | | |
| 5212 | | 5271 | |
| 5213 | // Ensure complete type definition is visible before accessing fields. | 5272 | // Ensure complete type definition is visible before accessing fields. |
| 5214 | try f.renderType(std.io.null_writer, struct_ty); | 5273 | _ = try f.typeToIndex(container_ty, .complete); |
| 5215 | | 5274 | |
| | 5275 | const writer = f.object.writer(); |
| 5216 | const local = try f.allocLocal(inst, field_ptr_ty); | 5276 | const local = try f.allocLocal(inst, field_ptr_ty); |
| 5217 | try f.writeCValue(writer, local, .Other); | 5277 | try f.writeCValue(writer, local, .Other); |
| 5218 | try writer.writeAll(" = ("); | 5278 | try writer.writeAll(" = ("); |
| 5219 | try f.renderTypecast(writer, field_ptr_ty); | 5279 | try f.renderType(writer, field_ptr_ty); |
| 5220 | try writer.writeByte(')'); | 5280 | try writer.writeByte(')'); |
| 5221 | | 5281 | |
| 5222 | const extra_name: CValue = switch (struct_ty.tag()) { | 5282 | switch (fieldLocation(container_ty, field_ptr_ty, field_index, target)) { |
| 5223 | .union_tagged, .union_safety_tagged => .{ .identifier = "payload" }, | 5283 | .begin => try f.writeCValue(writer, container_ptr_val, .Initializer), |
| 5224 | else => .none, | 5284 | .field => |field| { |
| 5225 | }; | 5285 | try writer.writeByte('&'); |
| 5226 | | 5286 | try f.writeCValueDerefMember(writer, container_ptr_val, field); |
| 5227 | const field_loc: union(enum) { | 5287 | }, |
| 5228 | begin: void, | 5288 | .byte_offset => |byte_offset| { |
| 5229 | field: CValue, | 5289 | var u8_ptr_pl = field_ptr_ty.ptrInfo(); |
| 5230 | end: void, | 5290 | u8_ptr_pl.data.pointee_type = Type.u8; |
| 5231 | } = switch (struct_ty.tag()) { | 5291 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); |
| 5232 | .tuple, .anon_struct, .@"struct" => switch (struct_ty.containerLayout()) { | | |
| 5233 | .Auto, .Extern => for (index..struct_ty.structFieldCount()) |field_i| { | | |
| 5234 | if (!struct_ty.structFieldIsComptime(field_i) and | | |
| 5235 | struct_ty.structFieldType(field_i).hasRuntimeBitsIgnoreComptime()) | | |
| 5236 | break .{ .field = if (struct_ty.isSimpleTuple()) | | |
| 5237 | .{ .field = field_i } | | |
| 5238 | else | | |
| 5239 | .{ .identifier = struct_ty.structFieldName(field_i) } }; | | |
| 5240 | } else .end, | | |
| 5241 | .Packed => if (field_ptr_info.data.host_size == 0) { | | |
| 5242 | const target = f.object.dg.module.getTarget(); | | |
| 5243 | | | |
| 5244 | const byte_offset = struct_ty.packedStructFieldByteOffset(index, target); | | |
| 5245 | var byte_offset_pl = Value.Payload.U64{ | | |
| 5246 | .base = .{ .tag = .int_u64 }, | | |
| 5247 | .data = byte_offset, | | |
| 5248 | }; | | |
| 5249 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); | | |
| 5250 | | | |
| 5251 | var u8_ptr_pl = field_ptr_info; | | |
| 5252 | u8_ptr_pl.data.pointee_type = Type.u8; | | |
| 5253 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | | |
| 5254 | | 5292 | |
| 5255 | if (!std.mem.isAligned(byte_offset, field_ptr_ty.ptrAlignment(target))) { | 5293 | var byte_offset_pl = Value.Payload.U64{ |
| 5256 | return f.fail("TODO: CBE: unaligned packed struct field pointer", .{}); | 5294 | .base = .{ .tag = .int_u64 }, |
| 5257 | } | 5295 | .data = byte_offset, |
| | 5296 | }; |
| | 5297 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); |
| 5258 | | 5298 | |
| 5259 | try writer.writeAll("&(("); | 5299 | try writer.writeAll("(("); |
| 5260 | try f.renderTypecast(writer, u8_ptr_ty); | 5300 | try f.renderType(writer, u8_ptr_ty); |
| 5261 | try writer.writeByte(')'); | 5301 | try writer.writeByte(')'); |
| 5262 | try f.writeCValue(writer, struct_ptr, .Other); | 5302 | try f.writeCValue(writer, container_ptr_val, .Other); |
| 5263 | try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); | 5303 | try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); |
| 5264 | return local; | | |
| 5265 | } else .begin, | | |
| 5266 | }, | 5304 | }, |
| 5267 | .@"union", .union_safety_tagged, .union_tagged => if (struct_ty.containerLayout() == .Packed) { | 5305 | .end => { |
| 5268 | try f.writeCValue(writer, struct_ptr, .Other); | 5306 | try f.writeCValue(writer, container_ptr_val, .Other); |
| 5269 | try writer.writeAll(";\n"); | 5307 | try writer.print(" + {}", .{try f.fmtIntLiteral(Type.usize, Value.one)}); |
| 5270 | return local; | 5308 | }, |
| 5271 | } else if (field_ty.hasRuntimeBitsIgnoreComptime()) .{ .field = .{ | 5309 | } |
| 5272 | .identifier = struct_ty.unionFields().keys()[index], | | |
| 5273 | } } else .end, | | |
| 5274 | else => unreachable, | | |
| 5275 | }; | | |
| 5276 | | 5310 | |
| 5277 | if (struct_ty.hasRuntimeBitsIgnoreComptime()) { | | |
| 5278 | try writer.writeByte('&'); | | |
| 5279 | switch (field_loc) { | | |
| 5280 | .begin, .end => { | | |
| 5281 | try writer.writeByte('('); | | |
| 5282 | try f.writeCValue(writer, struct_ptr, .Other); | | |
| 5283 | try writer.print(")[{}]", .{@boolToInt(field_loc == .end)}); | | |
| 5284 | }, | | |
| 5285 | .field => |field| if (extra_name != .none) { | | |
| 5286 | try f.writeCValueDerefMember(writer, struct_ptr, extra_name); | | |
| 5287 | try writer.writeByte('.'); | | |
| 5288 | try f.writeCValue(writer, field, .Other); | | |
| 5289 | } else try f.writeCValueDerefMember(writer, struct_ptr, field), | | |
| 5290 | } | | |
| 5291 | } else try f.writeCValue(writer, struct_ptr, .Other); | | |
| 5292 | try writer.writeAll(";\n"); | 5311 | try writer.writeAll(";\n"); |
| 5293 | return local; | 5312 | return local; |
| 5294 | } | 5313 | } |
| ... | @@ -5315,7 +5334,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5315,7 +5334,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5315 | const writer = f.object.writer(); | 5334 | const writer = f.object.writer(); |
| 5316 | | 5335 | |
| 5317 | // Ensure complete type definition is visible before accessing fields. | 5336 | // Ensure complete type definition is visible before accessing fields. |
| 5318 | try f.renderType(std.io.null_writer, struct_ty); | 5337 | _ = try f.typeToIndex(struct_ty, .complete); |
| 5319 | | 5338 | |
| 5320 | const extra_name: CValue = switch (struct_ty.tag()) { | 5339 | const extra_name: CValue = switch (struct_ty.tag()) { |
| 5321 | .union_tagged, .union_safety_tagged => .{ .identifier = "payload" }, | 5340 | .union_tagged, .union_safety_tagged => .{ .identifier = "payload" }, |
| ... | @@ -5362,7 +5381,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5362,7 +5381,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5362 | try writer.writeAll(" = zig_wrap_"); | 5381 | try writer.writeAll(" = zig_wrap_"); |
| 5363 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty); | 5382 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty); |
| 5364 | try writer.writeAll("(("); | 5383 | try writer.writeAll("(("); |
| 5365 | try f.renderTypecast(writer, field_int_ty); | 5384 | try f.renderType(writer, field_int_ty); |
| 5366 | try writer.writeByte(')'); | 5385 | try writer.writeByte(')'); |
| 5367 | const cant_cast = int_info.bits > 64; | 5386 | const cant_cast = int_info.bits > 64; |
| 5368 | if (cant_cast) { | 5387 | if (cant_cast) { |
| ... | @@ -5389,7 +5408,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5389,7 +5408,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5389 | try writer.writeAll(", "); | 5408 | try writer.writeAll(", "); |
| 5390 | try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument); | 5409 | try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument); |
| 5391 | try writer.writeAll(", sizeof("); | 5410 | try writer.writeAll(", sizeof("); |
| 5392 | try f.renderTypecast(writer, inst_ty); | 5411 | try f.renderType(writer, inst_ty); |
| 5393 | try writer.writeAll("));\n"); | 5412 | try writer.writeAll("));\n"); |
| 5394 | try freeLocal(f, inst, temp_local.new_local, 0); | 5413 | try freeLocal(f, inst, temp_local.new_local, 0); |
| 5395 | return local; | 5414 | return local; |
| ... | @@ -5411,7 +5430,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5411,7 +5430,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5411 | try writer.writeAll(", &"); | 5430 | try writer.writeAll(", &"); |
| 5412 | try f.writeCValue(writer, operand_lval, .FunctionArgument); | 5431 | try f.writeCValue(writer, operand_lval, .FunctionArgument); |
| 5413 | try writer.writeAll(", sizeof("); | 5432 | try writer.writeAll(", sizeof("); |
| 5414 | try f.renderTypecast(writer, inst_ty); | 5433 | try f.renderType(writer, inst_ty); |
| 5415 | try writer.writeAll("));\n"); | 5434 | try writer.writeAll("));\n"); |
| 5416 | | 5435 | |
| 5417 | if (struct_byval == .constant) { | 5436 | if (struct_byval == .constant) { |
| ... | @@ -5442,7 +5461,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5442,7 +5461,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5442 | } else try f.writeCValueMember(writer, struct_byval, field_name); | 5461 | } else try f.writeCValueMember(writer, struct_byval, field_name); |
| 5443 | if (is_array) { | 5462 | if (is_array) { |
| 5444 | try writer.writeAll(", sizeof("); | 5463 | try writer.writeAll(", sizeof("); |
| 5445 | try f.renderTypecast(writer, inst_ty); | 5464 | try f.renderType(writer, inst_ty); |
| 5446 | try writer.writeAll("))"); | 5465 | try writer.writeAll("))"); |
| 5447 | } | 5466 | } |
| 5448 | try writer.writeAll(";\n"); | 5467 | try writer.writeAll(";\n"); |
| ... | @@ -5510,7 +5529,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu | ... | @@ -5510,7 +5529,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 5510 | const local = try f.allocLocal(inst, inst_ty); | 5529 | const local = try f.allocLocal(inst, inst_ty); |
| 5511 | try f.writeCValue(w, local, .Other); | 5530 | try f.writeCValue(w, local, .Other); |
| 5512 | try w.writeAll(" = ("); | 5531 | try w.writeAll(" = ("); |
| 5513 | try f.renderTypecast(w, inst_ty); | 5532 | try f.renderType(w, inst_ty); |
| 5514 | try w.writeByte(')'); | 5533 | try w.writeByte(')'); |
| 5515 | try f.writeCValue(w, operand, .Initializer); | 5534 | try f.writeCValue(w, operand, .Initializer); |
| 5516 | try w.writeAll(";\n"); | 5535 | try w.writeAll(";\n"); |
| ... | @@ -5571,7 +5590,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5571,7 +5590,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5571 | try writer.writeAll(", "); | 5590 | try writer.writeAll(", "); |
| 5572 | try f.writeCValue(writer, payload, .FunctionArgument); | 5591 | try f.writeCValue(writer, payload, .FunctionArgument); |
| 5573 | try writer.writeAll(", sizeof("); | 5592 | try writer.writeAll(", sizeof("); |
| 5574 | try f.renderTypecast(writer, payload_ty); | 5593 | try f.renderType(writer, payload_ty); |
| 5575 | try writer.writeAll("));\n"); | 5594 | try writer.writeAll("));\n"); |
| 5576 | } | 5595 | } |
| 5577 | return local; | 5596 | return local; |
| ... | @@ -5691,7 +5710,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5691,7 +5710,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5691 | try writer.writeAll(", "); | 5710 | try writer.writeAll(", "); |
| 5692 | try f.writeCValue(writer, payload, .FunctionArgument); | 5711 | try f.writeCValue(writer, payload, .FunctionArgument); |
| 5693 | try writer.writeAll(", sizeof("); | 5712 | try writer.writeAll(", sizeof("); |
| 5694 | try f.renderTypecast(writer, payload_ty); | 5713 | try f.renderType(writer, payload_ty); |
| 5695 | try writer.writeAll("));\n"); | 5714 | try writer.writeAll("));\n"); |
| 5696 | } | 5715 | } |
| 5697 | return local; | 5716 | return local; |
| ... | @@ -5837,7 +5856,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5837,7 +5856,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5837 | try f.writeCValue(writer, local, .Other); | 5856 | try f.writeCValue(writer, local, .Other); |
| 5838 | | 5857 | |
| 5839 | try writer.writeAll(" = ("); | 5858 | try writer.writeAll(" = ("); |
| 5840 | try f.renderTypecast(writer, inst_ty); | 5859 | try f.renderType(writer, inst_ty); |
| 5841 | try writer.writeByte(')'); | 5860 | try writer.writeByte(')'); |
| 5842 | try f.writeCValue(writer, operand, .Other); | 5861 | try f.writeCValue(writer, operand, .Other); |
| 5843 | try writer.writeAll(";\n"); | 5862 | try writer.writeAll(";\n"); |
| ... | @@ -5959,7 +5978,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -5959,7 +5978,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 5959 | try writer.writeAll(";\n"); | 5978 | try writer.writeAll(";\n"); |
| 5960 | try writer.writeAll("if ("); | 5979 | try writer.writeAll("if ("); |
| 5961 | try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor}); | 5980 | try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor}); |
| 5962 | try f.renderTypecast(writer, ptr_ty.childType()); | 5981 | try f.renderType(writer, ptr_ty.childType()); |
| 5963 | try writer.writeByte(')'); | 5982 | try writer.writeByte(')'); |
| 5964 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | 5983 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); |
| 5965 | try writer.writeAll(" *)"); | 5984 | try writer.writeAll(" *)"); |
| ... | @@ -5988,7 +6007,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -5988,7 +6007,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 5988 | try writer.writeAll(";\n"); | 6007 | try writer.writeAll(";\n"); |
| 5989 | try f.writeCValue(writer, local, .Other); | 6008 | try f.writeCValue(writer, local, .Other); |
| 5990 | try writer.print(".is_null = zig_cmpxchg_{s}((zig_atomic(", .{flavor}); | 6009 | try writer.print(".is_null = zig_cmpxchg_{s}((zig_atomic(", .{flavor}); |
| 5991 | try f.renderTypecast(writer, ptr_ty.childType()); | 6010 | try f.renderType(writer, ptr_ty.childType()); |
| 5992 | try writer.writeByte(')'); | 6011 | try writer.writeByte(')'); |
| 5993 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | 6012 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); |
| 5994 | try writer.writeAll(" *)"); | 6013 | try writer.writeAll(" *)"); |
| ... | @@ -6031,12 +6050,12 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6031,12 +6050,12 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6031 | switch (extra.op()) { | 6050 | switch (extra.op()) { |
| 6032 | else => { | 6051 | else => { |
| 6033 | try writer.writeAll("zig_atomic("); | 6052 | try writer.writeAll("zig_atomic("); |
| 6034 | try f.renderTypecast(writer, ptr_ty.elemType()); | 6053 | try f.renderType(writer, ptr_ty.elemType()); |
| 6035 | try writer.writeByte(')'); | 6054 | try writer.writeByte(')'); |
| 6036 | }, | 6055 | }, |
| 6037 | .Nand, .Min, .Max => { | 6056 | .Nand, .Min, .Max => { |
| 6038 | // These are missing from stdatomic.h, so no atomic types for now. | 6057 | // These are missing from stdatomic.h, so no atomic types for now. |
| 6039 | try f.renderTypecast(writer, ptr_ty.elemType()); | 6058 | try f.renderType(writer, ptr_ty.elemType()); |
| 6040 | }, | 6059 | }, |
| 6041 | } | 6060 | } |
| 6042 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | 6061 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); |
| ... | @@ -6073,7 +6092,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6073,7 +6092,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6073 | try f.writeCValue(writer, local, .Other); | 6092 | try f.writeCValue(writer, local, .Other); |
| 6074 | | 6093 | |
| 6075 | try writer.writeAll(" = zig_atomic_load((zig_atomic("); | 6094 | try writer.writeAll(" = zig_atomic_load((zig_atomic("); |
| 6076 | try f.renderTypecast(writer, ptr_ty.elemType()); | 6095 | try f.renderType(writer, ptr_ty.elemType()); |
| 6077 | try writer.writeByte(')'); | 6096 | try writer.writeByte(')'); |
| 6078 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | 6097 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); |
| 6079 | try writer.writeAll(" *)"); | 6098 | try writer.writeAll(" *)"); |
| ... | @@ -6096,7 +6115,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa | ... | @@ -6096,7 +6115,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa |
| 6096 | const writer = f.object.writer(); | 6115 | const writer = f.object.writer(); |
| 6097 | | 6116 | |
| 6098 | try writer.writeAll("zig_atomic_store((zig_atomic("); | 6117 | try writer.writeAll("zig_atomic_store((zig_atomic("); |
| 6099 | try f.renderTypecast(writer, ptr_ty.elemType()); | 6118 | try f.renderType(writer, ptr_ty.elemType()); |
| 6100 | try writer.writeByte(')'); | 6119 | try writer.writeByte(')'); |
| 6101 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | 6120 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); |
| 6102 | try writer.writeAll(" *)"); | 6121 | try writer.writeAll(" *)"); |
| ... | @@ -6138,7 +6157,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6138,7 +6157,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6138 | try writer.writeAll(" += "); | 6157 | try writer.writeAll(" += "); |
| 6139 | try f.object.dg.renderValue(writer, Type.usize, Value.one, .Other); | 6158 | try f.object.dg.renderValue(writer, Type.usize, Value.one, .Other); |
| 6140 | try writer.writeAll(") (("); | 6159 | try writer.writeAll(") (("); |
| 6141 | try f.renderTypecast(writer, u8_ptr_ty); | 6160 | try f.renderType(writer, u8_ptr_ty); |
| 6142 | try writer.writeByte(')'); | 6161 | try writer.writeByte(')'); |
| 6143 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); | 6162 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); |
| 6144 | try writer.writeAll(")["); | 6163 | try writer.writeAll(")["); |
| ... | @@ -6514,7 +6533,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6514,7 +6533,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6514 | .Auto, .Extern => { | 6533 | .Auto, .Extern => { |
| 6515 | try f.writeCValue(writer, local, .Other); | 6534 | try f.writeCValue(writer, local, .Other); |
| 6516 | try writer.writeAll(" = ("); | 6535 | try writer.writeAll(" = ("); |
| 6517 | try f.renderTypecast(writer, inst_ty); | 6536 | try f.renderType(writer, inst_ty); |
| 6518 | try writer.writeAll(")"); | 6537 | try writer.writeAll(")"); |
| 6519 | try writer.writeByte('{'); | 6538 | try writer.writeByte('{'); |
| 6520 | var empty = true; | 6539 | var empty = true; |
| ... | @@ -6557,7 +6576,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6557,7 +6576,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6557 | try writer.writeAll(", "); | 6576 | try writer.writeAll(", "); |
| 6558 | try f.writeCValue(writer, resolved_element, .FunctionArgument); | 6577 | try f.writeCValue(writer, resolved_element, .FunctionArgument); |
| 6559 | try writer.writeAll(", sizeof("); | 6578 | try writer.writeAll(", sizeof("); |
| 6560 | try f.renderTypecast(writer, element_ty); | 6579 | try f.renderType(writer, element_ty); |
| 6561 | try writer.writeAll("));\n"); | 6580 | try writer.writeAll("));\n"); |
| 6562 | } | 6581 | } |
| 6563 | }, | 6582 | }, |
| ... | @@ -6602,11 +6621,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6602,11 +6621,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6602 | try f.renderIntCast(writer, inst_ty, element, field_ty, .FunctionArgument); | 6621 | try f.renderIntCast(writer, inst_ty, element, field_ty, .FunctionArgument); |
| 6603 | } else { | 6622 | } else { |
| 6604 | try writer.writeByte('('); | 6623 | try writer.writeByte('('); |
| 6605 | try f.renderTypecast(writer, inst_ty); | 6624 | try f.renderType(writer, inst_ty); |
| 6606 | try writer.writeByte(')'); | 6625 | try writer.writeByte(')'); |
| 6607 | if (field_ty.isPtrAtRuntime()) { | 6626 | if (field_ty.isPtrAtRuntime()) { |
| 6608 | try writer.writeByte('('); | 6627 | try writer.writeByte('('); |
| 6609 | try f.renderTypecast(writer, switch (int_info.signedness) { | 6628 | try f.renderType(writer, switch (int_info.signedness) { |
| 6610 | .unsigned => Type.usize, | 6629 | .unsigned => Type.usize, |
| 6611 | .signed => Type.isize, | 6630 | .signed => Type.isize, |
| 6612 | }); | 6631 | }); |