diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-10-26 03:49:16 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-26 03:49:16 -0400 |
| commit | ba817fae8f5f71469ae6ac70fc61b9d3a0e19335 (patch) | |
| tree | 03ab9b4214484497990249099af9b41b292f350a /src/codegen/c.zig | |
| parent | cc394431ae6eb69e7abd677c268a8ab7299f8aeb (diff) | |
| parent | cf9735a5e06d302a29d70c737aefd505ca34e0fa (diff) | |
| download | zig-ba817fae8f5f71469ae6ac70fc61b9d3a0e19335.tar.gz zig-ba817fae8f5f71469ae6ac70fc61b9d3a0e19335.zip | |
Merge pull request #17690
Sema: move remaining anon decls to new mechanism
Diffstat (limited to 'src/codegen/c.zig')
| -rw-r--r-- | src/codegen/c.zig | 122 |
1 files changed, 64 insertions, 58 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 4a9258d155..83d921ed9f 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); @@ -1284,11 +1290,14 @@ pub const DeclGen = struct { var index: usize = 0; while (index < ai.len) : (index += 1) { const elem_val = try val.elemValue(mod, index); - const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @as(u8, @intCast(elem_val.toUnsignedInt(mod))); + const elem_val_u8: u8 = if (elem_val.isUndef(mod)) + undefPattern(u8) + else + @intCast(elem_val.toUnsignedInt(mod)); try literal.writeChar(elem_val_u8); } if (ai.sentinel) |s| { - const s_u8 = @as(u8, @intCast(s.toUnsignedInt(mod))); + const s_u8: u8 = @intCast(s.toUnsignedInt(mod)); if (s_u8 != 0) try literal.writeChar(s_u8); } try literal.end(); @@ -1298,7 +1307,10 @@ pub const DeclGen = struct { while (index < ai.len) : (index += 1) { if (index != 0) try writer.writeByte(','); const elem_val = try val.elemValue(mod, index); - const elem_val_u8 = if (elem_val.isUndef(mod)) undefPattern(u8) else @as(u8, @intCast(elem_val.toUnsignedInt(mod))); + const elem_val_u8: u8 = if (elem_val.isUndef(mod)) + undefPattern(u8) + else + @intCast(elem_val.toUnsignedInt(mod)); try writer.print("'\\x{x}'", .{elem_val_u8}); } if (ai.sentinel) |s| { @@ -1566,18 +1578,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 +1602,7 @@ pub const DeclGen = struct { } try renderTypeSuffix( - dg.decl_index, + dg.pass, store.*, mod, w, @@ -1652,8 +1657,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 +1804,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 +2074,7 @@ fn renderTypeName( } } fn renderTypePrefix( - decl: Decl.OptionalIndex, + pass: DeclGen.Pass, store: CType.Store.Set, mod: *Module, w: anytype, @@ -2128,7 +2132,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 +2156,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 +2169,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 +2199,7 @@ fn renderTypePrefix( .packed_struct, .packed_union, => return renderTypePrefix( - decl, + pass, store, mod, w, @@ -2214,7 +2212,7 @@ fn renderTypePrefix( .varargs_function, => { const child_trailing = try renderTypePrefix( - decl, + pass, store, mod, w, @@ -2241,7 +2239,7 @@ fn renderTypePrefix( return trailing; } fn renderTypeSuffix( - decl: Decl.OptionalIndex, + pass: DeclGen.Pass, store: CType.Store.Set, mod: *Module, w: anytype, @@ -2295,7 +2293,7 @@ fn renderTypeSuffix( .pointer_volatile, .pointer_const_volatile, => try renderTypeSuffix( - decl, + pass, store, mod, w, @@ -2314,7 +2312,7 @@ fn renderTypeSuffix( try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len}); try renderTypeSuffix( - decl, + pass, store, mod, w, @@ -2356,9 +2354,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 +2370,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 +2390,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 +2404,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 +2433,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 +2558,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 +2698,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 +2785,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 +2831,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 +2854,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 +2867,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 +7285,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; |
