| author | |
| committer | |
| log | 192e9a315d92133b27d757f18bd4fd619976b755 |
| tree | bcfe68372b997e7c4247432112b686fe4ba04125 |
| parent | ce293c982e1b6d9db775e02fefb8905caa4ee748 |
3 files changed, 89 insertions(+), 45 deletions(-)
lib/zig.h+27-21| ... | ... | @@ -174,6 +174,12 @@ typedef char bool; |
| 174 | 174 | #define zig_extern extern |
| 175 | 175 | #endif |
| 176 | 176 | |
| 177 | #if _MSC_VER | |
| 178 | #define zig_extern_mangled zig_extern | |
| 179 | #else | |
| 180 | #define zig_extern_mangled static | |
| 181 | #endif | |
| 182 | ||
| 177 | 183 | #if zig_has_attribute(alias) |
| 178 | 184 | #define zig_export(sig, symbol, name) zig_extern sig __attribute__((alias(#symbol))) |
| 179 | 185 | #elif _MSC_VER |
| ... | ... | @@ -190,14 +196,14 @@ typedef char bool; |
| 190 | 196 | |
| 191 | 197 | #if _MSC_VER |
| 192 | 198 | #if _M_X64 |
| 193 | #define zig_import(sig, symbol, name) sig;\ | |
| 199 | #define zig_import(sig, symbol, name) zig_extern sig;\ | |
| 194 | 200 | __pragma(comment(linker, "/alternatename:" #symbol "=" #name )) |
| 195 | 201 | #else /*_M_X64 */ |
| 196 | #define zig_import(sig, symbol, name) sig;\ | |
| 202 | #define zig_import(sig, symbol, name) zig_extern sig;\ | |
| 197 | 203 | __pragma(comment(linker, "/alternatename:_" #symbol "=_" #name )) |
| 198 | 204 | #endif /*_M_X64 */ |
| 199 | 205 | #else |
| 200 | #define zig_import(sig, symbol, name) zig_extern sig asm(#name); | |
| 206 | #define zig_import(sig, symbol, name) zig_extern sig __asm(#name); | |
| 201 | 207 | #endif |
| 202 | 208 | |
| 203 | 209 | #define zig_expand_import(sig, symbol, name) zig_import(sig, symbol, name) |
| ... | ... | @@ -3344,24 +3350,24 @@ zig_float_negate_builtin(128, zig_make_u128, (UINT64_C(1) << 63, UINT64_C(0))) |
| 3344 | 3350 | zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \ |
| 3345 | 3351 | zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \ |
| 3346 | 3352 | zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, div, /) \ |
| 3347 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_sqrt(zig_f##w), zig_float_fn_f##w##_sqrt, zig_libc_name_f##w(sqrt)) \ | |
| 3348 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_sin(zig_f##w), zig_float_fn_f##w##_sin, zig_libc_name_f##w(sin)) \ | |
| 3349 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_cos(zig_f##w), zig_float_fn_f##w##_cos, zig_libc_name_f##w(cos)) \ | |
| 3350 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_tan(zig_f##w), zig_float_fn_f##w##_tan, zig_libc_name_f##w(tan)) \ | |
| 3351 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_exp(zig_f##w), zig_float_fn_f##w##_exp, zig_libc_name_f##w(exp)) \ | |
| 3352 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_exp2(zig_f##w), zig_float_fn_f##w##_exp2, zig_libc_name_f##w(exp2)) \ | |
| 3353 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_log(zig_f##w), zig_float_fn_f##w##_log, zig_libc_name_f##w(log)) \ | |
| 3354 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_log2(zig_f##w), zig_float_fn_f##w##_log2, zig_libc_name_f##w(log2)) \ | |
| 3355 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_log10(zig_f##w), zig_float_fn_f##w##_log10, zig_libc_name_f##w(log10)) \ | |
| 3356 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_fabs(zig_f##w), zig_float_fn_f##w##_fabs, zig_libc_name_f##w(fabs)) \ | |
| 3357 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_floor(zig_f##w), zig_float_fn_f##w##_floor, zig_libc_name_f##w(floor)) \ | |
| 3358 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_ceil(zig_f##w), zig_float_fn_f##w##_ceil, zig_libc_name_f##w(ceil)) \ | |
| 3359 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_round(zig_f##w), zig_float_fn_f##w##_round, zig_libc_name_f##w(round)) \ | |
| 3360 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_trunc(zig_f##w), zig_float_fn_f##w##_trunc, zig_libc_name_f##w(trunc)) \ | |
| 3361 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_fmod(zig_f##w, zig_f##w), zig_float_fn_f##w##_fmod, zig_libc_name_f##w(fmod)) \ | |
| 3362 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_fmin(zig_f##w, zig_f##w), zig_float_fn_f##w##_fmin, zig_libc_name_f##w(fmin)) \ | |
| 3363 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_fmax(zig_f##w, zig_f##w), zig_float_fn_f##w##_fmax, zig_libc_name_f##w(fmax)) \ | |
| 3364 | zig_expand_import(zig_extern zig_f##w zig_float_fn_f##w##_fma(zig_f##w, zig_f##w, zig_f##w), zig_float_fn_f##w##_fma, zig_libc_name_f##w(fma)) \ | |
| 3353 | zig_expand_import(zig_f##w zig_float_fn_f##w##_sqrt(zig_f##w), zig_float_fn_f##w##_sqrt, zig_libc_name_f##w(sqrt)) \ | |
| 3354 | zig_expand_import(zig_f##w zig_float_fn_f##w##_sin(zig_f##w), zig_float_fn_f##w##_sin, zig_libc_name_f##w(sin)) \ | |
| 3355 | zig_expand_import(zig_f##w zig_float_fn_f##w##_cos(zig_f##w), zig_float_fn_f##w##_cos, zig_libc_name_f##w(cos)) \ | |
| 3356 | zig_expand_import(zig_f##w zig_float_fn_f##w##_tan(zig_f##w), zig_float_fn_f##w##_tan, zig_libc_name_f##w(tan)) \ | |
| 3357 | zig_expand_import(zig_f##w zig_float_fn_f##w##_exp(zig_f##w), zig_float_fn_f##w##_exp, zig_libc_name_f##w(exp)) \ | |
| 3358 | zig_expand_import(zig_f##w zig_float_fn_f##w##_exp2(zig_f##w), zig_float_fn_f##w##_exp2, zig_libc_name_f##w(exp2)) \ | |
| 3359 | zig_expand_import(zig_f##w zig_float_fn_f##w##_log(zig_f##w), zig_float_fn_f##w##_log, zig_libc_name_f##w(log)) \ | |
| 3360 | zig_expand_import(zig_f##w zig_float_fn_f##w##_log2(zig_f##w), zig_float_fn_f##w##_log2, zig_libc_name_f##w(log2)) \ | |
| 3361 | zig_expand_import(zig_f##w zig_float_fn_f##w##_log10(zig_f##w), zig_float_fn_f##w##_log10, zig_libc_name_f##w(log10)) \ | |
| 3362 | zig_expand_import(zig_f##w zig_float_fn_f##w##_fabs(zig_f##w), zig_float_fn_f##w##_fabs, zig_libc_name_f##w(fabs)) \ | |
| 3363 | zig_expand_import(zig_f##w zig_float_fn_f##w##_floor(zig_f##w), zig_float_fn_f##w##_floor, zig_libc_name_f##w(floor)) \ | |
| 3364 | zig_expand_import(zig_f##w zig_float_fn_f##w##_ceil(zig_f##w), zig_float_fn_f##w##_ceil, zig_libc_name_f##w(ceil)) \ | |
| 3365 | zig_expand_import(zig_f##w zig_float_fn_f##w##_round(zig_f##w), zig_float_fn_f##w##_round, zig_libc_name_f##w(round)) \ | |
| 3366 | zig_expand_import(zig_f##w zig_float_fn_f##w##_trunc(zig_f##w), zig_float_fn_f##w##_trunc, zig_libc_name_f##w(trunc)) \ | |
| 3367 | zig_expand_import(zig_f##w zig_float_fn_f##w##_fmod(zig_f##w, zig_f##w), zig_float_fn_f##w##_fmod, zig_libc_name_f##w(fmod)) \ | |
| 3368 | zig_expand_import(zig_f##w zig_float_fn_f##w##_fmin(zig_f##w, zig_f##w), zig_float_fn_f##w##_fmin, zig_libc_name_f##w(fmin)) \ | |
| 3369 | zig_expand_import(zig_f##w zig_float_fn_f##w##_fmax(zig_f##w, zig_f##w), zig_float_fn_f##w##_fmax, zig_libc_name_f##w(fmax)) \ | |
| 3370 | zig_expand_import(zig_f##w zig_float_fn_f##w##_fma(zig_f##w, zig_f##w, zig_f##w), zig_float_fn_f##w##_fma, zig_libc_name_f##w(fma)) \ | |
| 3365 | 3371 | \ |
| 3366 | 3372 | static inline zig_f##w zig_div_trunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ |
| 3367 | 3373 | return zig_float_fn_f##w##_trunc(zig_div_f##w(lhs, rhs)); \ |
src/codegen/c.zig+61-23| ... | ... | @@ -272,6 +272,28 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool { |
| 272 | 272 | return false; |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | const DeclVisibility = enum { | |
| 276 | global, | |
| 277 | global_mangled, | |
| 278 | local, | |
| 279 | ||
| 280 | fn renderFwd(visibility: DeclVisibility, w: anytype) !void { | |
| 281 | try w.writeAll(switch (visibility) { | |
| 282 | .global => "zig_extern ", | |
| 283 | // MSVC doesn't support exporting `static` functions, so they need special treatment | |
| 284 | .global_mangled => "zig_extern_mangled ", | |
| 285 | .local => "static ", | |
| 286 | }); | |
| 287 | } | |
| 288 | ||
| 289 | fn renderDef(visibility: DeclVisibility, w: anytype) !void { | |
| 290 | return switch (visibility) { | |
| 291 | .global => {}, | |
| 292 | else => visibility.renderFwd(w), | |
| 293 | }; | |
| 294 | } | |
| 295 | }; | |
| 296 | ||
| 275 | 297 | /// This data is available when outputting .c code for a `InternPool.Index` |
| 276 | 298 | /// that corresponds to `func`. |
| 277 | 299 | /// It is not available when generating .h file. |
| ... | ... | @@ -1825,19 +1847,25 @@ pub const DeclGen = struct { |
| 1825 | 1847 | try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{}); |
| 1826 | 1848 | } |
| 1827 | 1849 | |
| 1828 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { | |
| 1850 | fn declVisibility(dg: *DeclGen, tv: TypedValue) DeclVisibility { | |
| 1829 | 1851 | const mod = dg.module; |
| 1830 | 1852 | return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) { |
| 1831 | 1853 | .variable => |variable| { |
| 1832 | 1854 | if (mod.decl_exports.get(variable.decl)) |exports| { |
| 1833 | return !isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true); | |
| 1834 | } else return false; | |
| 1855 | return if (isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true)) | |
| 1856 | .global_mangled | |
| 1857 | else | |
| 1858 | .global; | |
| 1859 | } else return .local; | |
| 1835 | 1860 | }, |
| 1836 | .extern_func => true, | |
| 1861 | .extern_func => .global, | |
| 1837 | 1862 | .func => |func| { |
| 1838 | 1863 | if (mod.decl_exports.get(func.owner_decl)) |exports| { |
| 1839 | return !isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true); | |
| 1840 | } else return false; | |
| 1864 | return if (isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true)) | |
| 1865 | .global_mangled | |
| 1866 | else | |
| 1867 | .global; | |
| 1868 | } else return .local; | |
| 1841 | 1869 | }, |
| 1842 | 1870 | else => unreachable, |
| 1843 | 1871 | }; |
| ... | ... | @@ -1923,8 +1951,8 @@ pub const DeclGen = struct { |
| 1923 | 1951 | fn renderFwdDecl(dg: *DeclGen, decl_index: Decl.Index, variable: InternPool.Key.Variable) !void { |
| 1924 | 1952 | const decl = dg.module.declPtr(decl_index); |
| 1925 | 1953 | const fwd = dg.fwd_decl.writer(); |
| 1926 | const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern; | |
| 1927 | try fwd.writeAll(if (is_global) "zig_extern " else "static "); | |
| 1954 | const visibility = if (variable.is_extern) .global else dg.declVisibility(.{ .ty = decl.ty, .val = decl.val }); | |
| 1955 | try visibility.renderFwd(fwd); | |
| 1928 | 1956 | const export_weak_linkage = if (dg.module.decl_exports.get(decl_index)) |exports| |
| 1929 | 1957 | exports.items[0].opts.linkage == .Weak |
| 1930 | 1958 | else |
| ... | ... | @@ -2735,9 +2763,10 @@ pub fn genFunc(f: *Function) !void { |
| 2735 | 2763 | o.code_header = std.ArrayList(u8).init(gpa); |
| 2736 | 2764 | defer o.code_header.deinit(); |
| 2737 | 2765 | |
| 2738 | const is_global = o.dg.declIsGlobal(tv); | |
| 2766 | const visibility = o.dg.declVisibility(tv); | |
| 2739 | 2767 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 2740 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | |
| 2768 | try visibility.renderFwd(fwd_decl_writer); | |
| 2769 | ||
| 2741 | 2770 | if (mod.decl_exports.get(decl_index)) |exports| |
| 2742 | 2771 | if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn "); |
| 2743 | 2772 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); |
| ... | ... | @@ -2745,7 +2774,7 @@ pub fn genFunc(f: *Function) !void { |
| 2745 | 2774 | try genExports(o); |
| 2746 | 2775 | |
| 2747 | 2776 | try o.indent_writer.insertNewline(); |
| 2748 | if (!is_global) try o.writer().writeAll("static "); | |
| 2777 | try visibility.renderDef(o.writer()); | |
| 2749 | 2778 | try o.dg.renderFunctionSignature(o.writer(), decl_index, .complete, .{ .export_index = 0 }); |
| 2750 | 2779 | try o.writer().writeByte(' '); |
| 2751 | 2780 | |
| ... | ... | @@ -2829,9 +2858,9 @@ pub fn genDecl(o: *Object) !void { |
| 2829 | 2858 | |
| 2830 | 2859 | if (variable.is_extern) return; |
| 2831 | 2860 | |
| 2832 | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; | |
| 2861 | const visibility = if (variable.is_extern) .global else o.dg.declVisibility(tv); | |
| 2833 | 2862 | const w = o.writer(); |
| 2834 | if (!is_global) try w.writeAll("static "); | |
| 2863 | try visibility.renderDef(w); | |
| 2835 | 2864 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); |
| 2836 | 2865 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); |
| 2837 | 2866 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| |
| ... | ... | @@ -2844,16 +2873,21 @@ pub fn genDecl(o: *Object) !void { |
| 2844 | 2873 | try w.writeByte(';'); |
| 2845 | 2874 | try o.indent_writer.insertNewline(); |
| 2846 | 2875 | } else { |
| 2847 | const is_global = o.dg.module.decl_exports.contains(decl_index); | |
| 2876 | const visibility: DeclVisibility = if (o.dg.module.decl_exports.get(decl_index)) |exports| b: { | |
| 2877 | break :b if (isMangledIdent(o.dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true)) | |
| 2878 | .global_mangled | |
| 2879 | else | |
| 2880 | .global; | |
| 2881 | } else .local; | |
| 2848 | 2882 | const decl_c_value = .{ .decl = decl_index }; |
| 2849 | return genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection"); | |
| 2883 | return genDeclValue(o, tv, visibility, decl_c_value, decl.alignment, decl.@"linksection"); | |
| 2850 | 2884 | } |
| 2851 | 2885 | } |
| 2852 | 2886 | |
| 2853 | 2887 | pub fn genDeclValue( |
| 2854 | 2888 | o: *Object, |
| 2855 | 2889 | tv: TypedValue, |
| 2856 | is_global: bool, | |
| 2890 | visibility: DeclVisibility, | |
| 2857 | 2891 | decl_c_value: CValue, |
| 2858 | 2892 | alignment: Alignment, |
| 2859 | 2893 | link_section: InternPool.OptionalNullTerminatedString, |
| ... | ... | @@ -2861,12 +2895,13 @@ pub fn genDeclValue( |
| 2861 | 2895 | const mod = o.dg.module; |
| 2862 | 2896 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 2863 | 2897 | |
| 2864 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | |
| 2898 | try visibility.renderFwd(fwd_decl_writer); | |
| 2865 | 2899 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); |
| 2866 | 2900 | try fwd_decl_writer.writeAll(";\n"); |
| 2867 | 2901 | |
| 2868 | 2902 | const w = o.writer(); |
| 2869 | if (!is_global) try w.writeAll("static "); | |
| 2903 | try visibility.renderDef(w); | |
| 2904 | ||
| 2870 | 2905 | if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| |
| 2871 | 2906 | try w.print("zig_linksection(\"{s}\", ", .{s}); |
| 2872 | 2907 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete); |
| ... | ... | @@ -2891,11 +2926,14 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
| 2891 | 2926 | |
| 2892 | 2927 | switch (tv.ty.zigTypeTag(mod)) { |
| 2893 | 2928 | .Fn => { |
| 2894 | const is_global = dg.declIsGlobal(tv); | |
| 2895 | if (is_global) { | |
| 2896 | try writer.writeAll("zig_extern "); | |
| 2897 | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); | |
| 2898 | try dg.fwd_decl.appendSlice(";\n"); | |
| 2929 | const visibility = dg.declVisibility(tv); | |
| 2930 | switch (visibility) { | |
| 2931 | .global, .global_mangled => { | |
| 2932 | try visibility.renderFwd(writer); | |
| 2933 | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); | |
| 2934 | try dg.fwd_decl.appendSlice(";\n"); | |
| 2935 | }, | |
| 2936 | .local => {}, | |
| 2899 | 2937 | } |
| 2900 | 2938 | }, |
| 2901 | 2939 | else => {}, |
src/link/C.zig+1-1| ... | ... | @@ -259,7 +259,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void { |
| 259 | 259 | }; |
| 260 | 260 | const c_value: codegen.CValue = .{ .constant = anon_decl }; |
| 261 | 261 | const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none; |
| 262 | codegen.genDeclValue(&object, tv, false, c_value, alignment, .none) catch |err| switch (err) { | |
| 262 | codegen.genDeclValue(&object, tv, .local, c_value, alignment, .none) catch |err| switch (err) { | |
| 263 | 263 | error.AnalysisFail => { |
| 264 | 264 | @panic("TODO: C backend AnalysisFail on anonymous decl"); |
| 265 | 265 | //try module.failed_decls.put(gpa, decl_index, object.dg.error_msg.?); |