| ... | ... | @@ -61,6 +61,11 @@ const FormatTypeAsCIdentContext = struct { |
| 61 | 61 | mod: *Module, |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | const ValueRenderLocation = enum { |
| 65 | FunctionArgument, |
| 66 | Other, |
| 67 | }; |
| 68 | |
| 64 | 69 | /// TODO make this not cut off at 128 bytes |
| 65 | 70 | fn formatTypeAsCIdentifier( |
| 66 | 71 | data: FormatTypeAsCIdentContext, |
| ... | ... | @@ -259,7 +264,7 @@ pub const Function = struct { |
| 259 | 264 | 0, |
| 260 | 265 | ); |
| 261 | 266 | try writer.writeAll(" = "); |
| 262 | | try f.object.dg.renderValue(writer, ty, val); |
| 267 | try f.object.dg.renderValue(writer, ty, val, .Other); |
| 263 | 268 | try writer.writeAll(";\n "); |
| 264 | 269 | return decl_c_value; |
| 265 | 270 | }, |
| ... | ... | @@ -298,7 +303,7 @@ pub const Function = struct { |
| 298 | 303 | .constant => |inst| { |
| 299 | 304 | const ty = f.air.typeOf(inst); |
| 300 | 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 | 308 | else => return f.object.dg.writeCValue(w, c_value), |
| 304 | 309 | } |
| ... | ... | @@ -310,7 +315,7 @@ pub const Function = struct { |
| 310 | 315 | const ty = f.air.typeOf(inst); |
| 311 | 316 | const val = f.air.value(inst).?; |
| 312 | 317 | try w.writeAll("(*"); |
| 313 | | try f.object.dg.renderValue(w, ty, val); |
| 318 | try f.object.dg.renderValue(w, ty, val, .Other); |
| 314 | 319 | return w.writeByte(')'); |
| 315 | 320 | }, |
| 316 | 321 | else => return f.object.dg.writeCValueDeref(w, c_value), |
| ... | ... | @@ -384,7 +389,7 @@ pub const DeclGen = struct { |
| 384 | 389 | try dg.renderTypecast(writer, ty); |
| 385 | 390 | try writer.writeAll("){"); |
| 386 | 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 | 393 | try writer.writeAll(", "); |
| 389 | 394 | try writer.print("{d}", .{val.sliceLen(dg.module)}); |
| 390 | 395 | try writer.writeAll("}"); |
| ... | ... | @@ -544,6 +549,7 @@ pub const DeclGen = struct { |
| 544 | 549 | writer: anytype, |
| 545 | 550 | ty: Type, |
| 546 | 551 | val: Value, |
| 552 | location: ValueRenderLocation, |
| 547 | 553 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 548 | 554 | const target = dg.module.getTarget(); |
| 549 | 555 | if (val.isUndefDeep()) { |
| ... | ... | @@ -636,9 +642,9 @@ pub const DeclGen = struct { |
| 636 | 642 | try writer.writeByte('('); |
| 637 | 643 | try dg.renderTypecast(writer, ty); |
| 638 | 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 | 646 | try writer.writeAll(", "); |
| 641 | | try dg.renderValue(writer, Type.usize, slice.len); |
| 647 | try dg.renderValue(writer, Type.usize, slice.len, location); |
| 642 | 648 | try writer.writeAll("}"); |
| 643 | 649 | }, |
| 644 | 650 | .function => { |
| ... | ... | @@ -670,7 +676,7 @@ pub const DeclGen = struct { |
| 670 | 676 | try writer.writeByte('{'); |
| 671 | 677 | const ai = ty.arrayInfo(); |
| 672 | 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 | 681 | try writer.writeByte('}'); |
| 676 | 682 | }, |
| ... | ... | @@ -680,17 +686,23 @@ pub const DeclGen = struct { |
| 680 | 686 | defer arena.deinit(); |
| 681 | 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 | 695 | try writer.writeByte('{'); |
| 684 | 696 | const ai = ty.arrayInfo(); |
| 685 | 697 | var index: usize = 0; |
| 686 | 698 | while (index < ai.len) : (index += 1) { |
| 687 | 699 | if (index != 0) try writer.writeAll(","); |
| 688 | 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 | 703 | if (ai.sentinel) |s| { |
| 692 | 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 | 707 | try writer.writeByte('}'); |
| 696 | 708 | }, |
| ... | ... | @@ -701,7 +713,7 @@ pub const DeclGen = struct { |
| 701 | 713 | var opt_buf: Type.Payload.ElemType = undefined; |
| 702 | 714 | const payload_type = ty.optionalChild(&opt_buf); |
| 703 | 715 | if (ty.isPtrLikeOptional()) { |
| 704 | | return dg.renderValue(writer, payload_type, val); |
| 716 | return dg.renderValue(writer, payload_type, val, location); |
| 705 | 717 | } |
| 706 | 718 | if (payload_type.abiSize(target) == 0) { |
| 707 | 719 | const is_null = val.castTag(.opt_payload) == null; |
| ... | ... | @@ -713,7 +725,7 @@ pub const DeclGen = struct { |
| 713 | 725 | if (val.castTag(.opt_payload)) |pl| { |
| 714 | 726 | const payload_val = pl.data; |
| 715 | 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 | 729 | try writer.writeAll(" }"); |
| 718 | 730 | } else { |
| 719 | 731 | try writer.writeAll(" .is_null = true }"); |
| ... | ... | @@ -740,7 +752,7 @@ pub const DeclGen = struct { |
| 740 | 752 | if (!payload_type.hasRuntimeBits()) { |
| 741 | 753 | // We use the error type directly as the type. |
| 742 | 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 | 758 | try writer.writeByte('('); |
| ... | ... | @@ -749,11 +761,11 @@ pub const DeclGen = struct { |
| 749 | 761 | if (val.castTag(.eu_payload)) |pl| { |
| 750 | 762 | const payload_val = pl.data; |
| 751 | 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 | 765 | try writer.writeAll(", .error = 0 }"); |
| 754 | 766 | } else { |
| 755 | 767 | try writer.writeAll(" .error = "); |
| 756 | | try dg.renderValue(writer, error_type, val); |
| 768 | try dg.renderValue(writer, error_type, val, location); |
| 757 | 769 | try writer.writeAll(" }"); |
| 758 | 770 | } |
| 759 | 771 | }, |
| ... | ... | @@ -767,7 +779,7 @@ pub const DeclGen = struct { |
| 767 | 779 | const enum_full = ty.cast(Type.Payload.EnumFull).?.data; |
| 768 | 780 | if (enum_full.values.count() != 0) { |
| 769 | 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 | 783 | } else { |
| 772 | 784 | return writer.print("{d}", .{field_index}); |
| 773 | 785 | } |
| ... | ... | @@ -776,7 +788,7 @@ pub const DeclGen = struct { |
| 776 | 788 | const enum_obj = ty.castTag(.enum_numbered).?.data; |
| 777 | 789 | if (enum_obj.values.count() != 0) { |
| 778 | 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 | 792 | } else { |
| 781 | 793 | return writer.print("{d}", .{field_index}); |
| 782 | 794 | } |
| ... | ... | @@ -787,7 +799,7 @@ pub const DeclGen = struct { |
| 787 | 799 | else => { |
| 788 | 800 | var int_tag_ty_buffer: Type.Payload.Bits = undefined; |
| 789 | 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 | 826 | if (!field_ty.hasRuntimeBits()) continue; |
| 815 | 827 | |
| 816 | 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 | 832 | try writer.writeAll("}"); |
| ... | ... | @@ -831,7 +843,7 @@ pub const DeclGen = struct { |
| 831 | 843 | if (ty.unionTagType()) |tag_ty| { |
| 832 | 844 | if (layout.tag_size != 0) { |
| 833 | 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 | 847 | try writer.writeAll(", "); |
| 836 | 848 | } |
| 837 | 849 | try writer.writeAll(".payload = {"); |
| ... | ... | @@ -842,7 +854,7 @@ pub const DeclGen = struct { |
| 842 | 854 | const field_name = ty.unionFields().keys()[index]; |
| 843 | 855 | if (field_ty.hasRuntimeBits()) { |
| 844 | 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 | 859 | if (ty.unionTagType()) |_| { |
| 848 | 860 | try writer.writeAll("}"); |
| ... | ... | @@ -988,7 +1000,7 @@ pub const DeclGen = struct { |
| 988 | 1000 | } |
| 989 | 1001 | if (ptr_sentinel) |s| { |
| 990 | 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 | 1005 | try bw.writeAll(";\n"); |
| 994 | 1006 | |
| ... | ... | @@ -1629,7 +1641,7 @@ pub fn genDecl(o: *Object) !void { |
| 1629 | 1641 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align"); |
| 1630 | 1642 | try w.writeAll(" = "); |
| 1631 | 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 | 1646 | try w.writeAll(";"); |
| 1635 | 1647 | try o.indent_writer.insertNewline(); |
| ... | ... | @@ -1644,7 +1656,7 @@ pub fn genDecl(o: *Object) !void { |
| 1644 | 1656 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align"); |
| 1645 | 1657 | |
| 1646 | 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 | 1660 | try writer.writeAll(";\n"); |
| 1649 | 1661 | } |
| 1650 | 1662 | } |
| ... | ... | @@ -2748,7 +2760,7 @@ fn airCall( |
| 2748 | 2760 | try writer.writeAll(", "); |
| 2749 | 2761 | } |
| 2750 | 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 | 2764 | } else { |
| 2753 | 2765 | const val = try f.resolveInst(arg); |
| 2754 | 2766 | try f.writeCValue(writer, val); |
| ... | ... | @@ -2964,7 +2976,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2964 | 2976 | for (items) |item| { |
| 2965 | 2977 | try f.object.indent_writer.insertNewline(); |
| 2966 | 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 | 2980 | try writer.writeAll(": "); |
| 2969 | 2981 | } |
| 2970 | 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 | 3426 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3415 | 3427 | try f.writeCValueDeref(writer, operand); |
| 3416 | 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 | 3430 | try writer.writeAll(";\n "); |
| 3419 | 3431 | |
| 3420 | 3432 | return operand; |
| 3421 | 3433 | } |
| 3422 | 3434 | try f.writeCValueDeref(writer, operand); |
| 3423 | 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 | 3437 | try writer.writeAll(";\n"); |
| 3426 | 3438 | |
| 3427 | 3439 | // Then return the payload pointer (only if it is used) |