authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-03 12:57:01-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-03 12:57:01-08:00
loga9337bef2d54201ab304bb3428479339ecaacbac
treee253679e591e86d84a29139b7d7987eab3c3718f
parent9a56228c2b90d94d01bb76784c77fdec5710cf0a
parent047d6d996e540eaa50ec24b0751d147bfe2cacdb
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18431 from jacobly0/cbe-extern

cbe: fix non-msvc externs and exports

14 files changed, 506 insertions(+), 223 deletions(-)

ci/x86_64-windows-debug.ps1+5-6
...@@ -96,9 +96,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E...@@ -96,9 +96,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
96CheckLastExitCode96CheckLastExitCode
9797
98Write-Output "Build and run behavior tests with msvc..."98Write-Output "Build and run behavior tests with msvc..."
99Write-Output "Skipped due to https://github.com/ziglang/zig/issues/17817"99& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
100#& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib100CheckLastExitCode
101#CheckLastExitCode101
102#102& .\test-x86_64-windows-msvc.exe
103#& .\test-x86_64-windows-msvc.exe103CheckLastExitCode
104#CheckLastExitCode
ci/x86_64-windows-release.ps1+5-6
...@@ -95,9 +95,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E...@@ -95,9 +95,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
95CheckLastExitCode95CheckLastExitCode
9696
97Write-Output "Build and run behavior tests with msvc..."97Write-Output "Build and run behavior tests with msvc..."
98Write-Output "Skipped due to https://github.com/ziglang/zig/issues/17817"98& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib
99#& cl.exe -I..\lib test-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /W3 /Z7 -link -nologo -debug -subsystem:console kernel32.lib ntdll.lib libcmt.lib99CheckLastExitCode
100#CheckLastExitCode100
101#101& .\test-x86_64-windows-msvc.exe
102#& .\test-x86_64-windows-msvc.exe102CheckLastExitCode
103#CheckLastExitCode
lib/std/math.zig+1
...@@ -1266,6 +1266,7 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {...@@ -1266,6 +1266,7 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
1266}1266}
12671267
1268test "lerp" {1268test "lerp" {
1269 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
1269 if (builtin.zig_backend == .stage2_x86_64 and1270 if (builtin.zig_backend == .stage2_x86_64 and
1270 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;1271 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .fma)) return error.SkipZigTest;
12711272
lib/zig.h+157-92
...@@ -25,11 +25,15 @@ typedef char bool;...@@ -25,11 +25,15 @@ typedef char bool;
25#endif25#endif
26#endif26#endif
2727
28#define zig_concat(lhs, rhs) lhs##rhs
29#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
30
28#if defined(__has_builtin)31#if defined(__has_builtin)
29#define zig_has_builtin(builtin) __has_builtin(__builtin_##builtin)32#define zig_has_builtin(builtin) __has_builtin(__builtin_##builtin)
30#else33#else
31#define zig_has_builtin(builtin) 034#define zig_has_builtin(builtin) 0
32#endif35#endif
36#define zig_expand_has_builtin(b) zig_has_builtin(b)
3337
34#if defined(__has_attribute)38#if defined(__has_attribute)
35#define zig_has_attribute(attribute) __has_attribute(attribute)39#define zig_has_attribute(attribute) __has_attribute(attribute)
...@@ -112,7 +116,7 @@ typedef char bool;...@@ -112,7 +116,7 @@ typedef char bool;
112#define zig_never_tail zig_never_tail_unavailable116#define zig_never_tail zig_never_tail_unavailable
113#endif117#endif
114118
115#if zig_has_attribute(always_inline)119#if zig_has_attribute(musttail)
116#define zig_always_tail __attribute__((musttail))120#define zig_always_tail __attribute__((musttail))
117#else121#else
118#define zig_always_tail zig_always_tail_unavailable122#define zig_always_tail zig_always_tail_unavailable
...@@ -180,20 +184,58 @@ typedef char bool;...@@ -180,20 +184,58 @@ typedef char bool;
180#define zig_extern extern184#define zig_extern extern
181#endif185#endif
182186
183#if zig_has_attribute(alias)187#if _MSC_VER
184#define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol)))
185#elif _MSC_VER
186#if _M_X64188#if _M_X64
187#define zig_export(sig, symbol, name) sig;\189#define zig_mangle_c(symbol) symbol
188 __pragma(comment(linker, "/alternatename:" name "=" symbol ))
189#else /*_M_X64 */190#else /*_M_X64 */
190#define zig_export(sig, symbol, name) sig;\191#define zig_mangle_c(symbol) "_" symbol
191 __pragma(comment(linker, "/alternatename:_" name "=_" symbol ))
192#endif /*_M_X64 */192#endif /*_M_X64 */
193#else /* _MSC_VER */
194#if __APPLE__
195#define zig_mangle_c(symbol) "_" symbol
196#else /* __APPLE__ */
197#define zig_mangle_c(symbol) symbol
198#endif /* __APPLE__ */
199#endif /* _MSC_VER */
200
201#if zig_has_attribute(alias) && !__APPLE__
202#define zig_export(symbol, name) __attribute__((alias(symbol)))
203#elif _MSC_VER
204#define zig_export(symbol, name) ; \
205 __pragma(comment(linker, "/alternatename:" zig_mangle_c(name) "=" zig_mangle_c(symbol)))
193#else206#else
194#define zig_export(sig, symbol, name) __asm(name " = " symbol)207#define zig_export(symbol, name) ; \
208 __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))
195#endif209#endif
196210
211#if _MSC_VER
212#define zig_mangled_tentative(mangled, unmangled)
213#define zig_mangled_final(mangled, unmangled) ; \
214 zig_export(#mangled, unmangled)
215#define zig_mangled_export(mangled, unmangled, symbol) \
216 zig_export(unmangled, #mangled) \
217 zig_export(symbol, unmangled)
218#else /* _MSC_VER */
219#define zig_mangled_tentative(mangled, unmangled) __asm(zig_mangle_c(unmangled))
220#define zig_mangled_final(mangled, unmangled) zig_mangled_tentative(mangled, unmangled)
221#define zig_mangled_export(mangled, unmangled, symbol) \
222 zig_mangled_final(mangled, unmangled) \
223 zig_export(symbol, unmangled)
224#endif /* _MSC_VER */
225
226#if _MSC_VER
227#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args;\
228 __pragma(comment(linker, "/alternatename:" zig_mangle_c(#fn_name) "=" zig_mangle_c(#libc_name)));
229#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, sig_args, call_args)
230#else /* _MSC_VER */
231#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args __asm(zig_mangle_c(#libc_name));
232#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type libc_name sig_args; \
233 static inline Type fn_name sig_args { return libc_name call_args; }
234#endif
235
236#define zig_expand_import_0(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, libc_name, sig_args, call_args)
237#define zig_expand_import_1(Type, fn_name, libc_name, sig_args, call_args) zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args)
238
197#if zig_has_attribute(weak) || defined(zig_gnuc)239#if zig_has_attribute(weak) || defined(zig_gnuc)
198#define zig_weak_linkage __attribute__((weak))240#define zig_weak_linkage __attribute__((weak))
199#define zig_weak_linkage_fn __attribute__((weak))241#define zig_weak_linkage_fn __attribute__((weak))
...@@ -267,9 +309,6 @@ typedef char bool;...@@ -267,9 +309,6 @@ typedef char bool;
267#define zig_wasm_memory_grow(index, delta) zig_unimplemented()309#define zig_wasm_memory_grow(index, delta) zig_unimplemented()
268#endif310#endif
269311
270#define zig_concat(lhs, rhs) lhs##rhs
271#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
272
273#if __STDC_VERSION__ >= 201112L312#if __STDC_VERSION__ >= 201112L
274#define zig_noreturn _Noreturn313#define zig_noreturn _Noreturn
275#elif zig_has_attribute(noreturn) || defined(zig_gnuc)314#elif zig_has_attribute(noreturn) || defined(zig_gnuc)
...@@ -2163,7 +2202,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2163,7 +2202,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
2163 const uint8_t *rhs_bytes = rhs;2202 const uint8_t *rhs_bytes = rhs;
2164 uint16_t byte_offset = 0;2203 uint16_t byte_offset = 0;
2165 uint16_t remaining_bytes = zig_int_bytes(bits);2204 uint16_t remaining_bytes = zig_int_bytes(bits);
2166 uint16_t top_bits = remaining_bytes * 8 - bits;2205 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);
2167 bool overflow = false;2206 bool overflow = false;
21682207
2169#if zig_big_endian2208#if zig_big_endian
...@@ -2171,7 +2210,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2171,7 +2210,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
2171#endif2210#endif
21722211
2173 while (remaining_bytes >= 128 / CHAR_BIT) {2212 while (remaining_bytes >= 128 / CHAR_BIT) {
2174 uint16_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);2213 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
21752214
2176#if zig_big_endian2215#if zig_big_endian
2177 byte_offset -= 128 / CHAR_BIT;2216 byte_offset -= 128 / CHAR_BIT;
...@@ -2211,7 +2250,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2211,7 +2250,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
2211 }2250 }
22122251
2213 while (remaining_bytes >= 64 / CHAR_BIT) {2252 while (remaining_bytes >= 64 / CHAR_BIT) {
2214 uint16_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);2253 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
22152254
2216#if zig_big_endian2255#if zig_big_endian
2217 byte_offset -= 64 / CHAR_BIT;2256 byte_offset -= 64 / CHAR_BIT;
...@@ -2251,7 +2290,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2251,7 +2290,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
2251 }2290 }
22522291
2253 while (remaining_bytes >= 32 / CHAR_BIT) {2292 while (remaining_bytes >= 32 / CHAR_BIT) {
2254 uint16_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);2293 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
22552294
2256#if zig_big_endian2295#if zig_big_endian
2257 byte_offset -= 32 / CHAR_BIT;2296 byte_offset -= 32 / CHAR_BIT;
...@@ -2291,7 +2330,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2291,7 +2330,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
2291 }2330 }
22922331
2293 while (remaining_bytes >= 16 / CHAR_BIT) {2332 while (remaining_bytes >= 16 / CHAR_BIT) {
2294 uint16_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);2333 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
22952334
2296#if zig_big_endian2335#if zig_big_endian
2297 byte_offset -= 16 / CHAR_BIT;2336 byte_offset -= 16 / CHAR_BIT;
...@@ -2331,7 +2370,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2331,7 +2370,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
2331 }2370 }
23322371
2333 while (remaining_bytes >= 8 / CHAR_BIT) {2372 while (remaining_bytes >= 8 / CHAR_BIT) {
2334 uint16_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);2373 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
23352374
2336#if zig_big_endian2375#if zig_big_endian
2337 byte_offset -= 8 / CHAR_BIT;2376 byte_offset -= 8 / CHAR_BIT;
...@@ -2379,7 +2418,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2379,7 +2418,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
2379 const uint8_t *rhs_bytes = rhs;2418 const uint8_t *rhs_bytes = rhs;
2380 uint16_t byte_offset = 0;2419 uint16_t byte_offset = 0;
2381 uint16_t remaining_bytes = zig_int_bytes(bits);2420 uint16_t remaining_bytes = zig_int_bytes(bits);
2382 uint16_t top_bits = remaining_bytes * 8 - bits;2421 uint8_t top_bits = (uint8_t)(remaining_bytes * 8 - bits);
2383 bool overflow = false;2422 bool overflow = false;
23842423
2385#if zig_big_endian2424#if zig_big_endian
...@@ -2387,7 +2426,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2387,7 +2426,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
2387#endif2426#endif
23882427
2389 while (remaining_bytes >= 128 / CHAR_BIT) {2428 while (remaining_bytes >= 128 / CHAR_BIT) {
2390 uint16_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);2429 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
23912430
2392#if zig_big_endian2431#if zig_big_endian
2393 byte_offset -= 128 / CHAR_BIT;2432 byte_offset -= 128 / CHAR_BIT;
...@@ -2427,7 +2466,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2427,7 +2466,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
2427 }2466 }
24282467
2429 while (remaining_bytes >= 64 / CHAR_BIT) {2468 while (remaining_bytes >= 64 / CHAR_BIT) {
2430 uint16_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);2469 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
24312470
2432#if zig_big_endian2471#if zig_big_endian
2433 byte_offset -= 64 / CHAR_BIT;2472 byte_offset -= 64 / CHAR_BIT;
...@@ -2467,7 +2506,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2467,7 +2506,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
2467 }2506 }
24682507
2469 while (remaining_bytes >= 32 / CHAR_BIT) {2508 while (remaining_bytes >= 32 / CHAR_BIT) {
2470 uint16_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);2509 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
24712510
2472#if zig_big_endian2511#if zig_big_endian
2473 byte_offset -= 32 / CHAR_BIT;2512 byte_offset -= 32 / CHAR_BIT;
...@@ -2507,7 +2546,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2507,7 +2546,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
2507 }2546 }
25082547
2509 while (remaining_bytes >= 16 / CHAR_BIT) {2548 while (remaining_bytes >= 16 / CHAR_BIT) {
2510 uint16_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);2549 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
25112550
2512#if zig_big_endian2551#if zig_big_endian
2513 byte_offset -= 16 / CHAR_BIT;2552 byte_offset -= 16 / CHAR_BIT;
...@@ -2547,7 +2586,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo...@@ -2547,7 +2586,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
2547 }2586 }
25482587
2549 while (remaining_bytes >= 8 / CHAR_BIT) {2588 while (remaining_bytes >= 8 / CHAR_BIT) {
2550 uint16_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);2589 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
25512590
2552#if zig_big_endian2591#if zig_big_endian
2553 byte_offset -= 8 / CHAR_BIT;2592 byte_offset -= 8 / CHAR_BIT;
...@@ -3093,6 +3132,7 @@ ypedef uint32_t zig_f32;...@@ -3093,6 +3132,7 @@ ypedef uint32_t zig_f32;
30933132
3094#define zig_has_f64 13133#define zig_has_f64 1
3095#define zig_libc_name_f64(name) name3134#define zig_libc_name_f64(name) name
3135
3096#if _MSC_VER3136#if _MSC_VER
3097#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )3137#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
3098#else3138#else
...@@ -3336,31 +3376,31 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))...@@ -3336,31 +3376,31 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
3336 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \3376 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \
3337 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \3377 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \
3338 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, div, /) \3378 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, div, /) \
3339 zig_extern zig_f##w zig_libc_name_f##w(sqrt)(zig_f##w); \3379 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sqrt)))(zig_f##w, zig_float_fn_f##w##_sqrt, zig_libc_name_f##w(sqrt), (zig_f##w x), (x)) \
3340 zig_extern zig_f##w zig_libc_name_f##w(sin)(zig_f##w); \3380 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sin)))(zig_f##w, zig_float_fn_f##w##_sin, zig_libc_name_f##w(sin), (zig_f##w x), (x)) \
3341 zig_extern zig_f##w zig_libc_name_f##w(cos)(zig_f##w); \3381 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(cos)))(zig_f##w, zig_float_fn_f##w##_cos, zig_libc_name_f##w(cos), (zig_f##w x), (x)) \
3342 zig_extern zig_f##w zig_libc_name_f##w(tan)(zig_f##w); \3382 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(tan)))(zig_f##w, zig_float_fn_f##w##_tan, zig_libc_name_f##w(tan), (zig_f##w x), (x)) \
3343 zig_extern zig_f##w zig_libc_name_f##w(exp)(zig_f##w); \3383 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp)))(zig_f##w, zig_float_fn_f##w##_exp, zig_libc_name_f##w(exp), (zig_f##w x), (x)) \
3344 zig_extern zig_f##w zig_libc_name_f##w(exp2)(zig_f##w); \3384 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp2)))(zig_f##w, zig_float_fn_f##w##_exp2, zig_libc_name_f##w(exp2), (zig_f##w x), (x)) \
3345 zig_extern zig_f##w zig_libc_name_f##w(log)(zig_f##w); \3385 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log)))(zig_f##w, zig_float_fn_f##w##_log, zig_libc_name_f##w(log), (zig_f##w x), (x)) \
3346 zig_extern zig_f##w zig_libc_name_f##w(log2)(zig_f##w); \3386 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log2)))(zig_f##w, zig_float_fn_f##w##_log2, zig_libc_name_f##w(log2), (zig_f##w x), (x)) \
3347 zig_extern zig_f##w zig_libc_name_f##w(log10)(zig_f##w); \3387 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log10)))(zig_f##w, zig_float_fn_f##w##_log10, zig_libc_name_f##w(log10), (zig_f##w x), (x)) \
3348 zig_extern zig_f##w zig_libc_name_f##w(fabs)(zig_f##w); \3388 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fabs)))(zig_f##w, zig_float_fn_f##w##_fabs, zig_libc_name_f##w(fabs), (zig_f##w x), (x)) \
3349 zig_extern zig_f##w zig_libc_name_f##w(floor)(zig_f##w); \3389 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(floor)))(zig_f##w, zig_float_fn_f##w##_floor, zig_libc_name_f##w(floor), (zig_f##w x), (x)) \
3350 zig_extern zig_f##w zig_libc_name_f##w(ceil)(zig_f##w); \3390 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(ceil)))(zig_f##w, zig_float_fn_f##w##_ceil, zig_libc_name_f##w(ceil), (zig_f##w x), (x)) \
3351 zig_extern zig_f##w zig_libc_name_f##w(round)(zig_f##w); \3391 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(round)))(zig_f##w, zig_float_fn_f##w##_round, zig_libc_name_f##w(round), (zig_f##w x), (x)) \
3352 zig_extern zig_f##w zig_libc_name_f##w(trunc)(zig_f##w); \3392 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(trunc)))(zig_f##w, zig_float_fn_f##w##_trunc, zig_libc_name_f##w(trunc), (zig_f##w x), (x)) \
3353 zig_extern zig_f##w zig_libc_name_f##w(fmod)(zig_f##w, zig_f##w); \3393 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmod)))(zig_f##w, zig_float_fn_f##w##_fmod, zig_libc_name_f##w(fmod), (zig_f##w x, zig_f##w y), (x, y)) \
3354 zig_extern zig_f##w zig_libc_name_f##w(fmin)(zig_f##w, zig_f##w); \3394 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmin)))(zig_f##w, zig_float_fn_f##w##_fmin, zig_libc_name_f##w(fmin), (zig_f##w x, zig_f##w y), (x, y)) \
3355 zig_extern zig_f##w zig_libc_name_f##w(fmax)(zig_f##w, zig_f##w); \3395 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_float_fn_f##w##_fmax, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \
3356 zig_extern zig_f##w zig_libc_name_f##w(fma)(zig_f##w, zig_f##w, zig_f##w); \3396 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_float_fn_f##w##_fma, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \
3357\3397\
3358 static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \3398 static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
3359 return zig_libc_name_f##w(trunc)(zig_div_f##w(lhs, rhs)); \3399 return zig_float_fn_f##w##_trunc(zig_div_f##w(lhs, rhs)); \
3360 } \3400 } \
3361\3401\
3362 static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \3402 static inline zig_f##w zig_div_floor_f##w(zig_f##w lhs, zig_f##w rhs) { \
3363 return zig_libc_name_f##w(floor)(zig_div_f##w(lhs, rhs)); \3403 return zig_float_fn_f##w##_floor(zig_div_f##w(lhs, rhs)); \
3364 } \3404 } \
3365\3405\
3366 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \3406 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
...@@ -3437,129 +3477,134 @@ zig_float_builtins(64)...@@ -3437,129 +3477,134 @@ zig_float_builtins(64)
3437/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */3477/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */
3438#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \3478#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \
3439 zig_##Type zig_atomicrmw_expected; \3479 zig_##Type zig_atomicrmw_expected; \
3440 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3480 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3441 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \3481 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \
3442 res = zig_atomicrmw_expected; \3482 res = zig_atomicrmw_expected; \
3443} while (0)3483} while (0)
3444#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \3484#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \
3445 zig_##Type zig_atomicrmw_expected; \3485 zig_##Type zig_atomicrmw_expected; \
3446 zig_##Type zig_atomicrmw_desired; \3486 zig_##Type zig_atomicrmw_desired; \
3447 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3487 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3448 do { \3488 do { \
3449 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \3489 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3450 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3490 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3451 res = zig_atomicrmw_expected; \3491 res = zig_atomicrmw_expected; \
3452} while (0)3492} while (0)
3453#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \3493#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \
3454 zig_##Type zig_atomicrmw_expected; \3494 zig_##Type zig_atomicrmw_expected; \
3455 zig_##Type zig_atomicrmw_desired; \3495 zig_##Type zig_atomicrmw_desired; \
3456 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3496 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3457 do { \3497 do { \
3458 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \3498 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3459 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3499 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3460 res = zig_atomicrmw_expected; \3500 res = zig_atomicrmw_expected; \
3461} while (0)3501} while (0)
3462#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \3502#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \
3463 zig_##Type zig_atomicrmw_expected; \3503 zig_##Type zig_atomicrmw_expected; \
3464 zig_##Type zig_atomicrmw_desired; \3504 zig_##Type zig_atomicrmw_desired; \
3465 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3505 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3466 do { \3506 do { \
3467 zig_atomicrmw_desired = zig_libc_name_##Type(fmin)(zig_atomicrmw_expected, arg); \3507 zig_atomicrmw_desired = zig_float_fn_##Type##_fmin(zig_atomicrmw_expected, arg); \
3468 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3508 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3469 res = zig_atomicrmw_expected; \3509 res = zig_atomicrmw_expected; \
3470} while (0)3510} while (0)
3471#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \3511#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \
3472 zig_##Type zig_atomicrmw_expected; \3512 zig_##Type zig_atomicrmw_expected; \
3473 zig_##Type zig_atomicrmw_desired; \3513 zig_##Type zig_atomicrmw_desired; \
3474 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3514 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3475 do { \3515 do { \
3476 zig_atomicrmw_desired = zig_libc_name_##Type(fmax)(zig_atomicrmw_expected, arg); \3516 zig_atomicrmw_desired = zig_float_fn_##Type##_fmax(zig_atomicrmw_expected, arg); \
3477 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3517 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3478 res = zig_atomicrmw_expected; \3518 res = zig_atomicrmw_expected; \
3479} while (0)3519} while (0)
34803520
3481#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \3521#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \
3482 zig_##Type zig_atomicrmw_expected; \3522 zig_##Type zig_atomicrmw_expected; \
3483 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3523 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3484 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \3524 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \
3485 res = zig_atomicrmw_expected; \3525 res = zig_atomicrmw_expected; \
3486} while (0)3526} while (0)
3487#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \3527#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \
3488 zig_##Type zig_atomicrmw_expected; \3528 zig_##Type zig_atomicrmw_expected; \
3489 zig_##Type zig_atomicrmw_desired; \3529 zig_##Type zig_atomicrmw_desired; \
3490 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3530 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3491 do { \3531 do { \
3492 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \3532 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
3493 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3533 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3494 res = zig_atomicrmw_expected; \3534 res = zig_atomicrmw_expected; \
3495} while (0)3535} while (0)
3496#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \3536#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \
3497 zig_##Type zig_atomicrmw_expected; \3537 zig_##Type zig_atomicrmw_expected; \
3498 zig_##Type zig_atomicrmw_desired; \3538 zig_##Type zig_atomicrmw_desired; \
3499 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3539 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3500 do { \3540 do { \
3501 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \3541 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
3502 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3542 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3503 res = zig_atomicrmw_expected; \3543 res = zig_atomicrmw_expected; \
3504} while (0)3544} while (0)
3505#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \3545#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \
3506 zig_##Type zig_atomicrmw_expected; \3546 zig_##Type zig_atomicrmw_expected; \
3507 zig_##Type zig_atomicrmw_desired; \3547 zig_##Type zig_atomicrmw_desired; \
3508 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3548 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3509 do { \3549 do { \
3510 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \3550 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \
3511 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3551 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3512 res = zig_atomicrmw_expected; \3552 res = zig_atomicrmw_expected; \
3513} while (0)3553} while (0)
3514#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \3554#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \
3515 zig_##Type zig_atomicrmw_expected; \3555 zig_##Type zig_atomicrmw_expected; \
3516 zig_##Type zig_atomicrmw_desired; \3556 zig_##Type zig_atomicrmw_desired; \
3517 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3557 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3518 do { \3558 do { \
3519 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \3559 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \
3520 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3560 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3521 res = zig_atomicrmw_expected; \3561 res = zig_atomicrmw_expected; \
3522} while (0)3562} while (0)
3523#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \3563#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \
3524 zig_##Type zig_atomicrmw_expected; \3564 zig_##Type zig_atomicrmw_expected; \
3525 zig_##Type zig_atomicrmw_desired; \3565 zig_##Type zig_atomicrmw_desired; \
3526 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3566 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3527 do { \3567 do { \
3528 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \3568 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \
3529 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3569 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3530 res = zig_atomicrmw_expected; \3570 res = zig_atomicrmw_expected; \
3531} while (0)3571} while (0)
3532#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \3572#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \
3533 zig_##Type zig_atomicrmw_expected; \3573 zig_##Type zig_atomicrmw_expected; \
3534 zig_##Type zig_atomicrmw_desired; \3574 zig_##Type zig_atomicrmw_desired; \
3535 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3575 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3536 do { \3576 do { \
3537 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \3577 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \
3538 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3578 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3539 res = zig_atomicrmw_expected; \3579 res = zig_atomicrmw_expected; \
3540} while (0)3580} while (0)
3541#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \3581#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \
3542 zig_##Type zig_atomicrmw_expected; \3582 zig_##Type zig_atomicrmw_expected; \
3543 zig_##Type zig_atomicrmw_desired; \3583 zig_##Type zig_atomicrmw_desired; \
3544 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3584 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3545 do { \3585 do { \
3546 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \3586 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \
3547 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3587 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3548 res = zig_atomicrmw_expected; \3588 res = zig_atomicrmw_expected; \
3549} while (0)3589} while (0)
3550#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \3590#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \
3551 zig_##Type zig_atomicrmw_expected; \3591 zig_##Type zig_atomicrmw_expected; \
3552 zig_##Type zig_atomicrmw_desired; \3592 zig_##Type zig_atomicrmw_desired; \
3553 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \3593 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3554 do { \3594 do { \
3555 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \3595 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \
3556 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \3596 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
3557 res = zig_atomicrmw_expected; \3597 res = zig_atomicrmw_expected; \
3558} while (0)3598} while (0)
35593599
3560#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)3600#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
3561#include <stdatomic.h>3601#include <stdatomic.h>
3562typedef enum memory_order zig_memory_order;3602typedef enum memory_order zig_memory_order;
3603#define zig_memory_order_relaxed memory_order_relaxed
3604#define zig_memory_order_acquire memory_order_acquire
3605#define zig_memory_order_release memory_order_release
3606#define zig_memory_order_acq_rel memory_order_acq_rel
3607#define zig_memory_order_seq_cst memory_order_seq_cst
3563#define zig_atomic(Type) _Atomic(Type)3608#define zig_atomic(Type) _Atomic(Type)
3564#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)3609#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
3565#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)3610#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
...@@ -3583,12 +3628,11 @@ typedef enum memory_order zig_memory_order;...@@ -3583,12 +3628,11 @@ typedef enum memory_order zig_memory_order;
3583#define zig_fence(order) atomic_thread_fence(order)3628#define zig_fence(order) atomic_thread_fence(order)
3584#elif defined(__GNUC__)3629#elif defined(__GNUC__)
3585typedef int zig_memory_order;3630typedef int zig_memory_order;
3586#define memory_order_relaxed __ATOMIC_RELAXED3631#define zig_memory_order_relaxed __ATOMIC_RELAXED
3587#define memory_order_consume __ATOMIC_CONSUME3632#define zig_memory_order_acquire __ATOMIC_ACQUIRE
3588#define memory_order_acquire __ATOMIC_ACQUIRE3633#define zig_memory_order_release __ATOMIC_RELEASE
3589#define memory_order_release __ATOMIC_RELEASE3634#define zig_memory_order_acq_rel __ATOMIC_ACQ_REL
3590#define memory_order_acq_rel __ATOMIC_ACQ_REL3635#define zig_memory_order_seq_cst __ATOMIC_SEQ_CST
3591#define memory_order_seq_cst __ATOMIC_SEQ_CST
3592#define zig_atomic(Type) Type3636#define zig_atomic(Type) Type
3593#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)3637#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)
3594#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), true, succ, fail)3638#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), true, succ, fail)
...@@ -3607,12 +3651,11 @@ typedef int zig_memory_order;...@@ -3607,12 +3651,11 @@ typedef int zig_memory_order;
3607#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg3651#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
3608#define zig_fence(order) __atomic_thread_fence(order)3652#define zig_fence(order) __atomic_thread_fence(order)
3609#elif _MSC_VER && (_M_IX86 || _M_X64)3653#elif _MSC_VER && (_M_IX86 || _M_X64)
3610#define memory_order_relaxed 03654#define zig_memory_order_relaxed 0
3611#define memory_order_consume 13655#define zig_memory_order_acquire 2
3612#define memory_order_acquire 23656#define zig_memory_order_release 3
3613#define memory_order_release 33657#define zig_memory_order_acq_rel 4
3614#define memory_order_acq_rel 43658#define zig_memory_order_seq_cst 5
3615#define memory_order_seq_cst 5
3616#define zig_atomic(Type) Type3659#define zig_atomic(Type) Type
3617#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)3660#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)
3618#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType)3661#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType)
...@@ -3634,12 +3677,11 @@ typedef int zig_memory_order;...@@ -3634,12 +3677,11 @@ typedef int zig_memory_order;
3634#endif3677#endif
3635/* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */3678/* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */
3636#else3679#else
3637#define memory_order_relaxed 03680#define zig_memory_order_relaxed 0
3638#define memory_order_consume 13681#define zig_memory_order_acquire 2
3639#define memory_order_acquire 23682#define zig_memory_order_release 3
3640#define memory_order_release 33683#define zig_memory_order_acq_rel 4
3641#define memory_order_acq_rel 43684#define zig_memory_order_seq_cst 5
3642#define memory_order_seq_cst 5
3643#define zig_atomic(Type) Type3685#define zig_atomic(Type) Type
3644#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable3686#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
3645#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable3687#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
...@@ -3830,9 +3872,32 @@ static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expec...@@ -3830,9 +3872,32 @@ static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expec
3830 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected);3872 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected);
3831}3873}
38323874
3875static inline zig_u128 zig_msvc_atomic_load_u128(zig_u128 volatile* obj) {
3876 zig_u128 expected = zig_make_u128(UINT64_C(0), UINT64_C(0));
3877 (void)zig_cmpxchg_strong(obj, expected, expected, zig_memory_order_seq_cst, zig_memory_order_seq_cst, u128, zig_u128);
3878 return expected;
3879}
3880
3881static inline void zig_msvc_atomic_store_u128(zig_u128 volatile* obj, zig_u128 arg) {
3882 zig_u128 expected = zig_make_u128(UINT64_C(0), UINT64_C(0));
3883 while (!zig_cmpxchg_weak(obj, expected, arg, zig_memory_order_seq_cst, zig_memory_order_seq_cst, u128, zig_u128));
3884}
3885
3833static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {3886static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
3834 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);3887 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);
3835}3888}
3889
3890static inline zig_i128 zig_msvc_atomic_load_i128(zig_i128 volatile* obj) {
3891 zig_i128 expected = zig_make_i128(INT64_C(0), UINT64_C(0));
3892 (void)zig_cmpxchg_strong(obj, expected, expected, zig_memory_order_seq_cst, zig_memory_order_seq_cst, i128, zig_i128);
3893 return expected;
3894}
3895
3896static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 arg) {
3897 zig_i128 expected = zig_make_i128(INT64_C(0), UINT64_C(0));
3898 while (!zig_cmpxchg_weak(obj, expected, arg, zig_memory_order_seq_cst, zig_memory_order_seq_cst, i128, zig_i128));
3899}
3900
3836#endif /* _M_IX86 */3901#endif /* _M_IX86 */
38373902
3838#endif /* _MSC_VER && (_M_IX86 || _M_X64) */3903#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
src/AstGen.zig+4
...@@ -4456,6 +4456,7 @@ fn globalVarDecl(...@@ -4456,6 +4456,7 @@ fn globalVarDecl(
4456 .align_inst = .none, // passed via the decls data4456 .align_inst = .none, // passed via the decls data
4457 .init = init_inst,4457 .init = init_inst,
4458 .is_extern = false,4458 .is_extern = false,
4459 .is_const = !is_mutable,
4459 .is_threadlocal = is_threadlocal,4460 .is_threadlocal = is_threadlocal,
4460 });4461 });
4461 break :vi var_inst;4462 break :vi var_inst;
...@@ -4474,6 +4475,7 @@ fn globalVarDecl(...@@ -4474,6 +4475,7 @@ fn globalVarDecl(
4474 .align_inst = .none, // passed via the decls data4475 .align_inst = .none, // passed via the decls data
4475 .init = .none,4476 .init = .none,
4476 .is_extern = true,4477 .is_extern = true,
4478 .is_const = !is_mutable,
4477 .is_threadlocal = is_threadlocal,4479 .is_threadlocal = is_threadlocal,
4478 });4480 });
4479 break :vi var_inst;4481 break :vi var_inst;
...@@ -11495,6 +11497,7 @@ const GenZir = struct {...@@ -11495,6 +11497,7 @@ const GenZir = struct {
11495 var_type: Zir.Inst.Ref,11497 var_type: Zir.Inst.Ref,
11496 init: Zir.Inst.Ref,11498 init: Zir.Inst.Ref,
11497 is_extern: bool,11499 is_extern: bool,
11500 is_const: bool,
11498 is_threadlocal: bool,11501 is_threadlocal: bool,
11499 }) !Zir.Inst.Ref {11502 }) !Zir.Inst.Ref {
11500 const astgen = gz.astgen;11503 const astgen = gz.astgen;
...@@ -11533,6 +11536,7 @@ const GenZir = struct {...@@ -11533,6 +11536,7 @@ const GenZir = struct {
11533 .has_align = args.align_inst != .none,11536 .has_align = args.align_inst != .none,
11534 .has_init = args.init != .none,11537 .has_init = args.init != .none,
11535 .is_extern = args.is_extern,11538 .is_extern = args.is_extern,
11539 .is_const = args.is_const,
11536 .is_threadlocal = args.is_threadlocal,11540 .is_threadlocal = args.is_threadlocal,
11537 }),11541 }),
11538 .operand = payload_index,11542 .operand = payload_index,
src/InternPool.zig+5-5
...@@ -1005,11 +1005,11 @@ pub const Key = union(enum) {...@@ -1005,11 +1005,11 @@ pub const Key = union(enum) {
1005 ty: Index,1005 ty: Index,
1006 init: Index,1006 init: Index,
1007 decl: DeclIndex,1007 decl: DeclIndex,
1008 lib_name: OptionalNullTerminatedString = .none,1008 lib_name: OptionalNullTerminatedString,
1009 is_extern: bool = false,1009 is_extern: bool,
1010 is_const: bool = false,1010 is_const: bool,
1011 is_threadlocal: bool = false,1011 is_threadlocal: bool,
1012 is_weak_linkage: bool = false,1012 is_weak_linkage: bool,
1013 };1013 };
10141014
1015 pub const ExternFunc = struct {1015 pub const ExternFunc = struct {
src/Sema.zig+7-3
...@@ -24760,7 +24760,9 @@ fn zirVarExtended(...@@ -24760,7 +24760,9 @@ fn zirVarExtended(
24760 .decl = sema.owner_decl_index,24760 .decl = sema.owner_decl_index,
24761 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, lib_name),24761 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, lib_name),
24762 .is_extern = small.is_extern,24762 .is_extern = small.is_extern,
24763 .is_const = small.is_const,
24763 .is_threadlocal = small.is_threadlocal,24764 .is_threadlocal = small.is_threadlocal,
24765 .is_weak_linkage = false,
24764 } })));24766 } })));
24765}24767}
2476624768
...@@ -25264,6 +25266,7 @@ fn zirBuiltinExtern(...@@ -25264,6 +25266,7 @@ fn zirBuiltinExtern(
25264 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {25266 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
25265 ty = try mod.optionalType(ty.toIntern());25267 ty = try mod.optionalType(ty.toIntern());
25266 }25268 }
25269 const ptr_info = ty.ptrInfo(mod);
2526725270
25268 // TODO check duplicate extern25271 // TODO check duplicate extern
2526925272
...@@ -25274,11 +25277,12 @@ fn zirBuiltinExtern(...@@ -25274,11 +25277,12 @@ fn zirBuiltinExtern(
2527425277
25275 {25278 {
25276 const new_var = try mod.intern(.{ .variable = .{25279 const new_var = try mod.intern(.{ .variable = .{
25277 .ty = ty.toIntern(),25280 .ty = ptr_info.child,
25278 .init = .none,25281 .init = .none,
25279 .decl = sema.owner_decl_index,25282 .decl = sema.owner_decl_index,
25283 .lib_name = options.library_name,
25280 .is_extern = true,25284 .is_extern = true,
25281 .is_const = true,25285 .is_const = ptr_info.flags.is_const,
25282 .is_threadlocal = options.is_thread_local,25286 .is_threadlocal = options.is_thread_local,
25283 .is_weak_linkage = options.linkage == .Weak,25287 .is_weak_linkage = options.linkage == .Weak,
25284 } });25288 } });
...@@ -25286,7 +25290,7 @@ fn zirBuiltinExtern(...@@ -25286,7 +25290,7 @@ fn zirBuiltinExtern(
25286 new_decl.src_line = sema.owner_decl.src_line;25290 new_decl.src_line = sema.owner_decl.src_line;
25287 // We only access this decl through the decl_ref with the correct type created25291 // We only access this decl through the decl_ref with the correct type created
25288 // below, so this type doesn't matter25292 // below, so this type doesn't matter
25289 new_decl.ty = ty;25293 new_decl.ty = Type.fromInterned(ptr_info.child);
25290 new_decl.val = Value.fromInterned(new_var);25294 new_decl.val = Value.fromInterned(new_var);
25291 new_decl.alignment = .none;25295 new_decl.alignment = .none;
25292 new_decl.@"linksection" = .none;25296 new_decl.@"linksection" = .none;
src/Zir.zig+2-1
...@@ -2610,8 +2610,9 @@ pub const Inst = struct {...@@ -2610,8 +2610,9 @@ pub const Inst = struct {
2610 has_align: bool,2610 has_align: bool,
2611 has_init: bool,2611 has_init: bool,
2612 is_extern: bool,2612 is_extern: bool,
2613 is_const: bool,
2613 is_threadlocal: bool,2614 is_threadlocal: bool,
2614 _: u11 = undefined,2615 _: u10 = undefined,
2615 };2616 };
2616 };2617 };
26172618
src/codegen/c.zig+183-77
...@@ -258,6 +258,20 @@ pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {...@@ -258,6 +258,20 @@ pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
258 return .{ .data = ident };258 return .{ .data = ident };
259}259}
260260
261// Returns true if `formatIdent` would make any edits to ident.
262// This must be kept in sync with `formatIdent`.
263pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
264 if (solo and isReservedIdent(ident)) return true;
265 for (ident, 0..) |c, i| {
266 switch (c) {
267 'a'...'z', 'A'...'Z', '_' => {},
268 '0'...'9' => if (i == 0) return true,
269 else => return true,
270 }
271 }
272 return false;
273}
274
261/// This data is available when outputting .c code for a `InternPool.Index`275/// This data is available when outputting .c code for a `InternPool.Index`
262/// that corresponds to `func`.276/// that corresponds to `func`.
263/// It is not available when generating .h file.277/// It is not available when generating .h file.
...@@ -646,7 +660,7 @@ pub const DeclGen = struct {...@@ -646,7 +660,7 @@ pub const DeclGen = struct {
646 if (decl.val.getExternFunc(mod)) |extern_func| if (extern_func.decl != decl_index)660 if (decl.val.getExternFunc(mod)) |extern_func| if (extern_func.decl != decl_index)
647 return dg.renderDeclValue(writer, ty, val, extern_func.decl, location);661 return dg.renderDeclValue(writer, ty, val, extern_func.decl, location);
648662
649 if (decl.val.getVariable(mod)) |variable| try dg.renderFwdDecl(decl_index, variable);663 if (decl.val.getVariable(mod)) |variable| try dg.renderFwdDecl(decl_index, variable, .tentative);
650664
651 // We shouldn't cast C function pointers as this is UB (when you call665 // We shouldn't cast C function pointers as this is UB (when you call
652 // them). The analysis until now should ensure that the C function666 // them). The analysis until now should ensure that the C function
...@@ -1593,7 +1607,7 @@ pub const DeclGen = struct {...@@ -1593,7 +1607,7 @@ pub const DeclGen = struct {
1593 kind: CType.Kind,1607 kind: CType.Kind,
1594 name: union(enum) {1608 name: union(enum) {
1595 export_index: u32,1609 export_index: u32,
1596 string: []const u8,1610 ident: []const u8,
1597 },1611 },
1598 ) !void {1612 ) !void {
1599 const store = &dg.ctypes.set;1613 const store = &dg.ctypes.set;
...@@ -1615,23 +1629,28 @@ pub const DeclGen = struct {...@@ -1615,23 +1629,28 @@ pub const DeclGen = struct {
1615 try w.writeAll("zig_cold ");1629 try w.writeAll("zig_cold ");
1616 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");1630 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
16171631
1618 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});1632 var trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
1619 try w.print("{}", .{trailing});
16201633
1621 if (toCallingConvention(fn_info.cc)) |call_conv| {1634 if (toCallingConvention(fn_info.cc)) |call_conv| {
1622 try w.print("zig_callconv({s}) ", .{call_conv});1635 try w.print("{}zig_callconv({s})", .{ trailing, call_conv });
1636 trailing = .maybe_space;
1623 }1637 }
16241638
1625 switch (kind) {1639 switch (kind) {
1626 .forward => {},1640 .forward => {},
1627 .complete => if (fn_info.alignment.toByteUnitsOptional()) |a|1641 .complete => if (fn_info.alignment.toByteUnitsOptional()) |a| {
1628 try w.print(" zig_align_fn({})", .{a}),1642 try w.print("{}zig_align_fn({})", .{ trailing, a });
1643 trailing = .maybe_space;
1644 },
1629 else => unreachable,1645 else => unreachable,
1630 }1646 }
16311647
1632 switch (name) {1648 switch (name) {
1633 .export_index => |export_index| try dg.renderDeclName(w, fn_decl_index, export_index),1649 .export_index => |export_index| {
1634 .string => |string| try w.writeAll(string),1650 try w.print("{}", .{trailing});
1651 try dg.renderDeclName(w, fn_decl_index, export_index);
1652 },
1653 .ident => |ident| try w.print("{}{ }", .{ trailing, fmtIdent(ident) }),
1635 }1654 }
16361655
1637 try renderTypeSuffix(1656 try renderTypeSuffix(
...@@ -1649,8 +1668,49 @@ pub const DeclGen = struct {...@@ -1649,8 +1668,49 @@ pub const DeclGen = struct {
1649 );1668 );
16501669
1651 switch (kind) {1670 switch (kind) {
1652 .forward => if (fn_info.alignment.toByteUnitsOptional()) |a|1671 .forward => {
1653 try w.print(" zig_align_fn({})", .{a}),1672 if (fn_info.alignment.toByteUnitsOptional()) |a| {
1673 try w.print(" zig_align_fn({})", .{a});
1674 }
1675 switch (name) {
1676 .export_index => |export_index| mangled: {
1677 const maybe_exports = mod.decl_exports.get(fn_decl_index);
1678 const external_name = ip.stringToSlice(
1679 if (maybe_exports) |exports|
1680 exports.items[export_index].opts.name
1681 else if (fn_decl.isExtern(mod))
1682 fn_decl.name
1683 else
1684 break :mangled,
1685 );
1686 const is_mangled = isMangledIdent(external_name, true);
1687 const is_export = export_index > 0;
1688 if (is_mangled and is_export) {
1689 try w.print(" zig_mangled_export({ }, {s}, {s})", .{
1690 fmtIdent(external_name),
1691 fmtStringLiteral(external_name, null),
1692 fmtStringLiteral(
1693 ip.stringToSlice(maybe_exports.?.items[0].opts.name),
1694 null,
1695 ),
1696 });
1697 } else if (is_mangled) {
1698 try w.print(" zig_mangled_final({ }, {s})", .{
1699 fmtIdent(external_name), fmtStringLiteral(external_name, null),
1700 });
1701 } else if (is_export) {
1702 try w.print(" zig_export({s}, {s})", .{
1703 fmtStringLiteral(
1704 ip.stringToSlice(maybe_exports.?.items[0].opts.name),
1705 null,
1706 ),
1707 fmtStringLiteral(external_name, null),
1708 });
1709 }
1710 },
1711 .ident => {},
1712 }
1713 },
1654 .complete => {},1714 .complete => {},
1655 else => unreachable,1715 else => unreachable,
1656 }1716 }
...@@ -1930,12 +1990,18 @@ pub const DeclGen = struct {...@@ -1930,12 +1990,18 @@ pub const DeclGen = struct {
1930 try dg.writeCValue(writer, member);1990 try dg.writeCValue(writer, member);
1931 }1991 }
19321992
1933 fn renderFwdDecl(dg: *DeclGen, decl_index: InternPool.DeclIndex, variable: InternPool.Key.Variable) !void {1993 fn renderFwdDecl(
1994 dg: *DeclGen,
1995 decl_index: InternPool.DeclIndex,
1996 variable: InternPool.Key.Variable,
1997 fwd_kind: enum { tentative, final },
1998 ) !void {
1934 const decl = dg.module.declPtr(decl_index);1999 const decl = dg.module.declPtr(decl_index);
1935 const fwd = dg.fwd_decl.writer();2000 const fwd = dg.fwd_decl.writer();
1936 const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern;2001 const is_global = variable.is_extern or dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val });
1937 try fwd.writeAll(if (is_global) "zig_extern " else "static ");2002 try fwd.writeAll(if (is_global) "zig_extern " else "static ");
1938 const export_weak_linkage = if (dg.module.decl_exports.get(decl_index)) |exports|2003 const maybe_exports = dg.module.decl_exports.get(decl_index);
2004 const export_weak_linkage = if (maybe_exports) |exports|
1939 exports.items[0].opts.linkage == .Weak2005 exports.items[0].opts.linkage == .Weak
1940 else2006 else
1941 false;2007 false;
...@@ -1949,6 +2015,21 @@ pub const DeclGen = struct {...@@ -1949,6 +2015,21 @@ pub const DeclGen = struct {
1949 decl.alignment,2015 decl.alignment,
1950 .complete,2016 .complete,
1951 );2017 );
2018 mangled: {
2019 const external_name = dg.module.intern_pool.stringToSlice(if (maybe_exports) |exports|
2020 exports.items[0].opts.name
2021 else if (variable.is_extern)
2022 decl.name
2023 else
2024 break :mangled);
2025 if (isMangledIdent(external_name, true)) {
2026 try fwd.print(" zig_mangled_{s}({ }, {s})", .{
2027 @tagName(fwd_kind),
2028 fmtIdent(external_name),
2029 fmtStringLiteral(external_name, null),
2030 });
2031 }
2032 }
1952 try fwd.writeAll(";\n");2033 try fwd.writeAll(";\n");
1953 }2034 }
19542035
...@@ -1958,9 +2039,13 @@ pub const DeclGen = struct {...@@ -1958,9 +2039,13 @@ pub const DeclGen = struct {
1958 try mod.markDeclAlive(decl);2039 try mod.markDeclAlive(decl);
19592040
1960 if (mod.decl_exports.get(decl_index)) |exports| {2041 if (mod.decl_exports.get(decl_index)) |exports| {
1961 try writer.print("{}", .{exports.items[export_index].opts.name.fmt(&mod.intern_pool)});2042 try writer.print("{ }", .{
2043 fmtIdent(mod.intern_pool.stringToSlice(exports.items[export_index].opts.name)),
2044 });
1962 } else if (decl.getExternDecl(mod).unwrap()) |extern_decl_index| {2045 } else if (decl.getExternDecl(mod).unwrap()) |extern_decl_index| {
1963 try writer.print("{}", .{mod.declPtr(extern_decl_index).name.fmt(&mod.intern_pool)});2046 try writer.print("{ }", .{
2047 fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(extern_decl_index).name)),
2048 });
1964 } else {2049 } else {
1965 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),2050 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
1966 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.2051 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
...@@ -2592,7 +2677,10 @@ fn genExports(o: *Object) !void {...@@ -2592,7 +2677,10 @@ fn genExports(o: *Object) !void {
25922677
2593 const mod = o.dg.module;2678 const mod = o.dg.module;
2594 const ip = &mod.intern_pool;2679 const ip = &mod.intern_pool;
2595 const decl_index = o.dg.pass.decl;2680 const decl_index = switch (o.dg.pass) {
2681 .decl => |decl| decl,
2682 .anon, .flush => return,
2683 };
2596 const decl = mod.declPtr(decl_index);2684 const decl = mod.declPtr(decl_index);
2597 const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) };2685 const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) };
2598 const fwd = o.dg.fwd_decl.writer();2686 const fwd = o.dg.fwd_decl.writer();
...@@ -2600,42 +2688,50 @@ fn genExports(o: *Object) !void {...@@ -2600,42 +2688,50 @@ fn genExports(o: *Object) !void {
2600 const exports = mod.decl_exports.get(decl_index) orelse return;2688 const exports = mod.decl_exports.get(decl_index) orelse return;
2601 if (exports.items.len < 2) return;2689 if (exports.items.len < 2) return;
26022690
2603 switch (ip.indexToKey(tv.val.toIntern())) {2691 const is_variable_const = switch (ip.indexToKey(tv.val.toIntern())) {
2604 .func => {2692 .func => return for (exports.items[1..], 1..) |@"export", i| {
2605 for (exports.items[1..], 1..) |@"export", i| {2693 try fwd.writeAll("zig_extern ");
2606 try fwd.writeAll("zig_export(");2694 if (@"export".opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage_fn ");
2607 if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage_fn ");2695 try o.dg.renderFunctionSignature(
2608 try o.dg.renderFunctionSignature(fwd, decl_index, .forward, .{ .export_index = @as(u32, @intCast(i)) });2696 fwd,
2609 try fwd.print(", {s}, {s});\n", .{2697 decl_index,
2610 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),2698 .forward,
2611 fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null),2699 .{ .export_index = @intCast(i) },
2612 });2700 );
2613 }2701 try fwd.writeAll(";\n");
2614 },2702 },
2615 .extern_func => {2703 .extern_func => {
2616 // TODO: when sema allows re-exporting extern decls2704 // TODO: when sema allows re-exporting extern decls
2617 unreachable;2705 unreachable;
2618 },2706 },
2619 .variable => |variable| {2707 .variable => |variable| variable.is_const,
2620 for (exports.items[1..], 1..) |@"export", i| {2708 else => true,
2621 try fwd.writeAll("zig_export(");2709 };
2622 if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage ");2710 for (exports.items[1..]) |@"export"| {
2623 const alias = ip.stringToSlice(@"export".opts.name);2711 try fwd.writeAll("zig_extern ");
2624 try o.dg.renderTypeAndName(2712 if (@"export".opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage ");
2625 fwd,2713 const export_name = ip.stringToSlice(@"export".opts.name);
2626 decl.ty,2714 try o.dg.renderTypeAndName(
2627 .{ .identifier = alias },2715 fwd,
2628 CQualifiers.init(.{ .@"const" = variable.is_const }),2716 decl.ty,
2629 decl.alignment,2717 .{ .identifier = export_name },
2630 .complete,2718 CQualifiers.init(.{ .@"const" = is_variable_const }),
2631 );2719 decl.alignment,
2632 try fwd.print(", {s}, {s});\n", .{2720 .complete,
2633 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),2721 );
2634 fmtStringLiteral(alias, null),2722 if (isMangledIdent(export_name, true)) {
2635 });2723 try fwd.print(" zig_mangled_export({ }, {s}, {s})", .{
2636 }2724 fmtIdent(export_name),
2637 },2725 fmtStringLiteral(export_name, null),
2638 else => {},2726 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
2727 });
2728 } else {
2729 try fwd.print(" zig_export({s}, {s})", .{
2730 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
2731 fmtStringLiteral(export_name, null),
2732 });
2733 }
2734 try fwd.writeAll(";\n");
2639 }2735 }
2640}2736}
26412737
...@@ -2707,12 +2803,12 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {...@@ -2707,12 +2803,12 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
2707 fwd_decl_writer,2803 fwd_decl_writer,
2708 fn_decl_index,2804 fn_decl_index,
2709 .forward,2805 .forward,
2710 .{ .string = fn_name },2806 .{ .ident = fn_name },
2711 );2807 );
2712 try fwd_decl_writer.writeAll(";\n");2808 try fwd_decl_writer.writeAll(";\n");
27132809
2714 try w.print("static zig_{s} ", .{@tagName(key)});2810 try w.print("static zig_{s} ", .{@tagName(key)});
2715 try o.dg.renderFunctionSignature(w, fn_decl_index, .complete, .{ .string = fn_name });2811 try o.dg.renderFunctionSignature(w, fn_decl_index, .complete, .{ .ident = fn_name });
2716 try w.writeAll(" {\n return ");2812 try w.writeAll(" {\n return ");
2717 try o.dg.renderDeclName(w, fn_decl_index, 0);2813 try o.dg.renderDeclName(w, fn_decl_index, 0);
2718 try w.writeByte('(');2814 try w.writeByte('(');
...@@ -2745,6 +2841,7 @@ pub fn genFunc(f: *Function) !void {...@@ -2745,6 +2841,7 @@ pub fn genFunc(f: *Function) !void {
2745 const is_global = o.dg.declIsGlobal(tv);2841 const is_global = o.dg.declIsGlobal(tv);
2746 const fwd_decl_writer = o.dg.fwd_decl.writer();2842 const fwd_decl_writer = o.dg.fwd_decl.writer();
2747 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");2843 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2844
2748 if (mod.decl_exports.get(decl_index)) |exports|2845 if (mod.decl_exports.get(decl_index)) |exports|
2749 if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn ");2846 if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn ");
2750 try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });2847 try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
...@@ -2831,12 +2928,12 @@ pub fn genDecl(o: *Object) !void {...@@ -2831,12 +2928,12 @@ pub fn genDecl(o: *Object) !void {
2831 try fwd_decl_writer.writeAll(";\n");2928 try fwd_decl_writer.writeAll(";\n");
2832 try genExports(o);2929 try genExports(o);
2833 } else if (tv.val.getVariable(mod)) |variable| {2930 } else if (tv.val.getVariable(mod)) |variable| {
2834 try o.dg.renderFwdDecl(decl_index, variable);2931 try o.dg.renderFwdDecl(decl_index, variable, .final);
2835 try genExports(o);2932 try genExports(o);
28362933
2837 if (variable.is_extern) return;2934 if (variable.is_extern) return;
28382935
2839 const is_global = o.dg.declIsGlobal(tv) or variable.is_extern;2936 const is_global = variable.is_extern or o.dg.declIsGlobal(tv);
2840 const w = o.writer();2937 const w = o.writer();
2841 if (!is_global) try w.writeAll("static ");2938 if (!is_global) try w.writeAll("static ");
2842 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");2939 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
...@@ -2853,7 +2950,7 @@ pub fn genDecl(o: *Object) !void {...@@ -2853,7 +2950,7 @@ pub fn genDecl(o: *Object) !void {
2853 } else {2950 } else {
2854 const is_global = o.dg.module.decl_exports.contains(decl_index);2951 const is_global = o.dg.module.decl_exports.contains(decl_index);
2855 const decl_c_value = .{ .decl = decl_index };2952 const decl_c_value = .{ .decl = decl_index };
2856 return genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection");2953 try genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection");
2857 }2954 }
2858}2955}
28592956
...@@ -2870,10 +2967,26 @@ pub fn genDeclValue(...@@ -2870,10 +2967,26 @@ pub fn genDeclValue(
28702967
2871 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");2968 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2872 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);2969 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
2970 switch (o.dg.pass) {
2971 .decl => |decl_index| {
2972 if (mod.decl_exports.get(decl_index)) |exports| {
2973 const export_name = mod.intern_pool.stringToSlice(exports.items[0].opts.name);
2974 if (isMangledIdent(export_name, true)) {
2975 try fwd_decl_writer.print(" zig_mangled_final({ }, {s})", .{
2976 fmtIdent(export_name), fmtStringLiteral(export_name, null),
2977 });
2978 }
2979 }
2980 },
2981 .anon => {},
2982 .flush => unreachable,
2983 }
2873 try fwd_decl_writer.writeAll(";\n");2984 try fwd_decl_writer.writeAll(";\n");
2985 try genExports(o);
28742986
2875 const w = o.writer();2987 const w = o.writer();
2876 if (!is_global) try w.writeAll("static ");2988 if (!is_global) try w.writeAll("static ");
2989
2877 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|2990 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
2878 try w.print("zig_linksection(\"{s}\", ", .{s});2991 try w.print("zig_linksection(\"{s}\", ", .{s});
2879 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete);2992 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete);
...@@ -2897,13 +3010,10 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {...@@ -2897,13 +3010,10 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
2897 const writer = dg.fwd_decl.writer();3010 const writer = dg.fwd_decl.writer();
28983011
2899 switch (tv.ty.zigTypeTag(mod)) {3012 switch (tv.ty.zigTypeTag(mod)) {
2900 .Fn => {3013 .Fn => if (dg.declIsGlobal(tv)) {
2901 const is_global = dg.declIsGlobal(tv);3014 try writer.writeAll("zig_extern ");
2902 if (is_global) {3015 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
2903 try writer.writeAll("zig_extern ");3016 try dg.fwd_decl.appendSlice(";\n");
2904 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
2905 try dg.fwd_decl.appendSlice(";\n");
2906 }
2907 },3017 },
2908 else => {},3018 else => {},
2909 }3019 }
...@@ -6895,9 +7005,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6895,9 +7005,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6895 try f.writeCValue(writer, accum, .Other);7005 try f.writeCValue(writer, accum, .Other);
6896 switch (op) {7006 switch (op) {
6897 .float_op => |func| {7007 .float_op => |func| {
6898 try writer.writeAll(" = zig_libc_name_");7008 try writer.writeAll(" = zig_float_fn_");
6899 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);7009 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
6900 try writer.print("({s})(", .{func.operation});7010 try writer.print("_{s}(", .{func.operation});
6901 try f.writeCValue(writer, accum, .FunctionArgument);7011 try f.writeCValue(writer, accum, .FunctionArgument);
6902 try writer.writeAll(", ");7012 try writer.writeAll(", ");
6903 try f.writeCValue(writer, operand, .Other);7013 try f.writeCValue(writer, operand, .Other);
...@@ -7229,11 +7339,9 @@ fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, oper...@@ -7229,11 +7339,9 @@ fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, oper
7229 const v = try Vectorize.start(f, inst, writer, ty);7339 const v = try Vectorize.start(f, inst, writer, ty);
7230 try f.writeCValue(writer, local, .Other);7340 try f.writeCValue(writer, local, .Other);
7231 try v.elem(f, writer);7341 try v.elem(f, writer);
7232 try writer.writeAll(" = zig_libc_name_");7342 try writer.writeAll(" = zig_float_fn_");
7233 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);7343 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
7234 try writer.writeByte('(');7344 try writer.print("_{s}(", .{operation});
7235 try writer.writeAll(operation);
7236 try writer.writeAll(")(");
7237 try f.writeCValue(writer, operand, .FunctionArgument);7345 try f.writeCValue(writer, operand, .FunctionArgument);
7238 try v.elem(f, writer);7346 try v.elem(f, writer);
7239 try writer.writeAll(");\n");7347 try writer.writeAll(");\n");
...@@ -7268,11 +7376,9 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa...@@ -7268,11 +7376,9 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
7268 const v = try Vectorize.start(f, inst, writer, inst_ty);7376 const v = try Vectorize.start(f, inst, writer, inst_ty);
7269 try f.writeCValue(writer, local, .Other);7377 try f.writeCValue(writer, local, .Other);
7270 try v.elem(f, writer);7378 try v.elem(f, writer);
7271 try writer.writeAll(" = zig_libc_name_");7379 try writer.writeAll(" = zig_float_fn_");
7272 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);7380 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
7273 try writer.writeByte('(');7381 try writer.print("_{s}(", .{operation});
7274 try writer.writeAll(operation);
7275 try writer.writeAll(")(");
7276 try f.writeCValue(writer, lhs, .FunctionArgument);7382 try f.writeCValue(writer, lhs, .FunctionArgument);
7277 try v.elem(f, writer);7383 try v.elem(f, writer);
7278 try writer.writeAll(", ");7384 try writer.writeAll(", ");
...@@ -7302,9 +7408,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7302,9 +7408,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7302 const v = try Vectorize.start(f, inst, writer, inst_ty);7408 const v = try Vectorize.start(f, inst, writer, inst_ty);
7303 try f.writeCValue(writer, local, .Other);7409 try f.writeCValue(writer, local, .Other);
7304 try v.elem(f, writer);7410 try v.elem(f, writer);
7305 try writer.writeAll(" = zig_libc_name_");7411 try writer.writeAll(" = zig_float_fn_");
7306 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);7412 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
7307 try writer.writeAll("(fma)(");7413 try writer.writeAll("_fma(");
7308 try f.writeCValue(writer, mulend1, .FunctionArgument);7414 try f.writeCValue(writer, mulend1, .FunctionArgument);
7309 try v.elem(f, writer);7415 try v.elem(f, writer);
7310 try writer.writeAll(", ");7416 try writer.writeAll(", ");
...@@ -7390,11 +7496,11 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7390,11 +7496,11 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
7390fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {7496fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
7391 return switch (order) {7497 return switch (order) {
7392 // Note: unordered is actually even less atomic than relaxed7498 // Note: unordered is actually even less atomic than relaxed
7393 .Unordered, .Monotonic => "memory_order_relaxed",7499 .Unordered, .Monotonic => "zig_memory_order_relaxed",
7394 .Acquire => "memory_order_acquire",7500 .Acquire => "zig_memory_order_acquire",
7395 .Release => "memory_order_release",7501 .Release => "zig_memory_order_release",
7396 .AcqRel => "memory_order_acq_rel",7502 .AcqRel => "zig_memory_order_acq_rel",
7397 .SeqCst => "memory_order_seq_cst",7503 .SeqCst => "zig_memory_order_seq_cst",
7398 };7504 };
7399}7505}
74007506
test/behavior.zig+1-3
...@@ -110,7 +110,6 @@ test {...@@ -110,7 +110,6 @@ test {
110 _ = @import("behavior/bugs/12551.zig");110 _ = @import("behavior/bugs/12551.zig");
111 _ = @import("behavior/bugs/12571.zig");111 _ = @import("behavior/bugs/12571.zig");
112 _ = @import("behavior/bugs/12644.zig");112 _ = @import("behavior/bugs/12644.zig");
113 _ = @import("behavior/bugs/12680.zig");
114 _ = @import("behavior/bugs/12723.zig");113 _ = @import("behavior/bugs/12723.zig");
115 _ = @import("behavior/bugs/12776.zig");114 _ = @import("behavior/bugs/12776.zig");
116 _ = @import("behavior/bugs/12786.zig");115 _ = @import("behavior/bugs/12786.zig");
...@@ -175,6 +174,7 @@ test {...@@ -175,6 +174,7 @@ test {
175 _ = @import("behavior/hasfield.zig");174 _ = @import("behavior/hasfield.zig");
176 _ = @import("behavior/if.zig");175 _ = @import("behavior/if.zig");
177 _ = @import("behavior/import.zig");176 _ = @import("behavior/import.zig");
177 _ = @import("behavior/import_c_keywords.zig");
178 _ = @import("behavior/incomplete_struct_param_tld.zig");178 _ = @import("behavior/incomplete_struct_param_tld.zig");
179 _ = @import("behavior/inline_switch.zig");179 _ = @import("behavior/inline_switch.zig");
180 _ = @import("behavior/int128.zig");180 _ = @import("behavior/int128.zig");
...@@ -251,9 +251,7 @@ test {...@@ -251,9 +251,7 @@ test {
251 }251 }
252252
253 if (builtin.zig_backend != .stage2_arm and253 if (builtin.zig_backend != .stage2_arm and
254 builtin.zig_backend != .stage2_x86_64 and
255 builtin.zig_backend != .stage2_aarch64 and254 builtin.zig_backend != .stage2_aarch64 and
256 builtin.zig_backend != .stage2_c and
257 builtin.zig_backend != .stage2_spirv64)255 builtin.zig_backend != .stage2_spirv64)
258 {256 {
259 _ = @import("behavior/export_keyword.zig");257 _ = @import("behavior/export_keyword.zig");
test/behavior/bugs/12680.zig deleted-22
...@@ -1,22 +0,0 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3const other_file = @import("12680_other_file.zig");
4const builtin = @import("builtin");
5
6extern fn test_func() callconv(.C) usize;
7
8test "export a function twice" {
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
14
15 if (builtin.os.tag == .macos and builtin.zig_backend == .stage2_c) {
16 // TODO: test.c: error: aliases are not supported on darwin
17 return error.SkipZigTest;
18 }
19
20 // If it exports the function correctly, `test_func` and `testFunc` will points to the same address.
21 try expectEqual(test_func(), other_file.testFunc());
22}
test/behavior/bugs/12680_other_file.zig deleted-8
...@@ -1,8 +0,0 @@
1// export this function twice
2pub export fn testFunc() callconv(.C) usize {
3 return @intFromPtr(&testFunc);
4}
5
6comptime {
7 @export(testFunc, .{ .name = "test_func", .linkage = .Strong });
8}
test/behavior/export_c_keywords.zig created+44
...@@ -0,0 +1,44 @@
1pub const Id = enum(c_int) {
2 c_keyword_variable = 12,
3 non_c_keyword_variable = 34,
4 c_keyword_constant = 56,
5 non_c_keyword_constant = 78,
6 c_keyword_function = 910,
7 non_c_keyword_function = 1112,
8};
9
10export var int: Id = .c_keyword_variable;
11
12export var some_non_c_keyword_variable: Id = .non_c_keyword_variable;
13
14export const @"if": Id = .c_keyword_constant;
15
16export const some_non_c_keyword_constant: Id = .non_c_keyword_constant;
17
18export fn float() Id {
19 return .c_keyword_function;
20}
21
22export fn some_non_c_keyword_function() Id {
23 return .non_c_keyword_function;
24}
25
26comptime {
27 @export(int, .{ .name = "long" });
28 @export(int, .{ .name = "an_alias_of_int" });
29
30 @export(some_non_c_keyword_variable, .{ .name = "void" });
31 @export(some_non_c_keyword_variable, .{ .name = "an_alias_of_some_non_c_keyword_variable" });
32
33 @export(@"if", .{ .name = "else" });
34 @export(@"if", .{ .name = "an_alias_of_if" });
35
36 @export(some_non_c_keyword_constant, .{ .name = "switch" });
37 @export(some_non_c_keyword_constant, .{ .name = "an_alias_of_some_non_c_keyword_constant" });
38
39 @export(float, .{ .name = "double" });
40 @export(float, .{ .name = "an_alias_of_float" });
41
42 @export(some_non_c_keyword_function, .{ .name = "break" });
43 @export(some_non_c_keyword_function, .{ .name = "an_alias_of_some_non_c_keyword_function" });
44}
test/behavior/import_c_keywords.zig created+92
...@@ -0,0 +1,92 @@
1const builtin = @import("builtin");
2const Id = @import("export_c_keywords.zig").Id;
3const std = @import("std");
4
5extern var int: Id;
6extern var long: Id;
7extern var an_alias_of_int: Id;
8
9extern var some_non_c_keyword_variable: Id;
10extern var @"void": Id;
11extern var an_alias_of_some_non_c_keyword_variable: Id;
12
13extern const @"if": Id;
14extern const @"else": Id;
15extern const an_alias_of_if: Id;
16
17extern const some_non_c_keyword_constant: Id;
18extern const @"switch": Id;
19extern const an_alias_of_some_non_c_keyword_constant: Id;
20
21extern fn float() Id;
22extern fn double() Id;
23extern fn an_alias_of_float() Id;
24
25extern fn some_non_c_keyword_function() Id;
26extern fn @"break"() Id;
27extern fn an_alias_of_some_non_c_keyword_function() Id;
28
29test "import c keywords" {
30 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
31 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
32 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
33 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
34 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
35 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
36
37 try std.testing.expect(int == .c_keyword_variable);
38 try std.testing.expect(long == .c_keyword_variable);
39 try std.testing.expect(an_alias_of_int == .c_keyword_variable);
40
41 try std.testing.expect(some_non_c_keyword_variable == .non_c_keyword_variable);
42 try std.testing.expect(@"void" == .non_c_keyword_variable);
43 try std.testing.expect(an_alias_of_some_non_c_keyword_variable == .non_c_keyword_variable);
44
45 try std.testing.expect(@"if" == .c_keyword_constant);
46 try std.testing.expect(@"else" == .c_keyword_constant);
47 try std.testing.expect(an_alias_of_if == .c_keyword_constant);
48
49 try std.testing.expect(some_non_c_keyword_constant == .non_c_keyword_constant);
50 try std.testing.expect(@"switch" == .non_c_keyword_constant);
51 try std.testing.expect(an_alias_of_some_non_c_keyword_constant == .non_c_keyword_constant);
52
53 try std.testing.expect(float() == .c_keyword_function);
54 try std.testing.expect(double() == .c_keyword_function);
55 try std.testing.expect(an_alias_of_float() == .c_keyword_function);
56
57 try std.testing.expect(some_non_c_keyword_function() == .non_c_keyword_function);
58 try std.testing.expect(@"break"() == .non_c_keyword_function);
59 try std.testing.expect(an_alias_of_some_non_c_keyword_function() == .non_c_keyword_function);
60
61 var ptr_id: *const Id = &long;
62 try std.testing.expect(ptr_id == &int);
63 ptr_id = &an_alias_of_int;
64 try std.testing.expect(ptr_id == &int);
65
66 ptr_id = &@"void";
67 try std.testing.expect(ptr_id == &some_non_c_keyword_variable);
68 ptr_id = &an_alias_of_some_non_c_keyword_variable;
69 try std.testing.expect(ptr_id == &some_non_c_keyword_variable);
70
71 ptr_id = &@"else";
72 try std.testing.expect(ptr_id == &@"if");
73 ptr_id = &an_alias_of_if;
74 try std.testing.expect(ptr_id == &@"if");
75
76 ptr_id = &@"switch";
77 try std.testing.expect(ptr_id == &some_non_c_keyword_constant);
78 ptr_id = &an_alias_of_some_non_c_keyword_constant;
79 try std.testing.expect(ptr_id == &some_non_c_keyword_constant);
80
81 if (builtin.target.ofmt != .coff and builtin.target.os.tag != .windows) {
82 var ptr_fn: *const fn () callconv(.C) Id = &double;
83 try std.testing.expect(ptr_fn == &float);
84 ptr_fn = &an_alias_of_float;
85 try std.testing.expect(ptr_fn == &float);
86
87 ptr_fn = &@"break";
88 try std.testing.expect(ptr_fn == &some_non_c_keyword_function);
89 ptr_fn = &an_alias_of_some_non_c_keyword_function;
90 try std.testing.expect(ptr_fn == &some_non_c_keyword_function);
91 }
92}