aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-01-06 16:47:09 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-01-06 16:47:09 -0700
commitefe94a9a1289db274be326d6d66a19caeee86d33 (patch)
tree95dd2f96a79284df771dad7746790daa4bc810be
parent91e3431d4a55aa46884b267be5aa586f3ed94f74 (diff)
downloadzig-efe94a9a1289db274be326d6d66a19caeee86d33.tar.gz
zig-efe94a9a1289db274be326d6d66a19caeee86d33.zip
stage2: C backend: support unused Decls
-rw-r--r--src/Compilation.zig4
-rw-r--r--src/link/C.zig54
-rw-r--r--test/stage2/cbe.zig10
3 files changed, 46 insertions, 22 deletions
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);
}
{