diff --git a/src/Compilation.zig b/src/Compilation.zig index 4efb845a82..8e2da5aec4 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -527,6 +527,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { if (options.root_pkg == null) break :blk false; + // If we are outputting .c code we must use Zig backend. + if (ofmt == .c) + break :blk false; + // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend // to compile zig code. if (build_options.is_stage1) diff --git a/src/link/C.zig b/src/link/C.zig index 32d859f43e..0ebfe288fc 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -151,36 +151,46 @@ pub fn flushModule(self: *C, comp: *Compilation) !void { var fn_count: usize = 0; // Forward decls and non-functions first. + // TODO: performance investigation: would keeping a list of Decls that we should + // generate, rather than querying here, be faster? for (module.decl_table.items()) |kv| { const decl = kv.value; - const decl_tv = decl.typed_value.most_recent.typed_value; - const buf = buf: { - if (decl_tv.val.castTag(.function)) |_| { - fn_count += 1; - break :buf decl.fn_link.c.fwd_decl.items; - } else { - break :buf decl.link.c.code.items; - } - }; - all_buffers.appendAssumeCapacity(.{ - .iov_base = buf.ptr, - .iov_len = buf.len, - }); - file_size += buf.len; + switch (decl.typed_value) { + .most_recent => |tvm| { + const buf = buf: { + if (tvm.typed_value.val.castTag(.function)) |_| { + fn_count += 1; + break :buf decl.fn_link.c.fwd_decl.items; + } else { + break :buf decl.link.c.code.items; + } + }; + all_buffers.appendAssumeCapacity(.{ + .iov_base = buf.ptr, + .iov_len = buf.len, + }); + file_size += buf.len; + }, + .never_succeeded => continue, + } } // Now the function bodies. try all_buffers.ensureCapacity(all_buffers.items.len + fn_count); for (module.decl_table.items()) |kv| { const decl = kv.value; - const decl_tv = decl.typed_value.most_recent.typed_value; - if (decl_tv.val.castTag(.function)) |_| { - const buf = decl.link.c.code.items; - all_buffers.appendAssumeCapacity(.{ - .iov_base = buf.ptr, - .iov_len = buf.len, - }); - file_size += buf.len; + switch (decl.typed_value) { + .most_recent => |tvm| { + if (tvm.typed_value.val.castTag(.function)) |_| { + const buf = decl.link.c.code.items; + all_buffers.appendAssumeCapacity(.{ + .iov_base = buf.ptr, + .iov_len = buf.len, + }); + file_size += buf.len; + } + }, + .never_succeeded => continue, } } diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig index 9163ac1662..6d4e2062bf 100644 --- a/test/stage2/cbe.zig +++ b/test/stage2/cbe.zig @@ -29,6 +29,16 @@ pub fn addCases(ctx: *TestContext) !void { \\ return 0; \\} , "yo" ++ std.cstr.line_sep); + + // Add an unused Decl + case.addCompareOutput( + \\extern fn puts(s: [*:0]const u8) c_int; + \\export fn main() c_int { + \\ _ = puts("yo!"); + \\ return 0; + \\} + \\fn unused() void {} + , "yo!" ++ std.cstr.line_sep); } {