| ... | @@ -272,6 +272,28 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool { | ... | @@ -272,6 +272,28 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool { |
| 272 | return false; | 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 | /// This data is available when outputting .c code for a `InternPool.Index` | 297 | /// This data is available when outputting .c code for a `InternPool.Index` |
| 276 | /// that corresponds to `func`. | 298 | /// that corresponds to `func`. |
| 277 | /// It is not available when generating .h file. | 299 | /// It is not available when generating .h file. |
| ... | @@ -1825,19 +1847,25 @@ pub const DeclGen = struct { | ... | @@ -1825,19 +1847,25 @@ pub const DeclGen = struct { |
| 1825 | try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{}); | 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 | const mod = dg.module; | 1851 | const mod = dg.module; |
| 1830 | return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) { | 1852 | return switch (mod.intern_pool.indexToKey(tv.val.ip_index)) { |
| 1831 | .variable => |variable| { | 1853 | .variable => |variable| { |
| 1832 | if (mod.decl_exports.get(variable.decl)) |exports| { | 1854 | if (mod.decl_exports.get(variable.decl)) |exports| { |
| 1833 | return !isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true); | 1855 | return if (isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true)) |
| 1834 | } else return false; | 1856 | .global_mangled |
| | 1857 | else |
| | 1858 | .global; |
| | 1859 | } else return .local; |
| 1835 | }, | 1860 | }, |
| 1836 | .extern_func => true, | 1861 | .extern_func => .global, |
| 1837 | .func => |func| { | 1862 | .func => |func| { |
| 1838 | if (mod.decl_exports.get(func.owner_decl)) |exports| { | 1863 | if (mod.decl_exports.get(func.owner_decl)) |exports| { |
| 1839 | return !isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true); | 1864 | return if (isMangledIdent(dg.module.intern_pool.stringToSlice(exports.items[0].opts.name), true)) |
| 1840 | } else return false; | 1865 | .global_mangled |
| | 1866 | else |
| | 1867 | .global; |
| | 1868 | } else return .local; |
| 1841 | }, | 1869 | }, |
| 1842 | else => unreachable, | 1870 | else => unreachable, |
| 1843 | }; | 1871 | }; |
| ... | @@ -1923,8 +1951,8 @@ pub const DeclGen = struct { | ... | @@ -1923,8 +1951,8 @@ pub const DeclGen = struct { |
| 1923 | fn renderFwdDecl(dg: *DeclGen, decl_index: Decl.Index, variable: InternPool.Key.Variable) !void { | 1951 | fn renderFwdDecl(dg: *DeclGen, decl_index: Decl.Index, variable: InternPool.Key.Variable) !void { |
| 1924 | const decl = dg.module.declPtr(decl_index); | 1952 | const decl = dg.module.declPtr(decl_index); |
| 1925 | const fwd = dg.fwd_decl.writer(); | 1953 | const fwd = dg.fwd_decl.writer(); |
| 1926 | const is_global = dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }) or variable.is_extern; | 1954 | const visibility = if (variable.is_extern) .global else dg.declVisibility(.{ .ty = decl.ty, .val = decl.val }); |
| 1927 | try fwd.writeAll(if (is_global) "zig_extern " else "static "); | 1955 | try visibility.renderFwd(fwd); |
| 1928 | const export_weak_linkage = if (dg.module.decl_exports.get(decl_index)) |exports| | 1956 | const export_weak_linkage = if (dg.module.decl_exports.get(decl_index)) |exports| |
| 1929 | exports.items[0].opts.linkage == .Weak | 1957 | exports.items[0].opts.linkage == .Weak |
| 1930 | else | 1958 | else |
| ... | @@ -2735,9 +2763,10 @@ pub fn genFunc(f: *Function) !void { | ... | @@ -2735,9 +2763,10 @@ pub fn genFunc(f: *Function) !void { |
| 2735 | o.code_header = std.ArrayList(u8).init(gpa); | 2763 | o.code_header = std.ArrayList(u8).init(gpa); |
| 2736 | defer o.code_header.deinit(); | 2764 | defer o.code_header.deinit(); |
| 2737 | | 2765 | |
| 2738 | const is_global = o.dg.declIsGlobal(tv); | 2766 | const visibility = o.dg.declVisibility(tv); |
| 2739 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | 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 | if (mod.decl_exports.get(decl_index)) |exports| | 2770 | if (mod.decl_exports.get(decl_index)) |exports| |
| 2742 | if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn "); | 2771 | if (exports.items[0].opts.linkage == .Weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn "); |
| 2743 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); | 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,7 +2774,7 @@ pub fn genFunc(f: *Function) !void { |
| 2745 | try genExports(o); | 2774 | try genExports(o); |
| 2746 | | 2775 | |
| 2747 | try o.indent_writer.insertNewline(); | 2776 | try o.indent_writer.insertNewline(); |
| 2748 | if (!is_global) try o.writer().writeAll("static "); | 2777 | try visibility.renderDef(o.writer()); |
| 2749 | try o.dg.renderFunctionSignature(o.writer(), decl_index, .complete, .{ .export_index = 0 }); | 2778 | try o.dg.renderFunctionSignature(o.writer(), decl_index, .complete, .{ .export_index = 0 }); |
| 2750 | try o.writer().writeByte(' '); | 2779 | try o.writer().writeByte(' '); |
| 2751 | | 2780 | |
| ... | @@ -2829,9 +2858,9 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2829,9 +2858,9 @@ pub fn genDecl(o: *Object) !void { |
| 2829 | | 2858 | |
| 2830 | if (variable.is_extern) return; | 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 | const w = o.writer(); | 2862 | const w = o.writer(); |
| 2834 | if (!is_global) try w.writeAll("static "); | 2863 | try visibility.renderDef(w); |
| 2835 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); | 2864 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); |
| 2836 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); | 2865 | if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); |
| 2837 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| | 2866 | if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| |
| ... | @@ -2844,16 +2873,21 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2844,16 +2873,21 @@ pub fn genDecl(o: *Object) !void { |
| 2844 | try w.writeByte(';'); | 2873 | try w.writeByte(';'); |
| 2845 | try o.indent_writer.insertNewline(); | 2874 | try o.indent_writer.insertNewline(); |
| 2846 | } else { | 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 | const decl_c_value = .{ .decl = decl_index }; | 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 | pub fn genDeclValue( | 2887 | pub fn genDeclValue( |
| 2854 | o: *Object, | 2888 | o: *Object, |
| 2855 | tv: TypedValue, | 2889 | tv: TypedValue, |
| 2856 | is_global: bool, | 2890 | visibility: DeclVisibility, |
| 2857 | decl_c_value: CValue, | 2891 | decl_c_value: CValue, |
| 2858 | alignment: Alignment, | 2892 | alignment: Alignment, |
| 2859 | link_section: InternPool.OptionalNullTerminatedString, | 2893 | link_section: InternPool.OptionalNullTerminatedString, |
| ... | @@ -2861,12 +2895,13 @@ pub fn genDeclValue( | ... | @@ -2861,12 +2895,13 @@ pub fn genDeclValue( |
| 2861 | const mod = o.dg.module; | 2895 | const mod = o.dg.module; |
| 2862 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | 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 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); | 2899 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); |
| 2866 | try fwd_decl_writer.writeAll(";\n"); | 2900 | try fwd_decl_writer.writeAll(";\n"); |
| 2867 | | 2901 | |
| 2868 | const w = o.writer(); | 2902 | const w = o.writer(); |
| 2869 | if (!is_global) try w.writeAll("static "); | 2903 | try visibility.renderDef(w); |
| | 2904 | |
| 2870 | if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| | 2905 | if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| |
| 2871 | try w.print("zig_linksection(\"{s}\", ", .{s}); | 2906 | try w.print("zig_linksection(\"{s}\", ", .{s}); |
| 2872 | try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete); | 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,11 +2926,14 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
| 2891 | | 2926 | |
| 2892 | switch (tv.ty.zigTypeTag(mod)) { | 2927 | switch (tv.ty.zigTypeTag(mod)) { |
| 2893 | .Fn => { | 2928 | .Fn => { |
| 2894 | const is_global = dg.declIsGlobal(tv); | 2929 | const visibility = dg.declVisibility(tv); |
| 2895 | if (is_global) { | 2930 | switch (visibility) { |
| 2896 | try writer.writeAll("zig_extern "); | 2931 | .global, .global_mangled => { |
| 2897 | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); | 2932 | try visibility.renderFwd(writer); |
| 2898 | try dg.fwd_decl.appendSlice(";\n"); | 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 | else => {}, | 2939 | else => {}, |