| ... | ... | @@ -1694,6 +1694,76 @@ pub const DeclGen = struct { |
| 1694 | 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 | 1767 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { |
| 1698 | 1768 | switch (tv.val.tag()) { |
| 1699 | 1769 | .extern_fn => return true, |
| ... | ... | @@ -1805,25 +1875,22 @@ pub fn genErrDecls(o: *Object) !void { |
| 1805 | 1875 | o.indent_writer.popIndent(); |
| 1806 | 1876 | try writer.writeAll("};\n"); |
| 1807 | 1877 | |
| 1808 | | const name_prefix = "zig_errorName_"; |
| 1809 | | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + max_name_len + 1); |
| 1878 | const name_prefix = "zig_errorName"; |
| 1879 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + "_".len + max_name_len + 1); |
| 1810 | 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 | 1883 | for (o.dg.module.error_name_list.items) |name| { |
| 1814 | | std.mem.copy(u8, name_buf[name_prefix.len..], name); |
| 1815 | | name_buf[name_prefix.len + name.len] = 0; |
| 1884 | std.mem.copy(u8, name_buf[name_prefix.len + "_".len ..], name); |
| 1885 | name_buf[name_prefix.len + "_".len + name.len] = 0; |
| 1816 | 1886 | |
| 1817 | | const identifier = name_buf[0 .. name_prefix.len + name.len :0]; |
| 1818 | | const nameZ = identifier[name_prefix.len..]; |
| 1887 | const identifier = name_buf[0 .. name_prefix.len + "_".len + name.len :0]; |
| 1888 | const name_z = identifier[name_prefix.len + "_".len ..]; |
| 1819 | 1889 | |
| 1820 | | var name_ty_pl = Type.Payload.Len{ |
| 1821 | | .base = .{ .tag = .array_u8_sentinel_0 }, |
| 1822 | | .data = name.len, |
| 1823 | | }; |
| 1890 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; |
| 1824 | 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 | 1894 | const name_val = Value.initPayload(&name_val_pl.base); |
| 1828 | 1895 | |
| 1829 | 1896 | try writer.writeAll("static "); |
| ... | ... | @@ -1840,11 +1907,18 @@ pub fn genErrDecls(o: *Object) !void { |
| 1840 | 1907 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); |
| 1841 | 1908 | |
| 1842 | 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 | 1911 | try writer.writeAll(" = {"); |
| 1845 | 1912 | for (o.dg.module.error_name_list.items) |name, value| { |
| 1846 | 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 | 1923 | try writer.writeAll("};\n"); |
| 1850 | 1924 | } |
| ... | ... | @@ -4210,18 +4284,19 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4210 | 4284 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4211 | 4285 | |
| 4212 | 4286 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 4213 | | const writer = f.object.writer(); |
| 4214 | 4287 | const inst_ty = f.air.typeOfIndex(inst); |
| 4288 | const enum_ty = f.air.typeOf(un_op); |
| 4215 | 4289 | const operand = try f.resolveInst(un_op); |
| 4290 | |
| 4291 | const writer = f.object.writer(); |
| 4216 | 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; |
| 4221 | | _ = local; |
| 4222 | | return f.fail("TODO: C backend: implement airTagName", .{}); |
| 4223 | | //try writer.writeAll(";\n"); |
| 4224 | | //return local; |
| 4299 | return local; |
| 4225 | 4300 | } |
| 4226 | 4301 | |
| 4227 | 4302 | fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |