diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-10-25 10:07:41 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-10-25 19:57:02 -0700 |
| commit | 51f7e5412afd4e934da8a5e93ad91e6de5ae02ca (patch) | |
| tree | 6c1a5e1ce641ab69d093cef46887d2c11b543c84 /src | |
| parent | 405ba2680f180541cb91323fad579e2ca5cf5eb0 (diff) | |
| download | zig-51f7e5412afd4e934da8a5e93ad91e6de5ae02ca.tar.gz zig-51f7e5412afd4e934da8a5e93ad91e6de5ae02ca.zip | |
cbe: update `DeclGen.decl_index` to support anon decls
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 2 | ||||
| -rw-r--r-- | src/codegen/c.zig | 110 | ||||
| -rw-r--r-- | src/link/C.zig | 26 |
3 files changed, 68 insertions, 70 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 30dbfe9ce1..efc95bfe25 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3556,7 +3556,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v .gpa = gpa, .module = module, .error_msg = null, - .decl_index = decl_index.toOptional(), + .pass = .{ .decl = decl_index }, .is_naked_fn = false, .fwd_decl = fwd_decl.toManaged(gpa), .ctypes = .{}, diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 4a9258d155..061b574afc 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -522,7 +522,7 @@ pub const Object = struct { pub const DeclGen = struct { gpa: mem.Allocator, module: *Module, - decl_index: Decl.OptionalIndex, + pass: Pass, is_naked_fn: bool, /// This is a borrowed reference from `link.C`. fwd_decl: std.ArrayList(u8), @@ -533,10 +533,16 @@ pub const DeclGen = struct { anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock), aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment), + pub const Pass = union(enum) { + decl: Decl.Index, + anon: InternPool.Index, + flush, + }; + fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { @setCold(true); const mod = dg.module; - const decl_index = dg.decl_index.unwrap().?; + const decl_index = dg.pass.decl; const decl = mod.declPtr(decl_index); const src = LazySrcLoc.nodeOffset(0); const src_loc = src.toSrcLoc(decl, mod); @@ -1566,18 +1572,11 @@ pub const DeclGen = struct { else => unreachable, } } - if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) try w.writeAll("zig_cold "); + if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) + try w.writeAll("zig_cold "); if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn "); - const trailing = try renderTypePrefix( - dg.decl_index, - store.*, - mod, - w, - fn_cty_idx, - .suffix, - .{}, - ); + const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{}); try w.print("{}", .{trailing}); if (toCallingConvention(fn_info.cc)) |call_conv| { @@ -1597,7 +1596,7 @@ pub const DeclGen = struct { } try renderTypeSuffix( - dg.decl_index, + dg.pass, store.*, mod, w, @@ -1652,8 +1651,8 @@ pub const DeclGen = struct { fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void { const store = &dg.ctypes.set; const mod = dg.module; - _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{}); - try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{}); + _ = try renderTypePrefix(dg.pass, store.*, mod, w, idx, .suffix, .{}); + try renderTypeSuffix(dg.pass, store.*, mod, w, idx, .suffix, .{}); } const IntCastContext = union(enum) { @@ -1799,11 +1798,10 @@ pub const DeclGen = struct { .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}), } - const trailing = - try renderTypePrefix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, qualifiers); + const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, cty_idx, .suffix, qualifiers); try w.print("{}", .{trailing}); try dg.writeCValue(w, name); - try renderTypeSuffix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, .{}); + try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{}); } fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { @@ -2070,7 +2068,7 @@ fn renderTypeName( } } fn renderTypePrefix( - decl: Decl.OptionalIndex, + pass: DeclGen.Pass, store: CType.Store.Set, mod: *Module, w: anytype, @@ -2128,7 +2126,7 @@ fn renderTypePrefix( => |tag| { const child_idx = cty.cast(CType.Payload.Child).?.data; const child_trailing = try renderTypePrefix( - decl, + pass, store, mod, w, @@ -2152,15 +2150,8 @@ fn renderTypePrefix( .vector, => { const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type; - const child_trailing = try renderTypePrefix( - decl, - store, - mod, - w, - child_idx, - .suffix, - qualifiers, - ); + const child_trailing = + try renderTypePrefix(pass, store, mod, w, child_idx, .suffix, qualifiers); switch (parent_fix) { .prefix => { try w.print("{}(", .{child_trailing}); @@ -2172,10 +2163,11 @@ fn renderTypePrefix( .fwd_anon_struct, .fwd_anon_union, - => if (decl.unwrap()) |decl_index| - try w.print("anon__{d}_{d}", .{ @intFromEnum(decl_index), idx }) - else - try renderTypeName(mod, w, idx, cty, ""), + => switch (pass) { + .decl => |decl_index| try w.print("decl__{d}_{d}", .{ @intFromEnum(decl_index), idx }), + .anon => |anon_decl| try w.print("anon__{d}_{d}", .{ @intFromEnum(anon_decl), idx }), + .flush => try renderTypeName(mod, w, idx, cty, ""), + }, .fwd_struct, .fwd_union, @@ -2201,7 +2193,7 @@ fn renderTypePrefix( .packed_struct, .packed_union, => return renderTypePrefix( - decl, + pass, store, mod, w, @@ -2214,7 +2206,7 @@ fn renderTypePrefix( .varargs_function, => { const child_trailing = try renderTypePrefix( - decl, + pass, store, mod, w, @@ -2241,7 +2233,7 @@ fn renderTypePrefix( return trailing; } fn renderTypeSuffix( - decl: Decl.OptionalIndex, + pass: DeclGen.Pass, store: CType.Store.Set, mod: *Module, w: anytype, @@ -2295,7 +2287,7 @@ fn renderTypeSuffix( .pointer_volatile, .pointer_const_volatile, => try renderTypeSuffix( - decl, + pass, store, mod, w, @@ -2314,7 +2306,7 @@ fn renderTypeSuffix( try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len}); try renderTypeSuffix( - decl, + pass, store, mod, w, @@ -2356,9 +2348,9 @@ fn renderTypeSuffix( if (need_comma) try w.writeAll(", "); need_comma = true; const trailing = - try renderTypePrefix(decl, store, mod, w, param_type, .suffix, qualifiers); + try renderTypePrefix(pass, store, mod, w, param_type, .suffix, qualifiers); if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_i }); - try renderTypeSuffix(decl, store, mod, w, param_type, .suffix, .{}); + try renderTypeSuffix(pass, store, mod, w, param_type, .suffix, .{}); } switch (tag) { .function => {}, @@ -2372,7 +2364,7 @@ fn renderTypeSuffix( if (!need_comma) try w.writeAll("void"); try w.writeByte(')'); - try renderTypeSuffix(decl, store, mod, w, data.return_type, .suffix, .{}); + try renderTypeSuffix(pass, store, mod, w, data.return_type, .suffix, .{}); }, } } @@ -2392,9 +2384,9 @@ fn renderAggregateFields( .eq => {}, .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}), } - const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{}); + const trailing = try renderTypePrefix(.flush, store, mod, writer, field.type, .suffix, .{}); try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) }); - try renderTypeSuffix(.none, store, mod, writer, field.type, .suffix, .{}); + try renderTypeSuffix(.flush, store, mod, writer, field.type, .suffix, .{}); try writer.writeAll(";\n"); } try writer.writeByteNTimes(' ', indent); @@ -2406,18 +2398,18 @@ pub fn genTypeDecl( writer: anytype, global_store: CType.Store.Set, global_idx: CType.Index, - decl: Decl.OptionalIndex, + pass: DeclGen.Pass, decl_store: CType.Store.Set, decl_idx: CType.Index, found_existing: bool, ) !void { const global_cty = global_store.indexToCType(global_idx); switch (global_cty.tag()) { - .fwd_anon_struct => if (decl != .none) { + .fwd_anon_struct => if (pass != .flush) { try writer.writeAll("typedef "); - _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{}); + _ = try renderTypePrefix(.flush, global_store, mod, writer, global_idx, .suffix, .{}); try writer.writeByte(' '); - _ = try renderTypePrefix(decl, decl_store, mod, writer, decl_idx, .suffix, .{}); + _ = try renderTypePrefix(pass, decl_store, mod, writer, decl_idx, .suffix, .{}); try writer.writeAll(";\n"); }, @@ -2435,7 +2427,15 @@ pub fn genTypeDecl( .fwd_union, => { const owner_decl = global_cty.cast(CType.Payload.FwdDecl).?.data; - _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{}); + _ = try renderTypePrefix( + .flush, + global_store, + mod, + writer, + global_idx, + .suffix, + .{}, + ); try writer.writeAll("; // "); try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer); try writer.writeByte('\n'); @@ -2552,7 +2552,7 @@ fn genExports(o: *Object) !void { const mod = o.dg.module; const ip = &mod.intern_pool; - const decl_index = o.dg.decl_index.unwrap().?; + const decl_index = o.dg.pass.decl; const decl = mod.declPtr(decl_index); const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() }; const fwd = o.dg.fwd_decl.writer(); @@ -2692,7 +2692,7 @@ pub fn genFunc(f: *Function) !void { const o = &f.object; const mod = o.dg.module; const gpa = o.dg.gpa; - const decl_index = o.dg.decl_index.unwrap().?; + const decl_index = o.dg.pass.decl; const decl = mod.declPtr(decl_index); const tv: TypedValue = .{ .ty = decl.ty, @@ -2779,7 +2779,7 @@ pub fn genDecl(o: *Object) !void { defer tracy.end(); const mod = o.dg.module; - const decl_index = o.dg.decl_index.unwrap().?; + const decl_index = o.dg.pass.decl; const decl = mod.declPtr(decl_index); const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() }; @@ -2825,13 +2825,13 @@ pub fn genDeclValue( alignment: Alignment, link_section: InternPool.OptionalNullTerminatedString, ) !void { + const mod = o.dg.module; const fwd_decl_writer = o.dg.fwd_decl.writer(); try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); try fwd_decl_writer.writeAll(";\n"); - const mod = o.dg.module; const w = o.writer(); if (!is_global) try w.writeAll("static "); if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s| @@ -2848,7 +2848,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { defer tracy.end(); const mod = dg.module; - const decl_index = dg.decl_index.unwrap().?; + const decl_index = dg.pass.decl; const decl = mod.declPtr(decl_index); const tv: TypedValue = .{ .ty = decl.ty, @@ -2861,7 +2861,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { const is_global = dg.declIsGlobal(tv); if (is_global) { try writer.writeAll("zig_extern "); - try dg.renderFunctionSignature(writer, dg.decl_index.unwrap().?, .complete, .{ .export_index = 0 }); + try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 }); try dg.fwd_decl.appendSlice(";\n"); } }, @@ -7279,7 +7279,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue { const mod = f.object.dg.module; const inst_ty = f.typeOfIndex(inst); - const decl_index = f.object.dg.decl_index.unwrap().?; + const decl_index = f.object.dg.pass.decl; const decl = mod.declPtr(decl_index); const fn_cty = try f.typeToCType(decl.ty, .complete); const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len; diff --git a/src/link/C.zig b/src/link/C.zig index 1d5672cf11..ee1d437b00 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -158,9 +158,7 @@ pub fn updateFunc( const decl_index = func.owner_decl; const decl = module.declPtr(decl_index); const gop = try self.decl_table.getOrPut(gpa, decl_index); - if (!gop.found_existing) { - gop.value_ptr.* = .{}; - } + if (!gop.found_existing) gop.value_ptr.* = .{}; const ctypes = &gop.value_ptr.ctypes; const lazy_fns = &gop.value_ptr.lazy_fns; const fwd_decl = &self.fwd_decl_buf; @@ -180,7 +178,7 @@ pub fn updateFunc( .gpa = gpa, .module = module, .error_msg = null, - .decl_index = decl_index.toOptional(), + .pass = .{ .decl = decl_index }, .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked, .fwd_decl = fwd_decl.toManaged(gpa), .ctypes = ctypes.*, @@ -235,7 +233,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void { .gpa = gpa, .module = module, .error_msg = null, - .decl_index = .none, + .pass = .{ .anon = anon_decl }, .is_naked_fn = false, .fwd_decl = fwd_decl.toManaged(gpa), .ctypes = .{}, @@ -302,7 +300,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi .gpa = gpa, .module = module, .error_msg = null, - .decl_index = decl_index.toOptional(), + .pass = .{ .decl = decl_index }, .is_naked_fn = false, .fwd_decl = fwd_decl.toManaged(gpa), .ctypes = ctypes.*, @@ -438,14 +436,14 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes. // This ensures that every lazy CType.Index exactly matches the global CType.Index. assert(f.ctypes.count() == 0); - try self.flushCTypes(&f, .none, f.lazy_ctypes); + try self.flushCTypes(&f, .flush, f.lazy_ctypes); - for (self.anon_decls.values()) |decl_block| { - try self.flushCTypes(&f, .none, decl_block.ctypes); + for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| { + try self.flushCTypes(&f, .{ .anon = anon_decl }, decl_block.ctypes); } for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| { - try self.flushCTypes(&f, decl_index.toOptional(), decl_block.ctypes); + try self.flushCTypes(&f, .{ .decl = decl_index }, decl_block.ctypes); } } @@ -516,7 +514,7 @@ const FlushDeclError = error{ fn flushCTypes( self: *C, f: *Flush, - decl_index: Module.Decl.OptionalIndex, + pass: codegen.DeclGen.Pass, decl_ctypes: codegen.CType.Store, ) FlushDeclError!void { const gpa = self.base.allocator; @@ -591,7 +589,7 @@ fn flushCTypes( writer, global_ctypes.set, global_idx, - decl_index, + pass, decl_ctypes.set, decl_idx, gop.found_existing, @@ -610,7 +608,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void { .gpa = gpa, .module = self.base.options.module.?, .error_msg = null, - .decl_index = .none, + .pass = .flush, .is_naked_fn = false, .fwd_decl = fwd_decl.toManaged(gpa), .ctypes = ctypes.*, @@ -652,7 +650,7 @@ fn flushLazyFn( .gpa = gpa, .module = self.base.options.module.?, .error_msg = null, - .decl_index = .none, + .pass = .flush, .is_naked_fn = false, .fwd_decl = fwd_decl.toManaged(gpa), .ctypes = ctypes.*, |
