| author | |
| committer | |
| log | 81c271cc6298bf164b202a194ef18b56665ce2d9 |
| tree | b5f6c7e64853d3cd7c1e1297e8b74fe61b5549d4 |
| parent | 2cfc08ba0d5ad2f0f4cef71ad4365dfd0e71b9bd |
4 files changed, 27 insertions(+), 14 deletions(-)
src/codegen/c.zig+7-6| ... | ... | @@ -2427,11 +2427,15 @@ pub fn genFunc(f: *Function) !void { |
| 2427 | 2427 | defer tracy.end(); |
| 2428 | 2428 | |
| 2429 | 2429 | const o = &f.object; |
| 2430 | const tv: TypedValue = .{ | |
| 2431 | .ty = o.dg.decl.ty, | |
| 2432 | .val = o.dg.decl.val, | |
| 2433 | }; | |
| 2430 | 2434 | |
| 2431 | 2435 | o.code_header = std.ArrayList(u8).init(f.object.dg.gpa); |
| 2432 | 2436 | defer o.code_header.deinit(); |
| 2433 | 2437 | |
| 2434 | const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl); | |
| 2438 | const is_global = o.dg.declIsGlobal(tv); | |
| 2435 | 2439 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 2436 | 2440 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2437 | 2441 | try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); |
| ... | ... | @@ -2478,14 +2482,11 @@ pub fn genDecl(o: *Object) !void { |
| 2478 | 2482 | try fwd_decl_writer.writeAll(";\n"); |
| 2479 | 2483 | } else if (tv.val.castTag(.variable)) |var_payload| { |
| 2480 | 2484 | const variable: *Module.Var = var_payload.data; |
| 2485 | ||
| 2481 | 2486 | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; |
| 2482 | 2487 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 2483 | 2488 | |
| 2484 | const decl_c_value: CValue = if (is_global) .{ | |
| 2485 | .bytes = mem.span(o.dg.decl.name), | |
| 2486 | } else .{ | |
| 2487 | .decl = o.dg.decl_index, | |
| 2488 | }; | |
| 2489 | const decl_c_value = CValue{ .decl = o.dg.decl_index }; | |
| 2489 | 2490 | |
| 2490 | 2491 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2491 | 2492 | if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal "); |
src/link/C.zig+20-6| ... | ... | @@ -290,9 +290,17 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) |
| 290 | 290 | f.remaining_decls.putAssumeCapacityNoClobber(decl_index, {}); |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | while (f.remaining_decls.popOrNull()) |kv| { | |
| 294 | const decl_index = kv.key; | |
| 295 | try self.flushDecl(&f, decl_index); | |
| 293 | { | |
| 294 | var export_names = std.StringHashMapUnmanaged(void){}; | |
| 295 | defer export_names.deinit(gpa); | |
| 296 | try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len)); | |
| 297 | for (module.decl_exports.values()) |exports| for (exports.items) |@"export"| | |
| 298 | try export_names.put(gpa, @"export".options.name, {}); | |
| 299 | ||
| 300 | while (f.remaining_decls.popOrNull()) |kv| { | |
| 301 | const decl_index = kv.key; | |
| 302 | try self.flushDecl(&f, decl_index, export_names); | |
| 303 | } | |
| 296 | 304 | } |
| 297 | 305 | |
| 298 | 306 | f.all_buffers.items[typedef_index] = .{ |
| ... | ... | @@ -415,7 +423,12 @@ fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void { |
| 415 | 423 | } |
| 416 | 424 | |
| 417 | 425 | /// Assumes `decl` was in the `remaining_decls` set, and has already been removed. |
| 418 | fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void { | |
| 426 | fn flushDecl( | |
| 427 | self: *C, | |
| 428 | f: *Flush, | |
| 429 | decl_index: Module.Decl.Index, | |
| 430 | export_names: std.StringHashMapUnmanaged(void), | |
| 431 | ) FlushDeclError!void { | |
| 419 | 432 | const module = self.base.options.module.?; |
| 420 | 433 | const decl = module.declPtr(decl_index); |
| 421 | 434 | // 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! |
| 423 | 436 | // file comes out correctly. |
| 424 | 437 | for (decl.dependencies.keys()) |dep| { |
| 425 | 438 | if (f.remaining_decls.swapRemove(dep)) { |
| 426 | try flushDecl(self, f, dep); | |
| 439 | try flushDecl(self, f, dep, export_names); | |
| 427 | 440 | } |
| 428 | 441 | } |
| 429 | 442 | |
| ... | ... | @@ -432,7 +445,8 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError! |
| 432 | 445 | |
| 433 | 446 | try self.flushTypedefs(f, decl_block.typedefs); |
| 434 | 447 | try f.all_buffers.ensureUnusedCapacity(gpa, 2); |
| 435 | f.appendBufAssumeCapacity(decl_block.fwd_decl.items); | |
| 448 | if (!(decl.isExtern() and export_names.contains(mem.span(decl.name)))) | |
| 449 | f.appendBufAssumeCapacity(decl_block.fwd_decl.items); | |
| 436 | 450 | } |
| 437 | 451 | |
| 438 | 452 | pub fn flushEmitH(module: *Module) !void { |
test/behavior/basic.zig-1| ... | ... | @@ -788,7 +788,6 @@ test "extern variable with non-pointer opaque type" { |
| 788 | 788 | return error.SkipZigTest; |
| 789 | 789 | } |
| 790 | 790 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 791 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 792 | 791 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 793 | 792 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 794 | 793 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/bugs/529.zig-1| ... | ... | @@ -11,7 +11,6 @@ comptime { |
| 11 | 11 | const builtin = @import("builtin"); |
| 12 | 12 | |
| 13 | 13 | test "issue 529 fixed" { |
| 14 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 15 | 14 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 16 | 15 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 17 | 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |