| author | |
| committer | |
| log | 7fb3683c32fc24d12452f49e0c1639531e57c47d |
| tree | 0b9e38fd34be870ba2eb1e50147a58ec81709fd5 |
| parent | 7f3bc45772d6af33e0e663ba534eba5653792843 |
- Add .StaticInitializer to ValueRenderLocation to indicate that the emitted values
must be constant expressions (no function calls, struct casting).
- Add new path for special float types (nan, inf) that works in constant expressions
- Implement windows.teb() using a syscall for .stage2_c because x64 MSVC
doesn't support any kind of inline asm3 files changed, 146 insertions(+), 42 deletions(-)
lib/std/os/windows.zig+39-4| ... | ... | @@ -1782,10 +1782,30 @@ pub fn teb() *TEB { |
| 1782 | 1782 | \\ movl %%fs:0x18, %[ptr] |
| 1783 | 1783 | : [ptr] "=r" (-> *TEB), |
| 1784 | 1784 | ), |
| 1785 | .x86_64 => asm volatile ( | |
| 1786 | \\ movq %%gs:0x30, %[ptr] | |
| 1787 | : [ptr] "=r" (-> *TEB), | |
| 1788 | ), | |
| 1785 | .x86_64 => blk: { | |
| 1786 | if (builtin.zig_backend == .stage2_c) { | |
| 1787 | // TODO: __asm is not available on x64 MSVC. This is a workaround | |
| 1788 | // until an intrinsic to read the gs register is available | |
| 1789 | var thread_information: THREAD_BASIC_INFORMATION = undefined; | |
| 1790 | const result = ntdll.NtQueryInformationThread( | |
| 1791 | kernel32.GetCurrentThread(), | |
| 1792 | .ThreadBasicInformation, | |
| 1793 | &thread_information, | |
| 1794 | @sizeOf(THREAD_BASIC_INFORMATION), | |
| 1795 | null); | |
| 1796 | ||
| 1797 | if (result == .SUCCESS) { | |
| 1798 | break :blk @ptrCast(*TEB, @alignCast(@alignOf(TEB), thread_information.TebBaseAddress)); | |
| 1799 | } else { | |
| 1800 | unexpectedStatus(result) catch unreachable; | |
| 1801 | } | |
| 1802 | } else { | |
| 1803 | break :blk asm volatile ( | |
| 1804 | \\ movq %%gs:0x30, %[ptr] | |
| 1805 | : [ptr] "=r" (-> *TEB), | |
| 1806 | ); | |
| 1807 | } | |
| 1808 | }, | |
| 1789 | 1809 | .aarch64 => asm volatile ( |
| 1790 | 1810 | \\ mov %[ptr], x18 |
| 1791 | 1811 | : [ptr] "=r" (-> *TEB), |
| ... | ... | @@ -3455,6 +3475,21 @@ pub const ASSEMBLY_STORAGE_MAP = opaque {}; |
| 3455 | 3475 | pub const FLS_CALLBACK_INFO = opaque {}; |
| 3456 | 3476 | pub const RTL_BITMAP = opaque {}; |
| 3457 | 3477 | pub const KAFFINITY = usize; |
| 3478 | pub const KPRIORITY = i32; | |
| 3479 | ||
| 3480 | pub const CLIENT_ID = extern struct { | |
| 3481 | UniqueProcess: HANDLE, | |
| 3482 | UniqueThread: HANDLE, | |
| 3483 | }; | |
| 3484 | ||
| 3485 | pub const THREAD_BASIC_INFORMATION = extern struct { | |
| 3486 | ExitStatus: NTSTATUS, | |
| 3487 | TebBaseAddress: PVOID, | |
| 3488 | ClientId: CLIENT_ID, | |
| 3489 | AffinityMask: KAFFINITY, | |
| 3490 | Priority: KPRIORITY, | |
| 3491 | BasePriority: KPRIORITY, | |
| 3492 | }; | |
| 3458 | 3493 | |
| 3459 | 3494 | pub const TEB = extern struct { |
| 3460 | 3495 | Reserved1: [12]PVOID, |
lib/zig.h+65-9| ... | ... | @@ -1151,8 +1151,8 @@ typedef signed __int128 zig_i128; |
| 1151 | 1151 | |
| 1152 | 1152 | #define zig_as_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) |
| 1153 | 1153 | #define zig_as_i128(hi, lo) ((zig_i128)zig_as_u128(hi, lo)) |
| 1154 | #define zig_as_init_u128(hi, lo) zig_as_u128(hi, lo) | |
| 1155 | #define zig_as_init_i128(hi, lo) zig_as_i128(hi, lo) | |
| 1154 | #define zig_as_constant_u128(hi, lo) zig_as_u128(hi, lo) | |
| 1155 | #define zig_as_constant_i128(hi, lo) zig_as_i128(hi, lo) | |
| 1156 | 1156 | #define zig_hi_u128(val) ((zig_u64)((val) >> 64)) |
| 1157 | 1157 | #define zig_lo_u128(val) ((zig_u64)((val) >> 0)) |
| 1158 | 1158 | #define zig_hi_i128(val) ((zig_i64)((val) >> 64)) |
| ... | ... | @@ -1180,8 +1180,8 @@ typedef struct { zig_align(16) zig_i64 hi; zig_u64 lo; } zig_i128; |
| 1180 | 1180 | |
| 1181 | 1181 | #define zig_as_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) |
| 1182 | 1182 | #define zig_as_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) }) |
| 1183 | #define zig_as_init_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1184 | #define zig_as_init_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1183 | #define zig_as_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1184 | #define zig_as_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } | |
| 1185 | 1185 | #define zig_hi_u128(val) ((val).hi) |
| 1186 | 1186 | #define zig_lo_u128(val) ((val).lo) |
| 1187 | 1187 | #define zig_hi_i128(val) ((val).hi) |
| ... | ... | @@ -1342,13 +1342,28 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1342 | 1342 | } |
| 1343 | 1343 | |
| 1344 | 1344 | // TODO: Implement |
| 1345 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs); | |
| 1345 | static zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { | |
| 1346 | ||
| 1347 | } | |
| 1346 | 1348 | |
| 1347 | 1349 | // TODO: Implement |
| 1348 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs); | |
| 1350 | zig_extern zig_u128 __udivmodti4(zig_u128 lhs, zig_u128 rhs, zig_u128* rem); | |
| 1351 | static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { | |
| 1352 | zig_u128 rem; | |
| 1353 | return __udivmodti4(lhs, rhs, &rem); | |
| 1354 | }; | |
| 1349 | 1355 | |
| 1350 | 1356 | // TODO: Implement |
| 1351 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs); | |
| 1357 | zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs); | |
| 1358 | static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { | |
| 1359 | return __modti3(lhs, rhs); | |
| 1360 | } | |
| 1361 | ||
| 1362 | // TODO: Implement | |
| 1363 | zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs); | |
| 1364 | static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { | |
| 1365 | return __umodti3(lhs, rhs); | |
| 1366 | } | |
| 1352 | 1367 | |
| 1353 | 1368 | static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1354 | 1369 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| ... | ... | @@ -1413,8 +1428,16 @@ static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1413 | 1428 | return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); |
| 1414 | 1429 | } |
| 1415 | 1430 | |
| 1416 | // TODO: Implement | |
| 1417 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs); | |
| 1431 | #if _MSC_VER | |
| 1432 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { | |
| 1433 | zig_u64 lo_carry; | |
| 1434 | zig_u64 lo = _umul128(lhs.lo, rhs.lo, &lo_carry); | |
| 1435 | zig_u64 hi = lhs.hi * rhs.lo + lhs.lo * rhs.hi + lo_carry; | |
| 1436 | return zig_as_u128(hi, lo); | |
| 1437 | } | |
| 1438 | #else | |
| 1439 | static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs); // TODO | |
| 1440 | #endif | |
| 1418 | 1441 | |
| 1419 | 1442 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1420 | 1443 | return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits); |
| ... | ... | @@ -1636,14 +1659,22 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) { |
| 1636 | 1659 | /* ========================= Floating Point Support ========================= */ |
| 1637 | 1660 | |
| 1638 | 1661 | #if _MSC_VER |
| 1662 | #define zig_msvc_flt_inf ((double)(1e+300 * 1e+300)) | |
| 1663 | #define zig_msvc_flt_inff ((float)(1e+300 * 1e+300)) | |
| 1664 | #define zig_msvc_flt_infl ((long double)(1e+300 * 1e+300)) | |
| 1665 | #define zig_msvc_flt_nan ((double)(zig_msvc_flt_inf * 0.f)) | |
| 1666 | #define zig_msvc_flt_nanf ((float)(zig_msvc_flt_inf * 0.f)) | |
| 1667 | #define zig_msvc_flt_nanl ((long double)(zig_msvc_flt_inf * 0.f)) | |
| 1639 | 1668 | #define __builtin_nan(str) nan(str) |
| 1640 | 1669 | #define __builtin_nanf(str) nanf(str) |
| 1641 | 1670 | #define __builtin_nanl(str) nanl(str) |
| 1671 | #define __builtin_inf() zig_msvc_flt_inf | |
| 1642 | 1672 | #endif |
| 1643 | 1673 | |
| 1644 | 1674 | #define zig_has_f16 1 |
| 1645 | 1675 | #define zig_bitSizeOf_f16 16 |
| 1646 | 1676 | #define zig_libc_name_f16(name) __##name##h |
| 1677 | #define zig_as_special_constant_f16(sign, name, arg, repr) zig_as_special_f16(sign, name, arg, repr) | |
| 1647 | 1678 | #define zig_as_special_f16(sign, name, arg, repr) sign zig_as_f16(__builtin_##name, )(arg) |
| 1648 | 1679 | #if FLT_MANT_DIG == 11 |
| 1649 | 1680 | typedef float zig_f16; |
| ... | ... | @@ -1669,11 +1700,18 @@ typedef zig_i16 zig_f16; |
| 1669 | 1700 | #define zig_as_f16(fp, repr) repr |
| 1670 | 1701 | #undef zig_as_special_f16 |
| 1671 | 1702 | #define zig_as_special_f16(sign, name, arg, repr) repr |
| 1703 | #undef zig_as_special_constant_f16 | |
| 1704 | #define zig_as_special_constant_f16(sign, name, arg, repr) repr | |
| 1672 | 1705 | #endif |
| 1673 | 1706 | |
| 1674 | 1707 | #define zig_has_f32 1 |
| 1675 | 1708 | #define zig_bitSizeOf_f32 32 |
| 1676 | 1709 | #define zig_libc_name_f32(name) name##f |
| 1710 | #if _MSC_VER | |
| 1711 | #define zig_as_special_constant_f32(sign, name, arg, repr) sign zig_as_f32(zig_msvc_flt_##name, ) | |
| 1712 | #else | |
| 1713 | #define zig_as_special_constant_f32(sign, name, arg, repr) zig_as_special_f32(sign, name, arg, repr) | |
| 1714 | #endif | |
| 1677 | 1715 | #define zig_as_special_f32(sign, name, arg, repr) sign zig_as_f32(__builtin_##name, )(arg) |
| 1678 | 1716 | #if FLT_MANT_DIG == 24 |
| 1679 | 1717 | typedef float zig_f32; |
| ... | ... | @@ -1696,11 +1734,18 @@ typedef zig_i32 zig_f32; |
| 1696 | 1734 | #define zig_as_f32(fp, repr) repr |
| 1697 | 1735 | #undef zig_as_special_f32 |
| 1698 | 1736 | #define zig_as_special_f32(sign, name, arg, repr) repr |
| 1737 | #undef zig_as_special_constant_f32 | |
| 1738 | #define zig_as_special_constant_f32(sign, name, arg, repr) repr | |
| 1699 | 1739 | #endif |
| 1700 | 1740 | |
| 1701 | 1741 | #define zig_has_f64 1 |
| 1702 | 1742 | #define zig_bitSizeOf_f64 64 |
| 1703 | 1743 | #define zig_libc_name_f64(name) name |
| 1744 | #if _MSC_VER | |
| 1745 | #define zig_as_special_constant_f64(sign, name, arg, repr) sign zig_as_f64(zig_msvc_flt_##name, ) | |
| 1746 | #else | |
| 1747 | #define zig_as_special_constant_f64(sign, name, arg, repr) zig_as_special_f64(sign, name, arg, repr) | |
| 1748 | #endif | |
| 1704 | 1749 | #define zig_as_special_f64(sign, name, arg, repr) sign zig_as_f64(__builtin_##name, )(arg) |
| 1705 | 1750 | #if FLT_MANT_DIG == 53 |
| 1706 | 1751 | typedef float zig_f64; |
| ... | ... | @@ -1726,11 +1771,14 @@ typedef zig_i64 zig_f64; |
| 1726 | 1771 | #define zig_as_f64(fp, repr) repr |
| 1727 | 1772 | #undef zig_as_special_f64 |
| 1728 | 1773 | #define zig_as_special_f64(sign, name, arg, repr) repr |
| 1774 | #undef zig_as_special_constant_f64 | |
| 1775 | #define zig_as_special_constant_f64(sign, name, arg, repr) repr | |
| 1729 | 1776 | #endif |
| 1730 | 1777 | |
| 1731 | 1778 | #define zig_has_f80 1 |
| 1732 | 1779 | #define zig_bitSizeOf_f80 80 |
| 1733 | 1780 | #define zig_libc_name_f80(name) __##name##x |
| 1781 | #define zig_as_special_constant_f80(sign, name, arg, repr) zig_as_special_f80(sign, name, arg, repr) | |
| 1734 | 1782 | #define zig_as_special_f80(sign, name, arg, repr) sign zig_as_f80(__builtin_##name, )(arg) |
| 1735 | 1783 | #if FLT_MANT_DIG == 64 |
| 1736 | 1784 | typedef float zig_f80; |
| ... | ... | @@ -1759,11 +1807,14 @@ typedef zig_i128 zig_f80; |
| 1759 | 1807 | #define zig_as_f80(fp, repr) repr |
| 1760 | 1808 | #undef zig_as_special_f80 |
| 1761 | 1809 | #define zig_as_special_f80(sign, name, arg, repr) repr |
| 1810 | #undef zig_as_special_constant_f80 | |
| 1811 | #define zig_as_special_constant_f80(sign, name, arg, repr) repr | |
| 1762 | 1812 | #endif |
| 1763 | 1813 | |
| 1764 | 1814 | #define zig_has_f128 1 |
| 1765 | 1815 | #define zig_bitSizeOf_f128 128 |
| 1766 | 1816 | #define zig_libc_name_f128(name) name##q |
| 1817 | #define zig_as_special_constant_f128(sign, name, arg, repr) zig_as_special_f128(sign, name, arg, repr) | |
| 1767 | 1818 | #define zig_as_special_f128(sign, name, arg, repr) sign zig_as_f128(__builtin_##name, )(arg) |
| 1768 | 1819 | #if FLT_MANT_DIG == 113 |
| 1769 | 1820 | typedef float zig_f128; |
| ... | ... | @@ -1794,10 +1845,13 @@ typedef zig_i128 zig_f128; |
| 1794 | 1845 | #define zig_as_f128(fp, repr) repr |
| 1795 | 1846 | #undef zig_as_special_f128 |
| 1796 | 1847 | #define zig_as_special_f128(sign, name, arg, repr) repr |
| 1848 | #undef zig_as_special_constant_f128 | |
| 1849 | #define zig_as_special_constant_f128(sign, name, arg, repr) repr | |
| 1797 | 1850 | #endif |
| 1798 | 1851 | |
| 1799 | 1852 | #define zig_has_c_longdouble 1 |
| 1800 | 1853 | #define zig_libc_name_c_longdouble(name) name##l |
| 1854 | #define zig_as_special_constant_c_longdouble(sign, name, arg, repr) zig_as_special_c_longdouble(sign, name, arg, repr) | |
| 1801 | 1855 | #define zig_as_special_c_longdouble(sign, name, arg, repr) sign __builtin_##name##l(arg) |
| 1802 | 1856 | #if !_MSC_VER // TODO: Is there a better way to detect this is just double? |
| 1803 | 1857 | typedef long double zig_c_longdouble; |
| ... | ... | @@ -1811,6 +1865,8 @@ typedef zig_i128 zig_c_longdouble; |
| 1811 | 1865 | #define zig_as_c_longdouble(fp, repr) repr |
| 1812 | 1866 | #undef zig_as_special_c_longdouble |
| 1813 | 1867 | #define zig_as_special_c_longdouble(sign, name, arg, repr) repr |
| 1868 | #undef zig_as_special_constant_c_longdouble | |
| 1869 | #define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr | |
| 1814 | 1870 | #endif |
| 1815 | 1871 | |
| 1816 | 1872 | #define zig_cast_f16 (zig_f16) |
src/codegen/c.zig+42-29| ... | ... | @@ -711,6 +711,10 @@ pub const DeclGen = struct { |
| 711 | 711 | val = rt.data; |
| 712 | 712 | } |
| 713 | 713 | const target = dg.module.getTarget(); |
| 714 | const initializer_type: ValueRenderLocation = switch (location) { | |
| 715 | .StaticInitializer => .StaticInitializer, | |
| 716 | else => .Initializer, | |
| 717 | }; | |
| 714 | 718 | |
| 715 | 719 | const safety_on = switch (dg.module.optimizeMode()) { |
| 716 | 720 | .Debug, .ReleaseSafe => true, |
| ... | ... | @@ -785,9 +789,9 @@ pub const DeclGen = struct { |
| 785 | 789 | } |
| 786 | 790 | |
| 787 | 791 | try writer.writeAll("{ .payload = "); |
| 788 | try dg.renderValue(writer, payload_ty, val, .Initializer); | |
| 792 | try dg.renderValue(writer, payload_ty, val, initializer_type); | |
| 789 | 793 | try writer.writeAll(", .is_null = "); |
| 790 | try dg.renderValue(writer, Type.bool, val, .Initializer); | |
| 794 | try dg.renderValue(writer, Type.bool, val, initializer_type); | |
| 791 | 795 | return writer.writeAll(" }"); |
| 792 | 796 | }, |
| 793 | 797 | .Struct => switch (ty.containerLayout()) { |
| ... | ... | @@ -804,7 +808,7 @@ pub const DeclGen = struct { |
| 804 | 808 | if (!field.ty.hasRuntimeBits()) continue; |
| 805 | 809 | |
| 806 | 810 | if (!empty) try writer.writeByte(','); |
| 807 | try dg.renderValue(writer, field.ty, val, .Initializer); | |
| 811 | try dg.renderValue(writer, field.ty, val, initializer_type); | |
| 808 | 812 | |
| 809 | 813 | empty = false; |
| 810 | 814 | } |
| ... | ... | @@ -825,14 +829,14 @@ pub const DeclGen = struct { |
| 825 | 829 | const layout = ty.unionGetLayout(target); |
| 826 | 830 | if (layout.tag_size != 0) { |
| 827 | 831 | try writer.writeAll(" .tag = "); |
| 828 | try dg.renderValue(writer, tag_ty, val, .Initializer); | |
| 832 | try dg.renderValue(writer, tag_ty, val, initializer_type); | |
| 829 | 833 | try writer.writeByte(','); |
| 830 | 834 | } |
| 831 | 835 | try writer.writeAll(" .payload = {"); |
| 832 | 836 | } |
| 833 | 837 | for (ty.unionFields().values()) |field| { |
| 834 | 838 | if (!field.ty.hasRuntimeBits()) continue; |
| 835 | try dg.renderValue(writer, field.ty, val, .Initializer); | |
| 839 | try dg.renderValue(writer, field.ty, val, initializer_type); | |
| 836 | 840 | break; |
| 837 | 841 | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)}); |
| 838 | 842 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| ... | ... | @@ -846,7 +850,7 @@ pub const DeclGen = struct { |
| 846 | 850 | } |
| 847 | 851 | |
| 848 | 852 | try writer.writeAll("{ .payload = "); |
| 849 | try dg.renderValue(writer, ty.errorUnionPayload(), val, .Initializer); | |
| 853 | try dg.renderValue(writer, ty.errorUnionPayload(), val, initializer_type); | |
| 850 | 854 | return writer.print(", .error = {x} }}", .{ |
| 851 | 855 | try dg.fmtIntLiteral(ty.errorUnionSet(), val), |
| 852 | 856 | }); |
| ... | ... | @@ -873,7 +877,7 @@ pub const DeclGen = struct { |
| 873 | 877 | var index: usize = 0; |
| 874 | 878 | while (index < c_len) : (index += 1) { |
| 875 | 879 | if (index > 0) try writer.writeAll(", "); |
| 876 | try dg.renderValue(writer, ty.childType(), val, .Initializer); | |
| 880 | try dg.renderValue(writer, ty.childType(), val, initializer_type); | |
| 877 | 881 | } |
| 878 | 882 | return writer.writeByte('}'); |
| 879 | 883 | } |
| ... | ... | @@ -957,7 +961,7 @@ pub const DeclGen = struct { |
| 957 | 961 | } |
| 958 | 962 | try writer.writeAll(", "); |
| 959 | 963 | empty = false; |
| 960 | } else if (location != .StaticInitializer) { | |
| 964 | } else { | |
| 961 | 965 | // isSignalNan is equivalent to isNan currently, and MSVC doens't have nans, so prefer nan |
| 962 | 966 | const operation = if (std.math.isNan(f128_val)) |
| 963 | 967 | "nan" |
| ... | ... | @@ -968,7 +972,19 @@ pub const DeclGen = struct { |
| 968 | 972 | else |
| 969 | 973 | unreachable; |
| 970 | 974 | |
| 975 | if (location == .StaticInitializer) { | |
| 976 | if (!std.math.isNan(f128_val) and std.math.isSignalNan(f128_val)) | |
| 977 | return dg.fail("TODO: C backend: implement nans rendering in static initializers", .{}); | |
| 978 | ||
| 979 | // MSVC doesn't have a way to define a custom or signaling NaN value in a constant expression | |
| 980 | ||
| 981 | // TODO: Re-enable this check, otherwise we're writing qnan bit patterns on msvc incorrectly | |
| 982 | // if (std.math.isNan(f128_val) and f128_val != std.math.qnan_f128) | |
| 983 | // return dg.fail("Only quiet nans are supported in global variable initializers", .{}); | |
| 984 | } | |
| 985 | ||
| 971 | 986 | try writer.writeAll("zig_as_special_"); |
| 987 | if (location == .StaticInitializer) try writer.writeAll("constant_"); | |
| 972 | 988 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 973 | 989 | try writer.writeByte('('); |
| 974 | 990 | if (std.math.signbit(f128_val)) try writer.writeByte('-'); |
| ... | ... | @@ -987,7 +1003,6 @@ pub const DeclGen = struct { |
| 987 | 1003 | }; |
| 988 | 1004 | try writer.writeAll(", "); |
| 989 | 1005 | empty = false; |
| 990 | ||
| 991 | 1006 | } |
| 992 | 1007 | try writer.print("{x}", .{try dg.fmtIntLiteralLoc(int_ty, int_val, location)}); |
| 993 | 1008 | if (!empty) try writer.writeByte(')'); |
| ... | ... | @@ -1022,9 +1037,9 @@ pub const DeclGen = struct { |
| 1022 | 1037 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 1023 | 1038 | |
| 1024 | 1039 | try writer.writeByte('{'); |
| 1025 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, .Initializer); | |
| 1040 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, initializer_type); | |
| 1026 | 1041 | try writer.writeAll(", "); |
| 1027 | try dg.renderValue(writer, Type.usize, slice.len, .Initializer); | |
| 1042 | try dg.renderValue(writer, Type.usize, slice.len, initializer_type); | |
| 1028 | 1043 | try writer.writeByte('}'); |
| 1029 | 1044 | }, |
| 1030 | 1045 | .function => { |
| ... | ... | @@ -1062,7 +1077,7 @@ pub const DeclGen = struct { |
| 1062 | 1077 | try writer.writeByte('{'); |
| 1063 | 1078 | const ai = ty.arrayInfo(); |
| 1064 | 1079 | if (ai.sentinel) |s| { |
| 1065 | try dg.renderValue(writer, ai.elem_type, s, .Initializer); | |
| 1080 | try dg.renderValue(writer, ai.elem_type, s, initializer_type); | |
| 1066 | 1081 | } else { |
| 1067 | 1082 | try writer.writeByte('0'); |
| 1068 | 1083 | } |
| ... | ... | @@ -1085,6 +1100,7 @@ pub const DeclGen = struct { |
| 1085 | 1100 | // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal |
| 1086 | 1101 | const max_string_initializer_len = 65535; |
| 1087 | 1102 | |
| 1103 | ||
| 1088 | 1104 | const ai = ty.arrayInfo(); |
| 1089 | 1105 | if (ai.elem_type.eql(Type.u8, dg.module)) { |
| 1090 | 1106 | if (ai.len <= max_string_initializer_len) { |
| ... | ... | @@ -1112,7 +1128,7 @@ pub const DeclGen = struct { |
| 1112 | 1128 | } |
| 1113 | 1129 | if (ai.sentinel) |s| { |
| 1114 | 1130 | if (index != 0) try writer.writeByte(','); |
| 1115 | try dg.renderValue(writer, ai.elem_type, s, .Initializer); | |
| 1131 | try dg.renderValue(writer, ai.elem_type, s, initializer_type); | |
| 1116 | 1132 | } |
| 1117 | 1133 | try writer.writeByte('}'); |
| 1118 | 1134 | } |
| ... | ... | @@ -1122,11 +1138,11 @@ pub const DeclGen = struct { |
| 1122 | 1138 | while (index < ai.len) : (index += 1) { |
| 1123 | 1139 | if (index != 0) try writer.writeByte(','); |
| 1124 | 1140 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); |
| 1125 | try dg.renderValue(writer, ai.elem_type, elem_val, .Initializer); | |
| 1141 | try dg.renderValue(writer, ai.elem_type, elem_val, initializer_type); | |
| 1126 | 1142 | } |
| 1127 | 1143 | if (ai.sentinel) |s| { |
| 1128 | 1144 | if (index != 0) try writer.writeByte(','); |
| 1129 | try dg.renderValue(writer, ai.elem_type, s, .Initializer); | |
| 1145 | try dg.renderValue(writer, ai.elem_type, s, initializer_type); | |
| 1130 | 1146 | } |
| 1131 | 1147 | try writer.writeByte('}'); |
| 1132 | 1148 | } |
| ... | ... | @@ -1162,9 +1178,9 @@ pub const DeclGen = struct { |
| 1162 | 1178 | const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else Value.undef; |
| 1163 | 1179 | |
| 1164 | 1180 | try writer.writeAll("{ .payload = "); |
| 1165 | try dg.renderValue(writer, payload_ty, payload_val, .Initializer); | |
| 1181 | try dg.renderValue(writer, payload_ty, payload_val, initializer_type); | |
| 1166 | 1182 | try writer.writeAll(", .is_null = "); |
| 1167 | try dg.renderValue(writer, Type.bool, is_null_val, .Initializer); | |
| 1183 | try dg.renderValue(writer, Type.bool, is_null_val, initializer_type); | |
| 1168 | 1184 | try writer.writeAll(" }"); |
| 1169 | 1185 | }, |
| 1170 | 1186 | .ErrorSet => { |
| ... | ... | @@ -1197,9 +1213,9 @@ pub const DeclGen = struct { |
| 1197 | 1213 | const error_val = if (val.errorUnionIsPayload()) Value.zero else val; |
| 1198 | 1214 | |
| 1199 | 1215 | try writer.writeAll("{ .payload = "); |
| 1200 | try dg.renderValue(writer, payload_ty, payload_val, .Initializer); | |
| 1216 | try dg.renderValue(writer, payload_ty, payload_val, initializer_type); | |
| 1201 | 1217 | try writer.writeAll(", .error = "); |
| 1202 | try dg.renderValue(writer, error_ty, error_val, .Initializer); | |
| 1218 | try dg.renderValue(writer, error_ty, error_val, initializer_type); | |
| 1203 | 1219 | try writer.writeAll(" }"); |
| 1204 | 1220 | }, |
| 1205 | 1221 | .Enum => { |
| ... | ... | @@ -1264,10 +1280,7 @@ pub const DeclGen = struct { |
| 1264 | 1280 | if (!field_ty.hasRuntimeBits()) continue; |
| 1265 | 1281 | |
| 1266 | 1282 | if (!empty) try writer.writeByte(','); |
| 1267 | try dg.renderValue(writer, field_ty, field_val, switch (location) { | |
| 1268 | .StaticInitializer => .StaticInitializer, | |
| 1269 | else => .Initializer, | |
| 1270 | }); | |
| 1283 | try dg.renderValue(writer, field_ty, field_val, initializer_type); | |
| 1271 | 1284 | |
| 1272 | 1285 | empty = false; |
| 1273 | 1286 | } |
| ... | ... | @@ -1297,7 +1310,7 @@ pub const DeclGen = struct { |
| 1297 | 1310 | |
| 1298 | 1311 | if (eff_num_fields == 0) { |
| 1299 | 1312 | try writer.writeByte('('); |
| 1300 | try dg.renderValue(writer, ty, Value.undef, .Initializer); | |
| 1313 | try dg.renderValue(writer, ty, Value.undef, initializer_type); | |
| 1301 | 1314 | try writer.writeByte(')'); |
| 1302 | 1315 | } else if (ty.bitSize(target) > 64) { |
| 1303 | 1316 | // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off)) |
| ... | ... | @@ -1385,7 +1398,7 @@ pub const DeclGen = struct { |
| 1385 | 1398 | try dg.renderTypecast(writer, ty); |
| 1386 | 1399 | try writer.writeByte(')'); |
| 1387 | 1400 | } |
| 1388 | try dg.renderValue(writer, field_ty, union_obj.val, .Initializer); | |
| 1401 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); | |
| 1389 | 1402 | } else { |
| 1390 | 1403 | try writer.writeAll("0"); |
| 1391 | 1404 | } |
| ... | ... | @@ -1397,7 +1410,7 @@ pub const DeclGen = struct { |
| 1397 | 1410 | const layout = ty.unionGetLayout(target); |
| 1398 | 1411 | if (layout.tag_size != 0) { |
| 1399 | 1412 | try writer.writeAll(".tag = "); |
| 1400 | try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer); | |
| 1413 | try dg.renderValue(writer, tag_ty, union_obj.tag, initializer_type); | |
| 1401 | 1414 | try writer.writeAll(", "); |
| 1402 | 1415 | } |
| 1403 | 1416 | try writer.writeAll(".payload = {"); |
| ... | ... | @@ -1406,11 +1419,11 @@ pub const DeclGen = struct { |
| 1406 | 1419 | var it = ty.unionFields().iterator(); |
| 1407 | 1420 | if (field_ty.hasRuntimeBits()) { |
| 1408 | 1421 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); |
| 1409 | try dg.renderValue(writer, field_ty, union_obj.val, .Initializer); | |
| 1422 | try dg.renderValue(writer, field_ty, union_obj.val, initializer_type); | |
| 1410 | 1423 | } else while (it.next()) |field| { |
| 1411 | 1424 | if (!field.value_ptr.ty.hasRuntimeBits()) continue; |
| 1412 | 1425 | try writer.print(".{ } = ", .{fmtIdent(field.key_ptr.*)}); |
| 1413 | try dg.renderValue(writer, field.value_ptr.ty, Value.undef, .Initializer); | |
| 1426 | try dg.renderValue(writer, field.value_ptr.ty, Value.undef, initializer_type); | |
| 1414 | 1427 | break; |
| 1415 | 1428 | } else try writer.writeAll(".empty_union = 0"); |
| 1416 | 1429 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| ... | ... | @@ -7239,7 +7252,7 @@ fn formatIntLiteral( |
| 7239 | 7252 | else => { |
| 7240 | 7253 | if (int_info.bits > 64 and data.location != null and data.location.? == .StaticInitializer) { |
| 7241 | 7254 | // MSVC treats casting the struct initializer as not constant (C2099), so an alternate form is used in global initializers |
| 7242 | try writer.print("zig_as_init_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }); | |
| 7255 | try writer.print("zig_as_constant_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }); | |
| 7243 | 7256 | } else { |
| 7244 | 7257 | try writer.print("zig_as_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }); |
| 7245 | 7258 | } |