| ... | ... | @@ -220,8 +220,8 @@ fn isReservedIdent(ident: []const u8) bool { |
| 220 | 220 | 'A'...'Z', '_' => return true, |
| 221 | 221 | else => return false, |
| 222 | 222 | } |
| 223 | | } else if (std.mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or |
| 224 | | std.mem.startsWith(u8, ident, "DUMMYUNIONNAME")) |
| 223 | } else if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or |
| 224 | mem.startsWith(u8, ident, "DUMMYUNIONNAME")) |
| 225 | 225 | { // windows.h |
| 226 | 226 | return true; |
| 227 | 227 | } else return reserved_idents.has(ident); |
| ... | ... | @@ -498,7 +498,7 @@ pub const Object = struct { |
| 498 | 498 | |
| 499 | 499 | /// This data is available both when outputting .c code and when outputting an .h file. |
| 500 | 500 | pub const DeclGen = struct { |
| 501 | | gpa: std.mem.Allocator, |
| 501 | gpa: mem.Allocator, |
| 502 | 502 | module: *Module, |
| 503 | 503 | decl: ?*Decl, |
| 504 | 504 | decl_index: Decl.OptionalIndex, |
| ... | ... | @@ -536,6 +536,9 @@ pub const DeclGen = struct { |
| 536 | 536 | if (func.data.owner_decl != decl_index) |
| 537 | 537 | return dg.renderDeclValue(writer, ty, val, func.data.owner_decl, location); |
| 538 | 538 | |
| 539 | if (decl.val.castTag(.variable)) |var_payload| |
| 540 | try dg.renderFwdDecl(decl_index, var_payload.data); |
| 541 | |
| 539 | 542 | if (ty.isSlice()) { |
| 540 | 543 | if (location == .StaticInitializer) { |
| 541 | 544 | try writer.writeByte('{'); |
| ... | ... | @@ -1816,8 +1819,23 @@ pub const DeclGen = struct { |
| 1816 | 1819 | try dg.writeCValue(writer, member); |
| 1817 | 1820 | } |
| 1818 | 1821 | |
| 1819 | | const IdentHasher = std.crypto.auth.siphash.SipHash128(1, 3); |
| 1820 | | const ident_hasher_init: IdentHasher = IdentHasher.init(&[_]u8{0} ** IdentHasher.key_length); |
| 1822 | fn renderFwdDecl(dg: *DeclGen, decl_index: Decl.Index, variable: *Module.Var) !void { |
| 1823 | const decl = dg.module.declPtr(decl_index); |
| 1824 | const fwd_decl_writer = dg.fwd_decl.writer(); |
| 1825 | const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern; |
| 1826 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 1827 | if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); |
| 1828 | if (variable.is_weak_linkage) try fwd_decl_writer.writeAll("zig_weak_linkage "); |
| 1829 | try dg.renderTypeAndName( |
| 1830 | fwd_decl_writer, |
| 1831 | decl.ty, |
| 1832 | .{ .decl = decl_index }, |
| 1833 | CQualifiers.init(.{ .@"const" = !variable.is_mutable }), |
| 1834 | decl.@"align", |
| 1835 | .complete, |
| 1836 | ); |
| 1837 | try fwd_decl_writer.writeAll(";\n"); |
| 1838 | } |
| 1821 | 1839 | |
| 1822 | 1840 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void { |
| 1823 | 1841 | const decl = dg.module.declPtr(decl_index); |
| ... | ... | @@ -1826,7 +1844,7 @@ pub const DeclGen = struct { |
| 1826 | 1844 | if (dg.module.decl_exports.get(decl_index)) |exports| { |
| 1827 | 1845 | try writer.writeAll(exports.items[export_index].options.name); |
| 1828 | 1846 | } else if (decl.isExtern()) { |
| 1829 | | try writer.writeAll(mem.sliceTo(decl.name, 0)); |
| 1847 | try writer.writeAll(mem.span(decl.name)); |
| 1830 | 1848 | } else { |
| 1831 | 1849 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), |
| 1832 | 1850 | // expand to 3x the length of its input, but let's cut it off at a much shorter limit. |
| ... | ... | @@ -2393,9 +2411,9 @@ pub fn genErrDecls(o: *Object) !void { |
| 2393 | 2411 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + max_name_len); |
| 2394 | 2412 | defer o.dg.gpa.free(name_buf); |
| 2395 | 2413 | |
| 2396 | | std.mem.copy(u8, name_buf, name_prefix); |
| 2414 | mem.copy(u8, name_buf, name_prefix); |
| 2397 | 2415 | for (o.dg.module.error_name_list.items) |name| { |
| 2398 | | std.mem.copy(u8, name_buf[name_prefix.len..], name); |
| 2416 | mem.copy(u8, name_buf[name_prefix.len..], name); |
| 2399 | 2417 | const identifier = name_buf[0 .. name_prefix.len + name.len]; |
| 2400 | 2418 | |
| 2401 | 2419 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; |
| ... | ... | @@ -2641,21 +2659,16 @@ pub fn genDecl(o: *Object) !void { |
| 2641 | 2659 | try genExports(o); |
| 2642 | 2660 | } else if (tv.val.castTag(.variable)) |var_payload| { |
| 2643 | 2661 | const variable: *Module.Var = var_payload.data; |
| 2644 | | |
| 2645 | | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; |
| 2646 | | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 2647 | | |
| 2648 | | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2649 | | if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); |
| 2650 | | try o.dg.renderTypeAndName(fwd_decl_writer, decl.ty, decl_c_value, .{}, decl.@"align", .complete); |
| 2651 | | try fwd_decl_writer.writeAll(";\n"); |
| 2662 | try o.dg.renderFwdDecl(decl_c_value.decl, variable); |
| 2652 | 2663 | try genExports(o); |
| 2653 | 2664 | |
| 2654 | 2665 | if (variable.is_extern) return; |
| 2655 | 2666 | |
| 2667 | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; |
| 2656 | 2668 | const w = o.writer(); |
| 2657 | 2669 | if (!is_global) try w.writeAll("static "); |
| 2658 | 2670 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); |
| 2671 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); |
| 2659 | 2672 | if (decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section}); |
| 2660 | 2673 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.@"align", .complete); |
| 2661 | 2674 | if (decl.@"linksection" != null) try w.writeAll(", read, write)"); |
| ... | ... | @@ -4729,9 +4742,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4729 | 4742 | const locals_begin = @intCast(LocalIndex, f.locals.items.len); |
| 4730 | 4743 | const constraints_extra_begin = extra_i; |
| 4731 | 4744 | for (outputs) |output| { |
| 4732 | | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4733 | | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 4734 | | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4745 | const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4746 | const constraint = mem.sliceTo(extra_bytes, 0); |
| 4747 | const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4735 | 4748 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4736 | 4749 | // for the string, we still use the next u32 for the null terminator. |
| 4737 | 4750 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| ... | ... | @@ -4761,14 +4774,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4761 | 4774 | } |
| 4762 | 4775 | } |
| 4763 | 4776 | for (inputs) |input| { |
| 4764 | | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4765 | | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 4766 | | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4777 | const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4778 | const constraint = mem.sliceTo(extra_bytes, 0); |
| 4779 | const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4767 | 4780 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4768 | 4781 | // for the string, we still use the next u32 for the null terminator. |
| 4769 | 4782 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 4770 | 4783 | |
| 4771 | | if (constraint.len < 1 or std.mem.indexOfScalar(u8, "=+&%", constraint[0]) != null or |
| 4784 | if (constraint.len < 1 or mem.indexOfScalar(u8, "=+&%", constraint[0]) != null or |
| 4772 | 4785 | (constraint[0] == '{' and constraint[constraint.len - 1] != '}')) |
| 4773 | 4786 | { |
| 4774 | 4787 | return f.fail("CBE: constraint not supported: '{s}'", .{constraint}); |
| ... | ... | @@ -4794,7 +4807,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4794 | 4807 | } |
| 4795 | 4808 | } |
| 4796 | 4809 | for (0..clobbers_len) |_| { |
| 4797 | | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 4810 | const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 4798 | 4811 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4799 | 4812 | // for the string, we still use the next u32 for the null terminator. |
| 4800 | 4813 | extra_i += clobber.len / 4 + 1; |
| ... | ... | @@ -4859,16 +4872,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4859 | 4872 | var locals_index = locals_begin; |
| 4860 | 4873 | try writer.writeByte(':'); |
| 4861 | 4874 | for (outputs, 0..) |output, index| { |
| 4862 | | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4863 | | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 4864 | | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4875 | const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4876 | const constraint = mem.sliceTo(extra_bytes, 0); |
| 4877 | const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4865 | 4878 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4866 | 4879 | // for the string, we still use the next u32 for the null terminator. |
| 4867 | 4880 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 4868 | 4881 | |
| 4869 | 4882 | if (index > 0) try writer.writeByte(','); |
| 4870 | 4883 | try writer.writeByte(' '); |
| 4871 | | if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); |
| 4884 | if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); |
| 4872 | 4885 | const is_reg = constraint[1] == '{'; |
| 4873 | 4886 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)}); |
| 4874 | 4887 | if (is_reg) { |
| ... | ... | @@ -4883,16 +4896,16 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4883 | 4896 | } |
| 4884 | 4897 | try writer.writeByte(':'); |
| 4885 | 4898 | for (inputs, 0..) |input, index| { |
| 4886 | | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4887 | | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 4888 | | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4899 | const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4900 | const constraint = mem.sliceTo(extra_bytes, 0); |
| 4901 | const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4889 | 4902 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4890 | 4903 | // for the string, we still use the next u32 for the null terminator. |
| 4891 | 4904 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 4892 | 4905 | |
| 4893 | 4906 | if (index > 0) try writer.writeByte(','); |
| 4894 | 4907 | try writer.writeByte(' '); |
| 4895 | | if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); |
| 4908 | if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); |
| 4896 | 4909 | |
| 4897 | 4910 | const is_reg = constraint[0] == '{'; |
| 4898 | 4911 | const input_val = try f.resolveInst(input); |
| ... | ... | @@ -4906,7 +4919,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4906 | 4919 | } |
| 4907 | 4920 | try writer.writeByte(':'); |
| 4908 | 4921 | for (0..clobbers_len) |clobber_i| { |
| 4909 | | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 4922 | const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 4910 | 4923 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4911 | 4924 | // for the string, we still use the next u32 for the null terminator. |
| 4912 | 4925 | extra_i += clobber.len / 4 + 1; |
| ... | ... | @@ -4921,9 +4934,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4921 | 4934 | extra_i = constraints_extra_begin; |
| 4922 | 4935 | locals_index = locals_begin; |
| 4923 | 4936 | for (outputs) |output| { |
| 4924 | | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4925 | | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 4926 | | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4937 | const extra_bytes = mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 4938 | const constraint = mem.sliceTo(extra_bytes, 0); |
| 4939 | const name = mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 4927 | 4940 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4928 | 4941 | // for the string, we still use the next u32 for the null terminator. |
| 4929 | 4942 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| ... | ... | @@ -7274,7 +7287,7 @@ fn formatIntLiteral( |
| 7274 | 7287 | var int_buf: Value.BigIntSpace = undefined; |
| 7275 | 7288 | const int = if (data.val.isUndefDeep()) blk: { |
| 7276 | 7289 | undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits)); |
| 7277 | | std.mem.set(BigIntLimb, undef_limbs, undefPattern(BigIntLimb)); |
| 7290 | mem.set(BigIntLimb, undef_limbs, undefPattern(BigIntLimb)); |
| 7278 | 7291 | |
| 7279 | 7292 | var undef_int = BigInt.Mutable{ |
| 7280 | 7293 | .limbs = undef_limbs, |
| ... | ... | @@ -7369,7 +7382,7 @@ fn formatIntLiteral( |
| 7369 | 7382 | } else { |
| 7370 | 7383 | try data.cty.renderLiteralPrefix(writer, data.kind); |
| 7371 | 7384 | wrap.convertToTwosComplement(int, data.int_info.signedness, c_bits); |
| 7372 | | std.mem.set(BigIntLimb, wrap.limbs[wrap.len..], 0); |
| 7385 | mem.set(BigIntLimb, wrap.limbs[wrap.len..], 0); |
| 7373 | 7386 | wrap.len = wrap.limbs.len; |
| 7374 | 7387 | const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count); |
| 7375 | 7388 | |