| ... | @@ -1694,6 +1694,76 @@ pub const DeclGen = struct { | ... | @@ -1694,6 +1694,76 @@ pub const DeclGen = struct { |
| 1694 | try w.writeAll(suffix.items); | 1694 | try w.writeAll(suffix.items); |
| 1695 | } | 1695 | } |
| 1696 | | 1696 | |
| | 1697 | fn renderTagNameFn(dg: *DeclGen, enum_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| | 1698 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| | 1699 | defer buffer.deinit(); |
| | 1700 | const bw = buffer.writer(); |
| | 1701 | |
| | 1702 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| | 1703 | |
| | 1704 | try buffer.appendSlice("static "); |
| | 1705 | try dg.renderType(bw, name_slice_ty); |
| | 1706 | const name_begin = buffer.items.len + " ".len; |
| | 1707 | try bw.print(" zig_tagName_{}(", .{typeToCIdentifier(enum_ty, dg.module)}); |
| | 1708 | const name_end = buffer.items.len - "(".len; |
| | 1709 | try dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, .Const, 0); |
| | 1710 | try buffer.appendSlice(") {\n switch (tag) {\n"); |
| | 1711 | for (enum_ty.enumFields().keys()) |name, index| { |
| | 1712 | const name_z = try dg.typedefs.allocator.dupeZ(u8, name); |
| | 1713 | defer dg.typedefs.allocator.free(name_z); |
| | 1714 | const name_bytes = name_z[0 .. name_z.len + 1]; |
| | 1715 | |
| | 1716 | var tag_val_pl: Value.Payload.U32 = .{ |
| | 1717 | .base = .{ .tag = .enum_field_index }, |
| | 1718 | .data = @intCast(u32, index), |
| | 1719 | }; |
| | 1720 | const tag_val = Value.initPayload(&tag_val_pl.base); |
| | 1721 | |
| | 1722 | var int_val_pl: Value.Payload.U64 = undefined; |
| | 1723 | const int_val = tag_val.enumToInt(enum_ty, &int_val_pl); |
| | 1724 | |
| | 1725 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; |
| | 1726 | const name_ty = Type.initPayload(&name_ty_pl.base); |
| | 1727 | |
| | 1728 | var name_val_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes }; |
| | 1729 | const name_val = Value.initPayload(&name_val_pl.base); |
| | 1730 | |
| | 1731 | var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| | 1732 | const len_val = Value.initPayload(&len_val_pl.base); |
| | 1733 | |
| | 1734 | try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val, .Other)}); |
| | 1735 | try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0); |
| | 1736 | try buffer.appendSlice(" = "); |
| | 1737 | try dg.renderValue(bw, name_ty, name_val, .Other); |
| | 1738 | try buffer.appendSlice(";\n return ("); |
| | 1739 | try dg.renderTypecast(bw, name_slice_ty); |
| | 1740 | try bw.print("){{{}, {}}};\n", .{ |
| | 1741 | fmtIdent("name"), |
| | 1742 | try dg.fmtIntLiteral(Type.usize, len_val, .Other), |
| | 1743 | }); |
| | 1744 | |
| | 1745 | try buffer.appendSlice(" }\n"); |
| | 1746 | } |
| | 1747 | try buffer.appendSlice(" }\n while (true) zig_breakpoint();\n}\n"); |
| | 1748 | |
| | 1749 | const rendered = buffer.toOwnedSlice(); |
| | 1750 | errdefer dg.typedefs.allocator.free(rendered); |
| | 1751 | const name = rendered[name_begin..name_end]; |
| | 1752 | |
| | 1753 | try dg.typedefs.ensureUnusedCapacity(1); |
| | 1754 | dg.typedefs.putAssumeCapacityNoClobber( |
| | 1755 | try enum_ty.copy(dg.typedefs_arena), |
| | 1756 | .{ .name = name, .rendered = rendered }, |
| | 1757 | ); |
| | 1758 | |
| | 1759 | return name; |
| | 1760 | } |
| | 1761 | |
| | 1762 | fn getTagNameFn(dg: *DeclGen, enum_ty: Type) ![]const u8 { |
| | 1763 | return dg.getTypedefName(enum_ty) orelse |
| | 1764 | try dg.renderTagNameFn(enum_ty); |
| | 1765 | } |
| | 1766 | |
| 1697 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { | 1767 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { |
| 1698 | switch (tv.val.tag()) { | 1768 | switch (tv.val.tag()) { |
| 1699 | .extern_fn => return true, | 1769 | .extern_fn => return true, |
| ... | @@ -1805,25 +1875,22 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -1805,25 +1875,22 @@ pub fn genErrDecls(o: *Object) !void { |
| 1805 | o.indent_writer.popIndent(); | 1875 | o.indent_writer.popIndent(); |
| 1806 | try writer.writeAll("};\n"); | 1876 | try writer.writeAll("};\n"); |
| 1807 | | 1877 | |
| 1808 | const name_prefix = "zig_errorName_"; | 1878 | const name_prefix = "zig_errorName"; |
| 1809 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + max_name_len + 1); | 1879 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + "_".len + max_name_len + 1); |
| 1810 | defer o.dg.gpa.free(name_buf); | 1880 | defer o.dg.gpa.free(name_buf); |
| 1811 | | 1881 | |
| 1812 | std.mem.copy(u8, name_buf, name_prefix); | 1882 | std.mem.copy(u8, name_buf, name_prefix ++ "_"); |
| 1813 | for (o.dg.module.error_name_list.items) |name| { | 1883 | for (o.dg.module.error_name_list.items) |name| { |
| 1814 | std.mem.copy(u8, name_buf[name_prefix.len..], name); | 1884 | std.mem.copy(u8, name_buf[name_prefix.len + "_".len ..], name); |
| 1815 | name_buf[name_prefix.len + name.len] = 0; | 1885 | name_buf[name_prefix.len + "_".len + name.len] = 0; |
| 1816 | | 1886 | |
| 1817 | const identifier = name_buf[0 .. name_prefix.len + name.len :0]; | 1887 | const identifier = name_buf[0 .. name_prefix.len + "_".len + name.len :0]; |
| 1818 | const nameZ = identifier[name_prefix.len..]; | 1888 | const name_z = identifier[name_prefix.len + "_".len ..]; |
| 1819 | | 1889 | |
| 1820 | var name_ty_pl = Type.Payload.Len{ | 1890 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; |
| 1821 | .base = .{ .tag = .array_u8_sentinel_0 }, | | |
| 1822 | .data = name.len, | | |
| 1823 | }; | | |
| 1824 | const name_ty = Type.initPayload(&name_ty_pl.base); | 1891 | const name_ty = Type.initPayload(&name_ty_pl.base); |
| 1825 | | 1892 | |
| 1826 | var name_val_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = nameZ }; | 1893 | var name_val_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z }; |
| 1827 | const name_val = Value.initPayload(&name_val_pl.base); | 1894 | const name_val = Value.initPayload(&name_val_pl.base); |
| 1828 | | 1895 | |
| 1829 | try writer.writeAll("static "); | 1896 | try writer.writeAll("static "); |
| ... | @@ -1840,11 +1907,18 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -1840,11 +1907,18 @@ pub fn genErrDecls(o: *Object) !void { |
| 1840 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); | 1907 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); |
| 1841 | | 1908 | |
| 1842 | try writer.writeAll("static "); | 1909 | try writer.writeAll("static "); |
| 1843 | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = "zig_errorName" }, .Const, 0); | 1910 | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, .Const, 0); |
| 1844 | try writer.writeAll(" = {"); | 1911 | try writer.writeAll(" = {"); |
| 1845 | for (o.dg.module.error_name_list.items) |name, value| { | 1912 | for (o.dg.module.error_name_list.items) |name, value| { |
| 1846 | if (value != 0) try writer.writeByte(','); | 1913 | if (value != 0) try writer.writeByte(','); |
| 1847 | try writer.print("{{zig_errorName_{}, {d}u}}", .{ fmtIdent(name), name.len }); | 1914 | |
| | 1915 | var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; |
| | 1916 | const len_val = Value.initPayload(&len_val_pl.base); |
| | 1917 | |
| | 1918 | try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{ |
| | 1919 | fmtIdent(name), |
| | 1920 | try o.dg.fmtIntLiteral(Type.usize, len_val, .Other), |
| | 1921 | }); |
| 1848 | } | 1922 | } |
| 1849 | try writer.writeAll("};\n"); | 1923 | try writer.writeAll("};\n"); |
| 1850 | } | 1924 | } |
| ... | @@ -4210,18 +4284,19 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4210,18 +4284,19 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4210 | if (f.liveness.isUnused(inst)) return CValue.none; | 4284 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4211 | | 4285 | |
| 4212 | const un_op = f.air.instructions.items(.data)[inst].un_op; | 4286 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 4213 | const writer = f.object.writer(); | | |
| 4214 | const inst_ty = f.air.typeOfIndex(inst); | 4287 | const inst_ty = f.air.typeOfIndex(inst); |
| | 4288 | const enum_ty = f.air.typeOf(un_op); |
| 4215 | const operand = try f.resolveInst(un_op); | 4289 | const operand = try f.resolveInst(un_op); |
| | 4290 | |
| | 4291 | const writer = f.object.writer(); |
| 4216 | const local = try f.allocLocal(inst_ty, .Const); | 4292 | const local = try f.allocLocal(inst_ty, .Const); |
| | 4293 | try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)}); |
| | 4294 | try f.writeCValue(writer, operand); |
| | 4295 | try writer.writeAll(");\n"); |
| 4217 | | 4296 | |
| 4218 | try writer.writeAll(" = "); | 4297 | try f.object.dg.fwd_decl.writer().writeAll("// This is where the fwd decl for tagName ended up\n"); |
| 4219 | | 4298 | |
| 4220 | _ = operand; | 4299 | return local; |
| 4221 | _ = local; | | |
| 4222 | return f.fail("TODO: C backend: implement airTagName", .{}); | | |
| 4223 | //try writer.writeAll(";\n"); | | |
| 4224 | //return local; | | |
| 4225 | } | 4300 | } |
| 4226 | | 4301 | |
| 4227 | fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { | 4302 | fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |