authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-25 10:07:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-25 19:57:02-07:00
log51f7e5412afd4e934da8a5e93ad91e6de5ae02ca
tree6c1a5e1ce641ab69d093cef46887d2c11b543c84
parent405ba2680f180541cb91323fad579e2ca5cf5eb0

cbe: update `DeclGen.decl_index` to support anon decls


3 files changed, 68 insertions(+), 70 deletions(-)

src/Compilation.zig+1-1
......@@ -3556,7 +3556,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
35563556 .gpa = gpa,
35573557 .module = module,
35583558 .error_msg = null,
3559 .decl_index = decl_index.toOptional(),
3559 .pass = .{ .decl = decl_index },
35603560 .is_naked_fn = false,
35613561 .fwd_decl = fwd_decl.toManaged(gpa),
35623562 .ctypes = .{},
src/codegen/c.zig+55-55
......@@ -522,7 +522,7 @@ pub const Object = struct {
522522pub const DeclGen = struct {
523523 gpa: mem.Allocator,
524524 module: *Module,
525 decl_index: Decl.OptionalIndex,
525 pass: Pass,
526526 is_naked_fn: bool,
527527 /// This is a borrowed reference from `link.C`.
528528 fwd_decl: std.ArrayList(u8),
......@@ -533,10 +533,16 @@ pub const DeclGen = struct {
533533 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),
534534 aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
535535
536 pub const Pass = union(enum) {
537 decl: Decl.Index,
538 anon: InternPool.Index,
539 flush,
540 };
541
536542 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
537543 @setCold(true);
538544 const mod = dg.module;
539 const decl_index = dg.decl_index.unwrap().?;
545 const decl_index = dg.pass.decl;
540546 const decl = mod.declPtr(decl_index);
541547 const src = LazySrcLoc.nodeOffset(0);
542548 const src_loc = src.toSrcLoc(decl, mod);
......@@ -1566,18 +1572,11 @@ pub const DeclGen = struct {
15661572 else => unreachable,
15671573 }
15681574 }
1569 if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold) try w.writeAll("zig_cold ");
1575 if (fn_decl.val.getFunction(mod)) |func| if (func.analysis(ip).is_cold)
1576 try w.writeAll("zig_cold ");
15701577 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
15711578
1572 const trailing = try renderTypePrefix(
1573 dg.decl_index,
1574 store.*,
1575 mod,
1576 w,
1577 fn_cty_idx,
1578 .suffix,
1579 .{},
1580 );
1579 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, fn_cty_idx, .suffix, .{});
15811580 try w.print("{}", .{trailing});
15821581
15831582 if (toCallingConvention(fn_info.cc)) |call_conv| {
......@@ -1597,7 +1596,7 @@ pub const DeclGen = struct {
15971596 }
15981597
15991598 try renderTypeSuffix(
1600 dg.decl_index,
1599 dg.pass,
16011600 store.*,
16021601 mod,
16031602 w,
......@@ -1652,8 +1651,8 @@ pub const DeclGen = struct {
16521651 fn renderCType(dg: *DeclGen, w: anytype, idx: CType.Index) error{ OutOfMemory, AnalysisFail }!void {
16531652 const store = &dg.ctypes.set;
16541653 const mod = dg.module;
1655 _ = try renderTypePrefix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1656 try renderTypeSuffix(dg.decl_index, store.*, mod, w, idx, .suffix, .{});
1654 _ = try renderTypePrefix(dg.pass, store.*, mod, w, idx, .suffix, .{});
1655 try renderTypeSuffix(dg.pass, store.*, mod, w, idx, .suffix, .{});
16571656 }
16581657
16591658 const IntCastContext = union(enum) {
......@@ -1799,11 +1798,10 @@ pub const DeclGen = struct {
17991798 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
18001799 }
18011800
1802 const trailing =
1803 try renderTypePrefix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, qualifiers);
1801 const trailing = try renderTypePrefix(dg.pass, store.*, mod, w, cty_idx, .suffix, qualifiers);
18041802 try w.print("{}", .{trailing});
18051803 try dg.writeCValue(w, name);
1806 try renderTypeSuffix(dg.decl_index, store.*, mod, w, cty_idx, .suffix, .{});
1804 try renderTypeSuffix(dg.pass, store.*, mod, w, cty_idx, .suffix, .{});
18071805 }
18081806
18091807 fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool {
......@@ -2070,7 +2068,7 @@ fn renderTypeName(
20702068 }
20712069}
20722070fn renderTypePrefix(
2073 decl: Decl.OptionalIndex,
2071 pass: DeclGen.Pass,
20742072 store: CType.Store.Set,
20752073 mod: *Module,
20762074 w: anytype,
......@@ -2128,7 +2126,7 @@ fn renderTypePrefix(
21282126 => |tag| {
21292127 const child_idx = cty.cast(CType.Payload.Child).?.data;
21302128 const child_trailing = try renderTypePrefix(
2131 decl,
2129 pass,
21322130 store,
21332131 mod,
21342132 w,
......@@ -2152,15 +2150,8 @@ fn renderTypePrefix(
21522150 .vector,
21532151 => {
21542152 const child_idx = cty.cast(CType.Payload.Sequence).?.data.elem_type;
2155 const child_trailing = try renderTypePrefix(
2156 decl,
2157 store,
2158 mod,
2159 w,
2160 child_idx,
2161 .suffix,
2162 qualifiers,
2163 );
2153 const child_trailing =
2154 try renderTypePrefix(pass, store, mod, w, child_idx, .suffix, qualifiers);
21642155 switch (parent_fix) {
21652156 .prefix => {
21662157 try w.print("{}(", .{child_trailing});
......@@ -2172,10 +2163,11 @@ fn renderTypePrefix(
21722163
21732164 .fwd_anon_struct,
21742165 .fwd_anon_union,
2175 => if (decl.unwrap()) |decl_index|
2176 try w.print("anon__{d}_{d}", .{ @intFromEnum(decl_index), idx })
2177 else
2178 try renderTypeName(mod, w, idx, cty, ""),
2166 => switch (pass) {
2167 .decl => |decl_index| try w.print("decl__{d}_{d}", .{ @intFromEnum(decl_index), idx }),
2168 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{ @intFromEnum(anon_decl), idx }),
2169 .flush => try renderTypeName(mod, w, idx, cty, ""),
2170 },
21792171
21802172 .fwd_struct,
21812173 .fwd_union,
......@@ -2201,7 +2193,7 @@ fn renderTypePrefix(
22012193 .packed_struct,
22022194 .packed_union,
22032195 => return renderTypePrefix(
2204 decl,
2196 pass,
22052197 store,
22062198 mod,
22072199 w,
......@@ -2214,7 +2206,7 @@ fn renderTypePrefix(
22142206 .varargs_function,
22152207 => {
22162208 const child_trailing = try renderTypePrefix(
2217 decl,
2209 pass,
22182210 store,
22192211 mod,
22202212 w,
......@@ -2241,7 +2233,7 @@ fn renderTypePrefix(
22412233 return trailing;
22422234}
22432235fn renderTypeSuffix(
2244 decl: Decl.OptionalIndex,
2236 pass: DeclGen.Pass,
22452237 store: CType.Store.Set,
22462238 mod: *Module,
22472239 w: anytype,
......@@ -2295,7 +2287,7 @@ fn renderTypeSuffix(
22952287 .pointer_volatile,
22962288 .pointer_const_volatile,
22972289 => try renderTypeSuffix(
2298 decl,
2290 pass,
22992291 store,
23002292 mod,
23012293 w,
......@@ -2314,7 +2306,7 @@ fn renderTypeSuffix(
23142306
23152307 try w.print("[{}]", .{cty.cast(CType.Payload.Sequence).?.data.len});
23162308 try renderTypeSuffix(
2317 decl,
2309 pass,
23182310 store,
23192311 mod,
23202312 w,
......@@ -2356,9 +2348,9 @@ fn renderTypeSuffix(
23562348 if (need_comma) try w.writeAll(", ");
23572349 need_comma = true;
23582350 const trailing =
2359 try renderTypePrefix(decl, store, mod, w, param_type, .suffix, qualifiers);
2351 try renderTypePrefix(pass, store, mod, w, param_type, .suffix, qualifiers);
23602352 if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_i });
2361 try renderTypeSuffix(decl, store, mod, w, param_type, .suffix, .{});
2353 try renderTypeSuffix(pass, store, mod, w, param_type, .suffix, .{});
23622354 }
23632355 switch (tag) {
23642356 .function => {},
......@@ -2372,7 +2364,7 @@ fn renderTypeSuffix(
23722364 if (!need_comma) try w.writeAll("void");
23732365 try w.writeByte(')');
23742366
2375 try renderTypeSuffix(decl, store, mod, w, data.return_type, .suffix, .{});
2367 try renderTypeSuffix(pass, store, mod, w, data.return_type, .suffix, .{});
23762368 },
23772369 }
23782370}
......@@ -2392,9 +2384,9 @@ fn renderAggregateFields(
23922384 .eq => {},
23932385 .gt => try writer.print("zig_align({}) ", .{field.alignas.toByteUnits()}),
23942386 }
2395 const trailing = try renderTypePrefix(.none, store, mod, writer, field.type, .suffix, .{});
2387 const trailing = try renderTypePrefix(.flush, store, mod, writer, field.type, .suffix, .{});
23962388 try writer.print("{}{ }", .{ trailing, fmtIdent(mem.span(field.name)) });
2397 try renderTypeSuffix(.none, store, mod, writer, field.type, .suffix, .{});
2389 try renderTypeSuffix(.flush, store, mod, writer, field.type, .suffix, .{});
23982390 try writer.writeAll(";\n");
23992391 }
24002392 try writer.writeByteNTimes(' ', indent);
......@@ -2406,18 +2398,18 @@ pub fn genTypeDecl(
24062398 writer: anytype,
24072399 global_store: CType.Store.Set,
24082400 global_idx: CType.Index,
2409 decl: Decl.OptionalIndex,
2401 pass: DeclGen.Pass,
24102402 decl_store: CType.Store.Set,
24112403 decl_idx: CType.Index,
24122404 found_existing: bool,
24132405) !void {
24142406 const global_cty = global_store.indexToCType(global_idx);
24152407 switch (global_cty.tag()) {
2416 .fwd_anon_struct => if (decl != .none) {
2408 .fwd_anon_struct => if (pass != .flush) {
24172409 try writer.writeAll("typedef ");
2418 _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{});
2410 _ = try renderTypePrefix(.flush, global_store, mod, writer, global_idx, .suffix, .{});
24192411 try writer.writeByte(' ');
2420 _ = try renderTypePrefix(decl, decl_store, mod, writer, decl_idx, .suffix, .{});
2412 _ = try renderTypePrefix(pass, decl_store, mod, writer, decl_idx, .suffix, .{});
24212413 try writer.writeAll(";\n");
24222414 },
24232415
......@@ -2435,7 +2427,15 @@ pub fn genTypeDecl(
24352427 .fwd_union,
24362428 => {
24372429 const owner_decl = global_cty.cast(CType.Payload.FwdDecl).?.data;
2438 _ = try renderTypePrefix(.none, global_store, mod, writer, global_idx, .suffix, .{});
2430 _ = try renderTypePrefix(
2431 .flush,
2432 global_store,
2433 mod,
2434 writer,
2435 global_idx,
2436 .suffix,
2437 .{},
2438 );
24392439 try writer.writeAll("; // ");
24402440 try mod.declPtr(owner_decl).renderFullyQualifiedName(mod, writer);
24412441 try writer.writeByte('\n');
......@@ -2552,7 +2552,7 @@ fn genExports(o: *Object) !void {
25522552
25532553 const mod = o.dg.module;
25542554 const ip = &mod.intern_pool;
2555 const decl_index = o.dg.decl_index.unwrap().?;
2555 const decl_index = o.dg.pass.decl;
25562556 const decl = mod.declPtr(decl_index);
25572557 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
25582558 const fwd = o.dg.fwd_decl.writer();
......@@ -2692,7 +2692,7 @@ pub fn genFunc(f: *Function) !void {
26922692 const o = &f.object;
26932693 const mod = o.dg.module;
26942694 const gpa = o.dg.gpa;
2695 const decl_index = o.dg.decl_index.unwrap().?;
2695 const decl_index = o.dg.pass.decl;
26962696 const decl = mod.declPtr(decl_index);
26972697 const tv: TypedValue = .{
26982698 .ty = decl.ty,
......@@ -2779,7 +2779,7 @@ pub fn genDecl(o: *Object) !void {
27792779 defer tracy.end();
27802780
27812781 const mod = o.dg.module;
2782 const decl_index = o.dg.decl_index.unwrap().?;
2782 const decl_index = o.dg.pass.decl;
27832783 const decl = mod.declPtr(decl_index);
27842784 const tv: TypedValue = .{ .ty = decl.ty, .val = (try decl.internValue(mod)).toValue() };
27852785
......@@ -2825,13 +2825,13 @@ pub fn genDeclValue(
28252825 alignment: Alignment,
28262826 link_section: InternPool.OptionalNullTerminatedString,
28272827) !void {
2828 const mod = o.dg.module;
28282829 const fwd_decl_writer = o.dg.fwd_decl.writer();
28292830
28302831 try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
28312832 try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete);
28322833 try fwd_decl_writer.writeAll(";\n");
28332834
2834 const mod = o.dg.module;
28352835 const w = o.writer();
28362836 if (!is_global) try w.writeAll("static ");
28372837 if (mod.intern_pool.stringToSliceUnwrap(link_section)) |s|
......@@ -2848,7 +2848,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
28482848 defer tracy.end();
28492849
28502850 const mod = dg.module;
2851 const decl_index = dg.decl_index.unwrap().?;
2851 const decl_index = dg.pass.decl;
28522852 const decl = mod.declPtr(decl_index);
28532853 const tv: TypedValue = .{
28542854 .ty = decl.ty,
......@@ -2861,7 +2861,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
28612861 const is_global = dg.declIsGlobal(tv);
28622862 if (is_global) {
28632863 try writer.writeAll("zig_extern ");
2864 try dg.renderFunctionSignature(writer, dg.decl_index.unwrap().?, .complete, .{ .export_index = 0 });
2864 try dg.renderFunctionSignature(writer, dg.pass.decl, .complete, .{ .export_index = 0 });
28652865 try dg.fwd_decl.appendSlice(";\n");
28662866 }
28672867 },
......@@ -7279,7 +7279,7 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
72797279fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
72807280 const mod = f.object.dg.module;
72817281 const inst_ty = f.typeOfIndex(inst);
7282 const decl_index = f.object.dg.decl_index.unwrap().?;
7282 const decl_index = f.object.dg.pass.decl;
72837283 const decl = mod.declPtr(decl_index);
72847284 const fn_cty = try f.typeToCType(decl.ty, .complete);
72857285 const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
src/link/C.zig+12-14
......@@ -158,9 +158,7 @@ pub fn updateFunc(
158158 const decl_index = func.owner_decl;
159159 const decl = module.declPtr(decl_index);
160160 const gop = try self.decl_table.getOrPut(gpa, decl_index);
161 if (!gop.found_existing) {
162 gop.value_ptr.* = .{};
163 }
161 if (!gop.found_existing) gop.value_ptr.* = .{};
164162 const ctypes = &gop.value_ptr.ctypes;
165163 const lazy_fns = &gop.value_ptr.lazy_fns;
166164 const fwd_decl = &self.fwd_decl_buf;
......@@ -180,7 +178,7 @@ pub fn updateFunc(
180178 .gpa = gpa,
181179 .module = module,
182180 .error_msg = null,
183 .decl_index = decl_index.toOptional(),
181 .pass = .{ .decl = decl_index },
184182 .is_naked_fn = decl.ty.fnCallingConvention(module) == .Naked,
185183 .fwd_decl = fwd_decl.toManaged(gpa),
186184 .ctypes = ctypes.*,
......@@ -235,7 +233,7 @@ fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
235233 .gpa = gpa,
236234 .module = module,
237235 .error_msg = null,
238 .decl_index = .none,
236 .pass = .{ .anon = anon_decl },
239237 .is_naked_fn = false,
240238 .fwd_decl = fwd_decl.toManaged(gpa),
241239 .ctypes = .{},
......@@ -302,7 +300,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi
302300 .gpa = gpa,
303301 .module = module,
304302 .error_msg = null,
305 .decl_index = decl_index.toOptional(),
303 .pass = .{ .decl = decl_index },
306304 .is_naked_fn = false,
307305 .fwd_decl = fwd_decl.toManaged(gpa),
308306 .ctypes = ctypes.*,
......@@ -438,14 +436,14 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
438436 // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.
439437 // This ensures that every lazy CType.Index exactly matches the global CType.Index.
440438 assert(f.ctypes.count() == 0);
441 try self.flushCTypes(&f, .none, f.lazy_ctypes);
439 try self.flushCTypes(&f, .flush, f.lazy_ctypes);
442440
443 for (self.anon_decls.values()) |decl_block| {
444 try self.flushCTypes(&f, .none, decl_block.ctypes);
441 for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| {
442 try self.flushCTypes(&f, .{ .anon = anon_decl }, decl_block.ctypes);
445443 }
446444
447445 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {
448 try self.flushCTypes(&f, decl_index.toOptional(), decl_block.ctypes);
446 try self.flushCTypes(&f, .{ .decl = decl_index }, decl_block.ctypes);
449447 }
450448 }
451449
......@@ -516,7 +514,7 @@ const FlushDeclError = error{
516514fn flushCTypes(
517515 self: *C,
518516 f: *Flush,
519 decl_index: Module.Decl.OptionalIndex,
517 pass: codegen.DeclGen.Pass,
520518 decl_ctypes: codegen.CType.Store,
521519) FlushDeclError!void {
522520 const gpa = self.base.allocator;
......@@ -591,7 +589,7 @@ fn flushCTypes(
591589 writer,
592590 global_ctypes.set,
593591 global_idx,
594 decl_index,
592 pass,
595593 decl_ctypes.set,
596594 decl_idx,
597595 gop.found_existing,
......@@ -610,7 +608,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
610608 .gpa = gpa,
611609 .module = self.base.options.module.?,
612610 .error_msg = null,
613 .decl_index = .none,
611 .pass = .flush,
614612 .is_naked_fn = false,
615613 .fwd_decl = fwd_decl.toManaged(gpa),
616614 .ctypes = ctypes.*,
......@@ -652,7 +650,7 @@ fn flushLazyFn(
652650 .gpa = gpa,
653651 .module = self.base.options.module.?,
654652 .error_msg = null,
655 .decl_index = .none,
653 .pass = .flush,
656654 .is_naked_fn = false,
657655 .fwd_decl = fwd_decl.toManaged(gpa),
658656 .ctypes = ctypes.*,