| ... | @@ -134,7 +134,7 @@ pub const Function = struct { | ... | @@ -134,7 +134,7 @@ pub const Function = struct { |
| 134 | const val = f.air.value(inst).?; | 134 | const val = f.air.value(inst).?; |
| 135 | return f.object.dg.renderValue(w, ty, val); | 135 | return f.object.dg.renderValue(w, ty, val); |
| 136 | }, | 136 | }, |
| 137 | else => return DeclGen.writeCValue(w, c_value), | 137 | else => return f.object.dg.writeCValue(w, c_value), |
| 138 | } | 138 | } |
| 139 | } | 139 | } |
| 140 | | 140 | |
| ... | @@ -202,12 +202,13 @@ pub const DeclGen = struct { | ... | @@ -202,12 +202,13 @@ pub const DeclGen = struct { |
| 202 | // Determine if we must pointer cast. | 202 | // Determine if we must pointer cast. |
| 203 | assert(decl.has_tv); | 203 | assert(decl.has_tv); |
| 204 | if (ty.eql(decl.ty)) { | 204 | if (ty.eql(decl.ty)) { |
| 205 | try writer.print("&{s}", .{decl.name}); | 205 | try writer.writeByte('&'); |
| 206 | } else { | 206 | } else { |
| 207 | try writer.writeAll("("); | 207 | try writer.writeAll("("); |
| 208 | try dg.renderType(writer, ty); | 208 | try dg.renderType(writer, ty); |
| 209 | try writer.print(")&{s}", .{decl.name}); | 209 | try writer.writeAll(")&"); |
| 210 | } | 210 | } |
| | 211 | try dg.renderDeclName(decl, writer); |
| 211 | } | 212 | } |
| 212 | | 213 | |
| 213 | fn renderValue( | 214 | fn renderValue( |
| ... | @@ -260,11 +261,11 @@ pub const DeclGen = struct { | ... | @@ -260,11 +261,11 @@ pub const DeclGen = struct { |
| 260 | }, | 261 | }, |
| 261 | .function => { | 262 | .function => { |
| 262 | const func = val.castTag(.function).?.data; | 263 | const func = val.castTag(.function).?.data; |
| 263 | try writer.print("{s}", .{func.owner_decl.name}); | 264 | try dg.renderDeclName(func.owner_decl, writer); |
| 264 | }, | 265 | }, |
| 265 | .extern_fn => { | 266 | .extern_fn => { |
| 266 | const decl = val.castTag(.extern_fn).?.data; | 267 | const decl = val.castTag(.extern_fn).?.data; |
| 267 | try writer.print("{s}", .{decl.name}); | 268 | try dg.renderDeclName(decl, writer); |
| 268 | }, | 269 | }, |
| 269 | else => unreachable, | 270 | else => unreachable, |
| 270 | }, | 271 | }, |
| ... | @@ -386,27 +387,15 @@ pub const DeclGen = struct { | ... | @@ -386,27 +387,15 @@ pub const DeclGen = struct { |
| 386 | .one => try writer.writeAll("1"), | 387 | .one => try writer.writeAll("1"), |
| 387 | .decl_ref => { | 388 | .decl_ref => { |
| 388 | const decl = val.castTag(.decl_ref).?.data; | 389 | const decl = val.castTag(.decl_ref).?.data; |
| 389 | decl.alive = true; | 390 | return dg.renderDeclValue(writer, ty, val, decl); |
| 390 | | | |
| 391 | // Determine if we must pointer cast. | | |
| 392 | assert(decl.has_tv); | | |
| 393 | if (ty.eql(decl.ty)) { | | |
| 394 | try writer.print("&{s}", .{decl.name}); | | |
| 395 | } else { | | |
| 396 | try writer.writeAll("("); | | |
| 397 | try dg.renderType(writer, ty); | | |
| 398 | try writer.print(")&{s}", .{decl.name}); | | |
| 399 | } | | |
| 400 | }, | 391 | }, |
| 401 | .function => { | 392 | .function => { |
| 402 | const decl = val.castTag(.function).?.data.owner_decl; | 393 | const decl = val.castTag(.function).?.data.owner_decl; |
| 403 | decl.alive = true; | 394 | return dg.renderDeclValue(writer, ty, val, decl); |
| 404 | try writer.print("{s}", .{decl.name}); | | |
| 405 | }, | 395 | }, |
| 406 | .extern_fn => { | 396 | .extern_fn => { |
| 407 | const decl = val.castTag(.extern_fn).?.data; | 397 | const decl = val.castTag(.extern_fn).?.data; |
| 408 | decl.alive = true; | 398 | return dg.renderDeclValue(writer, ty, val, decl); |
| 409 | try writer.print("{s}", .{decl.name}); | | |
| 410 | }, | 399 | }, |
| 411 | else => unreachable, | 400 | else => unreachable, |
| 412 | }, | 401 | }, |
| ... | @@ -459,8 +448,9 @@ pub const DeclGen = struct { | ... | @@ -459,8 +448,9 @@ pub const DeclGen = struct { |
| 459 | } | 448 | } |
| 460 | } | 449 | } |
| 461 | try dg.renderType(w, dg.decl.ty.fnReturnType()); | 450 | try dg.renderType(w, dg.decl.ty.fnReturnType()); |
| 462 | const decl_name = mem.span(dg.decl.name); | 451 | try w.writeAll(" "); |
| 463 | try w.print(" {s}(", .{decl_name}); | 452 | try dg.renderDeclName(dg.decl, w); |
| | 453 | try w.writeAll("("); |
| 464 | const param_len = dg.decl.ty.fnParamLen(); | 454 | const param_len = dg.decl.ty.fnParamLen(); |
| 465 | const is_var_args = dg.decl.ty.fnIsVarArgs(); | 455 | const is_var_args = dg.decl.ty.fnIsVarArgs(); |
| 466 | if (param_len == 0 and !is_var_args) | 456 | if (param_len == 0 and !is_var_args) |
| ... | @@ -634,7 +624,9 @@ pub const DeclGen = struct { | ... | @@ -634,7 +624,9 @@ pub const DeclGen = struct { |
| 634 | const name_index = buffer.items.len; | 624 | const name_index = buffer.items.len; |
| 635 | if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| { | 625 | if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| { |
| 636 | const func = inf_err_set_payload.data.func; | 626 | const func = inf_err_set_payload.data.func; |
| 637 | try bw.print("zig_E_{s};\n", .{func.owner_decl.name}); | 627 | try bw.writeAll("zig_E_"); |
| | 628 | try dg.renderDeclName(func.owner_decl, bw); |
| | 629 | try bw.writeAll(";\n"); |
| 638 | } else { | 630 | } else { |
| 639 | try bw.print("zig_E_{s}_{s};\n", .{ | 631 | try bw.print("zig_E_{s}_{s};\n", .{ |
| 640 | typeToCIdentifier(err_set_type), typeToCIdentifier(child_type), | 632 | typeToCIdentifier(err_set_type), typeToCIdentifier(child_type), |
| ... | @@ -768,7 +760,7 @@ pub const DeclGen = struct { | ... | @@ -768,7 +760,7 @@ pub const DeclGen = struct { |
| 768 | .Const => try w.writeAll("const "), | 760 | .Const => try w.writeAll("const "), |
| 769 | .Mut => {}, | 761 | .Mut => {}, |
| 770 | } | 762 | } |
| 771 | try writeCValue(w, name); | 763 | try dg.writeCValue(w, name); |
| 772 | try w.writeAll(")("); | 764 | try w.writeAll(")("); |
| 773 | const param_len = render_ty.fnParamLen(); | 765 | const param_len = render_ty.fnParamLen(); |
| 774 | const is_var_args = render_ty.fnIsVarArgs(); | 766 | const is_var_args = render_ty.fnIsVarArgs(); |
| ... | @@ -796,7 +788,7 @@ pub const DeclGen = struct { | ... | @@ -796,7 +788,7 @@ pub const DeclGen = struct { |
| 796 | .Mut => "", | 788 | .Mut => "", |
| 797 | }; | 789 | }; |
| 798 | try w.print(" {s}", .{const_prefix}); | 790 | try w.print(" {s}", .{const_prefix}); |
| 799 | try writeCValue(w, name); | 791 | try dg.writeCValue(w, name); |
| 800 | } | 792 | } |
| 801 | try w.writeAll(suffix.items); | 793 | try w.writeAll(suffix.items); |
| 802 | } | 794 | } |
| ... | @@ -816,18 +808,34 @@ pub const DeclGen = struct { | ... | @@ -816,18 +808,34 @@ pub const DeclGen = struct { |
| 816 | } | 808 | } |
| 817 | } | 809 | } |
| 818 | | 810 | |
| 819 | fn writeCValue(w: anytype, c_value: CValue) !void { | 811 | fn writeCValue(dg: DeclGen, w: anytype, c_value: CValue) !void { |
| 820 | switch (c_value) { | 812 | switch (c_value) { |
| 821 | .none => unreachable, | 813 | .none => unreachable, |
| 822 | .local => |i| return w.print("t{d}", .{i}), | 814 | .local => |i| return w.print("t{d}", .{i}), |
| 823 | .local_ref => |i| return w.print("&t{d}", .{i}), | 815 | .local_ref => |i| return w.print("&t{d}", .{i}), |
| 824 | .constant => unreachable, | 816 | .constant => unreachable, |
| 825 | .arg => |i| return w.print("a{d}", .{i}), | 817 | .arg => |i| return w.print("a{d}", .{i}), |
| 826 | .decl => |decl| return w.writeAll(mem.span(decl.name)), | 818 | .decl => |decl| return dg.renderDeclName(decl, w), |
| 827 | .decl_ref => |decl| return w.print("&{s}", .{decl.name}), | 819 | .decl_ref => |decl| { |
| | 820 | try w.writeByte('&'); |
| | 821 | return dg.renderDeclName(decl, w); |
| | 822 | }, |
| 828 | .bytes => |bytes| return w.writeAll(bytes), | 823 | .bytes => |bytes| return w.writeAll(bytes), |
| 829 | } | 824 | } |
| 830 | } | 825 | } |
| | 826 | |
| | 827 | fn renderDeclName(dg: DeclGen, decl: *Decl, writer: anytype) !void { |
| | 828 | if (dg.module.decl_exports.get(decl)) |exports| { |
| | 829 | return writer.writeAll(exports[0].options.name); |
| | 830 | } else if (decl.val.tag() == .extern_fn) { |
| | 831 | return writer.writeAll(mem.spanZ(decl.name)); |
| | 832 | } else { |
| | 833 | const gpa = dg.module.gpa; |
| | 834 | const name = try decl.getFullyQualifiedName(gpa); |
| | 835 | defer gpa.free(name); |
| | 836 | return writer.print("{}", .{fmtIdent(name)}); |
| | 837 | } |
| | 838 | } |
| 831 | }; | 839 | }; |
| 832 | | 840 | |
| 833 | pub fn genFunc(f: *Function) !void { | 841 | pub fn genFunc(f: *Function) !void { |
| ... | @@ -868,22 +876,33 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -868,22 +876,33 @@ pub fn genDecl(o: *Object) !void { |
| 868 | try writer.writeAll(";\n"); | 876 | try writer.writeAll(";\n"); |
| 869 | } else if (tv.val.castTag(.variable)) |var_payload| { | 877 | } else if (tv.val.castTag(.variable)) |var_payload| { |
| 870 | const variable: *Module.Var = var_payload.data; | 878 | const variable: *Module.Var = var_payload.data; |
| 871 | const is_global = o.dg.declIsGlobal(tv); | 879 | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; |
| 872 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | 880 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 873 | if (is_global or variable.is_extern) { | 881 | if (is_global) { |
| 874 | try fwd_decl_writer.writeAll("ZIG_EXTERN_C "); | 882 | try fwd_decl_writer.writeAll("ZIG_EXTERN_C "); |
| 875 | } | 883 | } |
| 876 | if (variable.is_threadlocal) { | 884 | if (variable.is_threadlocal) { |
| 877 | try fwd_decl_writer.writeAll("zig_threadlocal "); | 885 | try fwd_decl_writer.writeAll("zig_threadlocal "); |
| 878 | } | 886 | } |
| 879 | try o.dg.renderType(fwd_decl_writer, o.dg.decl.ty); | 887 | try o.dg.renderType(fwd_decl_writer, o.dg.decl.ty); |
| 880 | const decl_name = mem.span(o.dg.decl.name); | 888 | try fwd_decl_writer.writeAll(" "); |
| 881 | try fwd_decl_writer.print(" {s};\n", .{decl_name}); | 889 | if (is_global) { |
| | 890 | try fwd_decl_writer.writeAll(mem.span(o.dg.decl.name)); |
| | 891 | } else { |
| | 892 | try o.dg.renderDeclName(o.dg.decl, fwd_decl_writer); |
| | 893 | } |
| | 894 | try fwd_decl_writer.writeAll(";\n"); |
| 882 | | 895 | |
| 883 | try o.indent_writer.insertNewline(); | 896 | try o.indent_writer.insertNewline(); |
| 884 | const w = o.writer(); | 897 | const w = o.writer(); |
| 885 | try o.dg.renderType(w, o.dg.decl.ty); | 898 | try o.dg.renderType(w, o.dg.decl.ty); |
| 886 | try w.print(" {s} = ", .{decl_name}); | 899 | try w.writeAll(" "); |
| | 900 | if (is_global) { |
| | 901 | try w.writeAll(mem.span(o.dg.decl.name)); |
| | 902 | } else { |
| | 903 | try o.dg.renderDeclName(o.dg.decl, w); |
| | 904 | } |
| | 905 | try w.writeAll(" = "); |
| 887 | if (variable.init.tag() != .unreachable_value) { | 906 | if (variable.init.tag() != .unreachable_value) { |
| 888 | try o.dg.renderValue(w, tv.ty, variable.init); | 907 | try o.dg.renderValue(w, tv.ty, variable.init); |
| 889 | } | 908 | } |
| ... | @@ -1562,7 +1581,7 @@ fn airCall(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -1562,7 +1581,7 @@ fn airCall(f: *Function, inst: Air.Inst.Index) !CValue { |
| 1562 | else | 1581 | else |
| 1563 | unreachable; | 1582 | unreachable; |
| 1564 | | 1583 | |
| 1565 | try writer.writeAll(mem.spanZ(fn_decl.name)); | 1584 | try f.object.dg.renderDeclName(fn_decl, writer); |
| 1566 | } else { | 1585 | } else { |
| 1567 | const callee = try f.resolveInst(pl_op.operand); | 1586 | const callee = try f.resolveInst(pl_op.operand); |
| 1568 | try f.writeCValue(writer, callee); | 1587 | try f.writeCValue(writer, callee); |