| ... | @@ -61,6 +61,11 @@ const FormatTypeAsCIdentContext = struct { | ... | @@ -61,6 +61,11 @@ const FormatTypeAsCIdentContext = struct { |
| 61 | mod: *Module, | 61 | mod: *Module, |
| 62 | }; | 62 | }; |
| 63 | | 63 | |
| | 64 | const ValueRenderLocation = enum { |
| | 65 | FunctionArgument, |
| | 66 | Other, |
| | 67 | }; |
| | 68 | |
| 64 | /// TODO make this not cut off at 128 bytes | 69 | /// TODO make this not cut off at 128 bytes |
| 65 | fn formatTypeAsCIdentifier( | 70 | fn formatTypeAsCIdentifier( |
| 66 | data: FormatTypeAsCIdentContext, | 71 | data: FormatTypeAsCIdentContext, |
| ... | @@ -259,7 +264,7 @@ pub const Function = struct { | ... | @@ -259,7 +264,7 @@ pub const Function = struct { |
| 259 | 0, | 264 | 0, |
| 260 | ); | 265 | ); |
| 261 | try writer.writeAll(" = "); | 266 | try writer.writeAll(" = "); |
| 262 | try f.object.dg.renderValue(writer, ty, val); | 267 | try f.object.dg.renderValue(writer, ty, val, .Other); |
| 263 | try writer.writeAll(";\n "); | 268 | try writer.writeAll(";\n "); |
| 264 | return decl_c_value; | 269 | return decl_c_value; |
| 265 | }, | 270 | }, |
| ... | @@ -298,7 +303,7 @@ pub const Function = struct { | ... | @@ -298,7 +303,7 @@ pub const Function = struct { |
| 298 | .constant => |inst| { | 303 | .constant => |inst| { |
| 299 | const ty = f.air.typeOf(inst); | 304 | const ty = f.air.typeOf(inst); |
| 300 | const val = f.air.value(inst).?; | 305 | const val = f.air.value(inst).?; |
| 301 | return f.object.dg.renderValue(w, ty, val); | 306 | return f.object.dg.renderValue(w, ty, val, .Other); |
| 302 | }, | 307 | }, |
| 303 | else => return f.object.dg.writeCValue(w, c_value), | 308 | else => return f.object.dg.writeCValue(w, c_value), |
| 304 | } | 309 | } |
| ... | @@ -310,7 +315,7 @@ pub const Function = struct { | ... | @@ -310,7 +315,7 @@ pub const Function = struct { |
| 310 | const ty = f.air.typeOf(inst); | 315 | const ty = f.air.typeOf(inst); |
| 311 | const val = f.air.value(inst).?; | 316 | const val = f.air.value(inst).?; |
| 312 | try w.writeAll("(*"); | 317 | try w.writeAll("(*"); |
| 313 | try f.object.dg.renderValue(w, ty, val); | 318 | try f.object.dg.renderValue(w, ty, val, .Other); |
| 314 | return w.writeByte(')'); | 319 | return w.writeByte(')'); |
| 315 | }, | 320 | }, |
| 316 | else => return f.object.dg.writeCValueDeref(w, c_value), | 321 | else => return f.object.dg.writeCValueDeref(w, c_value), |
| ... | @@ -384,7 +389,7 @@ pub const DeclGen = struct { | ... | @@ -384,7 +389,7 @@ pub const DeclGen = struct { |
| 384 | try dg.renderTypecast(writer, ty); | 389 | try dg.renderTypecast(writer, ty); |
| 385 | try writer.writeAll("){"); | 390 | try writer.writeAll("){"); |
| 386 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 391 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 387 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr()); | 392 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other); |
| 388 | try writer.writeAll(", "); | 393 | try writer.writeAll(", "); |
| 389 | try writer.print("{d}", .{val.sliceLen(dg.module)}); | 394 | try writer.print("{d}", .{val.sliceLen(dg.module)}); |
| 390 | try writer.writeAll("}"); | 395 | try writer.writeAll("}"); |
| ... | @@ -544,6 +549,7 @@ pub const DeclGen = struct { | ... | @@ -544,6 +549,7 @@ pub const DeclGen = struct { |
| 544 | writer: anytype, | 549 | writer: anytype, |
| 545 | ty: Type, | 550 | ty: Type, |
| 546 | val: Value, | 551 | val: Value, |
| | 552 | location: ValueRenderLocation, |
| 547 | ) error{ OutOfMemory, AnalysisFail }!void { | 553 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 548 | const target = dg.module.getTarget(); | 554 | const target = dg.module.getTarget(); |
| 549 | if (val.isUndefDeep()) { | 555 | if (val.isUndefDeep()) { |
| ... | @@ -636,9 +642,9 @@ pub const DeclGen = struct { | ... | @@ -636,9 +642,9 @@ pub const DeclGen = struct { |
| 636 | try writer.writeByte('('); | 642 | try writer.writeByte('('); |
| 637 | try dg.renderTypecast(writer, ty); | 643 | try dg.renderTypecast(writer, ty); |
| 638 | try writer.writeAll("){"); | 644 | try writer.writeAll("){"); |
| 639 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr); | 645 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location); |
| 640 | try writer.writeAll(", "); | 646 | try writer.writeAll(", "); |
| 641 | try dg.renderValue(writer, Type.usize, slice.len); | 647 | try dg.renderValue(writer, Type.usize, slice.len, location); |
| 642 | try writer.writeAll("}"); | 648 | try writer.writeAll("}"); |
| 643 | }, | 649 | }, |
| 644 | .function => { | 650 | .function => { |
| ... | @@ -670,7 +676,7 @@ pub const DeclGen = struct { | ... | @@ -670,7 +676,7 @@ pub const DeclGen = struct { |
| 670 | try writer.writeByte('{'); | 676 | try writer.writeByte('{'); |
| 671 | const ai = ty.arrayInfo(); | 677 | const ai = ty.arrayInfo(); |
| 672 | if (ai.sentinel) |s| { | 678 | if (ai.sentinel) |s| { |
| 673 | try dg.renderValue(writer, ai.elem_type, s); | 679 | try dg.renderValue(writer, ai.elem_type, s, location); |
| 674 | } | 680 | } |
| 675 | try writer.writeByte('}'); | 681 | try writer.writeByte('}'); |
| 676 | }, | 682 | }, |
| ... | @@ -680,17 +686,23 @@ pub const DeclGen = struct { | ... | @@ -680,17 +686,23 @@ pub const DeclGen = struct { |
| 680 | defer arena.deinit(); | 686 | defer arena.deinit(); |
| 681 | const arena_allocator = arena.allocator(); | 687 | const arena_allocator = arena.allocator(); |
| 682 | | 688 | |
| | 689 | if (location == .FunctionArgument) { |
| | 690 | try writer.writeByte('('); |
| | 691 | try dg.renderTypecast(writer, ty); |
| | 692 | try writer.writeByte(')'); |
| | 693 | } |
| | 694 | |
| 683 | try writer.writeByte('{'); | 695 | try writer.writeByte('{'); |
| 684 | const ai = ty.arrayInfo(); | 696 | const ai = ty.arrayInfo(); |
| 685 | var index: usize = 0; | 697 | var index: usize = 0; |
| 686 | while (index < ai.len) : (index += 1) { | 698 | while (index < ai.len) : (index += 1) { |
| 687 | if (index != 0) try writer.writeAll(","); | 699 | if (index != 0) try writer.writeAll(","); |
| 688 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); | 700 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); |
| 689 | try dg.renderValue(writer, ai.elem_type, elem_val); | 701 | try dg.renderValue(writer, ai.elem_type, elem_val, .Other); |
| 690 | } | 702 | } |
| 691 | if (ai.sentinel) |s| { | 703 | if (ai.sentinel) |s| { |
| 692 | if (index != 0) try writer.writeAll(","); | 704 | if (index != 0) try writer.writeAll(","); |
| 693 | try dg.renderValue(writer, ai.elem_type, s); | 705 | try dg.renderValue(writer, ai.elem_type, s, .Other); |
| 694 | } | 706 | } |
| 695 | try writer.writeByte('}'); | 707 | try writer.writeByte('}'); |
| 696 | }, | 708 | }, |
| ... | @@ -701,7 +713,7 @@ pub const DeclGen = struct { | ... | @@ -701,7 +713,7 @@ pub const DeclGen = struct { |
| 701 | var opt_buf: Type.Payload.ElemType = undefined; | 713 | var opt_buf: Type.Payload.ElemType = undefined; |
| 702 | const payload_type = ty.optionalChild(&opt_buf); | 714 | const payload_type = ty.optionalChild(&opt_buf); |
| 703 | if (ty.isPtrLikeOptional()) { | 715 | if (ty.isPtrLikeOptional()) { |
| 704 | return dg.renderValue(writer, payload_type, val); | 716 | return dg.renderValue(writer, payload_type, val, location); |
| 705 | } | 717 | } |
| 706 | if (payload_type.abiSize(target) == 0) { | 718 | if (payload_type.abiSize(target) == 0) { |
| 707 | const is_null = val.castTag(.opt_payload) == null; | 719 | const is_null = val.castTag(.opt_payload) == null; |
| ... | @@ -713,7 +725,7 @@ pub const DeclGen = struct { | ... | @@ -713,7 +725,7 @@ pub const DeclGen = struct { |
| 713 | if (val.castTag(.opt_payload)) |pl| { | 725 | if (val.castTag(.opt_payload)) |pl| { |
| 714 | const payload_val = pl.data; | 726 | const payload_val = pl.data; |
| 715 | try writer.writeAll(" .is_null = false, .payload = "); | 727 | try writer.writeAll(" .is_null = false, .payload = "); |
| 716 | try dg.renderValue(writer, payload_type, payload_val); | 728 | try dg.renderValue(writer, payload_type, payload_val, location); |
| 717 | try writer.writeAll(" }"); | 729 | try writer.writeAll(" }"); |
| 718 | } else { | 730 | } else { |
| 719 | try writer.writeAll(" .is_null = true }"); | 731 | try writer.writeAll(" .is_null = true }"); |
| ... | @@ -740,7 +752,7 @@ pub const DeclGen = struct { | ... | @@ -740,7 +752,7 @@ pub const DeclGen = struct { |
| 740 | if (!payload_type.hasRuntimeBits()) { | 752 | if (!payload_type.hasRuntimeBits()) { |
| 741 | // We use the error type directly as the type. | 753 | // We use the error type directly as the type. |
| 742 | const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; | 754 | const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; |
| 743 | return dg.renderValue(writer, error_type, err_val); | 755 | return dg.renderValue(writer, error_type, err_val, location); |
| 744 | } | 756 | } |
| 745 | | 757 | |
| 746 | try writer.writeByte('('); | 758 | try writer.writeByte('('); |
| ... | @@ -749,11 +761,11 @@ pub const DeclGen = struct { | ... | @@ -749,11 +761,11 @@ pub const DeclGen = struct { |
| 749 | if (val.castTag(.eu_payload)) |pl| { | 761 | if (val.castTag(.eu_payload)) |pl| { |
| 750 | const payload_val = pl.data; | 762 | const payload_val = pl.data; |
| 751 | try writer.writeAll(" .payload = "); | 763 | try writer.writeAll(" .payload = "); |
| 752 | try dg.renderValue(writer, payload_type, payload_val); | 764 | try dg.renderValue(writer, payload_type, payload_val, location); |
| 753 | try writer.writeAll(", .error = 0 }"); | 765 | try writer.writeAll(", .error = 0 }"); |
| 754 | } else { | 766 | } else { |
| 755 | try writer.writeAll(" .error = "); | 767 | try writer.writeAll(" .error = "); |
| 756 | try dg.renderValue(writer, error_type, val); | 768 | try dg.renderValue(writer, error_type, val, location); |
| 757 | try writer.writeAll(" }"); | 769 | try writer.writeAll(" }"); |
| 758 | } | 770 | } |
| 759 | }, | 771 | }, |
| ... | @@ -767,7 +779,7 @@ pub const DeclGen = struct { | ... | @@ -767,7 +779,7 @@ pub const DeclGen = struct { |
| 767 | const enum_full = ty.cast(Type.Payload.EnumFull).?.data; | 779 | const enum_full = ty.cast(Type.Payload.EnumFull).?.data; |
| 768 | if (enum_full.values.count() != 0) { | 780 | if (enum_full.values.count() != 0) { |
| 769 | const tag_val = enum_full.values.keys()[field_index]; | 781 | const tag_val = enum_full.values.keys()[field_index]; |
| 770 | return dg.renderValue(writer, enum_full.tag_ty, tag_val); | 782 | return dg.renderValue(writer, enum_full.tag_ty, tag_val, location); |
| 771 | } else { | 783 | } else { |
| 772 | return writer.print("{d}", .{field_index}); | 784 | return writer.print("{d}", .{field_index}); |
| 773 | } | 785 | } |
| ... | @@ -776,7 +788,7 @@ pub const DeclGen = struct { | ... | @@ -776,7 +788,7 @@ pub const DeclGen = struct { |
| 776 | const enum_obj = ty.castTag(.enum_numbered).?.data; | 788 | const enum_obj = ty.castTag(.enum_numbered).?.data; |
| 777 | if (enum_obj.values.count() != 0) { | 789 | if (enum_obj.values.count() != 0) { |
| 778 | const tag_val = enum_obj.values.keys()[field_index]; | 790 | const tag_val = enum_obj.values.keys()[field_index]; |
| 779 | return dg.renderValue(writer, enum_obj.tag_ty, tag_val); | 791 | return dg.renderValue(writer, enum_obj.tag_ty, tag_val, location); |
| 780 | } else { | 792 | } else { |
| 781 | return writer.print("{d}", .{field_index}); | 793 | return writer.print("{d}", .{field_index}); |
| 782 | } | 794 | } |
| ... | @@ -787,7 +799,7 @@ pub const DeclGen = struct { | ... | @@ -787,7 +799,7 @@ pub const DeclGen = struct { |
| 787 | else => { | 799 | else => { |
| 788 | var int_tag_ty_buffer: Type.Payload.Bits = undefined; | 800 | var int_tag_ty_buffer: Type.Payload.Bits = undefined; |
| 789 | const int_tag_ty = ty.intTagType(&int_tag_ty_buffer); | 801 | const int_tag_ty = ty.intTagType(&int_tag_ty_buffer); |
| 790 | return dg.renderValue(writer, int_tag_ty, val); | 802 | return dg.renderValue(writer, int_tag_ty, val, location); |
| 791 | }, | 803 | }, |
| 792 | } | 804 | } |
| 793 | }, | 805 | }, |
| ... | @@ -814,7 +826,7 @@ pub const DeclGen = struct { | ... | @@ -814,7 +826,7 @@ pub const DeclGen = struct { |
| 814 | if (!field_ty.hasRuntimeBits()) continue; | 826 | if (!field_ty.hasRuntimeBits()) continue; |
| 815 | | 827 | |
| 816 | if (i != 0) try writer.writeAll(","); | 828 | if (i != 0) try writer.writeAll(","); |
| 817 | try dg.renderValue(writer, field_ty, field_val); | 829 | try dg.renderValue(writer, field_ty, field_val, location); |
| 818 | } | 830 | } |
| 819 | | 831 | |
| 820 | try writer.writeAll("}"); | 832 | try writer.writeAll("}"); |
| ... | @@ -831,7 +843,7 @@ pub const DeclGen = struct { | ... | @@ -831,7 +843,7 @@ pub const DeclGen = struct { |
| 831 | if (ty.unionTagType()) |tag_ty| { | 843 | if (ty.unionTagType()) |tag_ty| { |
| 832 | if (layout.tag_size != 0) { | 844 | if (layout.tag_size != 0) { |
| 833 | try writer.writeAll(".tag = "); | 845 | try writer.writeAll(".tag = "); |
| 834 | try dg.renderValue(writer, tag_ty, union_obj.tag); | 846 | try dg.renderValue(writer, tag_ty, union_obj.tag, location); |
| 835 | try writer.writeAll(", "); | 847 | try writer.writeAll(", "); |
| 836 | } | 848 | } |
| 837 | try writer.writeAll(".payload = {"); | 849 | try writer.writeAll(".payload = {"); |
| ... | @@ -842,7 +854,7 @@ pub const DeclGen = struct { | ... | @@ -842,7 +854,7 @@ pub const DeclGen = struct { |
| 842 | const field_name = ty.unionFields().keys()[index]; | 854 | const field_name = ty.unionFields().keys()[index]; |
| 843 | if (field_ty.hasRuntimeBits()) { | 855 | if (field_ty.hasRuntimeBits()) { |
| 844 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); | 856 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); |
| 845 | try dg.renderValue(writer, field_ty, union_obj.val); | 857 | try dg.renderValue(writer, field_ty, union_obj.val, location); |
| 846 | } | 858 | } |
| 847 | if (ty.unionTagType()) |_| { | 859 | if (ty.unionTagType()) |_| { |
| 848 | try writer.writeAll("}"); | 860 | try writer.writeAll("}"); |
| ... | @@ -988,7 +1000,7 @@ pub const DeclGen = struct { | ... | @@ -988,7 +1000,7 @@ pub const DeclGen = struct { |
| 988 | } | 1000 | } |
| 989 | if (ptr_sentinel) |s| { | 1001 | if (ptr_sentinel) |s| { |
| 990 | try bw.writeAll("_s_"); | 1002 | try bw.writeAll("_s_"); |
| 991 | try dg.renderValue(bw, child_type, s); | 1003 | try dg.renderValue(bw, child_type, s, .Other); |
| 992 | } | 1004 | } |
| 993 | try bw.writeAll(";\n"); | 1005 | try bw.writeAll(";\n"); |
| 994 | | 1006 | |
| ... | @@ -1629,7 +1641,7 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -1629,7 +1641,7 @@ pub fn genDecl(o: *Object) !void { |
| 1629 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align"); | 1641 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align"); |
| 1630 | try w.writeAll(" = "); | 1642 | try w.writeAll(" = "); |
| 1631 | if (variable.init.tag() != .unreachable_value) { | 1643 | if (variable.init.tag() != .unreachable_value) { |
| 1632 | try o.dg.renderValue(w, tv.ty, variable.init); | 1644 | try o.dg.renderValue(w, tv.ty, variable.init, .Other); |
| 1633 | } | 1645 | } |
| 1634 | try w.writeAll(";"); | 1646 | try w.writeAll(";"); |
| 1635 | try o.indent_writer.insertNewline(); | 1647 | try o.indent_writer.insertNewline(); |
| ... | @@ -1644,7 +1656,7 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -1644,7 +1656,7 @@ pub fn genDecl(o: *Object) !void { |
| 1644 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align"); | 1656 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align"); |
| 1645 | | 1657 | |
| 1646 | try writer.writeAll(" = "); | 1658 | try writer.writeAll(" = "); |
| 1647 | try o.dg.renderValue(writer, tv.ty, tv.val); | 1659 | try o.dg.renderValue(writer, tv.ty, tv.val, .Other); |
| 1648 | try writer.writeAll(";\n"); | 1660 | try writer.writeAll(";\n"); |
| 1649 | } | 1661 | } |
| 1650 | } | 1662 | } |
| ... | @@ -2748,7 +2760,7 @@ fn airCall( | ... | @@ -2748,7 +2760,7 @@ fn airCall( |
| 2748 | try writer.writeAll(", "); | 2760 | try writer.writeAll(", "); |
| 2749 | } | 2761 | } |
| 2750 | if (f.air.value(arg)) |val| { | 2762 | if (f.air.value(arg)) |val| { |
| 2751 | try f.object.dg.renderValue(writer, f.air.typeOf(arg), val); | 2763 | try f.object.dg.renderValue(writer, f.air.typeOf(arg), val, .FunctionArgument); |
| 2752 | } else { | 2764 | } else { |
| 2753 | const val = try f.resolveInst(arg); | 2765 | const val = try f.resolveInst(arg); |
| 2754 | try f.writeCValue(writer, val); | 2766 | try f.writeCValue(writer, val); |
| ... | @@ -2964,7 +2976,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2964,7 +2976,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2964 | for (items) |item| { | 2976 | for (items) |item| { |
| 2965 | try f.object.indent_writer.insertNewline(); | 2977 | try f.object.indent_writer.insertNewline(); |
| 2966 | try writer.writeAll("case "); | 2978 | try writer.writeAll("case "); |
| 2967 | try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?); | 2979 | try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other); |
| 2968 | try writer.writeAll(": "); | 2980 | try writer.writeAll(": "); |
| 2969 | } | 2981 | } |
| 2970 | // The case body must be noreturn so we don't need to insert a break. | 2982 | // The case body must be noreturn so we don't need to insert a break. |
| ... | @@ -3414,14 +3426,14 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3414,14 +3426,14 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3414 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 3426 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3415 | try f.writeCValueDeref(writer, operand); | 3427 | try f.writeCValueDeref(writer, operand); |
| 3416 | try writer.writeAll(" = "); | 3428 | try writer.writeAll(" = "); |
| 3417 | try f.object.dg.renderValue(writer, error_ty, Value.zero); | 3429 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); |
| 3418 | try writer.writeAll(";\n "); | 3430 | try writer.writeAll(";\n "); |
| 3419 | | 3431 | |
| 3420 | return operand; | 3432 | return operand; |
| 3421 | } | 3433 | } |
| 3422 | try f.writeCValueDeref(writer, operand); | 3434 | try f.writeCValueDeref(writer, operand); |
| 3423 | try writer.writeAll(".error = "); | 3435 | try writer.writeAll(".error = "); |
| 3424 | try f.object.dg.renderValue(writer, error_ty, Value.zero); | 3436 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); |
| 3425 | try writer.writeAll(";\n"); | 3437 | try writer.writeAll(";\n"); |
| 3426 | | 3438 | |
| 3427 | // Then return the payload pointer (only if it is used) | 3439 | // Then return the payload pointer (only if it is used) |