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
9696CheckLastExitCode
9797
9898Write-Output "Build and run behavior tests with msvc..."
99Write-Output "Skipped due to https://github.com/ziglang/zig/issues/17817"
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.lib
101#CheckLastExitCode
102#
103#& .\test-x86_64-windows-msvc.exe
104#CheckLastExitCode
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
100CheckLastExitCode
101
102& .\test-x86_64-windows-msvc.exe
103CheckLastExitCode
ci/x86_64-windows-release.ps1+5-6
......@@ -95,9 +95,8 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files\Microsoft Visual Studio\2022\E
9595CheckLastExitCode
9696
9797Write-Output "Build and run behavior tests with msvc..."
98Write-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#CheckLastExitCode
101#
102#& .\test-x86_64-windows-msvc.exe
103#CheckLastExitCode
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
99CheckLastExitCode
100
101& .\test-x86_64-windows-msvc.exe
102CheckLastExitCode
lib/std/math.zig+1
......@@ -1266,6 +1266,7 @@ pub fn lerp(a: anytype, b: anytype, t: anytype) @TypeOf(a, b, t) {
12661266}
12671267
12681268test "lerp" {
1269 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/17884
12691270 if (builtin.zig_backend == .stage2_x86_64 and
12701271 !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;
2525#endif
2626#endif
2727
28#define zig_concat(lhs, rhs) lhs##rhs
29#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
30
2831#if defined(__has_builtin)
2932#define zig_has_builtin(builtin) __has_builtin(__builtin_##builtin)
3033#else
3134#define zig_has_builtin(builtin) 0
3235#endif
36#define zig_expand_has_builtin(b) zig_has_builtin(b)
3337
3438#if defined(__has_attribute)
3539#define zig_has_attribute(attribute) __has_attribute(attribute)
......@@ -112,7 +116,7 @@ typedef char bool;
112116#define zig_never_tail zig_never_tail_unavailable
113117#endif
114118
115#if zig_has_attribute(always_inline)
119#if zig_has_attribute(musttail)
116120#define zig_always_tail __attribute__((musttail))
117121#else
118122#define zig_always_tail zig_always_tail_unavailable
......@@ -180,20 +184,58 @@ typedef char bool;
180184#define zig_extern extern
181185#endif
182186
183#if zig_has_attribute(alias)
184#define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(symbol)))
185#elif _MSC_VER
187#if _MSC_VER
186188#if _M_X64
187#define zig_export(sig, symbol, name) sig;\
188 __pragma(comment(linker, "/alternatename:" name "=" symbol ))
189#define zig_mangle_c(symbol) symbol
189190#else /*_M_X64 */
190#define zig_export(sig, symbol, name) sig;\
191 __pragma(comment(linker, "/alternatename:_" name "=_" symbol ))
191#define zig_mangle_c(symbol) "_" symbol
192192#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)))
193206#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))
195209#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
197239#if zig_has_attribute(weak) || defined(zig_gnuc)
198240#define zig_weak_linkage __attribute__((weak))
199241#define zig_weak_linkage_fn __attribute__((weak))
......@@ -267,9 +309,6 @@ typedef char bool;
267309#define zig_wasm_memory_grow(index, delta) zig_unimplemented()
268310#endif
269311
270#define zig_concat(lhs, rhs) lhs##rhs
271#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
272
273312#if __STDC_VERSION__ >= 201112L
274313#define zig_noreturn _Noreturn
275314#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
21632202 const uint8_t *rhs_bytes = rhs;
21642203 uint16_t byte_offset = 0;
21652204 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);
21672206 bool overflow = false;
21682207
21692208#if zig_big_endian
......@@ -2171,7 +2210,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
21712210#endif
21722211
21732212 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
21762215#if zig_big_endian
21772216 byte_offset -= 128 / CHAR_BIT;
......@@ -2211,7 +2250,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
22112250 }
22122251
22132252 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
22162255#if zig_big_endian
22172256 byte_offset -= 64 / CHAR_BIT;
......@@ -2251,7 +2290,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
22512290 }
22522291
22532292 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
22562295#if zig_big_endian
22572296 byte_offset -= 32 / CHAR_BIT;
......@@ -2291,7 +2330,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
22912330 }
22922331
22932332 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
22962335#if zig_big_endian
22972336 byte_offset -= 16 / CHAR_BIT;
......@@ -2331,7 +2370,7 @@ static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, boo
23312370 }
23322371
23332372 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
23362375#if zig_big_endian
23372376 byte_offset -= 8 / CHAR_BIT;
......@@ -2379,7 +2418,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
23792418 const uint8_t *rhs_bytes = rhs;
23802419 uint16_t byte_offset = 0;
23812420 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);
23832422 bool overflow = false;
23842423
23852424#if zig_big_endian
......@@ -2387,7 +2426,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
23872426#endif
23882427
23892428 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
23922431#if zig_big_endian
23932432 byte_offset -= 128 / CHAR_BIT;
......@@ -2427,7 +2466,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
24272466 }
24282467
24292468 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
24322471#if zig_big_endian
24332472 byte_offset -= 64 / CHAR_BIT;
......@@ -2467,7 +2506,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
24672506 }
24682507
24692508 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
24722511#if zig_big_endian
24732512 byte_offset -= 32 / CHAR_BIT;
......@@ -2507,7 +2546,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
25072546 }
25082547
25092548 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
25122551#if zig_big_endian
25132552 byte_offset -= 16 / CHAR_BIT;
......@@ -2547,7 +2586,7 @@ static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, boo
25472586 }
25482587
25492588 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
25522591#if zig_big_endian
25532592 byte_offset -= 8 / CHAR_BIT;
......@@ -3093,6 +3132,7 @@ ypedef uint32_t zig_f32;
30933132
30943133#define zig_has_f64 1
30953134#define zig_libc_name_f64(name) name
3135
30963136#if _MSC_VER
30973137#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
30983138#else
......@@ -3336,31 +3376,31 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0)))
33363376 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \
33373377 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \
33383378 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); \
3340 zig_extern zig_f##w zig_libc_name_f##w(sin)(zig_f##w); \
3341 zig_extern zig_f##w zig_libc_name_f##w(cos)(zig_f##w); \
3342 zig_extern zig_f##w zig_libc_name_f##w(tan)(zig_f##w); \
3343 zig_extern zig_f##w zig_libc_name_f##w(exp)(zig_f##w); \
3344 zig_extern zig_f##w zig_libc_name_f##w(exp2)(zig_f##w); \
3345 zig_extern zig_f##w zig_libc_name_f##w(log)(zig_f##w); \
3346 zig_extern zig_f##w zig_libc_name_f##w(log2)(zig_f##w); \
3347 zig_extern zig_f##w zig_libc_name_f##w(log10)(zig_f##w); \
3348 zig_extern zig_f##w zig_libc_name_f##w(fabs)(zig_f##w); \
3349 zig_extern zig_f##w zig_libc_name_f##w(floor)(zig_f##w); \
3350 zig_extern zig_f##w zig_libc_name_f##w(ceil)(zig_f##w); \
3351 zig_extern zig_f##w zig_libc_name_f##w(round)(zig_f##w); \
3352 zig_extern zig_f##w zig_libc_name_f##w(trunc)(zig_f##w); \
3353 zig_extern zig_f##w zig_libc_name_f##w(fmod)(zig_f##w, zig_f##w); \
3354 zig_extern zig_f##w zig_libc_name_f##w(fmin)(zig_f##w, zig_f##w); \
3355 zig_extern zig_f##w zig_libc_name_f##w(fmax)(zig_f##w, zig_f##w); \
3356 zig_extern zig_f##w zig_libc_name_f##w(fma)(zig_f##w, zig_f##w, 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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
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)) \
33573397\
33583398 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)); \
33603400 } \
33613401\
33623402 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)); \
33643404 } \
33653405\
33663406 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)
34373477/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */
34383478#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \
34393479 zig_##Type zig_atomicrmw_expected; \
3440 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3441 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3480 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3481 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \
34423482 res = zig_atomicrmw_expected; \
34433483} while (0)
34443484#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \
34453485 zig_##Type zig_atomicrmw_expected; \
34463486 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); \
34483488 do { \
34493489 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)); \
34513491 res = zig_atomicrmw_expected; \
34523492} while (0)
34533493#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \
34543494 zig_##Type zig_atomicrmw_expected; \
34553495 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); \
34573497 do { \
34583498 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)); \
34603500 res = zig_atomicrmw_expected; \
34613501} while (0)
34623502#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \
34633503 zig_##Type zig_atomicrmw_expected; \
34643504 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); \
34663506 do { \
3467 zig_atomicrmw_desired = zig_libc_name_##Type(fmin)(zig_atomicrmw_expected, arg); \
3468 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3507 zig_atomicrmw_desired = zig_float_fn_##Type##_fmin(zig_atomicrmw_expected, arg); \
3508 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
34693509 res = zig_atomicrmw_expected; \
34703510} while (0)
34713511#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \
34723512 zig_##Type zig_atomicrmw_expected; \
34733513 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); \
34753515 do { \
3476 zig_atomicrmw_desired = zig_libc_name_##Type(fmax)(zig_atomicrmw_expected, arg); \
3477 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, memory_order_relaxed, Type, ReprType)); \
3516 zig_atomicrmw_desired = zig_float_fn_##Type##_fmax(zig_atomicrmw_expected, arg); \
3517 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
34783518 res = zig_atomicrmw_expected; \
34793519} while (0)
34803520
34813521#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \
34823522 zig_##Type zig_atomicrmw_expected; \
3483 zig_atomic_load(zig_atomicrmw_expected, obj, memory_order_relaxed, Type, ReprType); \
3484 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, memory_order_relaxed, Type, ReprType)); \
3523 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
3524 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \
34853525 res = zig_atomicrmw_expected; \
34863526} while (0)
34873527#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \
34883528 zig_##Type zig_atomicrmw_expected; \
34893529 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); \
34913531 do { \
34923532 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)); \
34943534 res = zig_atomicrmw_expected; \
34953535} while (0)
34963536#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \
34973537 zig_##Type zig_atomicrmw_expected; \
34983538 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); \
35003540 do { \
35013541 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)); \
35033543 res = zig_atomicrmw_expected; \
35043544} while (0)
35053545#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \
35063546 zig_##Type zig_atomicrmw_expected; \
35073547 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); \
35093549 do { \
35103550 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)); \
35123552 res = zig_atomicrmw_expected; \
35133553} while (0)
35143554#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \
35153555 zig_##Type zig_atomicrmw_expected; \
35163556 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); \
35183558 do { \
35193559 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)); \
35213561 res = zig_atomicrmw_expected; \
35223562} while (0)
35233563#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \
35243564 zig_##Type zig_atomicrmw_expected; \
35253565 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); \
35273567 do { \
35283568 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)); \
35303570 res = zig_atomicrmw_expected; \
35313571} while (0)
35323572#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \
35333573 zig_##Type zig_atomicrmw_expected; \
35343574 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); \
35363576 do { \
35373577 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)); \
35393579 res = zig_atomicrmw_expected; \
35403580} while (0)
35413581#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \
35423582 zig_##Type zig_atomicrmw_expected; \
35433583 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); \
35453585 do { \
35463586 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)); \
35483588 res = zig_atomicrmw_expected; \
35493589} while (0)
35503590#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \
35513591 zig_##Type zig_atomicrmw_expected; \
35523592 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); \
35543594 do { \
35553595 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)); \
35573597 res = zig_atomicrmw_expected; \
35583598} while (0)
35593599
35603600#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
35613601#include <stdatomic.h>
35623602typedef 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
35633608#define zig_atomic(Type) _Atomic(Type)
35643609#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
35653610#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;
35833628#define zig_fence(order) atomic_thread_fence(order)
35843629#elif defined(__GNUC__)
35853630typedef int zig_memory_order;
3586#define memory_order_relaxed __ATOMIC_RELAXED
3587#define memory_order_consume __ATOMIC_CONSUME
3588#define memory_order_acquire __ATOMIC_ACQUIRE
3589#define memory_order_release __ATOMIC_RELEASE
3590#define memory_order_acq_rel __ATOMIC_ACQ_REL
3591#define memory_order_seq_cst __ATOMIC_SEQ_CST
3631#define zig_memory_order_relaxed __ATOMIC_RELAXED
3632#define zig_memory_order_acquire __ATOMIC_ACQUIRE
3633#define zig_memory_order_release __ATOMIC_RELEASE
3634#define zig_memory_order_acq_rel __ATOMIC_ACQ_REL
3635#define zig_memory_order_seq_cst __ATOMIC_SEQ_CST
35923636#define zig_atomic(Type) Type
35933637#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, &(expected), &(desired), false, succ, fail)
35943638#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;
36073651#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
36083652#define zig_fence(order) __atomic_thread_fence(order)
36093653#elif _MSC_VER && (_M_IX86 || _M_X64)
3610#define memory_order_relaxed 0
3611#define memory_order_consume 1
3612#define memory_order_acquire 2
3613#define memory_order_release 3
3614#define memory_order_acq_rel 4
3615#define memory_order_seq_cst 5
3654#define zig_memory_order_relaxed 0
3655#define zig_memory_order_acquire 2
3656#define zig_memory_order_release 3
3657#define zig_memory_order_acq_rel 4
3658#define zig_memory_order_seq_cst 5
36163659#define zig_atomic(Type) Type
36173660#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)
36183661#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;
36343677#endif
36353678/* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */
36363679#else
3637#define memory_order_relaxed 0
3638#define memory_order_consume 1
3639#define memory_order_acquire 2
3640#define memory_order_release 3
3641#define memory_order_acq_rel 4
3642#define memory_order_seq_cst 5
3680#define zig_memory_order_relaxed 0
3681#define zig_memory_order_acquire 2
3682#define zig_memory_order_release 3
3683#define zig_memory_order_acq_rel 4
3684#define zig_memory_order_seq_cst 5
36433685#define zig_atomic(Type) Type
36443686#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
36453687#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
38303872 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected);
38313873}
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
38333886static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
38343887 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);
38353888}
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
38363901#endif /* _M_IX86 */
38373902
38383903#endif /* _MSC_VER && (_M_IX86 || _M_X64) */
src/AstGen.zig+4
......@@ -4456,6 +4456,7 @@ fn globalVarDecl(
44564456 .align_inst = .none, // passed via the decls data
44574457 .init = init_inst,
44584458 .is_extern = false,
4459 .is_const = !is_mutable,
44594460 .is_threadlocal = is_threadlocal,
44604461 });
44614462 break :vi var_inst;
......@@ -4474,6 +4475,7 @@ fn globalVarDecl(
44744475 .align_inst = .none, // passed via the decls data
44754476 .init = .none,
44764477 .is_extern = true,
4478 .is_const = !is_mutable,
44774479 .is_threadlocal = is_threadlocal,
44784480 });
44794481 break :vi var_inst;
......@@ -11495,6 +11497,7 @@ const GenZir = struct {
1149511497 var_type: Zir.Inst.Ref,
1149611498 init: Zir.Inst.Ref,
1149711499 is_extern: bool,
11500 is_const: bool,
1149811501 is_threadlocal: bool,
1149911502 }) !Zir.Inst.Ref {
1150011503 const astgen = gz.astgen;
......@@ -11533,6 +11536,7 @@ const GenZir = struct {
1153311536 .has_align = args.align_inst != .none,
1153411537 .has_init = args.init != .none,
1153511538 .is_extern = args.is_extern,
11539 .is_const = args.is_const,
1153611540 .is_threadlocal = args.is_threadlocal,
1153711541 }),
1153811542 .operand = payload_index,
src/InternPool.zig+5-5
......@@ -1005,11 +1005,11 @@ pub const Key = union(enum) {
10051005 ty: Index,
10061006 init: Index,
10071007 decl: DeclIndex,
1008 lib_name: OptionalNullTerminatedString = .none,
1009 is_extern: bool = false,
1010 is_const: bool = false,
1011 is_threadlocal: bool = false,
1012 is_weak_linkage: bool = false,
1008 lib_name: OptionalNullTerminatedString,
1009 is_extern: bool,
1010 is_const: bool,
1011 is_threadlocal: bool,
1012 is_weak_linkage: bool,
10131013 };
10141014
10151015 pub const ExternFunc = struct {
src/Sema.zig+7-3
......@@ -24760,7 +24760,9 @@ fn zirVarExtended(
2476024760 .decl = sema.owner_decl_index,
2476124761 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, lib_name),
2476224762 .is_extern = small.is_extern,
24763 .is_const = small.is_const,
2476324764 .is_threadlocal = small.is_threadlocal,
24765 .is_weak_linkage = false,
2476424766 } })));
2476524767}
2476624768
......@@ -25264,6 +25266,7 @@ fn zirBuiltinExtern(
2526425266 if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) {
2526525267 ty = try mod.optionalType(ty.toIntern());
2526625268 }
25269 const ptr_info = ty.ptrInfo(mod);
2526725270
2526825271 // TODO check duplicate extern
2526925272
......@@ -25274,11 +25277,12 @@ fn zirBuiltinExtern(
2527425277
2527525278 {
2527625279 const new_var = try mod.intern(.{ .variable = .{
25277 .ty = ty.toIntern(),
25280 .ty = ptr_info.child,
2527825281 .init = .none,
2527925282 .decl = sema.owner_decl_index,
25283 .lib_name = options.library_name,
2528025284 .is_extern = true,
25281 .is_const = true,
25285 .is_const = ptr_info.flags.is_const,
2528225286 .is_threadlocal = options.is_thread_local,
2528325287 .is_weak_linkage = options.linkage == .Weak,
2528425288 } });
......@@ -25286,7 +25290,7 @@ fn zirBuiltinExtern(
2528625290 new_decl.src_line = sema.owner_decl.src_line;
2528725291 // We only access this decl through the decl_ref with the correct type created
2528825292 // below, so this type doesn't matter
25289 new_decl.ty = ty;
25293 new_decl.ty = Type.fromInterned(ptr_info.child);
2529025294 new_decl.val = Value.fromInterned(new_var);
2529125295 new_decl.alignment = .none;
2529225296 new_decl.@"linksection" = .none;
src/Zir.zig+2-1
......@@ -2610,8 +2610,9 @@ pub const Inst = struct {
26102610 has_align: bool,
26112611 has_init: bool,
26122612 is_extern: bool,
2613 is_const: bool,
26132614 is_threadlocal: bool,
2614 _: u11 = undefined,
2615 _: u10 = undefined,
26152616 };
26162617 };
26172618
src/codegen/c.zig+183-77
......@@ -258,6 +258,20 @@ pub fn fmtIdent(ident: []const u8) std.fmt.Formatter(formatIdent) {
258258 return .{ .data = ident };
259259}
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
261275/// This data is available when outputting .c code for a `InternPool.Index`
262276/// that corresponds to `func`.
263277/// It is not available when generating .h file.
......@@ -646,7 +660,7 @@ pub const DeclGen = struct {
646660 if (decl.val.getExternFunc(mod)) |extern_func| if (extern_func.decl != decl_index)
647661 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
651665 // We shouldn't cast C function pointers as this is UB (when you call
652666 // them). The analysis until now should ensure that the C function
......@@ -1593,7 +1607,7 @@ pub const DeclGen = struct {
15931607 kind: CType.Kind,
15941608 name: union(enum) {
15951609 export_index: u32,
1596 string: []const u8,
1610 ident: []const u8,
15971611 },
15981612 ) !void {
15991613 const store = &dg.ctypes.set;
......@@ -1615,23 +1629,28 @@ pub const DeclGen = struct {
16151629 try w.writeAll("zig_cold ");
16161630 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, .{});
1619 try w.print("{}", .{trailing});
1632 var trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
16201633
16211634 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;
16231637 }
16241638
16251639 switch (kind) {
16261640 .forward => {},
1627 .complete => if (fn_info.alignment.toByteUnitsOptional()) |a|
1628 try w.print(" zig_align_fn({})", .{a}),
1641 .complete => if (fn_info.alignment.toByteUnitsOptional()) |a| {
1642 try w.print("{}zig_align_fn({})", .{ trailing, a });
1643 trailing = .maybe_space;
1644 },
16291645 else => unreachable,
16301646 }
16311647
16321648 switch (name) {
1633 .export_index => |export_index| try dg.renderDeclName(w, fn_decl_index, export_index),
1634 .string => |string| try w.writeAll(string),
1649 .export_index => |export_index| {
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) }),
16351654 }
16361655
16371656 try renderTypeSuffix(
......@@ -1649,8 +1668,49 @@ pub const DeclGen = struct {
16491668 );
16501669
16511670 switch (kind) {
1652 .forward => if (fn_info.alignment.toByteUnitsOptional()) |a|
1653 try w.print(" zig_align_fn({})", .{a}),
1671 .forward => {
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 },
16541714 .complete => {},
16551715 else => unreachable,
16561716 }
......@@ -1930,12 +1990,18 @@ pub const DeclGen = struct {
19301990 try dg.writeCValue(writer, member);
19311991 }
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 {
19341999 const decl = dg.module.declPtr(decl_index);
19352000 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 });
19372002 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|
19392005 exports.items[0].opts.linkage == .Weak
19402006 else
19412007 false;
......@@ -1949,6 +2015,21 @@ pub const DeclGen = struct {
19492015 decl.alignment,
19502016 .complete,
19512017 );
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 }
19522033 try fwd.writeAll(";\n");
19532034 }
19542035
......@@ -1958,9 +2039,13 @@ pub const DeclGen = struct {
19582039 try mod.markDeclAlive(decl);
19592040
19602041 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 });
19622045 } 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 });
19642049 } else {
19652050 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
19662051 // 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 {
25922677
25932678 const mod = o.dg.module;
25942679 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 };
25962684 const decl = mod.declPtr(decl_index);
25972685 const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) };
25982686 const fwd = o.dg.fwd_decl.writer();
......@@ -2600,42 +2688,50 @@ fn genExports(o: *Object) !void {
26002688 const exports = mod.decl_exports.get(decl_index) orelse return;
26012689 if (exports.items.len < 2) return;
26022690
2603 switch (ip.indexToKey(tv.val.toIntern())) {
2604 .func => {
2605 for (exports.items[1..], 1..) |@"export", i| {
2606 try fwd.writeAll("zig_export(");
2607 if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage_fn ");
2608 try o.dg.renderFunctionSignature(fwd, decl_index, .forward, .{ .export_index = @as(u32, @intCast(i)) });
2609 try fwd.print(", {s}, {s});\n", .{
2610 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
2611 fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null),
2612 });
2613 }
2691 const is_variable_const = switch (ip.indexToKey(tv.val.toIntern())) {
2692 .func => return for (exports.items[1..], 1..) |@"export", i| {
2693 try fwd.writeAll("zig_extern ");
2694 if (@"export".opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage_fn ");
2695 try o.dg.renderFunctionSignature(
2696 fwd,
2697 decl_index,
2698 .forward,
2699 .{ .export_index = @intCast(i) },
2700 );
2701 try fwd.writeAll(";\n");
26142702 },
26152703 .extern_func => {
26162704 // TODO: when sema allows re-exporting extern decls
26172705 unreachable;
26182706 },
2619 .variable => |variable| {
2620 for (exports.items[1..], 1..) |@"export", i| {
2621 try fwd.writeAll("zig_export(");
2622 if (exports.items[i].opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage ");
2623 const alias = ip.stringToSlice(@"export".opts.name);
2624 try o.dg.renderTypeAndName(
2625 fwd,
2626 decl.ty,
2627 .{ .identifier = alias },
2628 CQualifiers.init(.{ .@"const" = variable.is_const }),
2629 decl.alignment,
2630 .complete,
2631 );
2632 try fwd.print(", {s}, {s});\n", .{
2633 fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null),
2634 fmtStringLiteral(alias, null),
2635 });
2636 }
2637 },
2638 else => {},
2707 .variable => |variable| variable.is_const,
2708 else => true,
2709 };
2710 for (exports.items[1..]) |@"export"| {
2711 try fwd.writeAll("zig_extern ");
2712 if (@"export".opts.linkage == .Weak) try fwd.writeAll("zig_weak_linkage ");
2713 const export_name = ip.stringToSlice(@"export".opts.name);
2714 try o.dg.renderTypeAndName(
2715 fwd,
2716 decl.ty,
2717 .{ .identifier = export_name },
2718 CQualifiers.init(.{ .@"const" = is_variable_const }),
2719 decl.alignment,
2720 .complete,
2721 );
2722 if (isMangledIdent(export_name, true)) {
2723 try fwd.print(" zig_mangled_export({ }, {s}, {s})", .{
2724 fmtIdent(export_name),
2725 fmtStringLiteral(export_name, null),
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");
26392735 }
26402736}
26412737
......@@ -2707,12 +2803,12 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
27072803 fwd_decl_writer,
27082804 fn_decl_index,
27092805 .forward,
2710 .{ .string = fn_name },
2806 .{ .ident = fn_name },
27112807 );
27122808 try fwd_decl_writer.writeAll(";\n");
27132809
27142810 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 });
27162812 try w.writeAll(" {\n return ");
27172813 try o.dg.renderDeclName(w, fn_decl_index, 0);
27182814 try w.writeByte('(');
......@@ -2745,6 +2841,7 @@ pub fn genFunc(f: *Function) !void {
27452841 const is_global = o.dg.declIsGlobal(tv);
27462842 const fwd_decl_writer = o.dg.fwd_decl.writer();
27472843 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
2844
27482845 if (mod.decl_exports.get(decl_index)) |exports|
27492846 if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn ");
27502847 try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 });
......@@ -2831,12 +2928,12 @@ pub fn genDecl(o: *Object) !void {
28312928 try fwd_decl_writer.writeAll(";\n");
28322929 try genExports(o);
28332930 } else if (tv.val.getVariable(mod)) |variable| {
2834 try o.dg.renderFwdDecl(decl_index, variable);
2931 try o.dg.renderFwdDecl(decl_index, variable, .final);
28352932 try genExports(o);
28362933
28372934 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);
28402937 const w = o.writer();
28412938 if (!is_global) try w.writeAll("static ");
28422939 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
......@@ -2853,7 +2950,7 @@ pub fn genDecl(o: *Object) !void {
28532950 } else {
28542951 const is_global = o.dg.module.decl_exports.contains(decl_index);
28552952 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");
28572954 }
28582955}
28592956
......@@ -2870,10 +2967,26 @@ pub fn genDeclValue(
28702967
28712968 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
28722969 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 }
28732984 try fwd_decl_writer.writeAll(";\n");
2985 try genExports(o);
28742986
28752987 const w = o.writer();
28762988 if (!is_global) try w.writeAll("static ");
2989
28772990 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
28782991 try w.print("zig_linksection(\"{s}\", ", .{s});
28792992 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 {
28973010 const writer = dg.fwd_decl.writer();
28983011
28993012 switch (tv.ty.zigTypeTag(mod)) {
2900 .Fn => {
2901 const is_global = dg.declIsGlobal(tv);
2902 if (is_global) {
2903 try writer.writeAll("zig_extern ");
2904 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
2905 try dg.fwd_decl.appendSlice(";\n");
2906 }
3013 .Fn => if (dg.declIsGlobal(tv)) {
3014 try writer.writeAll("zig_extern ");
3015 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
3016 try dg.fwd_decl.appendSlice(";\n");
29073017 },
29083018 else => {},
29093019 }
......@@ -6895,9 +7005,9 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
68957005 try f.writeCValue(writer, accum, .Other);
68967006 switch (op) {
68977007 .float_op => |func| {
6898 try writer.writeAll(" = zig_libc_name_");
7008 try writer.writeAll(" = zig_float_fn_");
68997009 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
6900 try writer.print("({s})(", .{func.operation});
7010 try writer.print("_{s}(", .{func.operation});
69017011 try f.writeCValue(writer, accum, .FunctionArgument);
69027012 try writer.writeAll(", ");
69037013 try f.writeCValue(writer, operand, .Other);
......@@ -7229,11 +7339,9 @@ fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, oper
72297339 const v = try Vectorize.start(f, inst, writer, ty);
72307340 try f.writeCValue(writer, local, .Other);
72317341 try v.elem(f, writer);
7232 try writer.writeAll(" = zig_libc_name_");
7342 try writer.writeAll(" = zig_float_fn_");
72337343 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
7234 try writer.writeByte('(');
7235 try writer.writeAll(operation);
7236 try writer.writeAll(")(");
7344 try writer.print("_{s}(", .{operation});
72377345 try f.writeCValue(writer, operand, .FunctionArgument);
72387346 try v.elem(f, writer);
72397347 try writer.writeAll(");\n");
......@@ -7268,11 +7376,9 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
72687376 const v = try Vectorize.start(f, inst, writer, inst_ty);
72697377 try f.writeCValue(writer, local, .Other);
72707378 try v.elem(f, writer);
7271 try writer.writeAll(" = zig_libc_name_");
7379 try writer.writeAll(" = zig_float_fn_");
72727380 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
7273 try writer.writeByte('(');
7274 try writer.writeAll(operation);
7275 try writer.writeAll(")(");
7381 try writer.print("_{s}(", .{operation});
72767382 try f.writeCValue(writer, lhs, .FunctionArgument);
72777383 try v.elem(f, writer);
72787384 try writer.writeAll(", ");
......@@ -7302,9 +7408,9 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
73027408 const v = try Vectorize.start(f, inst, writer, inst_ty);
73037409 try f.writeCValue(writer, local, .Other);
73047410 try v.elem(f, writer);
7305 try writer.writeAll(" = zig_libc_name_");
7411 try writer.writeAll(" = zig_float_fn_");
73067412 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
7307 try writer.writeAll("(fma)(");
7413 try writer.writeAll("_fma(");
73087414 try f.writeCValue(writer, mulend1, .FunctionArgument);
73097415 try v.elem(f, writer);
73107416 try writer.writeAll(", ");
......@@ -7390,11 +7496,11 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
73907496fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
73917497 return switch (order) {
73927498 // Note: unordered is actually even less atomic than relaxed
7393 .Unordered, .Monotonic => "memory_order_relaxed",
7394 .Acquire => "memory_order_acquire",
7395 .Release => "memory_order_release",
7396 .AcqRel => "memory_order_acq_rel",
7397 .SeqCst => "memory_order_seq_cst",
7499 .Unordered, .Monotonic => "zig_memory_order_relaxed",
7500 .Acquire => "zig_memory_order_acquire",
7501 .Release => "zig_memory_order_release",
7502 .AcqRel => "zig_memory_order_acq_rel",
7503 .SeqCst => "zig_memory_order_seq_cst",
73987504 };
73997505}
74007506
test/behavior.zig+1-3
......@@ -110,7 +110,6 @@ test {
110110 _ = @import("behavior/bugs/12551.zig");
111111 _ = @import("behavior/bugs/12571.zig");
112112 _ = @import("behavior/bugs/12644.zig");
113 _ = @import("behavior/bugs/12680.zig");
114113 _ = @import("behavior/bugs/12723.zig");
115114 _ = @import("behavior/bugs/12776.zig");
116115 _ = @import("behavior/bugs/12786.zig");
......@@ -175,6 +174,7 @@ test {
175174 _ = @import("behavior/hasfield.zig");
176175 _ = @import("behavior/if.zig");
177176 _ = @import("behavior/import.zig");
177 _ = @import("behavior/import_c_keywords.zig");
178178 _ = @import("behavior/incomplete_struct_param_tld.zig");
179179 _ = @import("behavior/inline_switch.zig");
180180 _ = @import("behavior/int128.zig");
......@@ -251,9 +251,7 @@ test {
251251 }
252252
253253 if (builtin.zig_backend != .stage2_arm and
254 builtin.zig_backend != .stage2_x86_64 and
255254 builtin.zig_backend != .stage2_aarch64 and
256 builtin.zig_backend != .stage2_c and
257255 builtin.zig_backend != .stage2_spirv64)
258256 {
259257 _ = @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}