aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/c.zig')
-rw-r--r--src/codegen/c.zig56
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 {