diff options
Diffstat (limited to 'src/codegen/c.zig')
| -rw-r--r-- | src/codegen/c.zig | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 440d838f91..3278ed89b0 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -530,7 +530,7 @@ pub const DeclGen = struct { ctypes: CType.Store, /// Keeps track of anonymous decls that need to be rendered before this /// (named) Decl in the output C code. - anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, void), + anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock), fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { @setCold(true); @@ -586,12 +586,13 @@ pub const DeclGen = struct { try dg.renderType(writer, ty); try writer.writeByte(')'); } - try writer.print("&__anon_{d}", .{@intFromEnum(decl_val)}); + try writer.writeByte('&'); + try renderAnonDeclName(writer, decl_val); if (need_typecast) try writer.writeByte(')'); // Indicate that the anon decl should be rendered to the output so that // our reference above is not undefined. - try dg.anon_decl_deps.put(dg.gpa, decl_val, {}); + _ = try dg.anon_decl_deps.getOrPut(dg.gpa, decl_val); } fn renderDeclValue( @@ -1806,7 +1807,7 @@ pub const DeclGen = struct { .none => unreachable, .local, .new_local => |i| return w.print("t{d}", .{i}), .local_ref => |i| return w.print("&t{d}", .{i}), - .constant => unreachable, + .constant => |val| return renderAnonDeclName(w, val), .arg => |i| return w.print("a{d}", .{i}), .arg_array => |i| return dg.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }), .field => |i| return w.print("f{d}", .{i}), @@ -1924,6 +1925,10 @@ pub const DeclGen = struct { } } + fn renderAnonDeclName(writer: anytype, anon_decl_val: InternPool.Index) !void { + return writer.print("__anon_{d}", .{@intFromEnum(anon_decl_val)}); + } + fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void { try dg.renderCTypeForBuiltinFnName(writer, try dg.typeToCType(ty, .complete)); } @@ -2761,7 +2766,6 @@ pub fn genDecl(o: *Object) !void { const mod = o.dg.module; const decl_index = o.dg.decl_index.unwrap().?; - const decl_c_value = .{ .decl = decl_index }; const decl = mod.declPtr(decl_index); const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() }; @@ -2785,6 +2789,7 @@ pub fn genDecl(o: *Object) !void { if (variable.is_threadlocal) try w.writeAll("zig_threadlocal "); if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| try w.print("zig_linksection(\"{s}\", ", .{s}); + const decl_c_value = .{ .decl = decl_index }; try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.alignment, .complete); if (decl.@"linksection" != .none) try w.writeAll(", read, write)"); try w.writeAll(" = "); @@ -2793,22 +2798,35 @@ pub fn genDecl(o: *Object) !void { try o.indent_writer.insertNewline(); } else { const is_global = o.dg.module.decl_exports.contains(decl_index); - const fwd_decl_writer = o.dg.fwd_decl.writer(); + const decl_c_value = .{ .decl = decl_index }; + return genDeclValue(o, tv, is_global, decl_c_value, decl.alignment, decl.@"linksection"); + } +} - try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); - try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, decl.alignment, .complete); - try fwd_decl_writer.writeAll(";\n"); +pub fn genDeclValue( + o: *Object, + tv: TypedValue, + is_global: bool, + decl_c_value: CValue, + alignment: Alignment, + link_section: InternPool.OptionalNullTerminatedString, +) !void { + const fwd_decl_writer = o.dg.fwd_decl.writer(); - const w = o.writer(); - if (!is_global) try w.writeAll("static "); - if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| - try w.print("zig_linksection(\"{s}\", ", .{s}); - try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.alignment, .complete); - if (decl.@"linksection" != .none) try w.writeAll(", read)"); - try w.writeAll(" = "); - try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); - try w.writeAll(";\n"); - } + try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); + try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); + try fwd_decl_writer.writeAll(";\n"); + + const mod = o.dg.module; + const w = o.writer(); + if (!is_global) try w.writeAll("static "); + if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| + try w.print("zig_linksection(\"{s}\", ", .{s}); + try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, alignment, .complete); + if (link_section != .none) try w.writeAll(", read)"); + try w.writeAll(" = "); + try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer); + try w.writeAll(";\n"); } pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
