Commit 9360e5887c
src/link/C.zig
@@ -8,10 +8,9 @@ const fs = std.fs;
const codegen = @import("../codegen/c.zig");
const link = @import("../link.zig");
const trace = @import("../tracy.zig").trace;
-const File = link.File;
const C = @This();
-pub const base_tag: File.Tag = .c;
+pub const base_tag: link.File.Tag = .c;
pub const Header = struct {
buf: std.ArrayList(u8),
@@ -40,13 +39,16 @@ pub const Header = struct {
}
};
-base: File,
+base: link.File,
+path: []const u8,
+
+// These are only valid during a flush()!
header: Header,
constants: std.ArrayList(u8),
main: std.ArrayList(u8),
-
called: std.StringHashMap(void),
+
error_msg: *Compilation.ErrorMsg = undefined,
pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*C {
@@ -55,9 +57,6 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
if (options.use_llvm) return error.LLVMHasNoCBackend;
if (options.use_lld) return error.LLDHasNoCBackend;
- const file = try options.emit.?.directory.handle.createFile(sub_path, .{ .truncate = true, .read = true, .mode = link.determineMode(options) });
- errdefer file.close();
-
var c_file = try allocator.create(C);
errdefer allocator.destroy(c_file);
@@ -65,13 +64,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
.base = .{
.tag = .c,
.options = options,
- .file = file,
+ .file = null,
.allocator = allocator,
},
- .main = std.ArrayList(u8).init(allocator),
- .header = Header.init(allocator, null),
- .constants = std.ArrayList(u8).init(allocator),
- .called = std.StringHashMap(void).init(allocator),
+ .main = undefined,
+ .header = undefined,
+ .constants = undefined,
+ .called = undefined,
+ .path = sub_path,
};
return c_file;
@@ -82,21 +82,7 @@ pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) er
return error.AnalysisFail;
}
-pub fn deinit(self: *C) void {
- self.main.deinit();
- self.header.deinit();
- self.constants.deinit();
- self.called.deinit();
-}
-
-pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
- codegen.generate(self, module, decl) catch |err| {
- if (err == error.AnalysisFail) {
- try module.failed_decls.put(module.gpa, decl, self.error_msg);
- }
- return err;
- };
-}
+pub fn deinit(self: *C) void {}
pub fn flush(self: *C, comp: *Compilation) !void {
return self.flushModule(comp);
@@ -106,7 +92,29 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
const tracy = trace(@src());
defer tracy.end();
- const writer = self.base.file.?.writer();
+ self.main = std.ArrayList(u8).init(self.base.allocator);
+ self.header = Header.init(self.base.allocator, null);
+ self.constants = std.ArrayList(u8).init(self.base.allocator);
+ self.called = std.StringHashMap(void).init(self.base.allocator);
+ defer self.main.deinit();
+ defer self.header.deinit();
+ defer self.constants.deinit();
+ defer self.called.deinit();
+
+ const module = self.base.options.module.?;
+ for (self.base.options.module.?.decl_table.entries.items) |kv| {
+ codegen.generate(self, module, kv.value) catch |err| {
+ if (err == error.AnalysisFail) {
+ try module.failed_decls.put(module.gpa, kv.value, self.error_msg);
+ }
+ return err;
+ };
+ }
+
+ const file = try self.base.options.emit.?.directory.handle.createFile(self.path, .{ .truncate = true, .read = true, .mode = link.determineMode(self.base.options) });
+ defer file.close();
+
+ const writer = file.writer();
try self.header.flush(writer);
if (self.header.buf.items.len > 0) {
try writer.writeByte('\n');
@@ -121,6 +129,4 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
}
}
try writer.writeAll(self.main.items);
- self.base.file.?.close();
- self.base.file = null;
}
src/link.zig
@@ -291,7 +291,7 @@ pub const File = struct {
.coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl),
.elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl),
.macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl),
- .c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl),
+ .c => {},
.wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl),
}
}
@@ -412,7 +412,7 @@ pub const File = struct {
.coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl),
.elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl),
.macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl),
- .c => unreachable,
+ .c => {},
.wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl),
}
}
test/stage2/cbe.zig
@@ -24,13 +24,13 @@ pub fn addCases(ctx: *TestContext) !void {
// Now change the message only
// TODO fix C backend not supporting updates
// https://github.com/ziglang/zig/issues/7589
- //case.addCompareOutput(
- // \\extern fn puts(s: [*:0]const u8) c_int;
- // \\export fn main() c_int {
- // \\ _ = puts("yo");
- // \\ return 0;
- // \\}
- //, "yo" ++ std.cstr.line_sep);
+ case.addCompareOutput(
+ \\extern fn puts(s: [*:0]const u8) c_int;
+ \\export fn main() c_int {
+ \\ _ = puts("yo");
+ \\ return 0;
+ \\}
+ , "yo" ++ std.cstr.line_sep);
}
{
@@ -111,15 +111,15 @@ pub fn addCases(ctx: *TestContext) !void {
,
\\static zig_noreturn void main(void);
\\
- \\zig_noreturn void _start(void) {
- \\ main();
- \\}
- \\
\\static zig_noreturn void main(void) {
\\ zig_breakpoint();
\\ zig_unreachable();
\\}
\\
+ \\zig_noreturn void _start(void) {
+ \\ main();
+ \\}
+ \\
);
// TODO: implement return values
// TODO: figure out a way to prevent asm constants from being generated
@@ -143,10 +143,6 @@ pub fn addCases(ctx: *TestContext) !void {
\\static uint8_t exitGood__anon_1[6] = "{rdi}";
\\static uint8_t exitGood__anon_2[8] = "syscall";
\\
- \\zig_noreturn void _start(void) {
- \\ exitGood();
- \\}
- \\
\\static zig_noreturn void exitGood(void) {
\\ register uintptr_t rax_constant __asm__("rax") = 231;
\\ register uintptr_t rdi_constant __asm__("rdi") = 0;
@@ -155,6 +151,10 @@ pub fn addCases(ctx: *TestContext) !void {
\\ zig_unreachable();
\\}
\\
+ \\zig_noreturn void _start(void) {
+ \\ exitGood();
+ \\}
+ \\
);
ctx.c("exit with parameter", linux_x64,
\\export fn _start() noreturn {