From 65a48df5324278c3d876e168b523894c8662e546 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sun, 23 Oct 2022 08:12:10 -0400 Subject: [PATCH] cbe: fix globals that reference functions Global constant initializers can reference functions, so forward declare the constants and initialize them later with the function definitions, which guarantees that they appear after all declarations. --- src/codegen/c.zig | 20 +++++++++++--------- src/link/C.zig | 14 ++++---------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index c12b028d0c9059c6d61f04011a0ecd91b0b863bd..5f62b93922d9e5a451b412427c9f3e0c93edf529 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2027,10 +2027,10 @@ pub fn genDecl(o: *Object) !void { .val = o.dg.decl.val, }; if (tv.val.tag() == .extern_fn) { - const writer = o.writer(); - try writer.writeAll("ZIG_EXTERN_C "); - try o.dg.renderFunctionSignature(writer, .Forward); - try writer.writeAll(";\n"); + const fwd_decl_writer = o.dg.fwd_decl.writer(); + try fwd_decl_writer.writeAll("ZIG_EXTERN_C "); + try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); + try fwd_decl_writer.writeAll(";\n"); } else if (tv.val.castTag(.variable)) |var_payload| { const variable: *Module.Var = var_payload.data; const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; @@ -2055,7 +2055,6 @@ pub fn genDecl(o: *Object) !void { return; } - try o.indent_writer.insertNewline(); const w = o.writer(); try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); try w.writeAll(" = "); @@ -2065,15 +2064,18 @@ pub fn genDecl(o: *Object) !void { try w.writeByte(';'); try o.indent_writer.insertNewline(); } else { + const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; + + const fwd_decl_writer = o.dg.fwd_decl.writer(); + try fwd_decl_writer.writeAll("static "); + try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); + try fwd_decl_writer.writeAll(";\n"); + const writer = o.writer(); try writer.writeAll("static "); - // TODO ask the Decl if it is const // https://github.com/ziglang/zig/issues/7582 - - const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); - try writer.writeAll(" = "); try o.dg.renderValue(writer, tv.ty, tv.val, .Initializer); try writer.writeAll(";\n"); diff --git a/src/link/C.zig b/src/link/C.zig index 8509e4ae8a378e837635758439b0c791aed99862..a52ac63df5c5e084ea6ebd8791db733f3029960b 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -301,11 +301,10 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) }; f.file_size += f.typedef_buf.items.len; - // Now the function bodies. - try f.all_buffers.ensureUnusedCapacity(gpa, f.fn_count); - for (decl_keys) |decl_index, i| - if (module.declPtr(decl_index).getFunction() != null) - f.appendBufAssumeCapacity(decl_values[i].code.items); + // Now the code. + try f.all_buffers.ensureUnusedCapacity(gpa, decl_values.len); + for (decl_values) |decl| + f.appendBufAssumeCapacity(decl.code.items); const file = self.base.file.?; try file.setEndPos(f.file_size); @@ -322,7 +321,6 @@ const Flush = struct { all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{}, /// Keeps track of the total bytes of `all_buffers`. file_size: u64 = 0, - fn_count: usize = 0, const Typedefs = std.HashMapUnmanaged( Type, @@ -435,10 +433,6 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError! try self.flushTypedefs(f, decl_block.typedefs); try f.all_buffers.ensureUnusedCapacity(gpa, 2); f.appendBufAssumeCapacity(decl_block.fwd_decl.items); - if (decl.getFunction()) |_| - f.fn_count += 1 - else - f.appendBufAssumeCapacity(decl_block.code.items); } pub fn flushEmitH(module: *Module) !void { -- 2.54.0