diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2022-12-03 03:39:28 -0500 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2022-12-03 08:21:03 -0500 |
| commit | 81c271cc6298bf164b202a194ef18b56665ce2d9 (patch) | |
| tree | b5f6c7e64853d3cd7c1e1297e8b74fe61b5549d4 /src | |
| parent | 2cfc08ba0d5ad2f0f4cef71ad4365dfd0e71b9bd (diff) | |
| download | zig-81c271cc6298bf164b202a194ef18b56665ce2d9.tar.gz zig-81c271cc6298bf164b202a194ef18b56665ce2d9.zip | |
cbe: don't emit extern decls that are already exported
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/c.zig | 13 | ||||
| -rw-r--r-- | src/link/C.zig | 26 |
2 files changed, 27 insertions, 12 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index ef125c6aee..48719d6efe 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2427,11 +2427,15 @@ pub fn genFunc(f: *Function) !void { defer tracy.end(); const o = &f.object; + const tv: TypedValue = .{ + .ty = o.dg.decl.ty, + .val = o.dg.decl.val, + }; o.code_header = std.ArrayList(u8).init(f.object.dg.gpa); defer o.code_header.deinit(); - const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl); + const is_global = o.dg.declIsGlobal(tv); const fwd_decl_writer = o.dg.fwd_decl.writer(); try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); @@ -2478,14 +2482,11 @@ pub fn genDecl(o: *Object) !void { 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; const fwd_decl_writer = o.dg.fwd_decl.writer(); - const decl_c_value: CValue = if (is_global) .{ - .bytes = mem.span(o.dg.decl.name), - } else .{ - .decl = o.dg.decl_index, - }; + const decl_c_value = CValue{ .decl = o.dg.decl_index }; try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); diff --git a/src/link/C.zig b/src/link/C.zig index 4af69e6fcf..a2d7ee143c 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -290,9 +290,17 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) f.remaining_decls.putAssumeCapacityNoClobber(decl_index, {}); } - while (f.remaining_decls.popOrNull()) |kv| { - const decl_index = kv.key; - try self.flushDecl(&f, decl_index); + { + var export_names = std.StringHashMapUnmanaged(void){}; + defer export_names.deinit(gpa); + try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len)); + for (module.decl_exports.values()) |exports| for (exports.items) |@"export"| + try export_names.put(gpa, @"export".options.name, {}); + + while (f.remaining_decls.popOrNull()) |kv| { + const decl_index = kv.key; + try self.flushDecl(&f, decl_index, export_names); + } } f.all_buffers.items[typedef_index] = .{ @@ -415,7 +423,12 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void { } /// Assumes `decl` was in the `remaining_decls` set, and has already been removed. -fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void { +fn flushDecl( + self: *C, + f: *Flush, + decl_index: Module.Decl.Index, + export_names: std.StringHashMapUnmanaged(void), +) FlushDeclError!void { const module = self.base.options.module.?; const decl = module.declPtr(decl_index); // Before flushing any particular Decl we must ensure its @@ -423,7 +436,7 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError! // file comes out correctly. for (decl.dependencies.keys()) |dep| { if (f.remaining_decls.swapRemove(dep)) { - try flushDecl(self, f, dep); + try flushDecl(self, f, dep, export_names); } } @@ -432,7 +445,8 @@ 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.isExtern() and export_names.contains(mem.span(decl.name)))) + f.appendBufAssumeCapacity(decl_block.fwd_decl.items); } pub fn flushEmitH(module: *Module) !void { |
