| ... | ... | @@ -110,15 +110,28 @@ pub const String = enum(u32) { |
| 110 | 110 | const quote_behavior = data.quote_behavior orelse return w.writeAll(string_slice); |
| 111 | 111 | return printEscapedString(string_slice, quote_behavior, w); |
| 112 | 112 | } |
| 113 | | pub fn fmt( |
| 114 | | self: String, |
| 115 | | builder: *const Builder, |
| 116 | | quote_behavior: ?QuoteBehavior, |
| 117 | | ) std.fmt.Formatter(FormatData, format) { |
| 113 | |
| 114 | pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(FormatData, format) { |
| 118 | 115 | return .{ .data = .{ |
| 119 | 116 | .string = self, |
| 120 | 117 | .builder = builder, |
| 121 | | .quote_behavior = quote_behavior, |
| 118 | .quote_behavior = .quote_unless_valid_identifier, |
| 119 | } }; |
| 120 | } |
| 121 | |
| 122 | pub fn fmtQ(self: String, builder: *const Builder) std.fmt.Formatter(FormatData, format) { |
| 123 | return .{ .data = .{ |
| 124 | .string = self, |
| 125 | .builder = builder, |
| 126 | .quote_behavior = .always_quote, |
| 127 | } }; |
| 128 | } |
| 129 | |
| 130 | pub fn fmtRaw(self: String, builder: *const Builder) std.fmt.Formatter(FormatData, format) { |
| 131 | return .{ .data = .{ |
| 132 | .string = self, |
| 133 | .builder = builder, |
| 134 | .quote_behavior = null, |
| 122 | 135 | } }; |
| 123 | 136 | } |
| 124 | 137 | |
| ... | ... | @@ -684,8 +697,8 @@ pub const Type = enum(u32) { |
| 684 | 697 | .function, .vararg_function => |kind| { |
| 685 | 698 | var extra = data.builder.typeExtraDataTrail(Type.Function, item.data); |
| 686 | 699 | const params = extra.trail.next(extra.data.params_len, Type, data.builder); |
| 687 | | try w.print("f_{fm}", .{extra.data.ret.fmt(data.builder)}); |
| 688 | | for (params) |param| try w.print("{fm}", .{param.fmt(data.builder)}); |
| 700 | try w.print("f_{f}", .{extra.data.ret.fmt(data.builder, .m)}); |
| 701 | for (params) |param| try w.print("{f}", .{param.fmt(data.builder, .m)}); |
| 689 | 702 | switch (kind) { |
| 690 | 703 | .function => {}, |
| 691 | 704 | .vararg_function => try w.writeAll("vararg"), |
| ... | ... | @@ -700,20 +713,20 @@ pub const Type = enum(u32) { |
| 700 | 713 | const types = extra.trail.next(extra.data.types_len, Type, data.builder); |
| 701 | 714 | const ints = extra.trail.next(extra.data.ints_len, u32, data.builder); |
| 702 | 715 | try w.print("t{s}", .{extra.data.name.slice(data.builder).?}); |
| 703 | | for (types) |ty| try w.print("_{fm}", .{ty.fmt(data.builder)}); |
| 716 | for (types) |ty| try w.print("_{f}", .{ty.fmt(data.builder, .m)}); |
| 704 | 717 | for (ints) |int| try w.print("_{d}", .{int}); |
| 705 | 718 | try w.writeByte('t'); |
| 706 | 719 | }, |
| 707 | 720 | .vector, .scalable_vector => |kind| { |
| 708 | 721 | const extra = data.builder.typeExtraData(Type.Vector, item.data); |
| 709 | | try w.print("{s}v{d}{fm}", .{ |
| 722 | try w.print("{s}v{d}{f}", .{ |
| 710 | 723 | switch (kind) { |
| 711 | 724 | .vector => "", |
| 712 | 725 | .scalable_vector => "nx", |
| 713 | 726 | else => unreachable, |
| 714 | 727 | }, |
| 715 | 728 | extra.len, |
| 716 | | extra.child.fmt(data.builder), |
| 729 | extra.child.fmt(data.builder, .m), |
| 717 | 730 | }); |
| 718 | 731 | }, |
| 719 | 732 | inline .small_array, .array => |kind| { |
| ... | ... | @@ -722,13 +735,13 @@ pub const Type = enum(u32) { |
| 722 | 735 | .array => Type.Array, |
| 723 | 736 | else => unreachable, |
| 724 | 737 | }, item.data); |
| 725 | | try w.print("a{d}{fm}", .{ extra.length(), extra.child.fmt(data.builder) }); |
| 738 | try w.print("a{d}{f}", .{ extra.length(), extra.child.fmt(data.builder, .m) }); |
| 726 | 739 | }, |
| 727 | 740 | .structure, .packed_structure => { |
| 728 | 741 | var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data); |
| 729 | 742 | const fields = extra.trail.next(extra.data.fields_len, Type, data.builder); |
| 730 | 743 | try w.writeAll("sl_"); |
| 731 | | for (fields) |field| try w.print("{fm}", .{field.fmt(data.builder)}); |
| 744 | for (fields) |field| try w.print("{f}", .{field.fmt(data.builder, .m)}); |
| 732 | 745 | try w.writeByte('s'); |
| 733 | 746 | }, |
| 734 | 747 | .named_structure => { |
| ... | ... | @@ -747,12 +760,12 @@ pub const Type = enum(u32) { |
| 747 | 760 | var extra = data.builder.typeExtraDataTrail(Type.Function, item.data); |
| 748 | 761 | const params = extra.trail.next(extra.data.params_len, Type, data.builder); |
| 749 | 762 | if (data.mode != .gt) |
| 750 | | try w.print("{f%} ", .{extra.data.ret.fmt(data.builder)}); |
| 763 | try w.print("{f} ", .{extra.data.ret.fmt(data.builder, .percent)}); |
| 751 | 764 | if (data.mode != .lt) { |
| 752 | 765 | try w.writeByte('('); |
| 753 | 766 | for (params, 0..) |param, index| { |
| 754 | 767 | if (index > 0) try w.writeAll(", "); |
| 755 | | try w.print("{f%}", .{param.fmt(data.builder)}); |
| 768 | try w.print("{f}", .{param.fmt(data.builder, .percent)}); |
| 756 | 769 | } |
| 757 | 770 | switch (kind) { |
| 758 | 771 | .function => {}, |
| ... | ... | @@ -772,22 +785,22 @@ pub const Type = enum(u32) { |
| 772 | 785 | const types = extra.trail.next(extra.data.types_len, Type, data.builder); |
| 773 | 786 | const ints = extra.trail.next(extra.data.ints_len, u32, data.builder); |
| 774 | 787 | try w.print( |
| 775 | | \\target({f"} |
| 776 | | , .{extra.data.name.fmt(data.builder)}); |
| 777 | | for (types) |ty| try w.print(", {f%}", .{ty.fmt(data.builder)}); |
| 788 | \\target({f} |
| 789 | , .{extra.data.name.fmtQ(data.builder)}); |
| 790 | for (types) |ty| try w.print(", {f}", .{ty.fmt(data.builder, .percent)}); |
| 778 | 791 | for (ints) |int| try w.print(", {d}", .{int}); |
| 779 | 792 | try w.writeByte(')'); |
| 780 | 793 | }, |
| 781 | 794 | .vector, .scalable_vector => |kind| { |
| 782 | 795 | const extra = data.builder.typeExtraData(Type.Vector, item.data); |
| 783 | | try w.print("<{s}{d} x {f%}>", .{ |
| 796 | try w.print("<{s}{d} x {f}>", .{ |
| 784 | 797 | switch (kind) { |
| 785 | 798 | .vector => "", |
| 786 | 799 | .scalable_vector => "vscale x ", |
| 787 | 800 | else => unreachable, |
| 788 | 801 | }, |
| 789 | 802 | extra.len, |
| 790 | | extra.child.fmt(data.builder), |
| 803 | extra.child.fmt(data.builder, .percent), |
| 791 | 804 | }); |
| 792 | 805 | }, |
| 793 | 806 | inline .small_array, .array => |kind| { |
| ... | ... | @@ -796,7 +809,7 @@ pub const Type = enum(u32) { |
| 796 | 809 | .array => Type.Array, |
| 797 | 810 | else => unreachable, |
| 798 | 811 | }, item.data); |
| 799 | | try w.print("[{d} x {f%}]", .{ extra.length(), extra.child.fmt(data.builder) }); |
| 812 | try w.print("[{d} x {f}]", .{ extra.length(), extra.child.fmt(data.builder, .percent) }); |
| 800 | 813 | }, |
| 801 | 814 | .structure, .packed_structure => |kind| { |
| 802 | 815 | var extra = data.builder.typeExtraDataTrail(Type.Structure, item.data); |
| ... | ... | @@ -809,7 +822,7 @@ pub const Type = enum(u32) { |
| 809 | 822 | try w.writeAll("{ "); |
| 810 | 823 | for (fields, 0..) |field, index| { |
| 811 | 824 | if (index > 0) try w.writeAll(", "); |
| 812 | | try w.print("{f%}", .{field.fmt(data.builder)}); |
| 825 | try w.print("{f}", .{field.fmt(data.builder, .percent)}); |
| 813 | 826 | } |
| 814 | 827 | try w.writeAll(" }"); |
| 815 | 828 | switch (kind) { |
| ... | ... | @@ -1225,7 +1238,7 @@ pub const Attribute = union(Kind) { |
| 1225 | 1238 | .inalloca, |
| 1226 | 1239 | .sret, |
| 1227 | 1240 | .elementtype, |
| 1228 | | => |ty| try w.print(" {s}({f%})", .{ @tagName(attribute), ty.fmt(data.builder) }), |
| 1241 | => |ty| try w.print(" {s}({f})", .{ @tagName(attribute), ty.fmt(data.builder, .percent) }), |
| 1229 | 1242 | .@"align" => |alignment| try w.print("{f }", .{alignment}), |
| 1230 | 1243 | .dereferenceable, |
| 1231 | 1244 | .dereferenceable_or_null, |
| ... | ... | @@ -1248,10 +1261,14 @@ pub const Attribute = union(Kind) { |
| 1248 | 1261 | } |
| 1249 | 1262 | try w.writeByte(')'); |
| 1250 | 1263 | }, |
| 1251 | | .alignstack => |alignment| try w.print( |
| 1252 | | if (data.mode == .pound) " {s}={d}" else " {s}({d})", |
| 1253 | | .{ @tagName(attribute), alignment.toByteUnits() orelse return }, |
| 1254 | | ), |
| 1264 | .alignstack => |alignment| { |
| 1265 | try w.print(" {s}", .{attribute}); |
| 1266 | const alignment_bytes = alignment.toByteUnits() orelse return; |
| 1267 | switch (data.mode) { |
| 1268 | .pound => try w.print("({d})", .{alignment_bytes}), |
| 1269 | else => try w.print("={d}", .{alignment_bytes}), |
| 1270 | } |
| 1271 | }, |
| 1255 | 1272 | .allockind => |allockind| { |
| 1256 | 1273 | try w.print(" {s}(\"", .{@tagName(attribute)}); |
| 1257 | 1274 | var any = false; |
| ... | ... | @@ -1297,9 +1314,9 @@ pub const Attribute = union(Kind) { |
| 1297 | 1314 | vscale_range.max.toByteUnits() orelse 0, |
| 1298 | 1315 | }), |
| 1299 | 1316 | .string => |string_attr| if (data.mode == .quote) { |
| 1300 | | try w.print(" {f\"}", .{string_attr.kind.fmt(data.builder)}); |
| 1317 | try w.print(" {f}", .{string_attr.kind.fmtQ(data.builder)}); |
| 1301 | 1318 | if (string_attr.value != .empty) |
| 1302 | | try w.print("={f\"}", .{string_attr.value.fmt(data.builder)}); |
| 1319 | try w.print("={f}", .{string_attr.value.fmtQ(data.builder)}); |
| 1303 | 1320 | }, |
| 1304 | 1321 | .none => unreachable, |
| 1305 | 1322 | } |
| ... | ... | @@ -1583,6 +1600,7 @@ pub const Attributes = enum(u32) { |
| 1583 | 1600 | for (data.attributes.slice(data.builder)) |attribute_index| try Attribute.Index.format(.{ |
| 1584 | 1601 | .attribute_index = attribute_index, |
| 1585 | 1602 | .builder = data.builder, |
| 1603 | .mode = .default, |
| 1586 | 1604 | }, w); |
| 1587 | 1605 | } |
| 1588 | 1606 | pub fn fmt(self: Attributes, builder: *const Builder) std.fmt.Formatter(FormatData, format) { |
| ... | ... | @@ -2315,7 +2333,7 @@ pub const Global = struct { |
| 2315 | 2333 | }; |
| 2316 | 2334 | fn format(data: FormatData, w: *Writer) Writer.Error!void { |
| 2317 | 2335 | try w.print("@{f}", .{ |
| 2318 | | data.global.unwrap(data.builder).name(data.builder).fmt(data.builder), |
| 2336 | data.global.unwrap(data.builder).name(data.builder).fmt(data.builder, null), |
| 2319 | 2337 | }); |
| 2320 | 2338 | } |
| 2321 | 2339 | pub fn fmt(self: Index, builder: *const Builder) std.fmt.Formatter(FormatData, format) { |
| ... | ... | @@ -4758,12 +4776,7 @@ pub const Function = struct { |
| 4758 | 4776 | instruction: Instruction.Index, |
| 4759 | 4777 | function: Function.Index, |
| 4760 | 4778 | builder: *Builder, |
| 4761 | | flags: Flags, |
| 4762 | | const Flags = struct { |
| 4763 | | comma: bool = false, |
| 4764 | | space: bool = false, |
| 4765 | | percent: bool = false, |
| 4766 | | }; |
| 4779 | flags: FormatFlags, |
| 4767 | 4780 | }; |
| 4768 | 4781 | fn format(data: FormatData, w: *Writer) Writer.Error!void { |
| 4769 | 4782 | if (data.flags.comma) { |
| ... | ... | @@ -4775,8 +4788,8 @@ pub const Function = struct { |
| 4775 | 4788 | try w.writeByte(' '); |
| 4776 | 4789 | } |
| 4777 | 4790 | if (data.flags.percent) try w.print( |
| 4778 | | "{f%} ", |
| 4779 | | .{data.instruction.typeOf(data.function, data.builder).fmt(data.builder)}, |
| 4791 | "{f} ", |
| 4792 | .{data.instruction.typeOf(data.function, data.builder).fmt(data.builder, .percent)}, |
| 4780 | 4793 | ); |
| 4781 | 4794 | assert(data.instruction != .none); |
| 4782 | 4795 | try w.print("%{f}", .{ |
| ... | ... | @@ -4787,7 +4800,7 @@ pub const Function = struct { |
| 4787 | 4800 | self: Instruction.Index, |
| 4788 | 4801 | function: Function.Index, |
| 4789 | 4802 | builder: *Builder, |
| 4790 | | flags: FormatData.Flags, |
| 4803 | flags: FormatFlags, |
| 4791 | 4804 | ) std.fmt.Formatter(FormatData, format) { |
| 4792 | 4805 | return .{ .data = .{ |
| 4793 | 4806 | .instruction = self, |
| ... | ... | @@ -6291,10 +6304,10 @@ pub const WipFunction = struct { |
| 6291 | 6304 | |
| 6292 | 6305 | while (true) { |
| 6293 | 6306 | gop.value_ptr.* = @enumFromInt(@intFromEnum(gop.value_ptr.*) + 1); |
| 6294 | | const unique_name = try wip_name.builder.fmt("{fr}{s}{fr}", .{ |
| 6295 | | name.fmt(wip_name.builder), |
| 6307 | const unique_name = try wip_name.builder.fmt("{f}{s}{f}", .{ |
| 6308 | name.fmtRaw(wip_name.builder), |
| 6296 | 6309 | sep, |
| 6297 | | gop.value_ptr.fmt(wip_name.builder), |
| 6310 | gop.value_ptr.fmtRaw(wip_name.builder), |
| 6298 | 6311 | }); |
| 6299 | 6312 | const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name); |
| 6300 | 6313 | if (!unique_gop.found_existing) { |
| ... | ... | @@ -7401,12 +7414,7 @@ pub const Constant = enum(u32) { |
| 7401 | 7414 | const FormatData = struct { |
| 7402 | 7415 | constant: Constant, |
| 7403 | 7416 | builder: *Builder, |
| 7404 | | flags: Flags, |
| 7405 | | const Flags = struct { |
| 7406 | | comma: bool = false, |
| 7407 | | space: bool = false, |
| 7408 | | percent: bool = false, |
| 7409 | | }; |
| 7417 | flags: FormatFlags, |
| 7410 | 7418 | }; |
| 7411 | 7419 | fn format(data: FormatData, w: *Writer) Writer.Error!void { |
| 7412 | 7420 | if (data.flags.comma) { |
| ... | ... | @@ -7418,7 +7426,7 @@ pub const Constant = enum(u32) { |
| 7418 | 7426 | try w.writeByte(' '); |
| 7419 | 7427 | } |
| 7420 | 7428 | if (data.flags.percent) |
| 7421 | | try w.print("{f%} ", .{data.constant.typeOf(data.builder).fmt(data.builder)}); |
| 7429 | try w.print("{f} ", .{data.constant.typeOf(data.builder).fmt(data.builder, .percent)}); |
| 7422 | 7430 | assert(data.constant != .no_init); |
| 7423 | 7431 | if (std.enums.tagName(Constant, data.constant)) |name| return w.writeAll(name); |
| 7424 | 7432 | switch (data.constant.unwrap()) { |
| ... | ... | @@ -7457,7 +7465,7 @@ pub const Constant = enum(u32) { |
| 7457 | 7465 | var stack align(@alignOf(ExpectedContents)) = |
| 7458 | 7466 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.builder.gpa); |
| 7459 | 7467 | const allocator = stack.get(); |
| 7460 | | const str = try bigint.toStringAlloc(allocator, 10, undefined); |
| 7468 | const str = bigint.toStringAlloc(allocator, 10, undefined) catch return error.WriteFailed; |
| 7461 | 7469 | defer allocator.free(str); |
| 7462 | 7470 | try w.writeAll(str); |
| 7463 | 7471 | }, |
| ... | ... | @@ -7563,7 +7571,7 @@ pub const Constant = enum(u32) { |
| 7563 | 7571 | }); |
| 7564 | 7572 | for (vals, 0..) |val, index| { |
| 7565 | 7573 | if (index > 0) try w.writeAll(", "); |
| 7566 | | try w.print("{f%}", .{val.fmt(data.builder)}); |
| 7574 | try w.print("{f}", .{val.fmt(data.builder, .{ .percent = true })}); |
| 7567 | 7575 | } |
| 7568 | 7576 | try w.writeAll(switch (tag) { |
| 7569 | 7577 | .structure => " }", |
| ... | ... | @@ -7579,12 +7587,12 @@ pub const Constant = enum(u32) { |
| 7579 | 7587 | try w.writeByte('<'); |
| 7580 | 7588 | for (0..len) |index| { |
| 7581 | 7589 | if (index > 0) try w.writeAll(", "); |
| 7582 | | try w.print("{f%}", .{extra.value.fmt(data.builder)}); |
| 7590 | try w.print("{f}", .{extra.value.fmt(data.builder, .{ .percent = true })}); |
| 7583 | 7591 | } |
| 7584 | 7592 | try w.writeByte('>'); |
| 7585 | 7593 | }, |
| 7586 | | .string => try w.print("c{f\"}", .{ |
| 7587 | | @as(String, @enumFromInt(item.data)).fmt(data.builder), |
| 7594 | .string => try w.print("c{f}", .{ |
| 7595 | @as(String, @enumFromInt(item.data)).fmtQ(data.builder), |
| 7588 | 7596 | }), |
| 7589 | 7597 | .blockaddress => |tag| { |
| 7590 | 7598 | const extra = data.builder.constantExtraData(BlockAddress, item.data); |
| ... | ... | @@ -7592,7 +7600,7 @@ pub const Constant = enum(u32) { |
| 7592 | 7600 | try w.print("{s}({f}, {f})", .{ |
| 7593 | 7601 | @tagName(tag), |
| 7594 | 7602 | function.global.fmt(data.builder), |
| 7595 | | extra.block.toInst(function).fmt(extra.function, data.builder), |
| 7603 | extra.block.toInst(function).fmt(extra.function, data.builder, .{}), |
| 7596 | 7604 | }); |
| 7597 | 7605 | }, |
| 7598 | 7606 | .dso_local_equivalent, |
| ... | ... | @@ -7611,10 +7619,10 @@ pub const Constant = enum(u32) { |
| 7611 | 7619 | .addrspacecast, |
| 7612 | 7620 | => |tag| { |
| 7613 | 7621 | const extra = data.builder.constantExtraData(Cast, item.data); |
| 7614 | | try w.print("{s} ({f%} to {f%})", .{ |
| 7622 | try w.print("{s} ({f} to {f})", .{ |
| 7615 | 7623 | @tagName(tag), |
| 7616 | | extra.val.fmt(data.builder), |
| 7617 | | extra.type.fmt(data.builder), |
| 7624 | extra.val.fmt(data.builder, .{ .percent = true }), |
| 7625 | extra.type.fmt(data.builder, .percent), |
| 7618 | 7626 | }); |
| 7619 | 7627 | }, |
| 7620 | 7628 | .getelementptr, |
| ... | ... | @@ -7623,12 +7631,12 @@ pub const Constant = enum(u32) { |
| 7623 | 7631 | var extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data); |
| 7624 | 7632 | const indices = |
| 7625 | 7633 | extra.trail.next(extra.data.info.indices_len, Constant, data.builder); |
| 7626 | | try w.print("{s} ({f%}, {f%}", .{ |
| 7634 | try w.print("{s} ({f}, {f}", .{ |
| 7627 | 7635 | @tagName(tag), |
| 7628 | | extra.data.type.fmt(data.builder), |
| 7629 | | extra.data.base.fmt(data.builder), |
| 7636 | extra.data.type.fmt(data.builder, .percent), |
| 7637 | extra.data.base.fmt(data.builder, .{ .percent = true }), |
| 7630 | 7638 | }); |
| 7631 | | for (indices) |index| try w.print(", {f%}", .{index.fmt(data.builder)}); |
| 7639 | for (indices) |index| try w.print(", {f}", .{index.fmt(data.builder, .{ .percent = true })}); |
| 7632 | 7640 | try w.writeByte(')'); |
| 7633 | 7641 | }, |
| 7634 | 7642 | .add, |
| ... | ... | @@ -7641,10 +7649,10 @@ pub const Constant = enum(u32) { |
| 7641 | 7649 | .xor, |
| 7642 | 7650 | => |tag| { |
| 7643 | 7651 | const extra = data.builder.constantExtraData(Binary, item.data); |
| 7644 | | try w.print("{s} ({f%}, {f%})", .{ |
| 7652 | try w.print("{s} ({f}, {f})", .{ |
| 7645 | 7653 | @tagName(tag), |
| 7646 | | extra.lhs.fmt(data.builder), |
| 7647 | | extra.rhs.fmt(data.builder), |
| 7654 | extra.lhs.fmt(data.builder, .{ .percent = true }), |
| 7655 | extra.rhs.fmt(data.builder, .{ .percent = true }), |
| 7648 | 7656 | }); |
| 7649 | 7657 | }, |
| 7650 | 7658 | .@"asm", |
| ... | ... | @@ -7665,10 +7673,10 @@ pub const Constant = enum(u32) { |
| 7665 | 7673 | .@"asm sideeffect alignstack inteldialect unwind", |
| 7666 | 7674 | => |tag| { |
| 7667 | 7675 | const extra = data.builder.constantExtraData(Assembly, item.data); |
| 7668 | | try w.print("{s} {f\"}, {f\"}", .{ |
| 7676 | try w.print("{s} {f}, {f}", .{ |
| 7669 | 7677 | @tagName(tag), |
| 7670 | | extra.assembly.fmt(data.builder), |
| 7671 | | extra.constraints.fmt(data.builder), |
| 7678 | extra.assembly.fmtQ(data.builder), |
| 7679 | extra.constraints.fmtQ(data.builder), |
| 7672 | 7680 | }); |
| 7673 | 7681 | }, |
| 7674 | 7682 | } |
| ... | ... | @@ -7676,7 +7684,7 @@ pub const Constant = enum(u32) { |
| 7676 | 7684 | .global => |global| try w.print("{f}", .{global.fmt(data.builder)}), |
| 7677 | 7685 | } |
| 7678 | 7686 | } |
| 7679 | | pub fn fmt(self: Constant, builder: *Builder, flags: FormatData.Flags) std.fmt.Formatter(FormatData, format) { |
| 7687 | pub fn fmt(self: Constant, builder: *Builder, flags: FormatFlags) std.fmt.Formatter(FormatData, format) { |
| 7680 | 7688 | return .{ .data = .{ |
| 7681 | 7689 | .constant = self, |
| 7682 | 7690 | .builder = builder, |
| ... | ... | @@ -7736,6 +7744,7 @@ pub const Value = enum(u32) { |
| 7736 | 7744 | value: Value, |
| 7737 | 7745 | function: Function.Index, |
| 7738 | 7746 | builder: *Builder, |
| 7747 | flags: FormatFlags, |
| 7739 | 7748 | }; |
| 7740 | 7749 | fn format(data: FormatData, w: *Writer) Writer.Error!void { |
| 7741 | 7750 | switch (data.value.unwrap()) { |
| ... | ... | @@ -7743,16 +7752,18 @@ pub const Value = enum(u32) { |
| 7743 | 7752 | .instruction = instruction, |
| 7744 | 7753 | .function = data.function, |
| 7745 | 7754 | .builder = data.builder, |
| 7755 | .flags = data.flags, |
| 7746 | 7756 | }, w), |
| 7747 | 7757 | .constant => |constant| try Constant.format(.{ |
| 7748 | 7758 | .constant = constant, |
| 7749 | 7759 | .builder = data.builder, |
| 7760 | .flags = data.flags, |
| 7750 | 7761 | }, w), |
| 7751 | 7762 | .metadata => unreachable, |
| 7752 | 7763 | } |
| 7753 | 7764 | } |
| 7754 | | pub fn fmt(self: Value, function: Function.Index, builder: *Builder) std.fmt.Formatter(FormatData, format) { |
| 7755 | | return .{ .data = .{ .value = self, .function = function, .builder = builder } }; |
| 7765 | pub fn fmt(self: Value, function: Function.Index, builder: *Builder, flags: FormatFlags) std.fmt.Formatter(FormatData, format) { |
| 7766 | return .{ .data = .{ .value = self, .function = function, .builder = builder, .flags = flags } }; |
| 7756 | 7767 | } |
| 7757 | 7768 | }; |
| 7758 | 7769 | |
| ... | ... | @@ -8196,9 +8207,7 @@ pub const Metadata = enum(u32) { |
| 8196 | 8207 | formatter: *Formatter, |
| 8197 | 8208 | prefix: []const u8 = "", |
| 8198 | 8209 | node: Node, |
| 8199 | | specialized: ?TODO, |
| 8200 | | |
| 8201 | | const TODO = opaque {}; |
| 8210 | specialized: ?FormatFlags, |
| 8202 | 8211 | |
| 8203 | 8212 | const Node = union(enum) { |
| 8204 | 8213 | none, |
| ... | ... | @@ -8228,7 +8237,6 @@ pub const Metadata = enum(u32) { |
| 8228 | 8237 | if (data.node == .none) return; |
| 8229 | 8238 | |
| 8230 | 8239 | const is_specialized = data.specialized != null; |
| 8231 | | const recurse_fmt_str = data.specialized orelse {}; |
| 8232 | 8240 | |
| 8233 | 8241 | if (data.formatter.need_comma) try w.writeAll(", "); |
| 8234 | 8242 | defer data.formatter.need_comma = true; |
| ... | ... | @@ -8251,13 +8259,15 @@ pub const Metadata = enum(u32) { |
| 8251 | 8259 | for (elements) |element| try format(.{ |
| 8252 | 8260 | .formatter = data.formatter, |
| 8253 | 8261 | .node = .{ .u64 = element }, |
| 8254 | | }, w, "%"); |
| 8262 | .specialized = .{ .percent = true }, |
| 8263 | }, w); |
| 8255 | 8264 | try w.writeByte(')'); |
| 8256 | 8265 | }, |
| 8257 | 8266 | .constant => try Constant.format(.{ |
| 8258 | 8267 | .constant = @enumFromInt(item.data), |
| 8259 | 8268 | .builder = builder, |
| 8260 | | }, w, recurse_fmt_str), |
| 8269 | .flags = data.specialized orelse .{}, |
| 8270 | }, w), |
| 8261 | 8271 | else => unreachable, |
| 8262 | 8272 | } |
| 8263 | 8273 | }, |
| ... | ... | @@ -8266,28 +8276,33 @@ pub const Metadata = enum(u32) { |
| 8266 | 8276 | .value = node.value, |
| 8267 | 8277 | .function = node.function, |
| 8268 | 8278 | .builder = builder, |
| 8269 | | }, w, switch (tag) { |
| 8270 | | .local_value => recurse_fmt_str, |
| 8271 | | .local_metadata => "%", |
| 8272 | | else => unreachable, |
| 8273 | | }), |
| 8279 | .flags = switch (tag) { |
| 8280 | .local_value => data.specialized orelse .{}, |
| 8281 | .local_metadata => .{ .percent = true }, |
| 8282 | else => unreachable, |
| 8283 | }, |
| 8284 | }, w), |
| 8274 | 8285 | inline .local_inline, .local_index => |node, tag| { |
| 8275 | | if (comptime std.mem.eql(u8, recurse_fmt_str, "%")) |
| 8276 | | try w.print("{f%} ", .{Type.metadata.fmt(builder)}); |
| 8286 | if (data.specialized) |flags| { |
| 8287 | if (flags.onlyPercent()) { |
| 8288 | try w.print("{f} ", .{Type.metadata.fmt(builder, .percent)}); |
| 8289 | } |
| 8290 | } |
| 8277 | 8291 | try format(.{ |
| 8278 | 8292 | .formatter = data.formatter, |
| 8279 | 8293 | .node = @unionInit(FormatData.Node, @tagName(tag)["local_".len..], node), |
| 8280 | | }, w, "%"); |
| 8294 | .specialized = .{ .percent = true }, |
| 8295 | }, w); |
| 8281 | 8296 | }, |
| 8282 | | .string => |node| try w.print((if (is_specialized) "" else "!") ++ "{f}", .{ |
| 8283 | | node.fmt(builder), |
| 8297 | .string => |node| try w.print("{s}{f}", .{ |
| 8298 | @as([]const u8, if (is_specialized) "" else "!"), node.fmt(builder), |
| 8284 | 8299 | }), |
| 8285 | 8300 | inline .bool, .u32, .u64 => |node| try w.print("{}", .{node}), |
| 8286 | 8301 | inline .di_flags, .sp_flags => |node| try w.print("{f}", .{node}), |
| 8287 | 8302 | .raw => |node| try w.writeAll(node), |
| 8288 | 8303 | } |
| 8289 | 8304 | } |
| 8290 | | inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype) switch (@TypeOf(node)) { |
| 8305 | inline fn fmt(formatter: *Formatter, prefix: []const u8, node: anytype, special: ?FormatFlags) switch (@TypeOf(node)) { |
| 8291 | 8306 | Metadata => Allocator.Error, |
| 8292 | 8307 | else => error{}, |
| 8293 | 8308 | }!std.fmt.Formatter(FormatData, format) { |
| ... | ... | @@ -8327,6 +8342,7 @@ pub const Metadata = enum(u32) { |
| 8327 | 8342 | .optional, .null => .none, |
| 8328 | 8343 | else => unreachable, |
| 8329 | 8344 | }, |
| 8345 | .specialized = special, |
| 8330 | 8346 | } }; |
| 8331 | 8347 | } |
| 8332 | 8348 | inline fn fmtLocal( |
| ... | ... | @@ -8359,6 +8375,7 @@ pub const Metadata = enum(u32) { |
| 8359 | 8375 | }; |
| 8360 | 8376 | }, |
| 8361 | 8377 | }, |
| 8378 | .specialized = null, |
| 8362 | 8379 | } }; |
| 8363 | 8380 | } |
| 8364 | 8381 | fn refUnwrapped(formatter: *Formatter, node: Metadata) Allocator.Error!FormatData.Node { |
| ... | ... | @@ -8437,6 +8454,7 @@ pub const Metadata = enum(u32) { |
| 8437 | 8454 | inline for (names) |name| @field(fmt_args, name) = try formatter.fmt( |
| 8438 | 8455 | name ++ ": ", |
| 8439 | 8456 | @field(nodes, name), |
| 8457 | null, |
| 8440 | 8458 | ); |
| 8441 | 8459 | try w.print(fmt_str, fmt_args); |
| 8442 | 8460 | } |
| ... | ... | @@ -8965,7 +8983,7 @@ pub fn getIntrinsic( |
| 8965 | 8983 | const w = &aw.writer; |
| 8966 | 8984 | defer self.strtab_string_bytes = aw.toArrayList(); |
| 8967 | 8985 | w.print("llvm.{s}", .{@tagName(id)}) catch return error.OutOfMemory; |
| 8968 | | for (overload) |ty| w.print(".{fm}", .{ty.fmt(self)}) catch return error.OutOfMemory; |
| 8986 | for (overload) |ty| w.print(".{f}", .{ty.fmt(self, .m)}) catch return error.OutOfMemory; |
| 8969 | 8987 | } |
| 8970 | 8988 | break :name try self.trailingStrtabString(); |
| 8971 | 8989 | }; |
| ... | ... | @@ -9399,7 +9417,7 @@ pub fn printToFile(b: *Builder, file: std.fs.File, buffer: []u8) !void { |
| 9399 | 9417 | try fw.interface.flush(); |
| 9400 | 9418 | } |
| 9401 | 9419 | |
| 9402 | | pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9420 | pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void { |
| 9403 | 9421 | var need_newline = false; |
| 9404 | 9422 | var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; |
| 9405 | 9423 | defer metadata_formatter.map.deinit(self.gpa); |
| ... | ... | @@ -9408,17 +9426,17 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9408 | 9426 | if (need_newline) try w.writeByte('\n') else need_newline = true; |
| 9409 | 9427 | if (self.source_filename != .none) try w.print( |
| 9410 | 9428 | \\; ModuleID = '{s}' |
| 9411 | | \\source_filename = {f"} |
| 9429 | \\source_filename = {f} |
| 9412 | 9430 | \\ |
| 9413 | | , .{ self.source_filename.slice(self).?, self.source_filename.fmt(self) }); |
| 9431 | , .{ self.source_filename.slice(self).?, self.source_filename.fmtQ(self) }); |
| 9414 | 9432 | if (self.data_layout != .none) try w.print( |
| 9415 | | \\target datalayout = {f"} |
| 9433 | \\target datalayout = {f} |
| 9416 | 9434 | \\ |
| 9417 | | , .{self.data_layout.fmt(self)}); |
| 9435 | , .{self.data_layout.fmtQ(self)}); |
| 9418 | 9436 | if (self.target_triple != .none) try w.print( |
| 9419 | | \\target triple = {f"} |
| 9437 | \\target triple = {f} |
| 9420 | 9438 | \\ |
| 9421 | | , .{self.target_triple.fmt(self)}); |
| 9439 | , .{self.target_triple.fmtQ(self)}); |
| 9422 | 9440 | } |
| 9423 | 9441 | |
| 9424 | 9442 | if (self.module_asm.items.len > 0) { |
| ... | ... | @@ -9436,7 +9454,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9436 | 9454 | for (self.types.keys(), self.types.values()) |id, ty| try w.print( |
| 9437 | 9455 | \\%{f} = type {f} |
| 9438 | 9456 | \\ |
| 9439 | | , .{ id.fmt(self), ty.fmt(self) }); |
| 9457 | , .{ id.fmt(self), ty.fmt(self, .default) }); |
| 9440 | 9458 | } |
| 9441 | 9459 | |
| 9442 | 9460 | if (self.variables.items.len > 0) { |
| ... | ... | @@ -9447,7 +9465,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9447 | 9465 | metadata_formatter.need_comma = true; |
| 9448 | 9466 | defer metadata_formatter.need_comma = undefined; |
| 9449 | 9467 | try w.print( |
| 9450 | | \\{f} ={f}{f}{f}{f}{f }{f}{f }{f} {s} {f%}{f }{f, }{f} |
| 9468 | \\{f} ={f}{f}{f}{f}{f }{f}{f }{f} {s} {f}{f}{f, }{f} |
| 9451 | 9469 | \\ |
| 9452 | 9470 | , .{ |
| 9453 | 9471 | variable.global.fmt(self), |
| ... | ... | @@ -9461,10 +9479,10 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9461 | 9479 | global.addr_space, |
| 9462 | 9480 | global.externally_initialized, |
| 9463 | 9481 | @tagName(variable.mutability), |
| 9464 | | global.type.fmt(self), |
| 9465 | | variable.init.fmt(self), |
| 9482 | global.type.fmt(self, .percent), |
| 9483 | variable.init.fmt(self, .{ .space = true }), |
| 9466 | 9484 | variable.alignment, |
| 9467 | | try metadata_formatter.fmt("!dbg ", global.dbg), |
| 9485 | try metadata_formatter.fmt("!dbg ", global.dbg, null), |
| 9468 | 9486 | }); |
| 9469 | 9487 | } |
| 9470 | 9488 | } |
| ... | ... | @@ -9477,7 +9495,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9477 | 9495 | metadata_formatter.need_comma = true; |
| 9478 | 9496 | defer metadata_formatter.need_comma = undefined; |
| 9479 | 9497 | try w.print( |
| 9480 | | \\{f} ={f}{f}{f}{f}{f }{f} alias {f%}, {f%}{f} |
| 9498 | \\{f} ={f}{f}{f}{f}{f }{f} alias {f}, {f}{f} |
| 9481 | 9499 | \\ |
| 9482 | 9500 | , .{ |
| 9483 | 9501 | alias.global.fmt(self), |
| ... | ... | @@ -9487,9 +9505,9 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9487 | 9505 | global.dll_storage_class, |
| 9488 | 9506 | alias.thread_local, |
| 9489 | 9507 | global.unnamed_addr, |
| 9490 | | global.type.fmt(self), |
| 9491 | | alias.aliasee.fmt(self), |
| 9492 | | try metadata_formatter.fmt("!dbg ", global.dbg), |
| 9508 | global.type.fmt(self, .percent), |
| 9509 | alias.aliasee.fmt(self, .{ .percent = true }), |
| 9510 | try metadata_formatter.fmt("!dbg ", global.dbg, null), |
| 9493 | 9511 | }); |
| 9494 | 9512 | } |
| 9495 | 9513 | } |
| ... | ... | @@ -9509,7 +9527,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9509 | 9527 | \\ |
| 9510 | 9528 | , .{function_attributes.fmt(self)}); |
| 9511 | 9529 | try w.print( |
| 9512 | | \\{s}{f}{f}{f}{f}{f}{f"} {f%} {f}( |
| 9530 | \\{s}{f}{f}{f}{f}{f}{f} {f} {f}( |
| 9513 | 9531 | , .{ |
| 9514 | 9532 | if (function.instructions.len > 0) "define" else "declare", |
| 9515 | 9533 | global.linkage, |
| ... | ... | @@ -9518,19 +9536,19 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9518 | 9536 | global.dll_storage_class, |
| 9519 | 9537 | function.call_conv, |
| 9520 | 9538 | function.attributes.ret(self).fmt(self), |
| 9521 | | global.type.functionReturn(self).fmt(self), |
| 9539 | global.type.functionReturn(self).fmt(self, .percent), |
| 9522 | 9540 | function.global.fmt(self), |
| 9523 | 9541 | }); |
| 9524 | 9542 | for (0..params_len) |arg| { |
| 9525 | 9543 | if (arg > 0) try w.writeAll(", "); |
| 9526 | 9544 | try w.print( |
| 9527 | | \\{f%}{f"} |
| 9545 | \\{f}{f} |
| 9528 | 9546 | , .{ |
| 9529 | | global.type.functionParameters(self)[arg].fmt(self), |
| 9547 | global.type.functionParameters(self)[arg].fmt(self, .percent), |
| 9530 | 9548 | function.attributes.param(arg, self).fmt(self), |
| 9531 | 9549 | }); |
| 9532 | 9550 | if (function.instructions.len > 0) |
| 9533 | | try w.print(" {f}", .{function.arg(@intCast(arg)).fmt(function_index, self)}) |
| 9551 | try w.print(" {f}", .{function.arg(@intCast(arg)).fmt(function_index, self, .{})}) |
| 9534 | 9552 | else |
| 9535 | 9553 | try w.print(" %{d}", .{arg}); |
| 9536 | 9554 | } |
| ... | ... | @@ -9550,7 +9568,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9550 | 9568 | defer metadata_formatter.need_comma = undefined; |
| 9551 | 9569 | try w.print("{f }{f}", .{ |
| 9552 | 9570 | function.alignment, |
| 9553 | | try metadata_formatter.fmt(" !dbg ", global.dbg), |
| 9571 | try metadata_formatter.fmt(" !dbg ", global.dbg, null), |
| 9554 | 9572 | }); |
| 9555 | 9573 | } |
| 9556 | 9574 | if (function.instructions.len > 0) { |
| ... | ... | @@ -9653,11 +9671,11 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9653 | 9671 | .xor, |
| 9654 | 9672 | => |tag| { |
| 9655 | 9673 | const extra = function.extraData(Function.Instruction.Binary, instruction.data); |
| 9656 | | try w.print(" %{f} = {s} {f%}, {f}", .{ |
| 9674 | try w.print(" %{f} = {s} {f}, {f}", .{ |
| 9657 | 9675 | instruction_index.name(&function).fmt(self), |
| 9658 | 9676 | @tagName(tag), |
| 9659 | | extra.lhs.fmt(function_index, self), |
| 9660 | | extra.rhs.fmt(function_index, self), |
| 9677 | extra.lhs.fmt(function_index, self, .{ .percent = true }), |
| 9678 | extra.rhs.fmt(function_index, self, .{ .percent = true }), |
| 9661 | 9679 | }); |
| 9662 | 9680 | }, |
| 9663 | 9681 | .addrspacecast, |
| ... | ... | @@ -9675,25 +9693,28 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9675 | 9693 | .zext, |
| 9676 | 9694 | => |tag| { |
| 9677 | 9695 | const extra = function.extraData(Function.Instruction.Cast, instruction.data); |
| 9678 | | try w.print(" %{f} = {s} {f%} to {f%}", .{ |
| 9696 | try w.print(" %{f} = {s} {f} to {f}", .{ |
| 9679 | 9697 | instruction_index.name(&function).fmt(self), |
| 9680 | 9698 | @tagName(tag), |
| 9681 | | extra.val.fmt(function_index, self), |
| 9682 | | extra.type.fmt(self), |
| 9699 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 9700 | extra.type.fmt(self, .percent), |
| 9683 | 9701 | }); |
| 9684 | 9702 | }, |
| 9685 | 9703 | .alloca, |
| 9686 | 9704 | .@"alloca inalloca", |
| 9687 | 9705 | => |tag| { |
| 9688 | 9706 | const extra = function.extraData(Function.Instruction.Alloca, instruction.data); |
| 9689 | | try w.print(" %{f} = {s} {f%}{f,%}{f, }{f, }", .{ |
| 9707 | try w.print(" %{f} = {s} {f}{f}{f, }{f, }", .{ |
| 9690 | 9708 | instruction_index.name(&function).fmt(self), |
| 9691 | 9709 | @tagName(tag), |
| 9692 | | extra.type.fmt(self), |
| 9710 | extra.type.fmt(self, .percent), |
| 9693 | 9711 | Value.fmt(switch (extra.len) { |
| 9694 | 9712 | .@"1" => .none, |
| 9695 | 9713 | else => extra.len, |
| 9696 | | }, function_index, self), |
| 9714 | }, function_index, self, .{ |
| 9715 | .comma = true, |
| 9716 | .percent = true, |
| 9717 | }), |
| 9697 | 9718 | extra.info.alignment, |
| 9698 | 9719 | extra.info.addr_space, |
| 9699 | 9720 | }); |
| ... | ... | @@ -9702,13 +9723,13 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9702 | 9723 | .atomicrmw => |tag| { |
| 9703 | 9724 | const extra = |
| 9704 | 9725 | function.extraData(Function.Instruction.AtomicRmw, instruction.data); |
| 9705 | | try w.print(" %{f} = {s}{f } {s} {f%}, {f%}{f }{f }{f, }", .{ |
| 9726 | try w.print(" %{f} = {s}{f } {s} {f}, {f}{f }{f }{f, }", .{ |
| 9706 | 9727 | instruction_index.name(&function).fmt(self), |
| 9707 | 9728 | @tagName(tag), |
| 9708 | 9729 | extra.info.access_kind, |
| 9709 | 9730 | @tagName(extra.info.atomic_rmw_operation), |
| 9710 | | extra.ptr.fmt(function_index, self), |
| 9711 | | extra.val.fmt(function_index, self), |
| 9731 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 9732 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 9712 | 9733 | extra.info.sync_scope, |
| 9713 | 9734 | extra.info.success_ordering, |
| 9714 | 9735 | extra.info.alignment, |
| ... | ... | @@ -9724,16 +9745,16 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9724 | 9745 | }, |
| 9725 | 9746 | .br => |tag| { |
| 9726 | 9747 | const target: Function.Block.Index = @enumFromInt(instruction.data); |
| 9727 | | try w.print(" {s} {f%}", .{ |
| 9728 | | @tagName(tag), target.toInst(&function).fmt(function_index, self), |
| 9748 | try w.print(" {s} {f}", .{ |
| 9749 | @tagName(tag), target.toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 9729 | 9750 | }); |
| 9730 | 9751 | }, |
| 9731 | 9752 | .br_cond => { |
| 9732 | 9753 | const extra = function.extraData(Function.Instruction.BrCond, instruction.data); |
| 9733 | | try w.print(" br {f%}, {f%}, {f%}", .{ |
| 9734 | | extra.cond.fmt(function_index, self), |
| 9735 | | extra.then.toInst(&function).fmt(function_index, self), |
| 9736 | | extra.@"else".toInst(&function).fmt(function_index, self), |
| 9754 | try w.print(" br {f}, {f}, {f}", .{ |
| 9755 | extra.cond.fmt(function_index, self, .{ .percent = true }), |
| 9756 | extra.then.toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 9757 | extra.@"else".toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 9737 | 9758 | }); |
| 9738 | 9759 | metadata_formatter.need_comma = true; |
| 9739 | 9760 | defer metadata_formatter.need_comma = undefined; |
| ... | ... | @@ -9741,7 +9762,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9741 | 9762 | .none => {}, |
| 9742 | 9763 | .unpredictable => try w.writeAll("!unpredictable !{}"), |
| 9743 | 9764 | _ => try w.print("{f}", .{ |
| 9744 | | try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights)))), |
| 9765 | try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights))), null), |
| 9745 | 9766 | }), |
| 9746 | 9767 | } |
| 9747 | 9768 | }, |
| ... | ... | @@ -9766,7 +9787,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9766 | 9787 | }), |
| 9767 | 9788 | .none => unreachable, |
| 9768 | 9789 | } |
| 9769 | | try w.print("{s}{f}{f}{f} {f%} {f}(", .{ |
| 9790 | try w.print("{s}{f}{f}{f} {f} {f}(", .{ |
| 9770 | 9791 | @tagName(tag), |
| 9771 | 9792 | extra.data.info.call_conv, |
| 9772 | 9793 | extra.data.attributes.ret(self).fmt(self), |
| ... | ... | @@ -9774,15 +9795,15 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9774 | 9795 | switch (extra.data.ty.functionKind(self)) { |
| 9775 | 9796 | .normal => ret_ty, |
| 9776 | 9797 | .vararg => extra.data.ty, |
| 9777 | | }.fmt(self), |
| 9778 | | extra.data.callee.fmt(function_index, self), |
| 9798 | }.fmt(self, .percent), |
| 9799 | extra.data.callee.fmt(function_index, self, .{}), |
| 9779 | 9800 | }); |
| 9780 | 9801 | for (0.., args) |arg_index, arg| { |
| 9781 | 9802 | if (arg_index > 0) try w.writeAll(", "); |
| 9782 | 9803 | metadata_formatter.need_comma = false; |
| 9783 | 9804 | defer metadata_formatter.need_comma = undefined; |
| 9784 | | try w.print("{f%}{f}{f}", .{ |
| 9785 | | arg.typeOf(function_index, self).fmt(self), |
| 9805 | try w.print("{f}{f}{f}", .{ |
| 9806 | arg.typeOf(function_index, self).fmt(self, .percent), |
| 9786 | 9807 | extra.data.attributes.param(arg_index, self).fmt(self), |
| 9787 | 9808 | try metadata_formatter.fmtLocal(" ", arg, function_index), |
| 9788 | 9809 | }); |
| ... | ... | @@ -9805,13 +9826,13 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9805 | 9826 | => |tag| { |
| 9806 | 9827 | const extra = |
| 9807 | 9828 | function.extraData(Function.Instruction.CmpXchg, instruction.data); |
| 9808 | | try w.print(" %{f} = {s}{f } {f%}, {f%}, {f%}{f }{f }{f }{f, }", .{ |
| 9829 | try w.print(" %{f} = {s}{f } {f}, {f}, {f}{f }{f }{f }{f, }", .{ |
| 9809 | 9830 | instruction_index.name(&function).fmt(self), |
| 9810 | 9831 | @tagName(tag), |
| 9811 | 9832 | extra.info.access_kind, |
| 9812 | | extra.ptr.fmt(function_index, self), |
| 9813 | | extra.cmp.fmt(function_index, self), |
| 9814 | | extra.new.fmt(function_index, self), |
| 9833 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 9834 | extra.cmp.fmt(function_index, self, .{ .percent = true }), |
| 9835 | extra.new.fmt(function_index, self, .{ .percent = true }), |
| 9815 | 9836 | extra.info.sync_scope, |
| 9816 | 9837 | extra.info.success_ordering, |
| 9817 | 9838 | extra.info.failure_ordering, |
| ... | ... | @@ -9821,11 +9842,11 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9821 | 9842 | .extractelement => |tag| { |
| 9822 | 9843 | const extra = |
| 9823 | 9844 | function.extraData(Function.Instruction.ExtractElement, instruction.data); |
| 9824 | | try w.print(" %{f} = {s} {f%}, {f%}", .{ |
| 9845 | try w.print(" %{f} = {s} {f}, {f}", .{ |
| 9825 | 9846 | instruction_index.name(&function).fmt(self), |
| 9826 | 9847 | @tagName(tag), |
| 9827 | | extra.val.fmt(function_index, self), |
| 9828 | | extra.index.fmt(function_index, self), |
| 9848 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 9849 | extra.index.fmt(function_index, self, .{ .percent = true }), |
| 9829 | 9850 | }); |
| 9830 | 9851 | }, |
| 9831 | 9852 | .extractvalue => |tag| { |
| ... | ... | @@ -9834,10 +9855,10 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9834 | 9855 | instruction.data, |
| 9835 | 9856 | ); |
| 9836 | 9857 | const indices = extra.trail.next(extra.data.indices_len, u32, &function); |
| 9837 | | try w.print(" %{f} = {s} {f%}", .{ |
| 9858 | try w.print(" %{f} = {s} {f}", .{ |
| 9838 | 9859 | instruction_index.name(&function).fmt(self), |
| 9839 | 9860 | @tagName(tag), |
| 9840 | | extra.data.val.fmt(function_index, self), |
| 9861 | extra.data.val.fmt(function_index, self, .{ .percent = true }), |
| 9841 | 9862 | }); |
| 9842 | 9863 | for (indices) |index| try w.print(", {d}", .{index}); |
| 9843 | 9864 | }, |
| ... | ... | @@ -9853,10 +9874,10 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9853 | 9874 | .@"fneg fast", |
| 9854 | 9875 | => |tag| { |
| 9855 | 9876 | const val: Value = @enumFromInt(instruction.data); |
| 9856 | | try w.print(" %{f} = {s} {f%}", .{ |
| 9877 | try w.print(" %{f} = {s} {f}", .{ |
| 9857 | 9878 | instruction_index.name(&function).fmt(self), |
| 9858 | 9879 | @tagName(tag), |
| 9859 | | val.fmt(function_index, self), |
| 9880 | val.fmt(function_index, self, .{ .percent = true }), |
| 9860 | 9881 | }); |
| 9861 | 9882 | }, |
| 9862 | 9883 | .getelementptr, |
| ... | ... | @@ -9867,14 +9888,14 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9867 | 9888 | instruction.data, |
| 9868 | 9889 | ); |
| 9869 | 9890 | const indices = extra.trail.next(extra.data.indices_len, Value, &function); |
| 9870 | | try w.print(" %{f} = {s} {f%}, {f%}", .{ |
| 9891 | try w.print(" %{f} = {s} {f}, {f}", .{ |
| 9871 | 9892 | instruction_index.name(&function).fmt(self), |
| 9872 | 9893 | @tagName(tag), |
| 9873 | | extra.data.type.fmt(self), |
| 9874 | | extra.data.base.fmt(function_index, self), |
| 9894 | extra.data.type.fmt(self, .percent), |
| 9895 | extra.data.base.fmt(function_index, self, .{ .percent = true }), |
| 9875 | 9896 | }); |
| 9876 | | for (indices) |index| try w.print(", {f%}", .{ |
| 9877 | | index.fmt(function_index, self), |
| 9897 | for (indices) |index| try w.print(", {f}", .{ |
| 9898 | index.fmt(function_index, self, .{ .percent = true }), |
| 9878 | 9899 | }); |
| 9879 | 9900 | }, |
| 9880 | 9901 | .indirectbr => |tag| { |
| ... | ... | @@ -9882,14 +9903,14 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9882 | 9903 | function.extraDataTrail(Function.Instruction.IndirectBr, instruction.data); |
| 9883 | 9904 | const targets = |
| 9884 | 9905 | extra.trail.next(extra.data.targets_len, Function.Block.Index, &function); |
| 9885 | | try w.print(" {s} {f%}, [", .{ |
| 9906 | try w.print(" {s} {f}, [", .{ |
| 9886 | 9907 | @tagName(tag), |
| 9887 | | extra.data.addr.fmt(function_index, self), |
| 9908 | extra.data.addr.fmt(function_index, self, .{ .percent = true }), |
| 9888 | 9909 | }); |
| 9889 | 9910 | for (0.., targets) |target_index, target| { |
| 9890 | 9911 | if (target_index > 0) try w.writeAll(", "); |
| 9891 | | try w.print("{f%}", .{ |
| 9892 | | target.toInst(&function).fmt(function_index, self), |
| 9912 | try w.print("{f}", .{ |
| 9913 | target.toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 9893 | 9914 | }); |
| 9894 | 9915 | } |
| 9895 | 9916 | try w.writeByte(']'); |
| ... | ... | @@ -9897,23 +9918,23 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9897 | 9918 | .insertelement => |tag| { |
| 9898 | 9919 | const extra = |
| 9899 | 9920 | function.extraData(Function.Instruction.InsertElement, instruction.data); |
| 9900 | | try w.print(" %{f} = {s} {f%}, {f%}, {f%}", .{ |
| 9921 | try w.print(" %{f} = {s} {f}, {f}, {f}", .{ |
| 9901 | 9922 | instruction_index.name(&function).fmt(self), |
| 9902 | 9923 | @tagName(tag), |
| 9903 | | extra.val.fmt(function_index, self), |
| 9904 | | extra.elem.fmt(function_index, self), |
| 9905 | | extra.index.fmt(function_index, self), |
| 9924 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 9925 | extra.elem.fmt(function_index, self, .{ .percent = true }), |
| 9926 | extra.index.fmt(function_index, self, .{ .percent = true }), |
| 9906 | 9927 | }); |
| 9907 | 9928 | }, |
| 9908 | 9929 | .insertvalue => |tag| { |
| 9909 | 9930 | var extra = |
| 9910 | 9931 | function.extraDataTrail(Function.Instruction.InsertValue, instruction.data); |
| 9911 | 9932 | const indices = extra.trail.next(extra.data.indices_len, u32, &function); |
| 9912 | | try w.print(" %{f} = {s} {f%}, {f%}", .{ |
| 9933 | try w.print(" %{f} = {s} {f}, {f}", .{ |
| 9913 | 9934 | instruction_index.name(&function).fmt(self), |
| 9914 | 9935 | @tagName(tag), |
| 9915 | | extra.data.val.fmt(function_index, self), |
| 9916 | | extra.data.elem.fmt(function_index, self), |
| 9936 | extra.data.val.fmt(function_index, self, .{ .percent = true }), |
| 9937 | extra.data.elem.fmt(function_index, self, .{ .percent = true }), |
| 9917 | 9938 | }); |
| 9918 | 9939 | for (indices) |index| try w.print(", {d}", .{index}); |
| 9919 | 9940 | }, |
| ... | ... | @@ -9921,12 +9942,12 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9921 | 9942 | .@"load atomic", |
| 9922 | 9943 | => |tag| { |
| 9923 | 9944 | const extra = function.extraData(Function.Instruction.Load, instruction.data); |
| 9924 | | try w.print(" %{f} = {s}{f } {f%}, {f%}{f }{f }{f, }", .{ |
| 9945 | try w.print(" %{f} = {s}{f } {f}, {f}{f }{f }{f, }", .{ |
| 9925 | 9946 | instruction_index.name(&function).fmt(self), |
| 9926 | 9947 | @tagName(tag), |
| 9927 | 9948 | extra.info.access_kind, |
| 9928 | | extra.type.fmt(self), |
| 9929 | | extra.ptr.fmt(function_index, self), |
| 9949 | extra.type.fmt(self, .percent), |
| 9950 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 9930 | 9951 | extra.info.sync_scope, |
| 9931 | 9952 | extra.info.success_ordering, |
| 9932 | 9953 | extra.info.alignment, |
| ... | ... | @@ -9939,24 +9960,24 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9939 | 9960 | const vals = extra.trail.next(block_incoming_len, Value, &function); |
| 9940 | 9961 | const blocks = |
| 9941 | 9962 | extra.trail.next(block_incoming_len, Function.Block.Index, &function); |
| 9942 | | try w.print(" %{f} = {s} {f%} ", .{ |
| 9963 | try w.print(" %{f} = {s} {f} ", .{ |
| 9943 | 9964 | instruction_index.name(&function).fmt(self), |
| 9944 | 9965 | @tagName(tag), |
| 9945 | | vals[0].typeOf(function_index, self).fmt(self), |
| 9966 | vals[0].typeOf(function_index, self).fmt(self, .percent), |
| 9946 | 9967 | }); |
| 9947 | 9968 | for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| { |
| 9948 | 9969 | if (incoming_index > 0) try w.writeAll(", "); |
| 9949 | 9970 | try w.print("[ {f}, {f} ]", .{ |
| 9950 | | incoming_val.fmt(function_index, self), |
| 9951 | | incoming_block.toInst(&function).fmt(function_index, self), |
| 9971 | incoming_val.fmt(function_index, self, .{}), |
| 9972 | incoming_block.toInst(&function).fmt(function_index, self, .{}), |
| 9952 | 9973 | }); |
| 9953 | 9974 | } |
| 9954 | 9975 | }, |
| 9955 | 9976 | .ret => |tag| { |
| 9956 | 9977 | const val: Value = @enumFromInt(instruction.data); |
| 9957 | | try w.print(" {s} {f%}", .{ |
| 9978 | try w.print(" {s} {f}", .{ |
| 9958 | 9979 | @tagName(tag), |
| 9959 | | val.fmt(function_index, self), |
| 9980 | val.fmt(function_index, self, .{ .percent = true }), |
| 9960 | 9981 | }); |
| 9961 | 9982 | }, |
| 9962 | 9983 | .@"ret void", |
| ... | ... | @@ -9966,34 +9987,34 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 9966 | 9987 | .@"select fast", |
| 9967 | 9988 | => |tag| { |
| 9968 | 9989 | const extra = function.extraData(Function.Instruction.Select, instruction.data); |
| 9969 | | try w.print(" %{f} = {s} {f%}, {f%}, {f%}", .{ |
| 9990 | try w.print(" %{f} = {s} {f}, {f}, {f}", .{ |
| 9970 | 9991 | instruction_index.name(&function).fmt(self), |
| 9971 | 9992 | @tagName(tag), |
| 9972 | | extra.cond.fmt(function_index, self), |
| 9973 | | extra.lhs.fmt(function_index, self), |
| 9974 | | extra.rhs.fmt(function_index, self), |
| 9993 | extra.cond.fmt(function_index, self, .{ .percent = true }), |
| 9994 | extra.lhs.fmt(function_index, self, .{ .percent = true }), |
| 9995 | extra.rhs.fmt(function_index, self, .{ .percent = true }), |
| 9975 | 9996 | }); |
| 9976 | 9997 | }, |
| 9977 | 9998 | .shufflevector => |tag| { |
| 9978 | 9999 | const extra = |
| 9979 | 10000 | function.extraData(Function.Instruction.ShuffleVector, instruction.data); |
| 9980 | | try w.print(" %{f} = {s} {f%}, {f%}, {f%}", .{ |
| 10001 | try w.print(" %{f} = {s} {f}, {f}, {f}", .{ |
| 9981 | 10002 | instruction_index.name(&function).fmt(self), |
| 9982 | 10003 | @tagName(tag), |
| 9983 | | extra.lhs.fmt(function_index, self), |
| 9984 | | extra.rhs.fmt(function_index, self), |
| 9985 | | extra.mask.fmt(function_index, self), |
| 10004 | extra.lhs.fmt(function_index, self, .{ .percent = true }), |
| 10005 | extra.rhs.fmt(function_index, self, .{ .percent = true }), |
| 10006 | extra.mask.fmt(function_index, self, .{ .percent = true }), |
| 9986 | 10007 | }); |
| 9987 | 10008 | }, |
| 9988 | 10009 | .store, |
| 9989 | 10010 | .@"store atomic", |
| 9990 | 10011 | => |tag| { |
| 9991 | 10012 | const extra = function.extraData(Function.Instruction.Store, instruction.data); |
| 9992 | | try w.print(" {s}{f } {f%}, {f%}{f }{f }{f, }", .{ |
| 10013 | try w.print(" {s}{f } {f}, {f}{f }{f }{f, }", .{ |
| 9993 | 10014 | @tagName(tag), |
| 9994 | 10015 | extra.info.access_kind, |
| 9995 | | extra.val.fmt(function_index, self), |
| 9996 | | extra.ptr.fmt(function_index, self), |
| 10016 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 10017 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 9997 | 10018 | extra.info.sync_scope, |
| 9998 | 10019 | extra.info.success_ordering, |
| 9999 | 10020 | extra.info.alignment, |
| ... | ... | @@ -10005,16 +10026,16 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 10005 | 10026 | const vals = extra.trail.next(extra.data.cases_len, Constant, &function); |
| 10006 | 10027 | const blocks = |
| 10007 | 10028 | extra.trail.next(extra.data.cases_len, Function.Block.Index, &function); |
| 10008 | | try w.print(" {s} {f%}, {f%} [\n", .{ |
| 10029 | try w.print(" {s} {f}, {f} [\n", .{ |
| 10009 | 10030 | @tagName(tag), |
| 10010 | | extra.data.val.fmt(function_index, self), |
| 10011 | | extra.data.default.toInst(&function).fmt(function_index, self), |
| 10031 | extra.data.val.fmt(function_index, self, .{ .percent = true }), |
| 10032 | extra.data.default.toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 10012 | 10033 | }); |
| 10013 | 10034 | for (vals, blocks) |case_val, case_block| try w.print( |
| 10014 | | " {f%}, {f%}\n", |
| 10035 | " {f}, {f}\n", |
| 10015 | 10036 | .{ |
| 10016 | | case_val.fmt(self), |
| 10017 | | case_block.toInst(&function).fmt(function_index, self), |
| 10037 | case_val.fmt(self, .{ .percent = true }), |
| 10038 | case_block.toInst(&function).fmt(function_index, self, .{ .percent = true }), |
| 10018 | 10039 | }, |
| 10019 | 10040 | ); |
| 10020 | 10041 | try w.writeAll(" ]"); |
| ... | ... | @@ -10024,17 +10045,17 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 10024 | 10045 | .none => {}, |
| 10025 | 10046 | .unpredictable => try w.writeAll("!unpredictable !{}"), |
| 10026 | 10047 | _ => try w.print("{f}", .{ |
| 10027 | | try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights)))), |
| 10048 | try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights))), null), |
| 10028 | 10049 | }), |
| 10029 | 10050 | } |
| 10030 | 10051 | }, |
| 10031 | 10052 | .va_arg => |tag| { |
| 10032 | 10053 | const extra = function.extraData(Function.Instruction.VaArg, instruction.data); |
| 10033 | | try w.print(" %{f} = {s} {f%}, {f%}", .{ |
| 10054 | try w.print(" %{f} = {s} {f}, {f}", .{ |
| 10034 | 10055 | instruction_index.name(&function).fmt(self), |
| 10035 | 10056 | @tagName(tag), |
| 10036 | | extra.list.fmt(function_index, self), |
| 10037 | | extra.type.fmt(self), |
| 10057 | extra.list.fmt(function_index, self, .{ .percent = true }), |
| 10058 | extra.type.fmt(self, .percent), |
| 10038 | 10059 | }); |
| 10039 | 10060 | }, |
| 10040 | 10061 | } |
| ... | ... | @@ -10068,7 +10089,7 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 10068 | 10089 | try w.writeAll(" = !{"); |
| 10069 | 10090 | metadata_formatter.need_comma = false; |
| 10070 | 10091 | defer metadata_formatter.need_comma = undefined; |
| 10071 | | for (elements) |element| try w.print("{f}", .{try metadata_formatter.fmt("", element)}); |
| 10092 | for (elements) |element| try w.print("{f}", .{try metadata_formatter.fmt("", element, null)}); |
| 10072 | 10093 | try w.writeAll("}\n"); |
| 10073 | 10094 | } |
| 10074 | 10095 | } |
| ... | ... | @@ -10371,28 +10392,28 @@ pub fn print(self: *Builder, w: *Writer) Writer.Error!void { |
| 10371 | 10392 | var extra = self.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data); |
| 10372 | 10393 | const elements = extra.trail.next(extra.data.elements_len, Metadata, self); |
| 10373 | 10394 | try w.writeAll("!{"); |
| 10374 | | for (elements) |element| try w.print("{[element]f%}", .{ |
| 10375 | | .element = try metadata_formatter.fmt("", element), |
| 10395 | for (elements) |element| try w.print("{[element]f}", .{ |
| 10396 | .element = try metadata_formatter.fmt("", element, .{ .percent = true }), |
| 10376 | 10397 | }); |
| 10377 | 10398 | try w.writeAll("}\n"); |
| 10378 | 10399 | }, |
| 10379 | 10400 | .str_tuple => { |
| 10380 | 10401 | var extra = self.metadataExtraDataTrail(Metadata.StrTuple, metadata_item.data); |
| 10381 | 10402 | const elements = extra.trail.next(extra.data.elements_len, Metadata, self); |
| 10382 | | try w.print("!{{{[str]f%}", .{ |
| 10383 | | .str = try metadata_formatter.fmt("", extra.data.str), |
| 10403 | try w.print("!{{{[str]f}", .{ |
| 10404 | .str = try metadata_formatter.fmt("", extra.data.str, .{ .percent = true }), |
| 10384 | 10405 | }); |
| 10385 | | for (elements) |element| try w.print("{[element]f%}", .{ |
| 10386 | | .element = try metadata_formatter.fmt("", element), |
| 10406 | for (elements) |element| try w.print("{[element]f}", .{ |
| 10407 | .element = try metadata_formatter.fmt("", element, .{ .percent = true }), |
| 10387 | 10408 | }); |
| 10388 | 10409 | try w.writeAll("}\n"); |
| 10389 | 10410 | }, |
| 10390 | 10411 | .module_flag => { |
| 10391 | 10412 | const extra = self.metadataExtraData(Metadata.ModuleFlag, metadata_item.data); |
| 10392 | | try w.print("!{{{[behavior]f%}{[name]f%}{[constant]f%}}}\n", .{ |
| 10393 | | .behavior = try metadata_formatter.fmt("", extra.behavior), |
| 10394 | | .name = try metadata_formatter.fmt("", extra.name), |
| 10395 | | .constant = try metadata_formatter.fmt("", extra.constant), |
| 10413 | try w.print("!{{{[behavior]f}{[name]f}{[constant]f}}}\n", .{ |
| 10414 | .behavior = try metadata_formatter.fmt("", extra.behavior, .{ .percent = true }), |
| 10415 | .name = try metadata_formatter.fmt("", extra.name, .{ .percent = true }), |
| 10416 | .constant = try metadata_formatter.fmt("", extra.constant, .{ .percent = true }), |
| 10396 | 10417 | }); |
| 10397 | 10418 | }, |
| 10398 | 10419 | .local_var => { |
| ... | ... | @@ -15109,3 +15130,13 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15109 | 15130 | |
| 15110 | 15131 | return bitcode.toOwnedSlice(); |
| 15111 | 15132 | } |
| 15133 | |
| 15134 | const FormatFlags = struct { |
| 15135 | comma: bool = false, |
| 15136 | space: bool = false, |
| 15137 | percent: bool = false, |
| 15138 | |
| 15139 | fn onlyPercent(f: FormatFlags) bool { |
| 15140 | return !f.comma and !f.space and f.percent; |
| 15141 | } |
| 15142 | }; |