| ... | @@ -731,8 +731,6 @@ pub const DeclGen = struct { | ... | @@ -731,8 +731,6 @@ pub const DeclGen = struct { |
| 731 | if (decl.val.getExternFunc(zcu)) |extern_func| if (extern_func.decl != decl_index) | 731 | if (decl.val.getExternFunc(zcu)) |extern_func| if (extern_func.decl != decl_index) |
| 732 | return dg.renderDeclValue(writer, extern_func.decl, location); | 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 | // We shouldn't cast C function pointers as this is UB (when you call | 734 | // We shouldn't cast C function pointers as this is UB (when you call |
| 737 | // them). The analysis until now should ensure that the C function | 735 | // them). The analysis until now should ensure that the C function |
| 738 | // pointers are compatible. If they are not, then there is a bug | 736 | // pointers are compatible. If they are not, then there is a bug |
| ... | @@ -748,7 +746,7 @@ pub const DeclGen = struct { | ... | @@ -748,7 +746,7 @@ pub const DeclGen = struct { |
| 748 | try writer.writeByte(')'); | 746 | try writer.writeByte(')'); |
| 749 | } | 747 | } |
| 750 | try writer.writeByte('&'); | 748 | try writer.writeByte('&'); |
| 751 | try dg.renderDeclName(writer, decl_index, 0); | 749 | try dg.renderDeclName(writer, decl_index); |
| 752 | if (need_cast) try writer.writeByte(')'); | 750 | if (need_cast) try writer.writeByte(')'); |
| 753 | } | 751 | } |
| 754 | | 752 | |
| ... | @@ -1765,19 +1763,22 @@ pub const DeclGen = struct { | ... | @@ -1765,19 +1763,22 @@ pub const DeclGen = struct { |
| 1765 | fn renderFunctionSignature( | 1763 | fn renderFunctionSignature( |
| 1766 | dg: *DeclGen, | 1764 | dg: *DeclGen, |
| 1767 | w: anytype, | 1765 | w: anytype, |
| 1768 | fn_decl_index: InternPool.DeclIndex, | 1766 | fn_val: Value, |
| | 1767 | fn_align: InternPool.Alignment, |
| 1769 | kind: CType.Kind, | 1768 | kind: CType.Kind, |
| 1770 | name: union(enum) { | 1769 | name: union(enum) { |
| 1771 | export_index: u32, | 1770 | decl: InternPool.DeclIndex, |
| 1772 | ident: []const u8, | | |
| 1773 | fmt_ctype_pool_string: std.fmt.Formatter(formatCTypePoolString), | 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 | ) !void { | 1777 | ) !void { |
| 1776 | const zcu = dg.zcu; | 1778 | const zcu = dg.zcu; |
| 1777 | const ip = &zcu.intern_pool; | 1779 | const ip = &zcu.intern_pool; |
| 1778 | | 1780 | |
| 1779 | const fn_decl = zcu.declPtr(fn_decl_index); | 1781 | const fn_ty = fn_val.typeOf(zcu); |
| 1780 | const fn_ty = fn_decl.typeOf(zcu); | | |
| 1781 | const fn_ctype = try dg.ctypeFromType(fn_ty, kind); | 1782 | const fn_ctype = try dg.ctypeFromType(fn_ty, kind); |
| 1782 | | 1783 | |
| 1783 | const fn_info = zcu.typeToFunc(fn_ty).?; | 1784 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| ... | @@ -1788,7 +1789,7 @@ pub const DeclGen = struct { | ... | @@ -1788,7 +1789,7 @@ pub const DeclGen = struct { |
| 1788 | else => unreachable, | 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 | try w.writeAll("zig_cold "); | 1793 | try w.writeAll("zig_cold "); |
| 1793 | if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn "); | 1794 | if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn "); |
| 1794 | | 1795 | |
| ... | @@ -1799,22 +1800,11 @@ pub const DeclGen = struct { | ... | @@ -1799,22 +1800,11 @@ pub const DeclGen = struct { |
| 1799 | trailing = .maybe_space; | 1800 | trailing = .maybe_space; |
| 1800 | } | 1801 | } |
| 1801 | | 1802 | |
| 1802 | switch (kind) { | 1803 | try w.print("{}", .{trailing}); |
| 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 | | | |
| 1811 | switch (name) { | 1804 | switch (name) { |
| 1812 | .export_index => |export_index| { | 1805 | .decl => |decl_index| try dg.renderDeclName(w, decl_index), |
| 1813 | try w.print("{}", .{trailing}); | 1806 | .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}), |
| 1814 | try dg.renderDeclName(w, fn_decl_index, export_index); | 1807 | .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}), |
| 1815 | }, | | |
| 1816 | .ident => |ident| try w.print("{}{ }", .{ trailing, fmtIdent(ident) }), | | |
| 1817 | .fmt_ctype_pool_string => |fmt| try w.print("{}{ }", .{ trailing, fmt }), | | |
| 1818 | } | 1808 | } |
| 1819 | | 1809 | |
| 1820 | try renderTypeSuffix( | 1810 | try renderTypeSuffix( |
| ... | @@ -1833,44 +1823,30 @@ pub const DeclGen = struct { | ... | @@ -1833,44 +1823,30 @@ pub const DeclGen = struct { |
| 1833 | | 1823 | |
| 1834 | switch (kind) { | 1824 | switch (kind) { |
| 1835 | .forward => { | 1825 | .forward => { |
| 1836 | if (fn_decl.alignment.toByteUnits()) |a| { | 1826 | if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a}); |
| 1837 | try w.print(" zig_align_fn({})", .{a}); | | |
| 1838 | } | | |
| 1839 | switch (name) { | 1827 | switch (name) { |
| 1840 | .export_index => |export_index| mangled: { | 1828 | .decl, .fmt_ctype_pool_string => {}, |
| 1841 | const maybe_exports = zcu.decl_exports.get(fn_decl_index); | 1829 | .@"export" => |@"export"| { |
| 1842 | const external_name = (if (maybe_exports) |exports| | 1830 | const extern_name = @"export".extern_name.toSlice(ip); |
| 1843 | exports.items[export_index].opts.name | 1831 | const is_mangled = isMangledIdent(extern_name, true); |
| 1844 | else if (fn_decl.isExtern(zcu)) | 1832 | const is_export = @"export".extern_name != @"export".main_name; |
| 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; | | |
| 1850 | if (is_mangled and is_export) { | 1833 | if (is_mangled and is_export) { |
| 1851 | try w.print(" zig_mangled_export({ }, {s}, {s})", .{ | 1834 | try w.print(" zig_mangled_export({ }, {s}, {s})", .{ |
| 1852 | fmtIdent(external_name), | 1835 | fmtIdent(extern_name), |
| 1853 | fmtStringLiteral(external_name, null), | 1836 | fmtStringLiteral(extern_name, null), |
| 1854 | fmtStringLiteral( | 1837 | fmtStringLiteral(@"export".main_name.toSlice(ip), null), |
| 1855 | maybe_exports.?.items[0].opts.name.toSlice(ip), | | |
| 1856 | null, | | |
| 1857 | ), | | |
| 1858 | }); | 1838 | }); |
| 1859 | } else if (is_mangled) { | 1839 | } else if (is_mangled) { |
| 1860 | try w.print(" zig_mangled_final({ }, {s})", .{ | 1840 | try w.print(" zig_mangled({ }, {s})", .{ |
| 1861 | fmtIdent(external_name), fmtStringLiteral(external_name, null), | 1841 | fmtIdent(extern_name), fmtStringLiteral(extern_name, null), |
| 1862 | }); | 1842 | }); |
| 1863 | } else if (is_export) { | 1843 | } else if (is_export) { |
| 1864 | try w.print(" zig_export({s}, {s})", .{ | 1844 | try w.print(" zig_export({s}, {s})", .{ |
| 1865 | fmtStringLiteral( | 1845 | fmtStringLiteral(@"export".main_name.toSlice(ip), null), |
| 1866 | maybe_exports.?.items[0].opts.name.toSlice(ip), | 1846 | fmtStringLiteral(extern_name, null), |
| 1867 | null, | | |
| 1868 | ), | | |
| 1869 | fmtStringLiteral(external_name, null), | | |
| 1870 | }); | 1847 | }); |
| 1871 | } | 1848 | } |
| 1872 | }, | 1849 | }, |
| 1873 | .ident, .fmt_ctype_pool_string => {}, | | |
| 1874 | } | 1850 | } |
| 1875 | }, | 1851 | }, |
| 1876 | .complete => {}, | 1852 | .complete => {}, |
| ... | @@ -2085,21 +2061,11 @@ pub const DeclGen = struct { | ... | @@ -2085,21 +2061,11 @@ pub const DeclGen = struct { |
| 2085 | try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.zcu, w, ctype, .suffix, .{}); | 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 | fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void { | 2064 | fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void { |
| 2099 | switch (c_value) { | 2065 | switch (c_value) { |
| 2100 | .new_local, .local => |i| try w.print("t{d}", .{i}), | 2066 | .new_local, .local => |i| try w.print("t{d}", .{i}), |
| 2101 | .constant => |val| try renderAnonDeclName(w, val), | 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 | .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}), | 2069 | .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}), |
| 2104 | else => unreachable, | 2070 | else => unreachable, |
| 2105 | } | 2071 | } |
| ... | @@ -2111,10 +2077,10 @@ pub const DeclGen = struct { | ... | @@ -2111,10 +2077,10 @@ pub const DeclGen = struct { |
| 2111 | .constant => |val| try renderAnonDeclName(w, val), | 2077 | .constant => |val| try renderAnonDeclName(w, val), |
| 2112 | .arg, .arg_array => unreachable, | 2078 | .arg, .arg_array => unreachable, |
| 2113 | .field => |i| try w.print("f{d}", .{i}), | 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 | .decl_ref => |decl| { | 2081 | .decl_ref => |decl| { |
| 2116 | try w.writeByte('&'); | 2082 | try w.writeByte('&'); |
| 2117 | try dg.renderDeclName(w, decl, 0); | 2083 | try dg.renderDeclName(w, decl); |
| 2118 | }, | 2084 | }, |
| 2119 | .undef => |ty| try dg.renderUndefValue(w, ty, .Other), | 2085 | .undef => |ty| try dg.renderUndefValue(w, ty, .Other), |
| 2120 | .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}), | 2086 | .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}), |
| ... | @@ -2142,10 +2108,10 @@ pub const DeclGen = struct { | ... | @@ -2142,10 +2108,10 @@ pub const DeclGen = struct { |
| 2142 | .field => |i| try w.print("f{d}", .{i}), | 2108 | .field => |i| try w.print("f{d}", .{i}), |
| 2143 | .decl => |decl| { | 2109 | .decl => |decl| { |
| 2144 | try w.writeAll("(*"); | 2110 | try w.writeAll("(*"); |
| 2145 | try dg.renderDeclName(w, decl, 0); | 2111 | try dg.renderDeclName(w, decl); |
| 2146 | try w.writeByte(')'); | 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 | .undef => unreachable, | 2115 | .undef => unreachable, |
| 2150 | .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}), | 2116 | .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}), |
| 2151 | .payload_identifier => |ident| try w.print("(*{ }.{ })", .{ | 2117 | .payload_identifier => |ident| try w.print("(*{ }.{ })", .{ |
| ... | @@ -2195,19 +2161,12 @@ pub const DeclGen = struct { | ... | @@ -2195,19 +2161,12 @@ pub const DeclGen = struct { |
| 2195 | dg: *DeclGen, | 2161 | dg: *DeclGen, |
| 2196 | decl_index: InternPool.DeclIndex, | 2162 | decl_index: InternPool.DeclIndex, |
| 2197 | variable: InternPool.Key.Variable, | 2163 | variable: InternPool.Key.Variable, |
| 2198 | fwd_kind: enum { tentative, final }, | | |
| 2199 | ) !void { | 2164 | ) !void { |
| 2200 | const zcu = dg.zcu; | 2165 | const zcu = dg.zcu; |
| 2201 | const decl = zcu.declPtr(decl_index); | 2166 | const decl = zcu.declPtr(decl_index); |
| 2202 | const fwd = dg.fwdDeclWriter(); | 2167 | const fwd = dg.fwdDeclWriter(); |
| 2203 | const is_global = variable.is_extern or dg.declIsGlobal(decl.val); | 2168 | try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static "); |
| 2204 | try fwd.writeAll(if (is_global) "zig_extern " else "static "); | 2169 | if (variable.is_weak_linkage) try fwd.writeAll("zig_weak_linkage "); |
| 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 "); | | |
| 2211 | if (variable.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal "); | 2170 | if (variable.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal "); |
| 2212 | try dg.renderTypeAndName( | 2171 | try dg.renderTypeAndName( |
| 2213 | fwd, | 2172 | fwd, |
| ... | @@ -2217,38 +2176,17 @@ pub const DeclGen = struct { | ... | @@ -2217,38 +2176,17 @@ pub const DeclGen = struct { |
| 2217 | decl.alignment, | 2176 | decl.alignment, |
| 2218 | .complete, | 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 | try fwd.writeAll(";\n"); | 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 | const zcu = dg.zcu; | 2183 | const zcu = dg.zcu; |
| 2240 | const ip = &zcu.intern_pool; | 2184 | const ip = &zcu.intern_pool; |
| 2241 | const decl = zcu.declPtr(decl_index); | 2185 | const decl = zcu.declPtr(decl_index); |
| 2242 | | 2186 | |
| 2243 | if (zcu.decl_exports.get(decl_index)) |exports| { | 2187 | if (decl.getExternDecl(zcu).unwrap()) |extern_decl_index| try writer.print("{ }", .{ |
| 2244 | try writer.print("{ }", .{ | 2188 | fmtIdent(zcu.declPtr(extern_decl_index).name.toSlice(ip)), |
| 2245 | fmtIdent(exports.items[export_index].opts.name.toSlice(ip)), | 2189 | }) else { |
| 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 { | | |
| 2252 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), | 2190 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), |
| 2253 | // expand to 3x the length of its input, but let's cut it off at a much shorter limit. | 2191 | // expand to 3x the length of its input, but let's cut it off at a much shorter limit. |
| 2254 | var name: [100]u8 = undefined; | 2192 | var name: [100]u8 = undefined; |
| ... | @@ -2761,69 +2699,6 @@ pub fn genErrDecls(o: *Object) !void { | ... | @@ -2761,69 +2699,6 @@ pub fn genErrDecls(o: *Object) !void { |
| 2761 | try writer.writeAll("};\n"); | 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 | pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void { | 2702 | pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void { |
| 2828 | const zcu = o.dg.zcu; | 2703 | const zcu = o.dg.zcu; |
| 2829 | const ip = &zcu.intern_pool; | 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,19 +2760,19 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn |
| 2885 | const fn_info = fn_ctype.info(ctype_pool).function; | 2760 | const fn_info = fn_ctype.info(ctype_pool).function; |
| 2886 | const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool); | 2761 | const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool); |
| 2887 | | 2762 | |
| 2888 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2763 | const fwd = o.dg.fwdDeclWriter(); |
| 2889 | try fwd_decl_writer.print("static zig_{s} ", .{@tagName(key)}); | 2764 | try fwd.print("static zig_{s} ", .{@tagName(key)}); |
| 2890 | try o.dg.renderFunctionSignature(fwd_decl_writer, fn_decl_index, .forward, .{ | 2765 | try o.dg.renderFunctionSignature(fwd, fn_decl.val, fn_decl.alignment, .forward, .{ |
| 2891 | .fmt_ctype_pool_string = fn_name, | 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)}); | 2770 | try w.print("zig_{s} ", .{@tagName(key)}); |
| 2896 | try o.dg.renderFunctionSignature(w, fn_decl_index, .complete, .{ | 2771 | try o.dg.renderFunctionSignature(w, fn_decl.val, .none, .complete, .{ |
| 2897 | .fmt_ctype_pool_string = fn_name, | 2772 | .fmt_ctype_pool_string = fn_name, |
| 2898 | }); | 2773 | }); |
| 2899 | try w.writeAll(" {\n return "); | 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 | try w.writeByte('('); | 2776 | try w.writeByte('('); |
| 2902 | for (0..fn_info.param_ctypes.len) |arg| { | 2777 | for (0..fn_info.param_ctypes.len) |arg| { |
| 2903 | if (arg > 0) try w.writeAll(", "); | 2778 | if (arg > 0) try w.writeAll(", "); |
| ... | @@ -2921,21 +2796,26 @@ pub fn genFunc(f: *Function) !void { | ... | @@ -2921,21 +2796,26 @@ pub fn genFunc(f: *Function) !void { |
| 2921 | o.code_header = std.ArrayList(u8).init(gpa); | 2796 | o.code_header = std.ArrayList(u8).init(gpa); |
| 2922 | defer o.code_header.deinit(); | 2797 | defer o.code_header.deinit(); |
| 2923 | | 2798 | |
| 2924 | const is_global = o.dg.declIsGlobal(decl.val); | 2799 | const fwd = o.dg.fwdDeclWriter(); |
| 2925 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2800 | try fwd.writeAll("static "); |
| 2926 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | 2801 | try o.dg.renderFunctionSignature( |
| 2927 | | 2802 | fwd, |
| 2928 | if (zcu.decl_exports.get(decl_index)) |exports| | 2803 | decl.val, |
| 2929 | if (exports.items[0].opts.linkage == .weak) try fwd_decl_writer.writeAll("zig_weak_linkage_fn "); | 2804 | decl.alignment, |
| 2930 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); | 2805 | .forward, |
| 2931 | try fwd_decl_writer.writeAll(";\n"); | 2806 | .{ .decl = decl_index }, |
| 2932 | try genExports(o); | 2807 | ); |
| | 2808 | try fwd.writeAll(";\n"); |
| 2933 | | 2809 | |
| 2934 | try o.indent_writer.insertNewline(); | | |
| 2935 | if (!is_global) try o.writer().writeAll("static "); | | |
| 2936 | if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s| | 2810 | if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s| |
| 2937 | try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)}); | 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 | try o.writer().writeByte(' '); | 2819 | try o.writer().writeByte(' '); |
| 2940 | | 2820 | |
| 2941 | // In case we need to use the header, populate it with a copy of the function | 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,7 +2829,6 @@ pub fn genFunc(f: *Function) !void { |
| 2949 | | 2829 | |
| 2950 | const main_body = f.air.getMainBody(); | 2830 | const main_body = f.air.getMainBody(); |
| 2951 | try genBodyResolveState(f, undefined, &.{}, main_body, false); | 2831 | try genBodyResolveState(f, undefined, &.{}, main_body, false); |
| 2952 | | | |
| 2953 | try o.indent_writer.insertNewline(); | 2832 | try o.indent_writer.insertNewline(); |
| 2954 | | 2833 | |
| 2955 | // Take advantage of the free_locals map to bucket locals per type. All | 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,20 +2886,25 @@ pub fn genDecl(o: *Object) !void { |
| 3007 | | 2886 | |
| 3008 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return; | 2887 | if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return; |
| 3009 | if (decl.val.getExternFunc(zcu)) |_| { | 2888 | if (decl.val.getExternFunc(zcu)) |_| { |
| 3010 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | 2889 | const fwd = o.dg.fwdDeclWriter(); |
| 3011 | try fwd_decl_writer.writeAll("zig_extern "); | 2890 | try fwd.writeAll("zig_extern "); |
| 3012 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); | 2891 | try o.dg.renderFunctionSignature( |
| 3013 | try fwd_decl_writer.writeAll(";\n"); | 2892 | fwd, |
| 3014 | try genExports(o); | 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 | } else if (decl.val.getVariable(zcu)) |variable| { | 2902 | } else if (decl.val.getVariable(zcu)) |variable| { |
| 3016 | try o.dg.renderFwdDecl(decl_index, variable, .final); | 2903 | try o.dg.renderFwdDecl(decl_index, variable); |
| 3017 | try genExports(o); | | |
| 3018 | | 2904 | |
| 3019 | if (variable.is_extern) return; | 2905 | if (variable.is_extern) return; |
| 3020 | | 2906 | |
| 3021 | const is_global = variable.is_extern or o.dg.declIsGlobal(decl.val); | | |
| 3022 | const w = o.writer(); | 2907 | const w = o.writer(); |
| 3023 | if (!is_global) try w.writeAll("static "); | | |
| 3024 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); | 2908 | if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage "); |
| 3025 | if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal "); | 2909 | if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal "); |
| 3026 | if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s| | 2910 | if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s| |
| ... | @@ -3032,46 +2916,27 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -3032,46 +2916,27 @@ pub fn genDecl(o: *Object) !void { |
| 3032 | try w.writeByte(';'); | 2916 | try w.writeByte(';'); |
| 3033 | try o.indent_writer.insertNewline(); | 2917 | try o.indent_writer.insertNewline(); |
| 3034 | } else { | 2918 | } else { |
| 3035 | const is_global = o.dg.zcu.decl_exports.contains(decl_index); | | |
| 3036 | const decl_c_value = .{ .decl = decl_index }; | 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 | pub fn genDeclValue( | 2924 | pub fn genDeclValue( |
| 3042 | o: *Object, | 2925 | o: *Object, |
| 3043 | val: Value, | 2926 | val: Value, |
| 3044 | is_global: bool, | | |
| 3045 | decl_c_value: CValue, | 2927 | decl_c_value: CValue, |
| 3046 | alignment: Alignment, | 2928 | alignment: Alignment, |
| 3047 | @"linksection": InternPool.OptionalNullTerminatedString, | 2929 | @"linksection": InternPool.OptionalNullTerminatedString, |
| 3048 | ) !void { | 2930 | ) !void { |
| 3049 | const zcu = o.dg.zcu; | 2931 | const zcu = o.dg.zcu; |
| 3050 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | | |
| 3051 | | | |
| 3052 | const ty = val.typeOf(zcu); | 2932 | const ty = val.typeOf(zcu); |
| 3053 | | 2933 | |
| 3054 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); | 2934 | const fwd = o.dg.fwdDeclWriter(); |
| 3055 | try o.dg.renderTypeAndName(fwd_decl_writer, ty, decl_c_value, Const, alignment, .complete); | 2935 | try fwd.writeAll("static "); |
| 3056 | switch (o.dg.pass) { | 2936 | try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete); |
| 3057 | .decl => |decl_index| { | 2937 | try fwd.writeAll(";\n"); |
| 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); | | |
| 3072 | | 2938 | |
| 3073 | const w = o.writer(); | 2939 | const w = o.writer(); |
| 3074 | if (!is_global) try w.writeAll("static "); | | |
| 3075 | if (@"linksection".toSlice(&zcu.intern_pool)) |s| | 2940 | if (@"linksection".toSlice(&zcu.intern_pool)) |s| |
| 3076 | try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)}); | 2941 | try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)}); |
| 3077 | try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete); | 2942 | try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete); |
| ... | @@ -3080,24 +2945,73 @@ pub fn genDeclValue( | ... | @@ -3080,24 +2945,73 @@ pub fn genDeclValue( |
| 3080 | try w.writeAll(";\n"); | 2945 | try w.writeAll(";\n"); |
| 3081 | } | 2946 | } |
| 3082 | | 2947 | |
| 3083 | pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { | 2948 | pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void { |
| 3084 | if (true) @panic("TODO jacobly"); | | |
| 3085 | | | |
| 3086 | const tracy = trace(@src()); | | |
| 3087 | defer tracy.end(); | | |
| 3088 | | | |
| 3089 | const zcu = dg.zcu; | 2949 | const zcu = dg.zcu; |
| 3090 | const decl_index = dg.pass.decl; | 2950 | const ip = &zcu.intern_pool; |
| 3091 | const decl = zcu.declPtr(decl_index); | 2951 | const fwd = dg.fwdDeclWriter(); |
| 3092 | const writer = dg.fwdDeclWriter(); | | |
| 3093 | | 2952 | |
| 3094 | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { | 2953 | const main_name = zcu.all_exports.items[export_indices[0]].opts.name; |
| 3095 | .Fn => if (dg.declIsGlobal(decl.val)) { | 2954 | try fwd.writeAll("#define "); |
| 3096 | try writer.writeAll("zig_extern "); | 2955 | switch (exported) { |
| 3097 | try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); | 2956 | .decl_index => |decl_index| try dg.renderDeclName(fwd, decl_index), |
| 3098 | try dg.fwd_decl.appendSlice(";\n"); | 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,7 +4468,7 @@ fn airCall( |
| 4554 | }; | 4468 | }; |
| 4555 | }; | 4469 | }; |
| 4556 | switch (modifier) { | 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 | inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName( | 4472 | inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName( |
| 4559 | @unionInit(LazyFnKey, @tagName(m), fn_decl), | 4473 | @unionInit(LazyFnKey, @tagName(m), fn_decl), |
| 4560 | @unionInit(LazyFnValue.Data, @tagName(m), {}), | 4474 | @unionInit(LazyFnValue.Data, @tagName(m), {}), |