authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-06 16:47:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-06 16:47:09-07:00
logefe94a9a1289db274be326d6d66a19caeee86d33
tree95dd2f96a79284df771dad7746790daa4bc810be
parent91e3431d4a55aa46884b267be5aa586f3ed94f74

stage2: C backend: support unused Decls


3 files changed, 46 insertions(+), 22 deletions(-)

src/Compilation.zig+4
......@@ -527,6 +527,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
527527 if (options.root_pkg == null)
528528 break :blk false;
529529
530 // If we are outputting .c code we must use Zig backend.
531 if (ofmt == .c)
532 break :blk false;
533
530534 // If we are the stage1 compiler, we depend on the stage1 c++ llvm backend
531535 // to compile zig code.
532536 if (build_options.is_stage1)
src/link/C.zig+32-22
......@@ -151,36 +151,46 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
151151 var fn_count: usize = 0;
152152
153153 // Forward decls and non-functions first.
154 // TODO: performance investigation: would keeping a list of Decls that we should
155 // generate, rather than querying here, be faster?
154156 for (module.decl_table.items()) |kv| {
155157 const decl = kv.value;
156 const decl_tv = decl.typed_value.most_recent.typed_value;
157 const buf = buf: {
158 if (decl_tv.val.castTag(.function)) |_| {
159 fn_count += 1;
160 break :buf decl.fn_link.c.fwd_decl.items;
161 } else {
162 break :buf decl.link.c.code.items;
163 }
164 };
165 all_buffers.appendAssumeCapacity(.{
166 .iov_base = buf.ptr,
167 .iov_len = buf.len,
168 });
169 file_size += buf.len;
158 switch (decl.typed_value) {
159 .most_recent => |tvm| {
160 const buf = buf: {
161 if (tvm.typed_value.val.castTag(.function)) |_| {
162 fn_count += 1;
163 break :buf decl.fn_link.c.fwd_decl.items;
164 } else {
165 break :buf decl.link.c.code.items;
166 }
167 };
168 all_buffers.appendAssumeCapacity(.{
169 .iov_base = buf.ptr,
170 .iov_len = buf.len,
171 });
172 file_size += buf.len;
173 },
174 .never_succeeded => continue,
175 }
170176 }
171177
172178 // Now the function bodies.
173179 try all_buffers.ensureCapacity(all_buffers.items.len + fn_count);
174180 for (module.decl_table.items()) |kv| {
175181 const decl = kv.value;
176 const decl_tv = decl.typed_value.most_recent.typed_value;
177 if (decl_tv.val.castTag(.function)) |_| {
178 const buf = decl.link.c.code.items;
179 all_buffers.appendAssumeCapacity(.{
180 .iov_base = buf.ptr,
181 .iov_len = buf.len,
182 });
183 file_size += buf.len;
182 switch (decl.typed_value) {
183 .most_recent => |tvm| {
184 if (tvm.typed_value.val.castTag(.function)) |_| {
185 const buf = decl.link.c.code.items;
186 all_buffers.appendAssumeCapacity(.{
187 .iov_base = buf.ptr,
188 .iov_len = buf.len,
189 });
190 file_size += buf.len;
191 }
192 },
193 .never_succeeded => continue,
184194 }
185195 }
186196
test/stage2/cbe.zig+10
......@@ -29,6 +29,16 @@ pub fn addCases(ctx: *TestContext) !void {
2929 \\ return 0;
3030 \\}
3131 , "yo" ++ std.cstr.line_sep);
32
33 // Add an unused Decl
34 case.addCompareOutput(
35 \\extern fn puts(s: [*:0]const u8) c_int;
36 \\export fn main() c_int {
37 \\ _ = puts("yo!");
38 \\ return 0;
39 \\}
40 \\fn unused() void {}
41 , "yo!" ++ std.cstr.line_sep);
3242 }
3343
3444 {