| ... | ... | @@ -731,8 +731,6 @@ pub const DeclGen = struct { |
| 731 | 731 | if (decl.val.getExternFunc(zcu)) |extern_func| if (extern_func.decl != decl_index) |
| 732 | 732 | return dg.renderDeclValue(writer, extern_func.decl, location); |
| 733 | 733 | |
| 734 | | if (decl.val.getVariable(zcu)) |variable| try dg.renderFwdDecl(decl_index, variable, .tentative); |
| 735 | | |
| 736 | 734 | // We shouldn't cast C function pointers as this is UB (when you call |
| 737 | 735 | // them). The analysis until now should ensure that the C function |
| 738 | 736 | // pointers are compatible. If they are not, then there is a bug |
| ... | ... | @@ -748,7 +746,7 @@ pub const DeclGen = struct { |
| 748 | 746 | try writer.writeByte(')'); |
| 749 | 747 | } |
| 750 | 748 | try writer.writeByte('&'); |
| 751 | | try dg.renderDeclName(writer, decl_index, 0); |
| 749 | try dg.renderDeclName(writer, decl_index); |
| 752 | 750 | if (need_cast) try writer.writeByte(')'); |
| 753 | 751 | } |
| 754 | 752 | |
| ... | ... | @@ -1765,19 +1763,22 @@ pub const DeclGen = struct { |
| 1765 | 1763 | fn renderFunctionSignature( |
| 1766 | 1764 | dg: *DeclGen, |
| 1767 | 1765 | w: anytype, |
| 1768 | | fn_decl_index: InternPool.DeclIndex, |
| 1766 | fn_val: Value, |
| 1767 | fn_align: InternPool.Alignment, |
| 1769 | 1768 | kind: CType.Kind, |
| 1770 | 1769 | name: union(enum) { |
| 1771 | | export_index: u32, |
| 1772 | | ident: []const u8, |
| 1770 | decl: InternPool.DeclIndex, |
| 1773 | 1771 | fmt_ctype_pool_string: std.fmt.Formatter(formatCTypePoolString), |
| 1772 | @"export": struct { |
| 1773 | main_name: InternPool.NullTerminatedString, |
| 1774 | extern_name: InternPool.NullTerminatedString, |
| 1775 | }, |
| 1774 | 1776 | }, |
| 1775 | 1777 | ) !void { |
| 1776 | 1778 | const zcu = dg.zcu; |
| 1777 | 1779 | const ip = &zcu.intern_pool; |
| 1778 | 1780 | |
| 1779 | | const fn_decl = zcu.declPtr(fn_decl_index); |
| 1780 | | const fn_ty = fn_decl.typeOf(zcu); |
| 1781 | const fn_ty = fn_val.typeOf(zcu); |
| 1781 | 1782 | const fn_ctype = try dg.ctypeFromType(fn_ty, kind); |
| 1782 | 1783 | |
| 1783 | 1784 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| ... | ... | @@ -1788,7 +1789,7 @@ pub const DeclGen = struct { |
| 1788 | 1789 | else => unreachable, |
| 1789 | 1790 | } |
| 1790 | 1791 | } |
| 1791 | | if (fn_decl.val.getFunction(zcu)) |func| if (func.analysis(ip).is_cold) |
| 1792 | if (fn_val.getFunction(zcu)) |func| if (func.analysis(ip).is_cold) |
| 1792 | 1793 | try w.writeAll("zig_cold "); |
| 1793 | 1794 | if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn "); |
| 1794 | 1795 | |
| ... | ... | @@ -1799,22 +1800,11 @@ pub const DeclGen = struct { |
| 1799 | 1800 | trailing = .maybe_space; |
| 1800 | 1801 | } |
| 1801 | 1802 | |
| 1802 | | switch (kind) { |
| 1803 | | .forward => {}, |
| 1804 | | .complete => if (fn_decl.alignment.toByteUnits()) |a| { |
| 1805 | | try w.print("{}zig_align_fn({})", .{ trailing, a }); |
| 1806 | | trailing = .maybe_space; |
| 1807 | | }, |
| 1808 | | else => unreachable, |
| 1809 | | } |
| 1810 | | |
| 1803 | try w.print("{}", .{trailing}); |
| 1811 | 1804 | switch (name) { |
| 1812 | | .export_index => |export_index| { |
| 1813 | | try w.print("{}", .{trailing}); |
| 1814 | | try dg.renderDeclName(w, fn_decl_index, export_index); |
| 1815 | | }, |
| 1816 | | .ident => |ident| try w.print("{}{ }", .{ trailing, fmtIdent(ident) }), |
| 1817 | | .fmt_ctype_pool_string => |fmt| try w.print("{}{ }", .{ trailing, fmt }), |
| 1805 | .decl => |decl_index| try dg.renderDeclName(w, decl_index), |
| 1806 | .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}), |
| 1807 | .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}), |
| 1818 | 1808 | } |
| 1819 | 1809 | |
| 1820 | 1810 | try renderTypeSuffix( |
| ... | ... | @@ -1833,44 +1823,30 @@ pub const DeclGen = struct { |
| 1833 | 1823 | |
| 1834 | 1824 | switch (kind) { |
| 1835 | 1825 | .forward => { |
| 1836 | | if (fn_decl.alignment.toByteUnits()) |a| { |
| 1837 | | try w.print(" zig_align_fn({})", .{a}); |
| 1838 | | } |
| 1826 | if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a}); |
| 1839 | 1827 | switch (name) { |
| 1840 | | .export_index => |export_index| mangled: { |
| 1841 | | const maybe_exports = zcu.decl_exports.get(fn_decl_index); |
| 1842 | | const external_name = (if (maybe_exports) |exports| |
| 1843 | | exports.items[export_index].opts.name |
| 1844 | | else if (fn_decl.isExtern(zcu)) |
| 1845 | | fn_decl.name |
| 1846 | | else |
| 1847 | | break :mangled).toSlice(ip); |
| 1848 | | const is_mangled = isMangledIdent(external_name, true); |
| 1849 | | const is_export = export_index > 0; |
| 1828 | .decl, .fmt_ctype_pool_string => {}, |
| 1829 | .@"export" => |@"export"| { |
| 1830 | const extern_name = @"export".extern_name.toSlice(ip); |
| 1831 | const is_mangled = isMangledIdent(extern_name, true); |
| 1832 | const is_export = @"export".extern_name != @"export".main_name; |
| 1850 | 1833 | if (is_mangled and is_export) { |
| 1851 | 1834 | try w.print(" zig_mangled_export({ }, {s}, {s})", .{ |
| 1852 | | fmtIdent(external_name), |
| 1853 | | fmtStringLiteral(external_name, null), |
| 1854 | | fmtStringLiteral( |
| 1855 | | maybe_exports.?.items[0].opts.name.toSlice(ip), |
| 1856 | | null, |
| 1857 | | ), |
| 1835 | fmtIdent(extern_name), |
| 1836 | fmtStringLiteral(extern_name, null), |
| 1837 | fmtStringLiteral(@"export".main_name.toSlice(ip), null), |
| 1858 | 1838 | }); |
| 1859 | 1839 | } else if (is_mangled) { |
| 1860 | | try w.print(" zig_mangled_final({ }, {s})", .{ |
| 1861 | | fmtIdent(external_name), fmtStringLiteral(external_name, null), |
| 1840 | try w.print(" zig_mangled({ }, {s})", .{ |
| 1841 | fmtIdent(extern_name), fmtStringLiteral(extern_name, null), |
| 1862 | 1842 | }); |
| 1863 | 1843 | } else if (is_export) { |
| 1864 | 1844 | try w.print(" zig_export({s}, {s})", .{ |
| 1865 | | fmtStringLiteral( |
| 1866 | | maybe_exports.?.items[0].opts.name.toSlice(ip), |
| 1867 | | null, |
| 1868 | | ), |
| 1869 | | fmtStringLiteral(external_name, null), |
| 1845 | fmtStringLiteral(@"export".main_name.toSlice(ip), null), |
| 1846 | fmtStringLiteral(extern_name, null), |
| 1870 | 1847 | }); |
| 1871 | 1848 | } |
| 1872 | 1849 | }, |
| 1873 | | .ident, .fmt_ctype_pool_string => {}, |
| 1874 | 1850 | } |
| 1875 | 1851 | }, |
| 1876 | 1852 | .complete => {}, |
| ... | ... | @@ -2085,21 +2061,11 @@ pub const DeclGen = struct { |
| 2085 | 2061 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{}); |
| 2086 | 2062 | } |
| 2087 | 2063 | |
| 2088 | | fn declIsGlobal(dg: *DeclGen, val: Value) bool { |
| 2089 | | const zcu = dg.zcu; |
| 2090 | | return switch (zcu.intern_pool.indexToKey(val.toIntern())) { |
| 2091 | | .variable => |variable| zcu.decl_exports.contains(variable.decl), |
| 2092 | | .extern_func => true, |
| 2093 | | .func => |func| zcu.decl_exports.contains(func.owner_decl), |
| 2094 | | else => unreachable, |
| 2095 | | }; |
| 2096 | | } |
| 2097 | | |
| 2098 | 2064 | fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void { |
| 2099 | 2065 | switch (c_value) { |
| 2100 | 2066 | .new_local, .local => |i| try w.print("t{d}", .{i}), |
| 2101 | 2067 | .constant => |val| try renderAnonDeclName(w, val), |
| 2102 | | .decl => |decl| try dg.renderDeclName(w, decl, 0), |
| 2068 | .decl => |decl| try dg.renderDeclName(w, decl), |
| 2103 | 2069 | .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}), |
| 2104 | 2070 | else => unreachable, |
| 2105 | 2071 | } |
| ... | ... | @@ -2111,10 +2077,10 @@ pub const DeclGen = struct { |
| 2111 | 2077 | .constant => |val| try renderAnonDeclName(w, val), |
| 2112 | 2078 | .arg, .arg_array => unreachable, |
| 2113 | 2079 | .field => |i| try w.print("f{d}", .{i}), |
| 2114 | | .decl => |decl| try dg.renderDeclName(w, decl, 0), |
| 2080 | .decl => |decl| try dg.renderDeclName(w, decl), |
| 2115 | 2081 | .decl_ref => |decl| { |
| 2116 | 2082 | try w.writeByte('&'); |
| 2117 | | try dg.renderDeclName(w, decl, 0); |
| 2083 | try dg.renderDeclName(w, decl); |
| 2118 | 2084 | }, |
| 2119 | 2085 | .undef => |ty| try dg.renderUndefValue(w, ty, .Other), |
| 2120 | 2086 | .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}), |
| ... | ... | @@ -2142,10 +2108,10 @@ pub const DeclGen = struct { |
| 2142 | 2108 | .field => |i| try w.print("f{d}", .{i}), |
| 2143 | 2109 | .decl => |decl| { |
| 2144 | 2110 | try w.writeAll("(*"); |
| 2145 | | try dg.renderDeclName(w, decl, 0); |
| 2111 | try dg.renderDeclName(w, decl); |
| 2146 | 2112 | try w.writeByte(')'); |
| 2147 | 2113 | }, |
| 2148 | | .decl_ref => |decl| try dg.renderDeclName(w, decl, 0), |
| 2114 | .decl_ref => |decl| try dg.renderDeclName(w, decl), |
| 2149 | 2115 | .undef => unreachable, |
| 2150 | 2116 | .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}), |
| 2151 | 2117 | .payload_identifier => |ident| try w.print("(*{ }.{ })", .{ |
| ... | ... | @@ -2195,19 +2161,12 @@ pub const DeclGen = struct { |
| 2195 | 2161 | dg: *DeclGen, |
| 2196 | 2162 | decl_index: InternPool.DeclIndex, |
| 2197 | 2163 | variable: InternPool.Key.Variable, |
| 2198 | | fwd_kind: enum { tentative, final }, |
| 2199 | 2164 | ) !void { |
| 2200 | 2165 | const zcu = dg.zcu; |
| 2201 | 2166 | const decl = zcu.declPtr(decl_index); |
| 2202 | 2167 | const fwd = dg.fwdDeclWriter(); |
| 2203 | | const is_global = variable.is_extern or dg.declIsGlobal(decl.val); |
| 2204 | | try fwd.writeAll(if (is_global) "zig_extern " else "static "); |
| 2205 | | const maybe_exports = zcu.decl_exports.get(decl_index); |
| 2206 | | const export_weak_linkage = if (maybe_exports) |exports| |
| 2207 | | exports.items[0].opts.linkage == .weak |
| 2208 | | else |
| 2209 | | false; |
| 2210 | | if (variable.is_weak_linkage or export_weak_linkage) try fwd.writeAll("zig_weak_linkage "); |
| 2168 | try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static "); |
| 2169 | if (variable.is_weak_linkage) try fwd.writeAll("zig_weak_linkage "); |
| 2211 | 2170 | if (variable.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal "); |
| 2212 | 2171 | try dg.renderTypeAndName( |
| 2213 | 2172 | fwd, |
| ... | ... | @@ -2217,38 +2176,17 @@ pub const DeclGen = struct { |
| 2217 | 2176 | decl.alignment, |
| 2218 | 2177 | .complete, |
| 2219 | 2178 | ); |
| 2220 | | mangled: { |
| 2221 | | const external_name = (if (maybe_exports) |exports| |
| 2222 | | exports.items[0].opts.name |
| 2223 | | else if (variable.is_extern) |
| 2224 | | decl.name |
| 2225 | | else |
| 2226 | | break :mangled).toSlice(&zcu.intern_pool); |
| 2227 | | if (isMangledIdent(external_name, true)) { |
| 2228 | | try fwd.print(" zig_mangled_{s}({ }, {s})", .{ |
| 2229 | | @tagName(fwd_kind), |
| 2230 | | fmtIdent(external_name), |
| 2231 | | fmtStringLiteral(external_name, null), |
| 2232 | | }); |
| 2233 | | } |
| 2234 | | } |
| 2235 | 2179 | try fwd.writeAll(";\n"); |
| 2236 | 2180 | } |
| 2237 | 2181 | |
| 2238 | | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex, export_index: u32) !void { |
| 2182 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex) !void { |
| 2239 | 2183 | const zcu = dg.zcu; |
| 2240 | 2184 | const ip = &zcu.intern_pool; |
| 2241 | 2185 | const decl = zcu.declPtr(decl_index); |
| 2242 | 2186 | |
| 2243 | | if (zcu.decl_exports.get(decl_index)) |exports| { |
| 2244 | | try writer.print("{ }", .{ |
| 2245 | | fmtIdent(exports.items[export_index].opts.name.toSlice(ip)), |
| 2246 | | }); |
| 2247 | | } else if (decl.getExternDecl(zcu).unwrap()) |extern_decl_index| { |
| 2248 | | try writer.print("{ }", .{ |
| 2249 | | fmtIdent(zcu.declPtr(extern_decl_index).name.toSlice(ip)), |
| 2250 | | }); |
| 2251 | | } else { |
| 2187 | if (decl.getExternDecl(zcu).unwrap()) |extern_decl_index| try writer.print("{ }", .{ |
| 2188 | fmtIdent(zcu.declPtr(extern_decl_index).name.toSlice(ip)), |
| 2189 | }) else { |
| 2252 | 2190 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), |
| 2253 | 2191 | // expand to 3x the length of its input, but let's cut it off at a much shorter limit. |
| 2254 | 2192 | var name: [100]u8 = undefined; |
| ... | ... | @@ -2761,69 +2699,6 @@ pub fn genErrDecls(o: *Object) !void { |
| 2761 | 2699 | try writer.writeAll("};\n"); |
| 2762 | 2700 | } |
| 2763 | 2701 | |
| 2764 | | fn genExports(o: *Object) !void { |
| 2765 | | const tracy = trace(@src()); |
| 2766 | | defer tracy.end(); |
| 2767 | | |
| 2768 | | const zcu = o.dg.zcu; |
| 2769 | | const ip = &zcu.intern_pool; |
| 2770 | | const decl_index = switch (o.dg.pass) { |
| 2771 | | .decl => |decl| decl, |
| 2772 | | .anon, .flush => return, |
| 2773 | | }; |
| 2774 | | const decl = zcu.declPtr(decl_index); |
| 2775 | | const fwd = o.dg.fwdDeclWriter(); |
| 2776 | | |
| 2777 | | const exports = zcu.decl_exports.get(decl_index) orelse return; |
| 2778 | | if (exports.items.len < 2) return; |
| 2779 | | |
| 2780 | | const is_variable_const = switch (ip.indexToKey(decl.val.toIntern())) { |
| 2781 | | .func => return for (exports.items[1..], 1..) |@"export", i| { |
| 2782 | | try fwd.writeAll("zig_extern "); |
| 2783 | | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn "); |
| 2784 | | try o.dg.renderFunctionSignature( |
| 2785 | | fwd, |
| 2786 | | decl_index, |
| 2787 | | .forward, |
| 2788 | | .{ .export_index = @intCast(i) }, |
| 2789 | | ); |
| 2790 | | try fwd.writeAll(";\n"); |
| 2791 | | }, |
| 2792 | | .extern_func => { |
| 2793 | | // TODO: when sema allows re-exporting extern decls |
| 2794 | | unreachable; |
| 2795 | | }, |
| 2796 | | .variable => |variable| variable.is_const, |
| 2797 | | else => true, |
| 2798 | | }; |
| 2799 | | for (exports.items[1..]) |@"export"| { |
| 2800 | | try fwd.writeAll("zig_extern "); |
| 2801 | | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage "); |
| 2802 | | const export_name = @"export".opts.name.toSlice(ip); |
| 2803 | | try o.dg.renderTypeAndName( |
| 2804 | | fwd, |
| 2805 | | decl.typeOf(zcu), |
| 2806 | | .{ .identifier = export_name }, |
| 2807 | | CQualifiers.init(.{ .@"const" = is_variable_const }), |
| 2808 | | decl.alignment, |
| 2809 | | .complete, |
| 2810 | | ); |
| 2811 | | if (isMangledIdent(export_name, true)) { |
| 2812 | | try fwd.print(" zig_mangled_export({ }, {s}, {s})", .{ |
| 2813 | | fmtIdent(export_name), |
| 2814 | | fmtStringLiteral(export_name, null), |
| 2815 | | fmtStringLiteral(exports.items[0].opts.name.toSlice(ip), null), |
| 2816 | | }); |
| 2817 | | } else { |
| 2818 | | try fwd.print(" zig_export({s}, {s})", .{ |
| 2819 | | fmtStringLiteral(exports.items[0].opts.name.toSlice(ip), null), |
| 2820 | | fmtStringLiteral(export_name, null), |
| 2821 | | }); |
| 2822 | | } |
| 2823 | | try fwd.writeAll(";\n"); |
| 2824 | | } |
| 2825 | | } |
| 2826 | | |
| 2827 | 2702 | pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void { |
| 2828 | 2703 | const zcu = o.dg.zcu; |
| 2829 | 2704 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -2885,19 +2760,19 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2885 | 2760 | const fn_info = fn_ctype.info(ctype_pool).function; |
| 2886 | 2761 | const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool); |
| 2887 | 2762 | |
| 2888 | | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 2889 | | try fwd_decl_writer.print("static zig_{s} ", .{@tagName(key)}); |
| 2890 | | try o.dg.renderFunctionSignature(fwd_decl_writer, fn_decl_index, .forward, .{ |
| 2763 | const fwd = o.dg.fwdDeclWriter(); |
| 2764 | try fwd.print("static zig_{s} ", .{@tagName(key)}); |
| 2765 | try o.dg.renderFunctionSignature(fwd, fn_decl.val, fn_decl.alignment, .forward, .{ |
| 2891 | 2766 | .fmt_ctype_pool_string = fn_name, |
| 2892 | 2767 | }); |
| 2893 | | try fwd_decl_writer.writeAll(";\n"); |
| 2768 | try fwd.writeAll(";\n"); |
| 2894 | 2769 | |
| 2895 | | try w.print("static zig_{s} ", .{@tagName(key)}); |
| 2896 | | try o.dg.renderFunctionSignature(w, fn_decl_index, .complete, .{ |
| 2770 | try w.print("zig_{s} ", .{@tagName(key)}); |
| 2771 | try o.dg.renderFunctionSignature(w, fn_decl.val, .none, .complete, .{ |
| 2897 | 2772 | .fmt_ctype_pool_string = fn_name, |
| 2898 | 2773 | }); |
| 2899 | 2774 | try w.writeAll(" {\n return "); |
| 2900 | | try o.dg.renderDeclName(w, fn_decl_index, 0); |
| 2775 | try o.dg.renderDeclName(w, fn_decl_index); |
| 2901 | 2776 | try w.writeByte('('); |
| 2902 | 2777 | for (0..fn_info.param_ctypes.len) |arg| { |
| 2903 | 2778 | if (arg > 0) try w.writeAll(", "); |
| ... | ... | @@ -2921,21 +2796,26 @@ pub fn genFunc(f: *Function) !void { |
| 2921 | 2796 | o.code_header = std.ArrayList(u8).init(gpa); |
| 2922 | 2797 | defer o.code_header.deinit(); |
| 2923 | 2798 | |
| 2924 | | const is_global = o.dg.declIsGlobal(decl.val); |
| 2925 | | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 2926 | | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2927 | | |
| 2928 | | if (zcu.decl_exports.get(decl_index)) |exports| |
| 2929 | | if (exports.items[0].opts.linkage == .weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn "); |
| 2930 | | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); |
| 2931 | | try fwd_decl_writer.writeAll(";\n"); |
| 2932 | | try genExports(o); |
| 2799 | const fwd = o.dg.fwdDeclWriter(); |
| 2800 | try fwd.writeAll("static "); |
| 2801 | try o.dg.renderFunctionSignature( |
| 2802 | fwd, |
| 2803 | decl.val, |
| 2804 | decl.alignment, |
| 2805 | .forward, |
| 2806 | .{ .decl = decl_index }, |
| 2807 | ); |
| 2808 | try fwd.writeAll(";\n"); |
| 2933 | 2809 | |
| 2934 | | try o.indent_writer.insertNewline(); |
| 2935 | | if (!is_global) try o.writer().writeAll("static "); |
| 2936 | 2810 | if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s| |
| 2937 | 2811 | try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)}); |
| 2938 | | try o.dg.renderFunctionSignature(o.writer(), decl_index, .complete, .{ .export_index = 0 }); |
| 2812 | try o.dg.renderFunctionSignature( |
| 2813 | o.writer(), |
| 2814 | decl.val, |
| 2815 | .none, |
| 2816 | .complete, |
| 2817 | .{ .decl = decl_index }, |
| 2818 | ); |
| 2939 | 2819 | try o.writer().writeByte(' '); |
| 2940 | 2820 | |
| 2941 | 2821 | // In case we need to use the header, populate it with a copy of the function |
| ... | ... | @@ -2949,7 +2829,6 @@ pub fn genFunc(f: *Function) !void { |
| 2949 | 2829 | |
| 2950 | 2830 | const main_body = f.air.getMainBody(); |
| 2951 | 2831 | try genBodyResolveState(f, undefined, &.{}, main_body, false); |
| 2952 | | |
| 2953 | 2832 | try o.indent_writer.insertNewline(); |
| 2954 | 2833 | |
| 2955 | 2834 | // Take advantage of the free_locals map to bucket locals per type. All |
| ... | ... | @@ -3007,20 +2886,25 @@ pub fn genDecl(o: *Object) !void { |
| 3007 | 2886 | |
| 3008 | 2887 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return; |
| 3009 | 2888 | if (decl.val.getExternFunc(zcu)) |_| { |
| 3010 | | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 3011 | | try fwd_decl_writer.writeAll("zig_extern "); |
| 3012 | | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); |
| 3013 | | try fwd_decl_writer.writeAll(";\n"); |
| 3014 | | try genExports(o); |
| 2889 | const fwd = o.dg.fwdDeclWriter(); |
| 2890 | try fwd.writeAll("zig_extern "); |
| 2891 | try o.dg.renderFunctionSignature( |
| 2892 | fwd, |
| 2893 | decl.val, |
| 2894 | decl.alignment, |
| 2895 | .forward, |
| 2896 | .{ .@"export" = .{ |
| 2897 | .main_name = decl.name, |
| 2898 | .extern_name = decl.name, |
| 2899 | } }, |
| 2900 | ); |
| 2901 | try fwd.writeAll(";\n"); |
| 3015 | 2902 | } else if (decl.val.getVariable(zcu)) |variable| { |
| 3016 | | try o.dg.renderFwdDecl(decl_index, variable, .final); |
| 3017 | | try genExports(o); |
| 2903 | try o.dg.renderFwdDecl(decl_index, variable); |
| 3018 | 2904 | |
| 3019 | 2905 | if (variable.is_extern) return; |
| 3020 | 2906 | |
| 3021 | | const is_global = variable.is_extern or o.dg.declIsGlobal(decl.val); |
| 3022 | 2907 | const w = o.writer(); |
| 3023 | | if (!is_global) try w.writeAll("static "); |
| 3024 | 2908 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); |
| 3025 | 2909 | if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal "); |
| 3026 | 2910 | if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s| |
| ... | ... | @@ -3032,46 +2916,27 @@ pub fn genDecl(o: *Object) !void { |
| 3032 | 2916 | try w.writeByte(';'); |
| 3033 | 2917 | try o.indent_writer.insertNewline(); |
| 3034 | 2918 | } else { |
| 3035 | | const is_global = o.dg.zcu.decl_exports.contains(decl_index); |
| 3036 | 2919 | const decl_c_value = .{ .decl = decl_index }; |
| 3037 | | try genDeclValue(o, decl.val, is_global, decl_c_value, decl.alignment, decl.@"linksection"); |
| 2920 | try genDeclValue(o, decl.val, decl_c_value, decl.alignment, decl.@"linksection"); |
| 3038 | 2921 | } |
| 3039 | 2922 | } |
| 3040 | 2923 | |
| 3041 | 2924 | pub fn genDeclValue( |
| 3042 | 2925 | o: *Object, |
| 3043 | 2926 | val: Value, |
| 3044 | | is_global: bool, |
| 3045 | 2927 | decl_c_value: CValue, |
| 3046 | 2928 | alignment: Alignment, |
| 3047 | 2929 | @"linksection": InternPool.OptionalNullTerminatedString, |
| 3048 | 2930 | ) !void { |
| 3049 | 2931 | const zcu = o.dg.zcu; |
| 3050 | | const fwd_decl_writer = o.dg.fwdDeclWriter(); |
| 3051 | | |
| 3052 | 2932 | const ty = val.typeOf(zcu); |
| 3053 | 2933 | |
| 3054 | | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 3055 | | try o.dg.renderTypeAndName(fwd_decl_writer, ty, decl_c_value, Const, alignment, .complete); |
| 3056 | | switch (o.dg.pass) { |
| 3057 | | .decl => |decl_index| { |
| 3058 | | if (zcu.decl_exports.get(decl_index)) |exports| { |
| 3059 | | const export_name = exports.items[0].opts.name.toSlice(&zcu.intern_pool); |
| 3060 | | if (isMangledIdent(export_name, true)) { |
| 3061 | | try fwd_decl_writer.print(" zig_mangled_final({ }, {s})", .{ |
| 3062 | | fmtIdent(export_name), fmtStringLiteral(export_name, null), |
| 3063 | | }); |
| 3064 | | } |
| 3065 | | } |
| 3066 | | }, |
| 3067 | | .anon => {}, |
| 3068 | | .flush => unreachable, |
| 3069 | | } |
| 3070 | | try fwd_decl_writer.writeAll(";\n"); |
| 3071 | | try genExports(o); |
| 2934 | const fwd = o.dg.fwdDeclWriter(); |
| 2935 | try fwd.writeAll("static "); |
| 2936 | try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete); |
| 2937 | try fwd.writeAll(";\n"); |
| 3072 | 2938 | |
| 3073 | 2939 | const w = o.writer(); |
| 3074 | | if (!is_global) try w.writeAll("static "); |
| 3075 | 2940 | if (@"linksection".toSlice(&zcu.intern_pool)) |s| |
| 3076 | 2941 | try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)}); |
| 3077 | 2942 | try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete); |
| ... | ... | @@ -3080,24 +2945,73 @@ pub fn genDeclValue( |
| 3080 | 2945 | try w.writeAll(";\n"); |
| 3081 | 2946 | } |
| 3082 | 2947 | |
| 3083 | | pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
| 3084 | | if (true) @panic("TODO jacobly"); |
| 3085 | | |
| 3086 | | const tracy = trace(@src()); |
| 3087 | | defer tracy.end(); |
| 3088 | | |
| 2948 | pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void { |
| 3089 | 2949 | const zcu = dg.zcu; |
| 3090 | | const decl_index = dg.pass.decl; |
| 3091 | | const decl = zcu.declPtr(decl_index); |
| 3092 | | const writer = dg.fwdDeclWriter(); |
| 2950 | const ip = &zcu.intern_pool; |
| 2951 | const fwd = dg.fwdDeclWriter(); |
| 3093 | 2952 | |
| 3094 | | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { |
| 3095 | | .Fn => if (dg.declIsGlobal(decl.val)) { |
| 3096 | | try writer.writeAll("zig_extern "); |
| 3097 | | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); |
| 3098 | | try dg.fwd_decl.appendSlice(";\n"); |
| 2953 | const main_name = zcu.all_exports.items[export_indices[0]].opts.name; |
| 2954 | try fwd.writeAll("#define "); |
| 2955 | switch (exported) { |
| 2956 | .decl_index => |decl_index| try dg.renderDeclName(fwd, decl_index), |
| 2957 | .value => |value| try DeclGen.renderAnonDeclName(fwd, Value.fromInterned(value)), |
| 2958 | } |
| 2959 | try fwd.writeByte(' '); |
| 2960 | try fwd.print("{ }", .{fmtIdent(main_name.toSlice(ip))}); |
| 2961 | try fwd.writeByte('\n'); |
| 2962 | |
| 2963 | const is_const = switch (ip.indexToKey(exported.getValue(zcu).toIntern())) { |
| 2964 | .func, .extern_func => return for (export_indices) |export_index| { |
| 2965 | const @"export" = &zcu.all_exports.items[export_index]; |
| 2966 | try fwd.writeAll("zig_extern "); |
| 2967 | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn "); |
| 2968 | try dg.renderFunctionSignature( |
| 2969 | fwd, |
| 2970 | exported.getValue(zcu), |
| 2971 | exported.getAlign(zcu), |
| 2972 | .forward, |
| 2973 | .{ .@"export" = .{ |
| 2974 | .main_name = main_name, |
| 2975 | .extern_name = @"export".opts.name, |
| 2976 | } }, |
| 2977 | ); |
| 2978 | try fwd.writeAll(";\n"); |
| 3099 | 2979 | }, |
| 3100 | | else => {}, |
| 2980 | .variable => |variable| variable.is_const, |
| 2981 | else => true, |
| 2982 | }; |
| 2983 | for (export_indices) |export_index| { |
| 2984 | const @"export" = &zcu.all_exports.items[export_index]; |
| 2985 | try fwd.writeAll("zig_extern "); |
| 2986 | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage "); |
| 2987 | const extern_name = @"export".opts.name.toSlice(ip); |
| 2988 | const is_mangled = isMangledIdent(extern_name, true); |
| 2989 | const is_export = @"export".opts.name != main_name; |
| 2990 | try dg.renderTypeAndName( |
| 2991 | fwd, |
| 2992 | exported.getValue(zcu).typeOf(zcu), |
| 2993 | .{ .identifier = extern_name }, |
| 2994 | CQualifiers.init(.{ .@"const" = is_const }), |
| 2995 | exported.getAlign(zcu), |
| 2996 | .complete, |
| 2997 | ); |
| 2998 | if (is_mangled and is_export) { |
| 2999 | try fwd.print(" zig_mangled_export({ }, {s}, {s})", .{ |
| 3000 | fmtIdent(extern_name), |
| 3001 | fmtStringLiteral(extern_name, null), |
| 3002 | fmtStringLiteral(main_name.toSlice(ip), null), |
| 3003 | }); |
| 3004 | } else if (is_mangled) { |
| 3005 | try fwd.print(" zig_mangled({ }, {s})", .{ |
| 3006 | fmtIdent(extern_name), fmtStringLiteral(extern_name, null), |
| 3007 | }); |
| 3008 | } else if (is_export) { |
| 3009 | try fwd.print(" zig_export({s}, {s})", .{ |
| 3010 | fmtStringLiteral(main_name.toSlice(ip), null), |
| 3011 | fmtStringLiteral(extern_name, null), |
| 3012 | }); |
| 3013 | } |
| 3014 | try fwd.writeAll(";\n"); |
| 3101 | 3015 | } |
| 3102 | 3016 | } |
| 3103 | 3017 | |
| ... | ... | @@ -4554,7 +4468,7 @@ fn airCall( |
| 4554 | 4468 | }; |
| 4555 | 4469 | }; |
| 4556 | 4470 | switch (modifier) { |
| 4557 | | .auto, .always_tail => try f.object.dg.renderDeclName(writer, fn_decl, 0), |
| 4471 | .auto, .always_tail => try f.object.dg.renderDeclName(writer, fn_decl), |
| 4558 | 4472 | inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName( |
| 4559 | 4473 | @unionInit(LazyFnKey, @tagName(m), fn_decl), |
| 4560 | 4474 | @unionInit(LazyFnValue.Data, @tagName(m), {}), |