aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2022-12-03 03:39:28 -0500
committerJacob Young <jacobly0@users.noreply.github.com>2022-12-03 08:21:03 -0500
commit81c271cc6298bf164b202a194ef18b56665ce2d9 (patch)
treeb5f6c7e64853d3cd7c1e1297e8b74fe61b5549d4 /src
parent2cfc08ba0d5ad2f0f4cef71ad4365dfd0e71b9bd (diff)
downloadzig-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.zig13
-rw-r--r--src/link/C.zig26
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 {