diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2022-10-23 08:12:10 -0400 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2022-10-25 05:11:29 -0400 |
| commit | 65a48df5324278c3d876e168b523894c8662e546 (patch) | |
| tree | c06ab8f0ddf444d82a8fa1524a6c9ac36cb5e1b0 /src | |
| parent | 8b6a3ba74ea50602284543382ff1729a60b75122 (diff) | |
| download | zig-65a48df5324278c3d876e168b523894c8662e546.tar.gz zig-65a48df5324278c3d876e168b523894c8662e546.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/c.zig | 20 | ||||
| -rw-r--r-- | 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 c12b028d0c..5f62b93922 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 8509e4ae8a..a52ac63df5 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 { |
