authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-07-28 17:09:14+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-11 07:29:41+01:00
log548a087fafeda5b07d2237d5137906b8d07da699
tree69135f129b84ab5b65f443d0a52899b232696e2b
parent531cd177e89c1edfcd2e52f74f220eb186a25f78
signature Commit is signed but in an unrecognized format.

compiler: split Decl into Nav and Cau

The type `Zcu.Decl` in the compiler is problematic: over time it has gained many responsibilities. Every source declaration, container type, generic instantiation, and `@extern` has a `Decl`. The functions of these `Decl`s are in some cases entirely disjoint. After careful analysis, I determined that the two main responsibilities of `Decl` are as follows: * A `Decl` acts as the "subject" of semantic analysis at comptime. A single unit of analysis is either a runtime function body, or a `Decl`. It registers incremental dependencies, tracks analysis errors, etc. * A `Decl` acts as a "global variable": a pointer to it is consistent, and it may be lowered to a specific symbol by the codegen backend. This commit eliminates `Decl` and introduces new types to model these responsibilities: `Cau` (Comptime Analysis Unit) and `Nav` (Named Addressable Value). Every source declaration, and every container type requiring resolution (so *not* including `opaque`), has a `Cau`. For a source declaration, this `Cau` performs the resolution of its value. (When #131 is implemented, it is unsolved whether type and value resolution will share a `Cau` or have two distinct `Cau`s.) For a type, this `Cau` is the context in which type resolution occurs. Every non-`comptime` source declaration, every generic instantiation, and every distinct `extern` has a `Nav`. These are sent to codegen/link: the backends by definition do not care about `Cau`s. This commit has some minor technically-breaking changes surrounding `usingnamespace`. I don't think they'll impact anyone, since the changes are fixes around semantics which were previously inconsistent (the behavior changed depending on hashmap iteration order!). Aside from that, this changeset has no significant user-facing changes. Instead, it is an internal refactor which makes it easier to correctly model the responsibilities of different objects, particularly regarding incremental compilation. The performance impact should be negligible, but I will take measurements before merging this work into `master`. Co-authored-by: Jacob Young <jacobly0@users.noreply.github.com> Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>

49 files changed, 6380 insertions(+), 7164 deletions(-)

src/Compilation.zig+76-151
......@@ -354,28 +354,25 @@ pub const RcIncludes = enum {
354354
355355const Job = union(enum) {
356356 /// Write the constant value for a Decl to the output file.
357 codegen_decl: InternPool.DeclIndex,
357 codegen_nav: InternPool.Nav.Index,
358358 /// Write the machine code for a function to the output file.
359 /// This will either be a non-generic `func_decl` or a `func_instance`.
360359 codegen_func: struct {
360 /// This will either be a non-generic `func_decl` or a `func_instance`.
361361 func: InternPool.Index,
362362 /// This `Air` is owned by the `Job` and allocated with `gpa`.
363363 /// It must be deinited when the job is processed.
364364 air: Air,
365365 },
366 /// Render the .h file snippet for the Decl.
367 emit_h_decl: InternPool.DeclIndex,
368 /// The Decl needs to be analyzed and possibly export itself.
369 /// It may have already be analyzed, or it may have been determined
370 /// to be outdated; in this case perform semantic analysis again.
371 analyze_decl: InternPool.DeclIndex,
366 /// The `Cau` must be semantically analyzed (and possibly export itself).
367 /// This may be its first time being analyzed, or it may be outdated.
368 analyze_cau: InternPool.Cau.Index,
372369 /// Analyze the body of a runtime function.
373370 /// After analysis, a `codegen_func` job will be queued.
374371 /// These must be separate jobs to ensure any needed type resolution occurs *before* codegen.
375372 analyze_func: InternPool.Index,
376373 /// The source file containing the Decl has been updated, and so the
377374 /// Decl may need its line number information updated in the debug info.
378 update_line_number: InternPool.DeclIndex,
375 update_line_number: void, // TODO
379376 /// The main source file for the module needs to be analyzed.
380377 analyze_mod: *Package.Module,
381378 /// Fully resolve the given `struct` or `union` type.
......@@ -419,7 +416,7 @@ const Job = union(enum) {
419416};
420417
421418const CodegenJob = union(enum) {
422 decl: InternPool.DeclIndex,
419 nav: InternPool.Nav.Index,
423420 func: struct {
424421 func: InternPool.Index,
425422 /// This `Air` is owned by the `Job` and allocated with `gpa`.
......@@ -1445,12 +1442,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
14451442 .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}),
14461443 };
14471444
1448 const emit_h: ?*Zcu.GlobalEmitH = if (options.emit_h) |loc| eh: {
1449 const eh = try arena.create(Zcu.GlobalEmitH);
1450 eh.* = .{ .loc = loc };
1451 break :eh eh;
1452 } else null;
1453
14541445 const std_mod = options.std_mod orelse try Package.Module.create(arena, .{
14551446 .global_cache_directory = options.global_cache_directory,
14561447 .paths = .{
......@@ -1478,7 +1469,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
14781469 .std_mod = std_mod,
14791470 .global_zir_cache = global_zir_cache,
14801471 .local_zir_cache = local_zir_cache,
1481 .emit_h = emit_h,
14821472 .error_limit = error_limit,
14831473 .llvm_object = null,
14841474 };
......@@ -2581,7 +2571,7 @@ fn addNonIncrementalStuffToCacheManifest(
25812571 man.hash.addOptionalBytes(comp.test_name_prefix);
25822572 man.hash.add(comp.skip_linker_dependencies);
25832573 man.hash.add(comp.formatted_panics);
2584 man.hash.add(mod.emit_h != null);
2574 //man.hash.add(mod.emit_h != null);
25852575 man.hash.add(mod.error_limit);
25862576 } else {
25872577 cache_helpers.addModule(&man.hash, comp.root_mod);
......@@ -2930,7 +2920,7 @@ const Header = extern struct {
29302920 intern_pool: extern struct {
29312921 thread_count: u32,
29322922 src_hash_deps_len: u32,
2933 decl_val_deps_len: u32,
2923 nav_val_deps_len: u32,
29342924 namespace_deps_len: u32,
29352925 namespace_name_deps_len: u32,
29362926 first_dependency_len: u32,
......@@ -2972,7 +2962,7 @@ pub fn saveState(comp: *Compilation) !void {
29722962 .intern_pool = .{
29732963 .thread_count = @intCast(ip.locals.len),
29742964 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
2975 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),
2965 .nav_val_deps_len = @intCast(ip.nav_val_deps.count()),
29762966 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
29772967 .namespace_name_deps_len = @intCast(ip.namespace_name_deps.count()),
29782968 .first_dependency_len = @intCast(ip.first_dependency.count()),
......@@ -2999,8 +2989,8 @@ pub fn saveState(comp: *Compilation) !void {
29992989
30002990 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.keys()));
30012991 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.values()));
3002 addBuf(&bufs, mem.sliceAsBytes(ip.decl_val_deps.keys()));
3003 addBuf(&bufs, mem.sliceAsBytes(ip.decl_val_deps.values()));
2992 addBuf(&bufs, mem.sliceAsBytes(ip.nav_val_deps.keys()));
2993 addBuf(&bufs, mem.sliceAsBytes(ip.nav_val_deps.values()));
30042994 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.keys()));
30052995 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.values()));
30062996 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_name_deps.keys()));
......@@ -3019,7 +3009,7 @@ pub fn saveState(comp: *Compilation) !void {
30193009 addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]);
30203010 addBuf(&bufs, mem.sliceAsBytes(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len]));
30213011 addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.bin_digest)[0..pt_header.intern_pool.files_len]));
3022 addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.root_decl)[0..pt_header.intern_pool.files_len]));
3012 addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.root_type)[0..pt_header.intern_pool.files_len]));
30233013 }
30243014
30253015 //// TODO: compilation errors
......@@ -3065,6 +3055,8 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
30653055 }
30663056
30673057 if (comp.module) |zcu| {
3058 const ip = &zcu.intern_pool;
3059
30683060 total += zcu.failed_exports.count();
30693061 total += zcu.failed_embed_files.count();
30703062
......@@ -3084,25 +3076,18 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
30843076 // When a parse error is introduced, we keep all the semantic analysis for
30853077 // the previous parse success, including compile errors, but we cannot
30863078 // emit them until the file succeeds parsing.
3087 for (zcu.failed_analysis.keys()) |key| {
3088 const decl_index = switch (key.unwrap()) {
3089 .decl => |d| d,
3090 .func => |ip_index| zcu.funcInfo(ip_index).owner_decl,
3079 for (zcu.failed_analysis.keys()) |anal_unit| {
3080 const file_index = switch (anal_unit.unwrap()) {
3081 .cau => |cau| zcu.namespacePtr(ip.getCau(cau).namespace).file_scope,
3082 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFull(ip).file,
30913083 };
3092 if (zcu.declFileScope(decl_index).okToReportErrors()) {
3084 if (zcu.fileByIndex(file_index).okToReportErrors()) {
30933085 total += 1;
3094 if (zcu.cimport_errors.get(key)) |errors| {
3086 if (zcu.cimport_errors.get(anal_unit)) |errors| {
30953087 total += errors.errorMessageCount();
30963088 }
30973089 }
30983090 }
3099 if (zcu.emit_h) |emit_h| {
3100 for (emit_h.failed_decls.keys()) |key| {
3101 if (zcu.declFileScope(key).okToReportErrors()) {
3102 total += 1;
3103 }
3104 }
3105 }
31063091
31073092 if (zcu.intern_pool.global_error_set.getNamesFromMainThread().len > zcu.error_limit) {
31083093 total += 1;
......@@ -3169,6 +3154,8 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
31693154 });
31703155 }
31713156 if (comp.module) |zcu| {
3157 const ip = &zcu.intern_pool;
3158
31723159 var all_references = try zcu.resolveReferences();
31733160 defer all_references.deinit(gpa);
31743161
......@@ -3219,14 +3206,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
32193206 if (err) |e| return e;
32203207 }
32213208 for (zcu.failed_analysis.keys(), zcu.failed_analysis.values()) |anal_unit, error_msg| {
3222 const decl_index = switch (anal_unit.unwrap()) {
3223 .decl => |d| d,
3224 .func => |ip_index| zcu.funcInfo(ip_index).owner_decl,
3209 const file_index = switch (anal_unit.unwrap()) {
3210 .cau => |cau| zcu.namespacePtr(ip.getCau(cau).namespace).file_scope,
3211 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFull(ip).file,
32253212 };
32263213
3227 // Skip errors for Decls within files that had a parse failure.
3214 // Skip errors for AnalUnits within files that had a parse failure.
32283215 // We'll try again once parsing succeeds.
3229 if (!zcu.declFileScope(decl_index).okToReportErrors()) continue;
3216 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;
32303217
32313218 try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);
32323219 if (zcu.cimport_errors.get(anal_unit)) |errors| {
......@@ -3250,15 +3237,6 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
32503237 }
32513238 }
32523239 }
3253 if (zcu.emit_h) |emit_h| {
3254 for (emit_h.failed_decls.keys(), emit_h.failed_decls.values()) |decl_index, error_msg| {
3255 // Skip errors for Decls within files that had a parse failure.
3256 // We'll try again once parsing succeeds.
3257 if (zcu.declFileScope(decl_index).okToReportErrors()) {
3258 try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);
3259 }
3260 }
3261 }
32623240 for (zcu.failed_exports.values()) |value| {
32633241 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
32643242 }
......@@ -3437,11 +3415,15 @@ pub fn addModuleErrorMsg(
34373415 const loc = std.zig.findLineColumn(source.bytes, span.main);
34383416 const rt_file_path = try src.file_scope.fullPath(gpa);
34393417 const name = switch (ref.referencer.unwrap()) {
3440 .decl => |d| mod.declPtr(d).name,
3441 .func => |f| mod.funcOwnerDeclPtr(f).name,
3418 .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
3419 .nav => |nav| ip.getNav(nav).name.toSlice(ip),
3420 .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
3421 .none => "comptime",
3422 },
3423 .func => |f| ip.getNav(mod.funcInfo(f).owner_nav).name.toSlice(ip),
34423424 };
34433425 try ref_traces.append(gpa, .{
3444 .decl_name = try eb.addString(name.toSlice(ip)),
3426 .decl_name = try eb.addString(name),
34453427 .src_loc = try eb.addSourceLocation(.{
34463428 .src_path = try eb.addString(rt_file_path),
34473429 .span_start = span.start,
......@@ -3617,10 +3599,10 @@ fn performAllTheWorkInner(
36173599 // Pre-load these things from our single-threaded context since they
36183600 // will be needed by the worker threads.
36193601 const path_digest = zcu.filePathDigest(file_index);
3620 const root_decl = zcu.fileRootDecl(file_index);
3602 const old_root_type = zcu.fileRootType(file_index);
36213603 const file = zcu.fileByIndex(file_index);
36223604 comp.thread_pool.spawnWgId(&astgen_wait_group, workerAstGenFile, .{
3623 comp, file, file_index, path_digest, root_decl, zir_prog_node, &astgen_wait_group, .root,
3605 comp, file, file_index, path_digest, old_root_type, zir_prog_node, &astgen_wait_group, .root,
36243606 });
36253607 }
36263608 }
......@@ -3682,7 +3664,7 @@ fn performAllTheWorkInner(
36823664 // which we need to work on, and queue it if so.
36833665 if (try zcu.findOutdatedToAnalyze()) |outdated| {
36843666 switch (outdated.unwrap()) {
3685 .decl => |decl| try comp.queueJob(.{ .analyze_decl = decl }),
3667 .cau => |cau| try comp.queueJob(.{ .analyze_cau = cau }),
36863668 .func => |func| try comp.queueJob(.{ .analyze_func = func }),
36873669 }
36883670 continue;
......@@ -3704,24 +3686,17 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
37043686
37053687fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {
37063688 switch (job) {
3707 .codegen_decl => |decl_index| {
3708 const decl = comp.module.?.declPtr(decl_index);
3709
3710 switch (decl.analysis) {
3711 .unreferenced => unreachable,
3712 .in_progress => unreachable,
3713
3714 .file_failure,
3715 .sema_failure,
3716 .codegen_failure,
3717 .dependency_failure,
3718 => {},
3719
3720 .complete => {
3721 assert(decl.has_tv);
3722 try comp.queueCodegenJob(tid, .{ .decl = decl_index });
3723 },
3689 .codegen_nav => |nav_index| {
3690 const zcu = comp.module.?;
3691 const nav = zcu.intern_pool.getNav(nav_index);
3692 if (nav.analysis_owner.unwrap()) |cau| {
3693 const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
3694 if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) {
3695 return;
3696 }
37243697 }
3698 assert(nav.status == .resolved);
3699 try comp.queueCodegenJob(tid, .{ .nav = nav_index });
37253700 },
37263701 .codegen_func => |func| {
37273702 // This call takes ownership of `func.air`.
......@@ -3740,82 +3715,30 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
37403715 error.AnalysisFail => return,
37413716 };
37423717 },
3743 .emit_h_decl => |decl_index| {
3744 if (true) @panic("regressed compiler feature: emit-h should hook into updateExports, " ++
3745 "not decl analysis, which is too early to know about @export calls");
3746
3718 .analyze_cau => |cau_index| {
37473719 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3748 const decl = pt.zcu.declPtr(decl_index);
3749
3750 switch (decl.analysis) {
3751 .unreferenced => unreachable,
3752 .in_progress => unreachable,
3753
3754 .file_failure,
3755 .sema_failure,
3756 .dependency_failure,
3757 => return,
3758
3759 // emit-h only requires semantic analysis of the Decl to be complete,
3760 // it does not depend on machine code generation to succeed.
3761 .codegen_failure, .complete => {
3762 const named_frame = tracy.namedFrame("emit_h_decl");
3763 defer named_frame.end();
3764
3765 const gpa = comp.gpa;
3766 const emit_h = pt.zcu.emit_h.?;
3767 _ = try emit_h.decl_table.getOrPut(gpa, decl_index);
3768 const decl_emit_h = emit_h.declPtr(decl_index);
3769 const fwd_decl = &decl_emit_h.fwd_decl;
3770 fwd_decl.shrinkRetainingCapacity(0);
3771 var ctypes_arena = std.heap.ArenaAllocator.init(gpa);
3772 defer ctypes_arena.deinit();
3773
3774 const file_scope = pt.zcu.namespacePtr(decl.src_namespace).fileScope(pt.zcu);
3775
3776 var dg: c_codegen.DeclGen = .{
3777 .gpa = gpa,
3778 .pt = pt,
3779 .mod = file_scope.mod,
3780 .error_msg = null,
3781 .pass = .{ .decl = decl_index },
3782 .is_naked_fn = false,
3783 .fwd_decl = fwd_decl.toManaged(gpa),
3784 .ctype_pool = c_codegen.CType.Pool.empty,
3785 .scratch = .{},
3786 .anon_decl_deps = .{},
3787 .aligned_anon_decls = .{},
3788 };
3789 defer {
3790 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();
3791 fwd_decl.shrinkAndFree(gpa, fwd_decl.items.len);
3792 dg.ctype_pool.deinit(gpa);
3793 dg.scratch.deinit(gpa);
3794 }
3795 try dg.ctype_pool.init(gpa);
3796
3797 c_codegen.genHeader(&dg) catch |err| switch (err) {
3798 error.AnalysisFail => {
3799 try emit_h.failed_decls.put(gpa, decl_index, dg.error_msg.?);
3800 return;
3801 },
3802 else => |e| return e,
3803 };
3804 },
3805 }
3806 },
3807 .analyze_decl => |decl_index| {
3808 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3809 pt.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {
3720 pt.ensureCauAnalyzed(cau_index) catch |err| switch (err) {
38103721 error.OutOfMemory => return error.OutOfMemory,
38113722 error.AnalysisFail => return,
38123723 };
3813 const decl = pt.zcu.declPtr(decl_index);
3814 if (decl.kind == .@"test" and comp.config.is_test) {
3724 queue_test_analysis: {
3725 if (!comp.config.is_test) break :queue_test_analysis;
3726
3727 // Check if this is a test function.
3728 const ip = &pt.zcu.intern_pool;
3729 const cau = ip.getCau(cau_index);
3730 const nav_index = switch (cau.owner.unwrap()) {
3731 .none, .type => break :queue_test_analysis,
3732 .nav => |nav| nav,
3733 };
3734 if (!pt.zcu.test_functions.contains(nav_index)) {
3735 break :queue_test_analysis;
3736 }
3737
38153738 // Tests are always emitted in test binaries. The decl_refs are created by
38163739 // Zcu.populateTestFunctions, but this will not queue body analysis, so do
38173740 // that now.
3818 try pt.zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern());
3741 try pt.zcu.ensureFuncBodyAnalysisQueued(ip.getNav(nav_index).status.resolved.val);
38193742 }
38203743 },
38213744 .resolve_type_fully => |ty| {
......@@ -3832,6 +3755,8 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
38323755 const named_frame = tracy.namedFrame("update_line_number");
38333756 defer named_frame.end();
38343757
3758 if (true) @panic("TODO: update_line_number");
3759
38353760 const gpa = comp.gpa;
38363761 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
38373762 const decl = pt.zcu.declPtr(decl_index);
......@@ -4054,12 +3979,12 @@ fn codegenThread(tid: usize, comp: *Compilation) void {
40543979
40553980fn processOneCodegenJob(tid: usize, comp: *Compilation, codegen_job: CodegenJob) JobError!void {
40563981 switch (codegen_job) {
4057 .decl => |decl_index| {
4058 const named_frame = tracy.namedFrame("codegen_decl");
3982 .nav => |nav_index| {
3983 const named_frame = tracy.namedFrame("codegen_nav");
40593984 defer named_frame.end();
40603985
40613986 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
4062 try pt.linkerUpdateDecl(decl_index);
3987 try pt.linkerUpdateNav(nav_index);
40633988 },
40643989 .func => |func| {
40653990 const named_frame = tracy.namedFrame("codegen_func");
......@@ -4366,7 +4291,7 @@ fn workerAstGenFile(
43664291 file: *Zcu.File,
43674292 file_index: Zcu.File.Index,
43684293 path_digest: Cache.BinDigest,
4369 root_decl: Zcu.Decl.OptionalIndex,
4294 old_root_type: InternPool.Index,
43704295 prog_node: std.Progress.Node,
43714296 wg: *WaitGroup,
43724297 src: Zcu.AstGenSrc,
......@@ -4375,7 +4300,7 @@ fn workerAstGenFile(
43754300 defer child_prog_node.end();
43764301
43774302 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
4378 pt.astGenFile(file, path_digest, root_decl) catch |err| switch (err) {
4303 pt.astGenFile(file, path_digest, old_root_type) catch |err| switch (err) {
43794304 error.AnalysisFail => return,
43804305 else => {
43814306 file.status = .retryable_failure;
......@@ -4406,7 +4331,7 @@ fn workerAstGenFile(
44064331 // `@import("builtin")` is handled specially.
44074332 if (mem.eql(u8, import_path, "builtin")) continue;
44084333
4409 const import_result, const imported_path_digest, const imported_root_decl = blk: {
4334 const import_result, const imported_path_digest, const imported_root_type = blk: {
44104335 comp.mutex.lock();
44114336 defer comp.mutex.unlock();
44124337
......@@ -4421,8 +4346,8 @@ fn workerAstGenFile(
44214346 comp.appendFileSystemInput(fsi, res.file.mod.root, res.file.sub_file_path) catch continue;
44224347 };
44234348 const imported_path_digest = pt.zcu.filePathDigest(res.file_index);
4424 const imported_root_decl = pt.zcu.fileRootDecl(res.file_index);
4425 break :blk .{ res, imported_path_digest, imported_root_decl };
4349 const imported_root_type = pt.zcu.fileRootType(res.file_index);
4350 break :blk .{ res, imported_path_digest, imported_root_type };
44264351 };
44274352 if (import_result.is_new) {
44284353 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
......@@ -4433,7 +4358,7 @@ fn workerAstGenFile(
44334358 .import_tok = item.data.token,
44344359 } };
44354360 comp.thread_pool.spawnWgId(wg, workerAstGenFile, .{
4436 comp, import_result.file, import_result.file_index, imported_path_digest, imported_root_decl, prog_node, wg, sub_src,
4361 comp, import_result.file, import_result.file_index, imported_path_digest, imported_root_type, prog_node, wg, sub_src,
44374362 });
44384363 }
44394364 }
src/InternPool.zig+921-459
......@@ -24,12 +24,14 @@ tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th
2424/// These are also invalidated if tracking fails for this instruction.
2525/// Value is index into `dep_entries` of the first dependency on this hash.
2626src_hash_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index) = .{},
27/// Dependencies on the value of a Decl.
28/// Value is index into `dep_entries` of the first dependency on this Decl value.
29decl_val_deps: std.AutoArrayHashMapUnmanaged(DeclIndex, DepEntry.Index) = .{},
30/// Dependencies on the IES of a runtime function.
31/// Value is index into `dep_entries` of the first dependency on this Decl value.
32func_ies_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index) = .{},
27/// Dependencies on the value of a Nav.
28/// Value is index into `dep_entries` of the first dependency on this Nav value.
29nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index) = .{},
30/// Dependencies on an interned value, either:
31/// * a runtime function (invalidated when its IES changes)
32/// * a container type requiring resolution (invalidated when the type must be recreated at a new index)
33/// Value is index into `dep_entries` of the first dependency on this interned value.
34interned_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index) = .{},
3335/// Dependencies on the full set of names in a ZIR namespace.
3436/// Key refers to a `struct_decl`, `union_decl`, etc.
3537/// Value is index into `dep_entries` of the first dependency on this namespace.
......@@ -210,25 +212,25 @@ pub fn trackZir(
210212}
211213
212214/// Analysis Unit. Represents a single entity which undergoes semantic analysis.
213/// This is either a `Decl` (in future `Cau`) or a runtime function.
215/// This is either a `Cau` or a runtime function.
214216/// The LSB is used as a tag bit.
215217/// This is the "source" of an incremental dependency edge.
216218pub const AnalUnit = packed struct(u32) {
217 kind: enum(u1) { decl, func },
219 kind: enum(u1) { cau, func },
218220 index: u31,
219221 pub const Unwrapped = union(enum) {
220 decl: DeclIndex,
222 cau: Cau.Index,
221223 func: InternPool.Index,
222224 };
223225 pub fn unwrap(as: AnalUnit) Unwrapped {
224226 return switch (as.kind) {
225 .decl => .{ .decl = @enumFromInt(as.index) },
227 .cau => .{ .cau = @enumFromInt(as.index) },
226228 .func => .{ .func = @enumFromInt(as.index) },
227229 };
228230 }
229231 pub fn wrap(raw: Unwrapped) AnalUnit {
230232 return switch (raw) {
231 .decl => |decl| .{ .kind = .decl, .index = @intCast(@intFromEnum(decl)) },
233 .cau => |cau| .{ .kind = .cau, .index = @intCast(@intFromEnum(cau)) },
232234 .func => |func| .{ .kind = .func, .index = @intCast(@intFromEnum(func)) },
233235 };
234236 }
......@@ -247,10 +249,275 @@ pub const AnalUnit = packed struct(u32) {
247249 };
248250};
249251
252/// Comptime Analysis Unit. This is the "subject" of semantic analysis where the root context is
253/// comptime; every `Sema` is owned by either a `Cau` or a runtime function (see `AnalUnit`).
254/// The state stored here is immutable.
255///
256/// * Every ZIR `declaration` has a `Cau` (post-instantiation) to analyze the declaration body.
257/// * Every `struct`, `union`, and `enum` has a `Cau` for type resolution.
258///
259/// The analysis status of a `Cau` is known only from state in `Zcu`.
260/// An entry in `Zcu.failed_analysis` indicates an analysis failure with associated error message.
261/// An entry in `Zcu.transitive_failed_analysis` indicates a transitive analysis failure.
262///
263/// 12 bytes.
264pub const Cau = struct {
265 /// The `declaration`, `struct_decl`, `enum_decl`, or `union_decl` instruction which this `Cau` analyzes.
266 zir_index: TrackedInst.Index,
267 /// The namespace which this `Cau` should be analyzed within.
268 namespace: NamespaceIndex,
269 /// This field essentially tells us what to do with the information resulting from
270 /// semantic analysis. See `Owner.Unwrapped` for details.
271 owner: Owner,
272
273 /// See `Owner.Unwrapped` for details. In terms of representation, the `InternPool.Index`
274 /// or `Nav.Index` is cast to a `u31` and stored in `index`. As a special case, if
275 /// `@as(u32, @bitCast(owner)) == 0xFFFF_FFFF`, then the value is treated as `.none`.
276 pub const Owner = packed struct(u32) {
277 kind: enum(u1) { type, nav },
278 index: u31,
279
280 pub const Unwrapped = union(enum) {
281 /// This `Cau` exists in isolation. It is a global `comptime` declaration, or (TODO ANYTHING ELSE?).
282 /// After semantic analysis completes, the result is discarded.
283 none,
284 /// This `Cau` is owned by the given type for type resolution.
285 /// This is a `struct`, `union`, or `enum` type.
286 type: InternPool.Index,
287 /// This `Cau` is owned by the given `Nav` to resolve its value.
288 /// When analyzing the `Cau`, the resulting value is stored as the value of this `Nav`.
289 nav: Nav.Index,
290 };
291
292 pub fn unwrap(owner: Owner) Unwrapped {
293 if (@as(u32, @bitCast(owner)) == std.math.maxInt(u32)) {
294 return .none;
295 }
296 return switch (owner.kind) {
297 .type => .{ .type = @enumFromInt(owner.index) },
298 .nav => .{ .nav = @enumFromInt(owner.index) },
299 };
300 }
301
302 fn wrap(raw: Unwrapped) Owner {
303 return switch (raw) {
304 .none => @bitCast(@as(u32, std.math.maxInt(u32))),
305 .type => |ty| .{ .kind = .type, .index = @intCast(@intFromEnum(ty)) },
306 .nav => |nav| .{ .kind = .nav, .index = @intCast(@intFromEnum(nav)) },
307 };
308 }
309 };
310
311 pub const Index = enum(u32) {
312 _,
313 pub const Optional = enum(u32) {
314 none = std.math.maxInt(u32),
315 _,
316 pub fn unwrap(opt: Optional) ?Cau.Index {
317 return switch (opt) {
318 .none => null,
319 _ => @enumFromInt(@intFromEnum(opt)),
320 };
321 }
322 };
323 pub fn toOptional(i: Cau.Index) Optional {
324 return @enumFromInt(@intFromEnum(i));
325 }
326 const Unwrapped = struct {
327 tid: Zcu.PerThread.Id,
328 index: u32,
329
330 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Cau.Index {
331 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
332 assert(unwrapped.index <= ip.getIndexMask(u31));
333 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_31 |
334 unwrapped.index);
335 }
336 };
337 fn unwrap(cau_index: Cau.Index, ip: *const InternPool) Unwrapped {
338 return .{
339 .tid = @enumFromInt(@intFromEnum(cau_index) >> ip.tid_shift_31 & ip.getTidMask()),
340 .index = @intFromEnum(cau_index) & ip.getIndexMask(u31),
341 };
342 }
343 };
344};
345
346/// Named Addressable Value. Represents a global value with a name and address. This name may be
347/// generated, and the type (and hence address) may be comptime-only. A `Nav` whose type has runtime
348/// bits is sent to the linker to be emitted to the binary.
349///
350/// * Every ZIR `declaration` which is not a `comptime` declaration has a `Nav` (post-instantiation)
351/// which stores the declaration's resolved value.
352/// * Generic instances have a `Nav` corresponding to the instantiated function.
353/// * `@extern` calls create a `Nav` whose value is a `.@"extern"`.
354///
355/// `Nav.Repr` is the in-memory representation.
356pub const Nav = struct {
357 /// The unqualified name of this `Nav`. Namespace lookups use this name, and error messages may use it.
358 /// Additionally, extern `Nav`s (i.e. those whose value is an `extern`) use this name.
359 name: NullTerminatedString,
360 /// The fully-qualified name of this `Nav`.
361 fqn: NullTerminatedString,
362 /// If the value of this `Nav` is resolved by semantic analysis, it is within this `Cau`.
363 /// If this is `.none`, then `status == .resolved` always.
364 analysis_owner: Cau.Index.Optional,
365 /// TODO: this is a hack! If #20663 isn't accepted, let's figure out something a bit better.
366 is_usingnamespace: bool,
367 status: union(enum) {
368 /// This `Nav` is pending semantic analysis through `analysis_owner`.
369 unresolved,
370 /// The value of this `Nav` is resolved.
371 resolved: struct {
372 val: InternPool.Index,
373 alignment: Alignment,
374 @"linksection": OptionalNullTerminatedString,
375 @"addrspace": std.builtin.AddressSpace,
376 },
377 },
378
379 /// Asserts that `status == .resolved`.
380 pub fn typeOf(nav: Nav, ip: *const InternPool) InternPool.Index {
381 return ip.typeOf(nav.status.resolved.val);
382 }
383
384 /// Asserts that `status == .resolved`.
385 pub fn isExtern(nav: Nav, ip: *const InternPool) bool {
386 return ip.indexToKey(nav.status.resolved.val) == .@"extern";
387 }
388
389 /// Get the ZIR instruction corresponding to this `Nav`, used to resolve source locations.
390 /// This is a `declaration`.
391 pub fn srcInst(nav: Nav, ip: *const InternPool) TrackedInst.Index {
392 if (nav.analysis_owner.unwrap()) |cau| {
393 return ip.getCau(cau).zir_index;
394 }
395 // A `Nav` with no corresponding `Cau` always has a resolved value.
396 return switch (ip.indexToKey(nav.status.resolved.val)) {
397 .func => |func| {
398 // Since there was no `analysis_owner`, this must be an instantiation.
399 // Go up to the generic owner and consult *its* `analysis_owner`.
400 const go_nav = ip.getNav(ip.indexToKey(func.generic_owner).func.owner_nav);
401 const go_cau = ip.getCau(go_nav.analysis_owner.unwrap().?);
402 return go_cau.zir_index;
403 },
404 .@"extern" => |@"extern"| @"extern".zir_index, // extern / @extern
405 else => unreachable,
406 };
407 }
408
409 pub const Index = enum(u32) {
410 _,
411 pub const Optional = enum(u32) {
412 none = std.math.maxInt(u32),
413 _,
414 pub fn unwrap(opt: Optional) ?Nav.Index {
415 return switch (opt) {
416 .none => null,
417 _ => @enumFromInt(@intFromEnum(opt)),
418 };
419 }
420 };
421 pub fn toOptional(i: Nav.Index) Optional {
422 return @enumFromInt(@intFromEnum(i));
423 }
424 const Unwrapped = struct {
425 tid: Zcu.PerThread.Id,
426 index: u32,
427
428 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Nav.Index {
429 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
430 assert(unwrapped.index <= ip.getIndexMask(u32));
431 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
432 unwrapped.index);
433 }
434 };
435 fn unwrap(nav_index: Nav.Index, ip: *const InternPool) Unwrapped {
436 return .{
437 .tid = @enumFromInt(@intFromEnum(nav_index) >> ip.tid_shift_32 & ip.getTidMask()),
438 .index = @intFromEnum(nav_index) & ip.getIndexMask(u32),
439 };
440 }
441 };
442
443 /// The compact in-memory representation of a `Nav`.
444 /// 18 bytes.
445 const Repr = struct {
446 name: NullTerminatedString,
447 fqn: NullTerminatedString,
448 analysis_owner: Cau.Index.Optional,
449 /// Populated only if `bits.status == .resolved`.
450 val: InternPool.Index,
451 /// Populated only if `bits.status == .resolved`.
452 @"linksection": OptionalNullTerminatedString,
453 bits: Bits,
454
455 const Bits = packed struct(u16) {
456 status: enum(u1) { unresolved, resolved },
457 /// Populated only if `bits.status == .resolved`.
458 alignment: Alignment,
459 /// Populated only if `bits.status == .resolved`.
460 @"addrspace": std.builtin.AddressSpace,
461 _: u3 = 0,
462 is_usingnamespace: bool,
463 };
464
465 fn unpack(repr: Repr) Nav {
466 return .{
467 .name = repr.name,
468 .fqn = repr.fqn,
469 .analysis_owner = repr.analysis_owner,
470 .is_usingnamespace = repr.bits.is_usingnamespace,
471 .status = switch (repr.bits.status) {
472 .unresolved => .unresolved,
473 .resolved => .{ .resolved = .{
474 .val = repr.val,
475 .alignment = repr.bits.alignment,
476 .@"linksection" = repr.@"linksection",
477 .@"addrspace" = repr.bits.@"addrspace",
478 } },
479 },
480 };
481 }
482 };
483
484 fn pack(nav: Nav) Repr {
485 // Note that in the `unresolved` case, we do not mark fields as `undefined`, even though they should not be used.
486 // This is to avoid writing undefined bytes to disk when serializing buffers.
487 return .{
488 .name = nav.name,
489 .fqn = nav.fqn,
490 .analysis_owner = nav.analysis_owner,
491 .val = switch (nav.status) {
492 .unresolved => .none,
493 .resolved => |r| r.val,
494 },
495 .@"linksection" = switch (nav.status) {
496 .unresolved => .none,
497 .resolved => |r| r.@"linksection",
498 },
499 .bits = switch (nav.status) {
500 .unresolved => .{
501 .status = .unresolved,
502 .alignment = .none,
503 .@"addrspace" = .generic,
504 .is_usingnamespace = nav.is_usingnamespace,
505 },
506 .resolved => |r| .{
507 .status = .resolved,
508 .alignment = r.alignment,
509 .@"addrspace" = r.@"addrspace",
510 .is_usingnamespace = nav.is_usingnamespace,
511 },
512 },
513 };
514 }
515};
516
250517pub const Dependee = union(enum) {
251518 src_hash: TrackedInst.Index,
252 decl_val: DeclIndex,
253 func_ies: Index,
519 nav_val: Nav.Index,
520 interned: Index,
254521 namespace: TrackedInst.Index,
255522 namespace_name: NamespaceNameKey,
256523};
......@@ -297,8 +564,8 @@ pub const DependencyIterator = struct {
297564pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyIterator {
298565 const first_entry = switch (dependee) {
299566 .src_hash => |x| ip.src_hash_deps.get(x),
300 .decl_val => |x| ip.decl_val_deps.get(x),
301 .func_ies => |x| ip.func_ies_deps.get(x),
567 .nav_val => |x| ip.nav_val_deps.get(x),
568 .interned => |x| ip.interned_deps.get(x),
302569 .namespace => |x| ip.namespace_deps.get(x),
303570 .namespace_name => |x| ip.namespace_name_deps.get(x),
304571 } orelse return .{
......@@ -337,8 +604,8 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
337604 inline else => |dependee_payload, tag| new_index: {
338605 const gop = try switch (tag) {
339606 .src_hash => ip.src_hash_deps,
340 .decl_val => ip.decl_val_deps,
341 .func_ies => ip.func_ies_deps,
607 .nav_val => ip.nav_val_deps,
608 .interned => ip.interned_deps,
342609 .namespace => ip.namespace_deps,
343610 .namespace_name => ip.namespace_name_deps,
344611 }.getOrPut(gpa, dependee_payload);
......@@ -426,8 +693,9 @@ const Local = struct {
426693 tracked_insts: ListMutate,
427694 files: ListMutate,
428695 maps: ListMutate,
696 caus: ListMutate,
697 navs: ListMutate,
429698
430 decls: BucketListMutate,
431699 namespaces: BucketListMutate,
432700 } align(std.atomic.cache_line),
433701
......@@ -439,8 +707,9 @@ const Local = struct {
439707 tracked_insts: TrackedInsts,
440708 files: List(File),
441709 maps: Maps,
710 caus: Caus,
711 navs: Navs,
442712
443 decls: Decls,
444713 namespaces: Namespaces,
445714
446715 pub fn getLimbs(shared: *const Local.Shared) Limbs {
......@@ -461,15 +730,12 @@ const Local = struct {
461730 const Strings = List(struct { u8 });
462731 const TrackedInsts = List(struct { TrackedInst });
463732 const Maps = List(struct { FieldMap });
464
465 const decls_bucket_width = 8;
466 const decls_bucket_mask = (1 << decls_bucket_width) - 1;
467 const decl_next_free_field = "src_namespace";
468 const Decls = List(struct { *[1 << decls_bucket_width]Zcu.Decl });
733 const Caus = List(struct { Cau });
734 const Navs = List(Nav.Repr);
469735
470736 const namespaces_bucket_width = 8;
471737 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;
472 const namespace_next_free_field = "decl_index";
738 const namespace_next_free_field = "owner_type";
473739 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });
474740
475741 const ListMutate = struct {
......@@ -810,8 +1076,6 @@ const Local = struct {
8101076 ///
8111077 /// Key is the hash of the path to this file, used to store
8121078 /// `InternPool.TrackedInst`.
813 ///
814 /// Value is the `Decl` of the struct that represents this `File`.
8151079 pub fn getMutableFiles(local: *Local, gpa: Allocator) List(File).Mutable {
8161080 return .{
8171081 .gpa = gpa,
......@@ -835,26 +1099,34 @@ const Local = struct {
8351099 };
8361100 }
8371101
838 /// Rather than allocating Decl objects with an Allocator, we instead allocate
839 /// them with this BucketList. This provides four advantages:
840 /// * Stable memory so that one thread can access a Decl object while another
841 /// thread allocates additional Decl objects from this list.
842 /// * It allows us to use u32 indexes to reference Decl objects rather than
843 /// pointers, saving memory in Type, Value, and dependency sets.
844 /// * Using integers to reference Decl objects rather than pointers makes
845 /// serialization trivial.
846 /// * It provides a unique integer to be used for anonymous symbol names, avoiding
847 /// multi-threaded contention on an atomic counter.
848 pub fn getMutableDecls(local: *Local, gpa: Allocator) Decls.Mutable {
1102 pub fn getMutableCaus(local: *Local, gpa: Allocator) Caus.Mutable {
8491103 return .{
8501104 .gpa = gpa,
8511105 .arena = &local.mutate.arena,
852 .mutate = &local.mutate.decls.buckets_list,
853 .list = &local.shared.decls,
1106 .mutate = &local.mutate.caus,
1107 .list = &local.shared.caus,
8541108 };
8551109 }
8561110
857 /// Same pattern as with `getMutableDecls`.
1111 pub fn getMutableNavs(local: *Local, gpa: Allocator) Navs.Mutable {
1112 return .{
1113 .gpa = gpa,
1114 .arena = &local.mutate.arena,
1115 .mutate = &local.mutate.navs,
1116 .list = &local.shared.navs,
1117 };
1118 }
1119
1120 /// Rather than allocating Namespace objects with an Allocator, we instead allocate
1121 /// them with this BucketList. This provides four advantages:
1122 /// * Stable memory so that one thread can access a Namespace object while another
1123 /// thread allocates additional Namespace objects from this list.
1124 /// * It allows us to use u32 indexes to reference Namespace objects rather than
1125 /// pointers, saving memory in types.
1126 /// * Using integers to reference Namespace objects rather than pointers makes
1127 /// serialization trivial.
1128 /// * It provides a unique integer to be used for anonymous symbol names, avoiding
1129 /// multi-threaded contention on an atomic counter.
8581130 pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable {
8591131 return .{
8601132 .gpa = gpa,
......@@ -1038,51 +1310,6 @@ pub const RuntimeIndex = enum(u32) {
10381310
10391311pub const ComptimeAllocIndex = enum(u32) { _ };
10401312
1041pub const DeclIndex = enum(u32) {
1042 _,
1043
1044 const Unwrapped = struct {
1045 tid: Zcu.PerThread.Id,
1046 bucket_index: u32,
1047 index: u32,
1048
1049 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) DeclIndex {
1050 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
1051 assert(unwrapped.bucket_index <= ip.getIndexMask(u32) >> Local.decls_bucket_width);
1052 assert(unwrapped.index <= Local.decls_bucket_mask);
1053 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1054 unwrapped.bucket_index << Local.decls_bucket_width |
1055 unwrapped.index);
1056 }
1057 };
1058 fn unwrap(decl_index: DeclIndex, ip: *const InternPool) Unwrapped {
1059 const index = @intFromEnum(decl_index) & ip.getIndexMask(u32);
1060 return .{
1061 .tid = @enumFromInt(@intFromEnum(decl_index) >> ip.tid_shift_32 & ip.getTidMask()),
1062 .bucket_index = index >> Local.decls_bucket_width,
1063 .index = index & Local.decls_bucket_mask,
1064 };
1065 }
1066
1067 pub fn toOptional(i: DeclIndex) OptionalDeclIndex {
1068 return @enumFromInt(@intFromEnum(i));
1069 }
1070};
1071
1072pub const OptionalDeclIndex = enum(u32) {
1073 none = std.math.maxInt(u32),
1074 _,
1075
1076 pub fn init(oi: ?DeclIndex) OptionalDeclIndex {
1077 return @enumFromInt(@intFromEnum(oi orelse return .none));
1078 }
1079
1080 pub fn unwrap(oi: OptionalDeclIndex) ?DeclIndex {
1081 if (oi == .none) return null;
1082 return @enumFromInt(@intFromEnum(oi));
1083 }
1084};
1085
10861313pub const NamespaceIndex = enum(u32) {
10871314 _,
10881315
......@@ -1153,7 +1380,8 @@ pub const FileIndex = enum(u32) {
11531380const File = struct {
11541381 bin_digest: Cache.BinDigest,
11551382 file: *Zcu.File,
1156 root_decl: OptionalDeclIndex,
1383 /// `.none` means no type has been created yet.
1384 root_type: InternPool.Index,
11571385};
11581386
11591387/// An index into `strings`.
......@@ -1332,26 +1560,26 @@ pub const OptionalNullTerminatedString = enum(u32) {
13321560/// `Index` because we must differentiate between the following cases:
13331561/// * runtime-known value (where we store the type)
13341562/// * comptime-known value (where we store the value)
1335/// * decl val (so that we can analyze the value lazily)
1336/// * decl ref (so that we can analyze the reference lazily)
1563/// * `Nav` val (so that we can analyze the value lazily)
1564/// * `Nav` ref (so that we can analyze the reference lazily)
13371565pub const CaptureValue = packed struct(u32) {
1338 tag: enum(u2) { @"comptime", runtime, decl_val, decl_ref },
1566 tag: enum(u2) { @"comptime", runtime, nav_val, nav_ref },
13391567 idx: u30,
13401568
13411569 pub fn wrap(val: Unwrapped) CaptureValue {
13421570 return switch (val) {
13431571 .@"comptime" => |i| .{ .tag = .@"comptime", .idx = @intCast(@intFromEnum(i)) },
13441572 .runtime => |i| .{ .tag = .runtime, .idx = @intCast(@intFromEnum(i)) },
1345 .decl_val => |i| .{ .tag = .decl_val, .idx = @intCast(@intFromEnum(i)) },
1346 .decl_ref => |i| .{ .tag = .decl_ref, .idx = @intCast(@intFromEnum(i)) },
1573 .nav_val => |i| .{ .tag = .nav_val, .idx = @intCast(@intFromEnum(i)) },
1574 .nav_ref => |i| .{ .tag = .nav_ref, .idx = @intCast(@intFromEnum(i)) },
13471575 };
13481576 }
13491577 pub fn unwrap(val: CaptureValue) Unwrapped {
13501578 return switch (val.tag) {
13511579 .@"comptime" => .{ .@"comptime" = @enumFromInt(val.idx) },
13521580 .runtime => .{ .runtime = @enumFromInt(val.idx) },
1353 .decl_val => .{ .decl_val = @enumFromInt(val.idx) },
1354 .decl_ref => .{ .decl_ref = @enumFromInt(val.idx) },
1581 .nav_val => .{ .nav_val = @enumFromInt(val.idx) },
1582 .nav_ref => .{ .nav_ref = @enumFromInt(val.idx) },
13551583 };
13561584 }
13571585
......@@ -1360,8 +1588,8 @@ pub const CaptureValue = packed struct(u32) {
13601588 @"comptime": Index,
13611589 /// Index refers to the type.
13621590 runtime: Index,
1363 decl_val: DeclIndex,
1364 decl_ref: DeclIndex,
1591 nav_val: Nav.Index,
1592 nav_ref: Nav.Index,
13651593 };
13661594
13671595 pub const Slice = struct {
......@@ -1410,7 +1638,7 @@ pub const Key = union(enum) {
14101638 undef: Index,
14111639 simple_value: SimpleValue,
14121640 variable: Variable,
1413 extern_func: ExternFunc,
1641 @"extern": Extern,
14141642 func: Func,
14151643 int: Key.Int,
14161644 err: Error,
......@@ -1637,25 +1865,37 @@ pub const Key = union(enum) {
16371865 }
16381866 };
16391867
1868 /// A runtime variable defined in this `Zcu`.
16401869 pub const Variable = struct {
16411870 ty: Index,
16421871 init: Index,
1643 decl: DeclIndex,
1872 owner_nav: Nav.Index,
16441873 lib_name: OptionalNullTerminatedString,
1645 is_extern: bool,
1646 is_const: bool,
16471874 is_threadlocal: bool,
16481875 is_weak_linkage: bool,
16491876 };
16501877
1651 pub const ExternFunc = struct {
1878 pub const Extern = struct {
1879 /// The name of the extern symbol.
1880 name: NullTerminatedString,
1881 /// The type of the extern symbol itself.
1882 /// This may be `.anyopaque_type`, in which case the value may not be loaded.
16521883 ty: Index,
1653 /// The Decl that corresponds to the function itself.
1654 decl: DeclIndex,
16551884 /// Library name if specified.
16561885 /// For example `extern "c" fn write(...) usize` would have 'c' as library name.
16571886 /// Index into the string table bytes.
16581887 lib_name: OptionalNullTerminatedString,
1888 is_const: bool,
1889 is_threadlocal: bool,
1890 is_weak_linkage: bool,
1891 alignment: Alignment,
1892 @"addrspace": std.builtin.AddressSpace,
1893 /// The ZIR instruction which created this extern; used only for source locations.
1894 /// This is a `declaration`.
1895 zir_index: TrackedInst.Index,
1896 /// The `Nav` corresponding to this extern symbol.
1897 /// This is ignored by hashing and equality.
1898 owner_nav: Nav.Index,
16591899 };
16601900
16611901 pub const Func = struct {
......@@ -1687,8 +1927,7 @@ pub const Key = union(enum) {
16871927 /// so that it can be mutated.
16881928 /// This will be 0 when the function is not a generic function instantiation.
16891929 branch_quota_extra_index: u32,
1690 /// The Decl that corresponds to the function itself.
1691 owner_decl: DeclIndex,
1930 owner_nav: Nav.Index,
16921931 /// The ZIR instruction that is a function instruction. Use this to find
16931932 /// the body. We store this rather than the body directly so that when ZIR
16941933 /// is regenerated on update(), we can map this to the new corresponding
......@@ -1861,14 +2100,14 @@ pub const Key = union(enum) {
18612100 pub const BaseAddr = union(enum) {
18622101 const Tag = @typeInfo(BaseAddr).Union.tag_type.?;
18632102
1864 /// Points to the value of a single `Decl`, which may be constant or a `variable`.
1865 decl: DeclIndex,
2103 /// Points to the value of a single `Nav`, which may be constant or a `variable`.
2104 nav: Nav.Index,
18662105
18672106 /// Points to the value of a single comptime alloc stored in `Sema`.
18682107 comptime_alloc: ComptimeAllocIndex,
18692108
18702109 /// Points to a single unnamed constant value.
1871 anon_decl: AnonDecl,
2110 uav: Uav,
18722111
18732112 /// Points to a comptime field of a struct. Index is the field's value.
18742113 ///
......@@ -1923,15 +2162,11 @@ pub const Key = union(enum) {
19232162 /// the aggregate pointer.
19242163 arr_elem: BaseIndex,
19252164
1926 pub const MutDecl = struct {
1927 decl: DeclIndex,
1928 runtime_index: RuntimeIndex,
1929 };
19302165 pub const BaseIndex = struct {
19312166 base: Index,
19322167 index: u64,
19332168 };
1934 pub const AnonDecl = extern struct {
2169 pub const Uav = extern struct {
19352170 val: Index,
19362171 /// Contains the canonical pointer type of the anonymous
19372172 /// declaration. This may equal `ty` of the `Ptr` or it may be
......@@ -1944,10 +2179,10 @@ pub const Key = union(enum) {
19442179 if (@as(Key.Ptr.BaseAddr.Tag, a) != @as(Key.Ptr.BaseAddr.Tag, b)) return false;
19452180
19462181 return switch (a) {
1947 .decl => |a_decl| a_decl == b.decl,
2182 .nav => |a_nav| a_nav == b.nav,
19482183 .comptime_alloc => |a_alloc| a_alloc == b.comptime_alloc,
1949 .anon_decl => |ad| ad.val == b.anon_decl.val and
1950 ad.orig_ty == b.anon_decl.orig_ty,
2184 .uav => |ad| ad.val == b.uav.val and
2185 ad.orig_ty == b.uav.orig_ty,
19512186 .int => true,
19522187 .eu_payload => |a_eu_payload| a_eu_payload == b.eu_payload,
19532188 .opt_payload => |a_opt_payload| a_opt_payload == b.opt_payload,
......@@ -2048,7 +2283,7 @@ pub const Key = union(enum) {
20482283 .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)),
20492284 },
20502285
2051 .variable => |variable| Hash.hash(seed, asBytes(&variable.decl)),
2286 .variable => |variable| Hash.hash(seed, asBytes(&variable.owner_nav)),
20522287
20532288 .opaque_type,
20542289 .enum_type,
......@@ -2125,9 +2360,9 @@ pub const Key = union(enum) {
21252360 const big_offset: i128 = ptr.byte_offset;
21262361 const common = asBytes(&ptr.ty) ++ asBytes(&big_offset);
21272362 return switch (ptr.base_addr) {
2128 inline .decl,
2363 inline .nav,
21292364 .comptime_alloc,
2130 .anon_decl,
2365 .uav,
21312366 .int,
21322367 .eu_payload,
21332368 .opt_payload,
......@@ -2231,7 +2466,7 @@ pub const Key = union(enum) {
22312466 // function instances which have inferred error sets.
22322467
22332468 if (func.generic_owner == .none and func.resolved_error_set_extra_index == 0) {
2234 const bytes = asBytes(&func.owner_decl) ++ asBytes(&func.ty) ++
2469 const bytes = asBytes(&func.owner_nav) ++ asBytes(&func.ty) ++
22352470 [1]u8{@intFromBool(func.uncoerced_ty == func.ty)};
22362471 return Hash.hash(seed, bytes);
22372472 }
......@@ -2250,7 +2485,11 @@ pub const Key = union(enum) {
22502485 return hasher.final();
22512486 },
22522487
2253 .extern_func => |x| Hash.hash(seed, asBytes(&x.ty) ++ asBytes(&x.decl)),
2488 .@"extern" => |e| Hash.hash(seed, asBytes(&e.name) ++
2489 asBytes(&e.ty) ++ asBytes(&e.lib_name) ++
2490 asBytes(&e.is_const) ++ asBytes(&e.is_threadlocal) ++
2491 asBytes(&e.is_weak_linkage) ++ asBytes(&e.alignment) ++
2492 asBytes(&e.@"addrspace") ++ asBytes(&e.zir_index)),
22542493 };
22552494 }
22562495
......@@ -2331,11 +2570,19 @@ pub const Key = union(enum) {
23312570
23322571 .variable => |a_info| {
23332572 const b_info = b.variable;
2334 return a_info.decl == b_info.decl;
2573 return a_info.owner_nav == b_info.owner_nav;
23352574 },
2336 .extern_func => |a_info| {
2337 const b_info = b.extern_func;
2338 return a_info.ty == b_info.ty and a_info.decl == b_info.decl;
2575 .@"extern" => |a_info| {
2576 const b_info = b.@"extern";
2577 return a_info.name == b_info.name and
2578 a_info.ty == b_info.ty and
2579 a_info.lib_name == b_info.lib_name and
2580 a_info.is_const == b_info.is_const and
2581 a_info.is_threadlocal == b_info.is_threadlocal and
2582 a_info.is_weak_linkage == b_info.is_weak_linkage and
2583 a_info.alignment == b_info.alignment and
2584 a_info.@"addrspace" == b_info.@"addrspace" and
2585 a_info.zir_index == b_info.zir_index;
23392586 },
23402587 .func => |a_info| {
23412588 const b_info = b.func;
......@@ -2344,7 +2591,7 @@ pub const Key = union(enum) {
23442591 return false;
23452592
23462593 if (a_info.generic_owner == .none) {
2347 if (a_info.owner_decl != b_info.owner_decl)
2594 if (a_info.owner_nav != b_info.owner_nav)
23482595 return false;
23492596 } else {
23502597 if (!std.mem.eql(
......@@ -2594,7 +2841,7 @@ pub const Key = union(enum) {
25942841 .float,
25952842 .opt,
25962843 .variable,
2597 .extern_func,
2844 .@"extern",
25982845 .func,
25992846 .err,
26002847 .error_union,
......@@ -2632,8 +2879,11 @@ pub const LoadedUnionType = struct {
26322879 tid: Zcu.PerThread.Id,
26332880 /// The index of the `Tag.TypeUnion` payload.
26342881 extra_index: u32,
2635 /// The Decl that corresponds to the union itself.
2636 decl: DeclIndex,
2882 // TODO: the non-fqn will be needed by the new dwarf structure
2883 /// The name of this union type.
2884 name: NullTerminatedString,
2885 /// The `Cau` within which type resolution occurs.
2886 cau: Cau.Index,
26372887 /// Represents the declarations inside this union.
26382888 namespace: OptionalNamespaceIndex,
26392889 /// The enum tag type.
......@@ -2949,7 +3199,8 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
29493199 return .{
29503200 .tid = unwrapped_index.tid,
29513201 .extra_index = data,
2952 .decl = type_union.data.decl,
3202 .name = type_union.data.name,
3203 .cau = type_union.data.cau,
29533204 .namespace = type_union.data.namespace,
29543205 .enum_tag_ty = type_union.data.tag_ty,
29553206 .field_types = field_types,
......@@ -2963,8 +3214,11 @@ pub const LoadedStructType = struct {
29633214 tid: Zcu.PerThread.Id,
29643215 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.
29653216 extra_index: u32,
2966 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.
2967 decl: OptionalDeclIndex,
3217 // TODO: the non-fqn will be needed by the new dwarf structure
3218 /// The name of this struct type.
3219 name: NullTerminatedString,
3220 /// The `Cau` within which type resolution occurs. `none` when the struct is `@TypeOf(.{})`.
3221 cau: Cau.Index.Optional,
29683222 /// `none` when the struct has no declarations.
29693223 namespace: OptionalNamespaceIndex,
29703224 /// Index of the `struct_decl` or `reify` ZIR instruction.
......@@ -3563,7 +3817,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
35633817 if (item.data == 0) return .{
35643818 .tid = .main,
35653819 .extra_index = 0,
3566 .decl = .none,
3820 .name = .empty,
3821 .cau = .none,
35673822 .namespace = .none,
35683823 .zir_index = .none,
35693824 .layout = .auto,
......@@ -3577,7 +3832,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
35773832 .names_map = .none,
35783833 .captures = CaptureValue.Slice.empty,
35793834 };
3580 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]);
3835 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);
3836 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "cau").?]);
35813837 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
35823838 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
35833839 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
......@@ -3667,7 +3923,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36673923 return .{
36683924 .tid = unwrapped_index.tid,
36693925 .extra_index = item.data,
3670 .decl = decl.toOptional(),
3926 .name = name,
3927 .cau = cau.toOptional(),
36713928 .namespace = namespace,
36723929 .zir_index = zir_index.toOptional(),
36733930 .layout = if (flags.is_extern) .@"extern" else .auto,
......@@ -3683,7 +3940,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36833940 };
36843941 },
36853942 .type_struct_packed, .type_struct_packed_inits => {
3686 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]);
3943 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]);
3944 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?]);
36873945 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
36883946 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
36893947 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
......@@ -3729,7 +3987,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
37293987 return .{
37303988 .tid = unwrapped_index.tid,
37313989 .extra_index = item.data,
3732 .decl = decl.toOptional(),
3990 .name = name,
3991 .cau = cau.toOptional(),
37333992 .namespace = namespace,
37343993 .zir_index = zir_index.toOptional(),
37353994 .layout = .@"packed",
......@@ -3749,8 +4008,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
37494008}
37504009
37514010const LoadedEnumType = struct {
3752 /// The Decl that corresponds to the enum itself.
3753 decl: DeclIndex,
4011 // TODO: the non-fqn will be needed by the new dwarf structure
4012 /// The name of this enum type.
4013 name: NullTerminatedString,
4014 /// The `Cau` within which type resolution occurs.
4015 /// `null` if this is a generated tag type.
4016 cau: Cau.Index.Optional,
37544017 /// Represents the declarations inside this enum.
37554018 namespace: OptionalNamespaceIndex,
37564019 /// An integer type which is used for the numerical value of the enum.
......@@ -3827,15 +4090,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38274090 .type_enum_auto => {
38284091 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
38294092 var extra_index: u32 = @intCast(extra.end);
3830 if (extra.data.zir_index == .none) {
4093 const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: {
38314094 extra_index += 1; // owner_union
3832 }
4095 break :cau .none;
4096 } else cau: {
4097 const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4098 extra_index += 1; // cau
4099 break :cau cau.toOptional();
4100 };
38334101 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
38344102 extra_index += 2; // type_hash: PackedU64
38354103 break :c 0;
38364104 } else extra.data.captures_len;
38374105 return .{
3838 .decl = extra.data.decl,
4106 .name = extra.data.name,
4107 .cau = cau,
38394108 .namespace = extra.data.namespace,
38404109 .tag_ty = extra.data.int_tag_type,
38414110 .names = .{
......@@ -3861,15 +4130,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38614130 };
38624131 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
38634132 var extra_index: u32 = @intCast(extra.end);
3864 if (extra.data.zir_index == .none) {
4133 const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: {
38654134 extra_index += 1; // owner_union
3866 }
4135 break :cau .none;
4136 } else cau: {
4137 const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4138 extra_index += 1; // cau
4139 break :cau cau.toOptional();
4140 };
38674141 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
38684142 extra_index += 2; // type_hash: PackedU64
38694143 break :c 0;
38704144 } else extra.data.captures_len;
38714145 return .{
3872 .decl = extra.data.decl,
4146 .name = extra.data.name,
4147 .cau = cau,
38734148 .namespace = extra.data.namespace,
38744149 .tag_ty = extra.data.int_tag_type,
38754150 .names = .{
......@@ -3896,10 +4171,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38964171
38974172/// Note that this type doubles as the payload for `Tag.type_opaque`.
38984173pub const LoadedOpaqueType = struct {
3899 /// The opaque's owner Decl.
3900 decl: DeclIndex,
39014174 /// Contains the declarations inside this opaque.
39024175 namespace: OptionalNamespaceIndex,
4176 // TODO: the non-fqn will be needed by the new dwarf structure
4177 /// The name of this opaque type.
4178 name: NullTerminatedString,
39034179 /// Index of the `opaque_decl` or `reify` instruction.
39044180 zir_index: TrackedInst.Index,
39054181 captures: CaptureValue.Slice,
......@@ -3915,7 +4191,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
39154191 else
39164192 extra.data.captures_len;
39174193 return .{
3918 .decl = extra.data.decl,
4194 .name = extra.data.name,
39194195 .namespace = extra.data.namespace,
39204196 .zir_index = extra.data.zir_index,
39214197 .captures = .{
......@@ -4216,10 +4492,10 @@ pub const Index = enum(u32) {
42164492
42174493 undef: DataIsIndex,
42184494 simple_value: void,
4219 ptr_decl: struct { data: *PtrDecl },
4495 ptr_nav: struct { data: *PtrNav },
42204496 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },
4221 ptr_anon_decl: struct { data: *PtrAnonDecl },
4222 ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned },
4497 ptr_uav: struct { data: *PtrUav },
4498 ptr_uav_aligned: struct { data: *PtrUavAligned },
42234499 ptr_comptime_field: struct { data: *PtrComptimeField },
42244500 ptr_int: struct { data: *PtrInt },
42254501 ptr_eu_payload: struct { data: *PtrBase },
......@@ -4255,7 +4531,7 @@ pub const Index = enum(u32) {
42554531 float_c_longdouble_f128: struct { data: *Float128 },
42564532 float_comptime_float: struct { data: *Float128 },
42574533 variable: struct { data: *Tag.Variable },
4258 extern_func: struct { data: *Key.ExternFunc },
4534 @"extern": struct { data: *Tag.Extern },
42594535 func_decl: struct {
42604536 const @"data.analysis.inferred_error_set" = opaque {};
42614537 data: *Tag.FuncDecl,
......@@ -4669,23 +4945,23 @@ pub const Tag = enum(u8) {
46694945 /// A value that can be represented with only an enum tag.
46704946 /// data is SimpleValue enum value.
46714947 simple_value,
4672 /// A pointer to a decl.
4673 /// data is extra index of `PtrDecl`, which contains the type and address.
4674 ptr_decl,
4948 /// A pointer to a `Nav`.
4949 /// data is extra index of `PtrNav`, which contains the type and address.
4950 ptr_nav,
46754951 /// A pointer to a decl that can be mutated at comptime.
46764952 /// data is extra index of `PtrComptimeAlloc`, which contains the type and address.
46774953 ptr_comptime_alloc,
4678 /// A pointer to an anonymous decl.
4679 /// data is extra index of `PtrAnonDecl`, which contains the pointer type and decl value.
4680 /// The alignment of the anonymous decl is communicated via the pointer type.
4681 ptr_anon_decl,
4682 /// A pointer to an anonymous decl.
4683 /// data is extra index of `PtrAnonDeclAligned`, which contains the pointer
4954 /// A pointer to an anonymous addressable value.
4955 /// data is extra index of `PtrUav`, which contains the pointer type and decl value.
4956 /// The alignment of the uav is communicated via the pointer type.
4957 ptr_uav,
4958 /// A pointer to an unnamed addressable value.
4959 /// data is extra index of `PtrUavAligned`, which contains the pointer
46844960 /// type and decl value.
46854961 /// The original pointer type is also provided, which will be different than `ty`.
4686 /// This encoding is only used when a pointer to an anonymous decl is
4962 /// This encoding is only used when a pointer to a Uav is
46874963 /// coerced to a different pointer type with a different alignment.
4688 ptr_anon_decl_aligned,
4964 ptr_uav_aligned,
46894965 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.
46904966 ptr_comptime_field,
46914967 /// A pointer with an integer value.
......@@ -4800,9 +5076,10 @@ pub const Tag = enum(u8) {
48005076 /// A global variable.
48015077 /// data is extra index to Variable.
48025078 variable,
4803 /// An extern function.
4804 /// data is extra index to ExternFunc.
4805 extern_func,
5079 /// An extern function or variable.
5080 /// data is extra index to Extern.
5081 /// Some parts of the key are stored in `owner_nav`.
5082 @"extern",
48065083 /// A non-extern function corresponding directly to the AST node from whence it originated.
48075084 /// data is extra index to `FuncDecl`.
48085085 /// Only the owner Decl is used for hashing and equality because the other
......@@ -4843,7 +5120,6 @@ pub const Tag = enum(u8) {
48435120 const TypeValue = Key.TypeValue;
48445121 const Error = Key.Error;
48455122 const EnumTag = Key.EnumTag;
4846 const ExternFunc = Key.ExternFunc;
48475123 const Union = Key.Union;
48485124 const TypePointer = Key.PtrType;
48495125
......@@ -4877,10 +5153,10 @@ pub const Tag = enum(u8) {
48775153
48785154 .undef => unreachable,
48795155 .simple_value => unreachable,
4880 .ptr_decl => PtrDecl,
5156 .ptr_nav => PtrNav,
48815157 .ptr_comptime_alloc => PtrComptimeAlloc,
4882 .ptr_anon_decl => PtrAnonDecl,
4883 .ptr_anon_decl_aligned => PtrAnonDeclAligned,
5158 .ptr_uav => PtrUav,
5159 .ptr_uav_aligned => PtrUavAligned,
48845160 .ptr_comptime_field => PtrComptimeField,
48855161 .ptr_int => PtrInt,
48865162 .ptr_eu_payload => PtrBase,
......@@ -4916,7 +5192,7 @@ pub const Tag = enum(u8) {
49165192 .float_c_longdouble_f128 => unreachable,
49175193 .float_comptime_float => unreachable,
49185194 .variable => Variable,
4919 .extern_func => ExternFunc,
5195 .@"extern" => Extern,
49205196 .func_decl => FuncDecl,
49215197 .func_instance => FuncInstance,
49225198 .func_coerced => FuncCoerced,
......@@ -4933,21 +5209,29 @@ pub const Tag = enum(u8) {
49335209 ty: Index,
49345210 /// May be `none`.
49355211 init: Index,
4936 decl: DeclIndex,
5212 owner_nav: Nav.Index,
49375213 /// Library name if specified.
49385214 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.
49395215 lib_name: OptionalNullTerminatedString,
49405216 flags: Flags,
49415217
49425218 pub const Flags = packed struct(u32) {
4943 is_extern: bool,
49445219 is_const: bool,
49455220 is_threadlocal: bool,
49465221 is_weak_linkage: bool,
4947 _: u28 = 0,
5222 _: u29 = 0,
49485223 };
49495224 };
49505225
5226 pub const Extern = struct {
5227 // name, alignment, addrspace come from `owner_nav`.
5228 ty: Index,
5229 lib_name: OptionalNullTerminatedString,
5230 flags: Variable.Flags,
5231 owner_nav: Nav.Index,
5232 zir_index: TrackedInst.Index,
5233 };
5234
49515235 /// Trailing:
49525236 /// 0. element: Index for each len
49535237 /// len is determined by the aggregate type.
......@@ -4962,7 +5246,7 @@ pub const Tag = enum(u8) {
49625246 /// A `none` value marks that the inferred error set is not resolved yet.
49635247 pub const FuncDecl = struct {
49645248 analysis: FuncAnalysis,
4965 owner_decl: DeclIndex,
5249 owner_nav: Nav.Index,
49665250 ty: Index,
49675251 zir_body_inst: TrackedInst.Index,
49685252 lbrace_line: u32,
......@@ -4979,7 +5263,7 @@ pub const Tag = enum(u8) {
49795263 pub const FuncInstance = struct {
49805264 analysis: FuncAnalysis,
49815265 // Needed by the linker for codegen. Not part of hashing or equality.
4982 owner_decl: DeclIndex,
5266 owner_nav: Nav.Index,
49835267 ty: Index,
49845268 branch_quota: u32,
49855269 /// Points to a `FuncDecl`.
......@@ -5029,6 +5313,7 @@ pub const Tag = enum(u8) {
50295313 /// 3. field type: Index for each field; declaration order
50305314 /// 4. field align: Alignment for each field; declaration order
50315315 pub const TypeUnion = struct {
5316 name: NullTerminatedString,
50325317 flags: Flags,
50335318 /// This could be provided through the tag type, but it is more convenient
50345319 /// to store it directly. This is also necessary for `dumpStatsFallible` to
......@@ -5038,7 +5323,7 @@ pub const Tag = enum(u8) {
50385323 size: u32,
50395324 /// Only valid after .have_layout
50405325 padding: u32,
5041 decl: DeclIndex,
5326 cau: Cau.Index,
50425327 namespace: OptionalNamespaceIndex,
50435328 /// The enum that provides the list of field names and values.
50445329 tag_ty: Index,
......@@ -5068,7 +5353,8 @@ pub const Tag = enum(u8) {
50685353 /// 4. name: NullTerminatedString for each fields_len
50695354 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits
50705355 pub const TypeStructPacked = struct {
5071 decl: DeclIndex,
5356 name: NullTerminatedString,
5357 cau: Cau.Index,
50725358 zir_index: TrackedInst.Index,
50735359 fields_len: u32,
50745360 namespace: OptionalNamespaceIndex,
......@@ -5120,7 +5406,8 @@ pub const Tag = enum(u8) {
51205406 /// field_index: RuntimeOrder // for each field in runtime order
51215407 /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved
51225408 pub const TypeStruct = struct {
5123 decl: DeclIndex,
5409 name: NullTerminatedString,
5410 cau: Cau.Index,
51245411 zir_index: TrackedInst.Index,
51255412 fields_len: u32,
51265413 flags: Flags,
......@@ -5164,8 +5451,7 @@ pub const Tag = enum(u8) {
51645451 /// Trailing:
51655452 /// 0. capture: CaptureValue // for each `captures_len`
51665453 pub const TypeOpaque = struct {
5167 /// The opaque's owner Decl.
5168 decl: DeclIndex,
5454 name: NullTerminatedString,
51695455 /// Contains the declarations inside this opaque.
51705456 namespace: OptionalNamespaceIndex,
51715457 /// The index of the `opaque_decl` instruction.
......@@ -5188,29 +5474,19 @@ pub const FuncAnalysis = packed struct(u32) {
51885474 inferred_error_set: bool,
51895475 disable_instrumentation: bool,
51905476
5191 _: u13 = 0,
5477 _: u19 = 0,
51925478
5193 pub const State = enum(u8) {
5194 /// This function has not yet undergone analysis, because we have not
5195 /// seen a potential runtime call. It may be analyzed in future.
5196 none,
5197 /// Analysis for this function has been queued, but not yet completed.
5479 pub const State = enum(u2) {
5480 /// The runtime function has never been referenced.
5481 /// As such, it has never been analyzed, nor is it queued for analysis.
5482 unreferenced,
5483 /// The runtime function has been referenced, but has not yet been analyzed.
5484 /// Its semantic analysis is queued.
51985485 queued,
5199 /// This function intentionally only has ZIR generated because it is marked
5200 /// inline, which means no runtime version of the function will be generated.
5201 inline_only,
5202 in_progress,
5203 /// There will be a corresponding ErrorMsg in Zcu.failed_decls
5204 sema_failure,
5205 /// This function might be OK but it depends on another Decl which did not
5206 /// successfully complete semantic analysis.
5207 dependency_failure,
5208 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
5209 /// Indicates that semantic analysis succeeded, but code generation for
5210 /// this function failed.
5211 codegen_failure,
5212 /// Semantic analysis and code generation of this function succeeded.
5213 success,
5486 /// The runtime function has been (or is currently being) semantically analyzed.
5487 /// To know if analysis succeeded, consult `zcu.[transitive_]failed_analysis`.
5488 /// To know if analysis is up-to-date, consult `zcu.[potentially_]outdated`.
5489 analyzed,
52145490 };
52155491};
52165492
......@@ -5477,13 +5753,13 @@ pub const Array = struct {
54775753
54785754/// Trailing:
54795755/// 0. owner_union: Index // if `zir_index == .none`
5480/// 1. capture: CaptureValue // for each `captures_len`
5481/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5482/// 3. field name: NullTerminatedString for each fields_len; declaration order
5483/// 4. tag value: Index for each fields_len; declaration order
5756/// 1. cau: Cau.Index // if `zir_index != .none`
5757/// 2. capture: CaptureValue // for each `captures_len`
5758/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5759/// 4. field name: NullTerminatedString for each fields_len; declaration order
5760/// 5. tag value: Index for each fields_len; declaration order
54845761pub const EnumExplicit = struct {
5485 /// The Decl that corresponds to the enum itself.
5486 decl: DeclIndex,
5762 name: NullTerminatedString,
54875763 /// `std.math.maxInt(u32)` indicates this type is reified.
54885764 captures_len: u32,
54895765 /// This may be `none` if there are no declarations.
......@@ -5505,12 +5781,12 @@ pub const EnumExplicit = struct {
55055781
55065782/// Trailing:
55075783/// 0. owner_union: Index // if `zir_index == .none`
5508/// 1. capture: CaptureValue // for each `captures_len`
5509/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5510/// 3. field name: NullTerminatedString for each fields_len; declaration order
5784/// 1. cau: Cau.Index // if `zir_index != .none`
5785/// 2. capture: CaptureValue // for each `captures_len`
5786/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5787/// 4. field name: NullTerminatedString for each fields_len; declaration order
55115788pub const EnumAuto = struct {
5512 /// The Decl that corresponds to the enum itself.
5513 decl: DeclIndex,
5789 name: NullTerminatedString,
55145790 /// `std.math.maxInt(u32)` indicates this type is reified.
55155791 captures_len: u32,
55165792 /// This may be `none` if there are no declarations.
......@@ -5539,15 +5815,15 @@ pub const PackedU64 = packed struct(u64) {
55395815 }
55405816};
55415817
5542pub const PtrDecl = struct {
5818pub const PtrNav = struct {
55435819 ty: Index,
5544 decl: DeclIndex,
5820 nav: Nav.Index,
55455821 byte_offset_a: u32,
55465822 byte_offset_b: u32,
5547 fn init(ty: Index, decl: DeclIndex, byte_offset: u64) @This() {
5823 fn init(ty: Index, nav: Nav.Index, byte_offset: u64) @This() {
55485824 return .{
55495825 .ty = ty,
5550 .decl = decl,
5826 .nav = nav,
55515827 .byte_offset_a = @intCast(byte_offset >> 32),
55525828 .byte_offset_b = @truncate(byte_offset),
55535829 };
......@@ -5557,7 +5833,7 @@ pub const PtrDecl = struct {
55575833 }
55585834};
55595835
5560pub const PtrAnonDecl = struct {
5836pub const PtrUav = struct {
55615837 ty: Index,
55625838 val: Index,
55635839 byte_offset_a: u32,
......@@ -5575,7 +5851,7 @@ pub const PtrAnonDecl = struct {
55755851 }
55765852};
55775853
5578pub const PtrAnonDeclAligned = struct {
5854pub const PtrUavAligned = struct {
55795855 ty: Index,
55805856 val: Index,
55815857 /// Must be nonequal to `ty`. Only the alignment from this value is important.
......@@ -5805,8 +6081,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58056081 .tracked_insts = Local.TrackedInsts.empty,
58066082 .files = Local.List(File).empty,
58076083 .maps = Local.Maps.empty,
6084 .caus = Local.Caus.empty,
6085 .navs = Local.Navs.empty,
58086086
5809 .decls = Local.Decls.empty,
58106087 .namespaces = Local.Namespaces.empty,
58116088 },
58126089 .mutate = .{
......@@ -5819,8 +6096,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58196096 .tracked_insts = Local.ListMutate.empty,
58206097 .files = Local.ListMutate.empty,
58216098 .maps = Local.ListMutate.empty,
6099 .caus = Local.ListMutate.empty,
6100 .navs = Local.ListMutate.empty,
58226101
5823 .decls = Local.BucketListMutate.empty,
58246102 .namespaces = Local.BucketListMutate.empty,
58256103 },
58266104 });
......@@ -5878,8 +6156,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58786156
58796157pub fn deinit(ip: *InternPool, gpa: Allocator) void {
58806158 ip.src_hash_deps.deinit(gpa);
5881 ip.decl_val_deps.deinit(gpa);
5882 ip.func_ies_deps.deinit(gpa);
6159 ip.nav_val_deps.deinit(gpa);
6160 ip.interned_deps.deinit(gpa);
58836161 ip.namespace_deps.deinit(gpa);
58846162 ip.namespace_name_deps.deinit(gpa);
58856163
......@@ -5900,8 +6178,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
59006178 else
59016179 local.mutate.namespaces.last_bucket_len]) |*namespace|
59026180 {
5903 namespace.decls.deinit(gpa);
5904 namespace.usingnamespace_set.deinit(gpa);
6181 namespace.pub_decls.deinit(gpa);
6182 namespace.priv_decls.deinit(gpa);
6183 namespace.pub_usingnamespace.deinit(gpa);
6184 namespace.priv_usingnamespace.deinit(gpa);
6185 namespace.other_decls.deinit(gpa);
59056186 }
59066187 };
59076188 const maps = local.getMutableMaps(gpa);
......@@ -6082,14 +6363,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
60826363 if (extra.data.captures_len == std.math.maxInt(u32)) {
60836364 break :ns .{ .reified = .{
60846365 .zir_index = zir_index,
6085 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6366 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
60866367 } };
60876368 }
60886369 break :ns .{ .declared = .{
60896370 .zir_index = zir_index,
60906371 .captures = .{ .owned = .{
60916372 .tid = unwrapped_index.tid,
6092 .start = extra.end,
6373 .start = extra.end + 1,
60936374 .len = extra.data.captures_len,
60946375 } },
60956376 } };
......@@ -6106,14 +6387,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
61066387 if (extra.data.captures_len == std.math.maxInt(u32)) {
61076388 break :ns .{ .reified = .{
61086389 .zir_index = zir_index,
6109 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6390 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
61106391 } };
61116392 }
61126393 break :ns .{ .declared = .{
61136394 .zir_index = zir_index,
61146395 .captures = .{ .owned = .{
61156396 .tid = unwrapped_index.tid,
6116 .start = extra.end,
6397 .start = extra.end + 1,
61176398 .len = extra.data.captures_len,
61186399 } },
61196400 } };
......@@ -6132,24 +6413,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
61326413 .val = extra.val,
61336414 } };
61346415 },
6135 .ptr_decl => {
6136 const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data);
6137 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };
6416 .ptr_nav => {
6417 const info = extraData(unwrapped_index.getExtra(ip), PtrNav, data);
6418 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .nav = info.nav }, .byte_offset = info.byteOffset() } };
61386419 },
61396420 .ptr_comptime_alloc => {
61406421 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);
61416422 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
61426423 },
6143 .ptr_anon_decl => {
6144 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);
6145 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
6424 .ptr_uav => {
6425 const info = extraData(unwrapped_index.getExtra(ip), PtrUav, data);
6426 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
61466427 .val = info.val,
61476428 .orig_ty = info.ty,
61486429 } }, .byte_offset = info.byteOffset() } };
61496430 },
6150 .ptr_anon_decl_aligned => {
6151 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data);
6152 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
6431 .ptr_uav_aligned => {
6432 const info = extraData(unwrapped_index.getExtra(ip), PtrUavAligned, data);
6433 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
61536434 .val = info.val,
61546435 .orig_ty = info.orig_ty,
61556436 } }, .byte_offset = info.byteOffset() } };
......@@ -6293,15 +6574,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
62936574 return .{ .variable = .{
62946575 .ty = extra.ty,
62956576 .init = extra.init,
6296 .decl = extra.decl,
6577 .owner_nav = extra.owner_nav,
6578 .lib_name = extra.lib_name,
6579 .is_threadlocal = extra.flags.is_threadlocal,
6580 .is_weak_linkage = extra.flags.is_weak_linkage,
6581 } };
6582 },
6583 .@"extern" => {
6584 const extra = extraData(unwrapped_index.getExtra(ip), Tag.Extern, data);
6585 const nav = ip.getNav(extra.owner_nav);
6586 return .{ .@"extern" = .{
6587 .name = nav.name,
6588 .ty = extra.ty,
62976589 .lib_name = extra.lib_name,
6298 .is_extern = extra.flags.is_extern,
62996590 .is_const = extra.flags.is_const,
63006591 .is_threadlocal = extra.flags.is_threadlocal,
63016592 .is_weak_linkage = extra.flags.is_weak_linkage,
6593 .alignment = nav.status.resolved.alignment,
6594 .@"addrspace" = nav.status.resolved.@"addrspace",
6595 .zir_index = extra.zir_index,
6596 .owner_nav = extra.owner_nav,
63026597 } };
63036598 },
6304 .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) },
63056599 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
63066600 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
63076601 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },
......@@ -6513,7 +6807,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
65136807 .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?,
65146808 .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0,
65156809 .branch_quota_extra_index = 0,
6516 .owner_decl = func_decl.data.owner_decl,
6810 .owner_nav = func_decl.data.owner_nav,
65176811 .zir_body_inst = func_decl.data.zir_body_inst,
65186812 .lbrace_line = func_decl.data.lbrace_line,
65196813 .rbrace_line = func_decl.data.rbrace_line,
......@@ -6528,7 +6822,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
65286822 const extra_items = extra.view().items(.@"0");
65296823 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;
65306824 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .unordered));
6531 const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]);
6825 const owner_nav: Nav.Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?]);
65326826 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);
65336827 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
65346828 const func_decl = ip.funcDeclInfo(generic_owner);
......@@ -6541,7 +6835,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
65416835 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,
65426836 .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0,
65436837 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,
6544 .owner_decl = owner_decl,
6838 .owner_nav = owner_nav,
65456839 .zir_body_inst = func_decl.zir_body_inst,
65466840 .lbrace_line = func_decl.lbrace_line,
65476841 .rbrace_line = func_decl.rbrace_line,
......@@ -6905,7 +7199,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69057199
69067200 .enum_type => unreachable, // use getEnumType() instead
69077201 .func_type => unreachable, // use getFuncType() instead
6908 .extern_func => unreachable, // use getExternFunc() instead
7202 .@"extern" => unreachable, // use getExtern() instead
69097203 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead
69107204
69117205 .variable => |variable| {
......@@ -6916,11 +7210,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69167210 .data = try addExtra(extra, Tag.Variable{
69177211 .ty = variable.ty,
69187212 .init = variable.init,
6919 .decl = variable.decl,
7213 .owner_nav = variable.owner_nav,
69207214 .lib_name = variable.lib_name,
69217215 .flags = .{
6922 .is_extern = variable.is_extern,
6923 .is_const = variable.is_const,
7216 .is_const = false,
69247217 .is_threadlocal = variable.is_threadlocal,
69257218 .is_weak_linkage = variable.is_weak_linkage,
69267219 },
......@@ -6945,29 +7238,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69457238 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
69467239 assert(ptr_type.flags.size != .Slice);
69477240 items.appendAssumeCapacity(switch (ptr.base_addr) {
6948 .decl => |decl| .{
6949 .tag = .ptr_decl,
6950 .data = try addExtra(extra, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),
7241 .nav => |nav| .{
7242 .tag = .ptr_nav,
7243 .data = try addExtra(extra, PtrNav.init(ptr.ty, nav, ptr.byte_offset)),
69517244 },
69527245 .comptime_alloc => |alloc_index| .{
69537246 .tag = .ptr_comptime_alloc,
69547247 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
69557248 },
6956 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {
6957 if (ptr.ty != anon_decl.orig_ty) {
7249 .uav => |uav| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, uav.orig_ty)) item: {
7250 if (ptr.ty != uav.orig_ty) {
69587251 gop.cancel();
69597252 var new_key = key;
6960 new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty;
7253 new_key.ptr.base_addr.uav.orig_ty = ptr.ty;
69617254 gop = try ip.getOrPutKey(gpa, tid, new_key);
69627255 if (gop == .existing) return gop.existing;
69637256 }
69647257 break :item .{
6965 .tag = .ptr_anon_decl,
6966 .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),
7258 .tag = .ptr_uav,
7259 .data = try addExtra(extra, PtrUav.init(ptr.ty, uav.val, ptr.byte_offset)),
69677260 };
69687261 } else .{
6969 .tag = .ptr_anon_decl_aligned,
6970 .data = try addExtra(extra, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),
7262 .tag = .ptr_uav_aligned,
7263 .data = try addExtra(extra, PtrUavAligned.init(ptr.ty, uav.val, uav.orig_ty, ptr.byte_offset)),
69717264 },
69727265 .comptime_field => |field_val| item: {
69737266 assert(field_val != .none);
......@@ -7635,7 +7928,8 @@ pub fn getUnionType(
76357928 .fields_len = ini.fields_len,
76367929 .size = std.math.maxInt(u32),
76377930 .padding = std.math.maxInt(u32),
7638 .decl = undefined, // set by `finish`
7931 .name = undefined, // set by `finish`
7932 .cau = undefined, // set by `finish`
76397933 .namespace = .none, // set by `finish`
76407934 .tag_ty = ini.enum_tag_ty,
76417935 .zir_index = switch (ini.key) {
......@@ -7682,7 +7976,8 @@ pub fn getUnionType(
76827976 return .{ .wip = .{
76837977 .tid = tid,
76847978 .index = gop.put(),
7685 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
7979 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
7980 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "cau").?,
76867981 .namespace_extra_index = if (ini.has_namespace)
76877982 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?
76887983 else
......@@ -7693,18 +7988,44 @@ pub fn getUnionType(
76937988pub const WipNamespaceType = struct {
76947989 tid: Zcu.PerThread.Id,
76957990 index: Index,
7696 decl_extra_index: u32,
7991 type_name_extra_index: u32,
7992 cau_extra_index: ?u32,
76977993 namespace_extra_index: ?u32,
7698 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {
7699 const extra_items = ip.getLocalShared(wip.tid).extra.acquire().view().items(.@"0");
7700 extra_items[wip.decl_extra_index] = @intFromEnum(decl);
7994
7995 pub fn setName(
7996 wip: WipNamespaceType,
7997 ip: *InternPool,
7998 type_name: NullTerminatedString,
7999 ) void {
8000 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8001 const extra_items = extra.view().items(.@"0");
8002 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
8003 }
8004
8005 pub fn finish(
8006 wip: WipNamespaceType,
8007 ip: *InternPool,
8008 analysis_owner: Cau.Index.Optional,
8009 namespace: OptionalNamespaceIndex,
8010 ) Index {
8011 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8012 const extra_items = extra.view().items(.@"0");
8013
8014 if (wip.cau_extra_index) |i| {
8015 extra_items[i] = @intFromEnum(analysis_owner.unwrap().?);
8016 } else {
8017 assert(analysis_owner == .none);
8018 }
8019
77018020 if (wip.namespace_extra_index) |i| {
77028021 extra_items[i] = @intFromEnum(namespace.unwrap().?);
77038022 } else {
77048023 assert(namespace == .none);
77058024 }
8025
77068026 return wip.index;
77078027 }
8028
77088029 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
77098030 ip.remove(tid, wip.index);
77108031 }
......@@ -7784,7 +8105,8 @@ pub fn getStructType(
77848105 ini.fields_len + // names
77858106 ini.fields_len); // inits
77868107 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
7787 .decl = undefined, // set by `finish`
8108 .name = undefined, // set by `finish`
8109 .cau = undefined, // set by `finish`
77888110 .zir_index = zir_index,
77898111 .fields_len = ini.fields_len,
77908112 .namespace = .none,
......@@ -7818,7 +8140,8 @@ pub fn getStructType(
78188140 return .{ .wip = .{
78198141 .tid = tid,
78208142 .index = gop.put(),
7821 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
8143 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
8144 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?,
78228145 .namespace_extra_index = if (ini.has_namespace)
78238146 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?
78248147 else
......@@ -7843,7 +8166,8 @@ pub fn getStructType(
78438166 align_elements_len + comptime_elements_len +
78448167 2); // names_map + namespace
78458168 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
7846 .decl = undefined, // set by `finish`
8169 .name = undefined, // set by `finish`
8170 .cau = undefined, // set by `finish`
78478171 .zir_index = zir_index,
78488172 .fields_len = ini.fields_len,
78498173 .size = std.math.maxInt(u32),
......@@ -7908,7 +8232,8 @@ pub fn getStructType(
79088232 return .{ .wip = .{
79098233 .tid = tid,
79108234 .index = gop.put(),
7911 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
8235 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
8236 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "cau").?,
79128237 .namespace_extra_index = namespace_extra_index,
79138238 } };
79148239}
......@@ -8047,34 +8372,71 @@ pub fn getFuncType(
80478372 return gop.put();
80488373}
80498374
8050pub fn getExternFunc(
8375/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
8376/// This will *not* queue the extern for codegen: see `Zcu.PerThread.getExtern` for a wrapper which does.
8377pub fn getExtern(
80518378 ip: *InternPool,
80528379 gpa: Allocator,
80538380 tid: Zcu.PerThread.Id,
8054 key: Key.ExternFunc,
8055) Allocator.Error!Index {
8056 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });
8381 /// `key.owner_nav` is ignored.
8382 key: Key.Extern,
8383) Allocator.Error!struct {
8384 index: Index,
8385 /// Only set if the `Nav` was newly created.
8386 new_nav: Nav.Index.Optional,
8387} {
8388 var gop = try ip.getOrPutKey(gpa, tid, .{ .@"extern" = key });
80578389 defer gop.deinit();
8058 if (gop == .existing) return gop.existing;
8390 if (gop == .existing) return .{
8391 .index = gop.existing,
8392 .new_nav = .none,
8393 };
80598394
80608395 const local = ip.getLocal(tid);
80618396 const items = local.getMutableItems(gpa);
8062 try items.ensureUnusedCapacity(1);
80638397 const extra = local.getMutableExtra(gpa);
8398 try items.ensureUnusedCapacity(1);
8399 try extra.ensureUnusedCapacity(@typeInfo(Tag.Extern).Struct.fields.len);
8400 try local.getMutableNavs(gpa).ensureUnusedCapacity(1);
80648401
8065 const prev_extra_len = extra.mutate.len;
8066 const extra_index = try addExtra(extra, @as(Tag.ExternFunc, key));
8067 errdefer extra.mutate.len = prev_extra_len;
8402 // Predict the index the `@"extern" will live at, so we can construct the owner `Nav` before releasing the shard's mutex.
8403 const extern_index = Index.Unwrapped.wrap(.{
8404 .tid = tid,
8405 .index = items.mutate.len,
8406 }, ip);
8407 const owner_nav = ip.createNav(gpa, tid, .{
8408 .name = key.name,
8409 .fqn = key.name,
8410 .val = extern_index,
8411 .alignment = key.alignment,
8412 .@"linksection" = .none,
8413 .@"addrspace" = key.@"addrspace",
8414 }) catch unreachable; // capacity asserted above
8415 const extra_index = addExtraAssumeCapacity(extra, Tag.Extern{
8416 .ty = key.ty,
8417 .lib_name = key.lib_name,
8418 .flags = .{
8419 .is_const = key.is_const,
8420 .is_threadlocal = key.is_threadlocal,
8421 .is_weak_linkage = key.is_weak_linkage,
8422 },
8423 .zir_index = key.zir_index,
8424 .owner_nav = owner_nav,
8425 });
80688426 items.appendAssumeCapacity(.{
8069 .tag = .extern_func,
8427 .tag = .@"extern",
80708428 .data = extra_index,
80718429 });
8072 errdefer items.mutate.len -= 1;
8073 return gop.put();
8430 assert(gop.put() == extern_index);
8431
8432 return .{
8433 .index = extern_index,
8434 .new_nav = owner_nav.toOptional(),
8435 };
80748436}
80758437
80768438pub const GetFuncDeclKey = struct {
8077 owner_decl: DeclIndex,
8439 owner_nav: Nav.Index,
80788440 ty: Index,
80798441 zir_body_inst: TrackedInst.Index,
80808442 lbrace_line: u32,
......@@ -8105,7 +8467,7 @@ pub fn getFuncDecl(
81058467
81068468 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
81078469 .analysis = .{
8108 .state = if (key.cc == .Inline) .inline_only else .none,
8470 .state = .unreferenced,
81098471 .is_cold = false,
81108472 .is_noinline = key.is_noinline,
81118473 .calls_or_awaits_errorable_fn = false,
......@@ -8113,7 +8475,7 @@ pub fn getFuncDecl(
81138475 .inferred_error_set = false,
81148476 .disable_instrumentation = false,
81158477 },
8116 .owner_decl = key.owner_decl,
8478 .owner_nav = key.owner_nav,
81178479 .ty = key.ty,
81188480 .zir_body_inst = key.zir_body_inst,
81198481 .lbrace_line = key.lbrace_line,
......@@ -8140,7 +8502,7 @@ pub fn getFuncDecl(
81408502}
81418503
81428504pub const GetFuncDeclIesKey = struct {
8143 owner_decl: DeclIndex,
8505 owner_nav: Nav.Index,
81448506 param_types: []Index,
81458507 noalias_bits: u32,
81468508 comptime_bits: u32,
......@@ -8209,7 +8571,7 @@ pub fn getFuncDeclIes(
82098571
82108572 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
82118573 .analysis = .{
8212 .state = if (key.cc == .Inline) .inline_only else .none,
8574 .state = .unreferenced,
82138575 .is_cold = false,
82148576 .is_noinline = key.is_noinline,
82158577 .calls_or_awaits_errorable_fn = false,
......@@ -8217,7 +8579,7 @@ pub fn getFuncDeclIes(
82178579 .inferred_error_set = true,
82188580 .disable_instrumentation = false,
82198581 },
8220 .owner_decl = key.owner_decl,
8582 .owner_nav = key.owner_nav,
82218583 .ty = func_ty,
82228584 .zir_body_inst = key.zir_body_inst,
82238585 .lbrace_line = key.lbrace_line,
......@@ -8401,7 +8763,7 @@ pub fn getFuncInstance(
84018763
84028764 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
84038765 .analysis = .{
8404 .state = if (arg.cc == .Inline) .inline_only else .none,
8766 .state = .unreferenced,
84058767 .is_cold = false,
84068768 .is_noinline = arg.is_noinline,
84078769 .calls_or_awaits_errorable_fn = false,
......@@ -8409,9 +8771,9 @@ pub fn getFuncInstance(
84098771 .inferred_error_set = false,
84108772 .disable_instrumentation = false,
84118773 },
8412 // This is populated after we create the Decl below. It is not read
8774 // This is populated after we create the Nav below. It is not read
84138775 // by equality or hashing functions.
8414 .owner_decl = undefined,
8776 .owner_nav = undefined,
84158777 .ty = func_ty,
84168778 .branch_quota = 0,
84178779 .generic_owner = generic_owner,
......@@ -8501,7 +8863,7 @@ pub fn getFuncInstanceIes(
85018863
85028864 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
85038865 .analysis = .{
8504 .state = if (arg.cc == .Inline) .inline_only else .none,
8866 .state = .unreferenced,
85058867 .is_cold = false,
85068868 .is_noinline = arg.is_noinline,
85078869 .calls_or_awaits_errorable_fn = false,
......@@ -8509,9 +8871,9 @@ pub fn getFuncInstanceIes(
85098871 .inferred_error_set = true,
85108872 .disable_instrumentation = false,
85118873 },
8512 // This is populated after we create the Decl below. It is not read
8874 // This is populated after we create the Nav below. It is not read
85138875 // by equality or hashing functions.
8514 .owner_decl = undefined,
8876 .owner_nav = undefined,
85158877 .ty = func_ty,
85168878 .branch_quota = 0,
85178879 .generic_owner = generic_owner,
......@@ -8617,37 +8979,26 @@ fn finishFuncInstance(
86178979 alignment: Alignment,
86188980 section: OptionalNullTerminatedString,
86198981) Allocator.Error!void {
8620 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));
8621 const decl_index = try ip.createDecl(gpa, tid, .{
8622 .name = undefined,
8623 .fqn = undefined,
8624 .src_namespace = fn_owner_decl.src_namespace,
8625 .has_tv = true,
8626 .owns_tv = true,
8627 .val = @import("Value.zig").fromInterned(func_index),
8982 const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav);
8983 const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace;
8984
8985 // TODO: improve this name
8986 const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
8987 fn_owner_nav.name.fmt(ip), @intFromEnum(func_index),
8988 }, .no_embedded_nulls);
8989 const nav_index = try ip.createNav(gpa, tid, .{
8990 .name = nav_name,
8991 .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name),
8992 .val = func_index,
86288993 .alignment = alignment,
86298994 .@"linksection" = section,
8630 .@"addrspace" = fn_owner_decl.@"addrspace",
8631 .analysis = .complete,
8632 .zir_decl_index = fn_owner_decl.zir_decl_index,
8633 .is_pub = fn_owner_decl.is_pub,
8634 .is_exported = fn_owner_decl.is_exported,
8635 .kind = .anon,
8995 .@"addrspace" = fn_owner_nav.status.resolved.@"addrspace",
86368996 });
8637 errdefer ip.destroyDecl(tid, decl_index);
86388997
8639 // Populate the owner_decl field which was left undefined until now.
8998 // Populate the owner_nav field which was left undefined until now.
86408999 extra.view().items(.@"0")[
8641 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?
8642 ] = @intFromEnum(decl_index);
8643
8644 // TODO: improve this name
8645 const decl = ip.declPtr(decl_index);
8646 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
8647 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
8648 }, .no_embedded_nulls);
8649 decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace)
8650 .internFullyQualifiedName(ip, gpa, tid, decl.name);
9000 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?
9001 ] = @intFromEnum(nav_index);
86519002}
86529003
86539004pub const EnumTypeInit = struct {
......@@ -8671,23 +9022,36 @@ pub const WipEnumType = struct {
86719022 tid: Zcu.PerThread.Id,
86729023 index: Index,
86739024 tag_ty_index: u32,
8674 decl_index: u32,
8675 namespace_index: ?u32,
9025 type_name_extra_index: u32,
9026 cau_extra_index: u32,
9027 namespace_extra_index: ?u32,
86769028 names_map: MapIndex,
86779029 names_start: u32,
86789030 values_map: OptionalMapIndex,
86799031 values_start: u32,
86809032
9033 pub fn setName(
9034 wip: WipEnumType,
9035 ip: *InternPool,
9036 type_name: NullTerminatedString,
9037 ) void {
9038 const extra = ip.getLocalShared(wip.tid).extra.acquire();
9039 const extra_items = extra.view().items(.@"0");
9040 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
9041 }
9042
86819043 pub fn prepare(
86829044 wip: WipEnumType,
86839045 ip: *InternPool,
8684 decl: DeclIndex,
9046 analysis_owner: Cau.Index,
86859047 namespace: OptionalNamespaceIndex,
86869048 ) void {
86879049 const extra = ip.getLocalShared(wip.tid).extra.acquire();
86889050 const extra_items = extra.view().items(.@"0");
8689 extra_items[wip.decl_index] = @intFromEnum(decl);
8690 if (wip.namespace_index) |i| {
9051
9052 extra_items[wip.cau_extra_index] = @intFromEnum(analysis_owner);
9053
9054 if (wip.namespace_extra_index) |i| {
86919055 extra_items[i] = @intFromEnum(namespace.unwrap().?);
86929056 } else {
86939057 assert(namespace == .none);
......@@ -8780,10 +9144,11 @@ pub fn getEnumType(
87809144 .reified => 2, // type_hash: PackedU64
87819145 } +
87829146 // zig fmt: on
9147 1 + // cau
87839148 ini.fields_len); // field types
87849149
87859150 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
8786 .decl = undefined, // set by `prepare`
9151 .name = undefined, // set by `prepare`
87879152 .captures_len = switch (ini.key) {
87889153 .declared => |d| @intCast(d.captures.len),
87899154 .reified => std.math.maxInt(u32),
......@@ -8800,6 +9165,8 @@ pub fn getEnumType(
88009165 .tag = .type_enum_auto,
88019166 .data = extra_index,
88029167 });
9168 const cau_extra_index = extra.view().len;
9169 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
88039170 switch (ini.key) {
88049171 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
88059172 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
......@@ -8810,8 +9177,9 @@ pub fn getEnumType(
88109177 .tid = tid,
88119178 .index = gop.put(),
88129179 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
8813 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
8814 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
9180 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?,
9181 .cau_extra_index = @intCast(cau_extra_index),
9182 .namespace_extra_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
88159183 .names_map = names_map,
88169184 .names_start = @intCast(names_start),
88179185 .values_map = .none,
......@@ -8835,11 +9203,12 @@ pub fn getEnumType(
88359203 .reified => 2, // type_hash: PackedU64
88369204 } +
88379205 // zig fmt: on
9206 1 + // cau
88389207 ini.fields_len + // field types
88399208 ini.fields_len * @intFromBool(ini.has_values)); // field values
88409209
88419210 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
8842 .decl = undefined, // set by `prepare`
9211 .name = undefined, // set by `prepare`
88439212 .captures_len = switch (ini.key) {
88449213 .declared => |d| @intCast(d.captures.len),
88459214 .reified => std.math.maxInt(u32),
......@@ -8861,6 +9230,8 @@ pub fn getEnumType(
88619230 },
88629231 .data = extra_index,
88639232 });
9233 const cau_extra_index = extra.view().len;
9234 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
88649235 switch (ini.key) {
88659236 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
88669237 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
......@@ -8874,9 +9245,10 @@ pub fn getEnumType(
88749245 return .{ .wip = .{
88759246 .tid = tid,
88769247 .index = gop.put(),
8877 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
8878 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
8879 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
9248 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,
9249 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?,
9250 .cau_extra_index = @intCast(cau_extra_index),
9251 .namespace_extra_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").? else null,
88809252 .names_map = names_map,
88819253 .names_start = @intCast(names_start),
88829254 .values_map = values_map,
......@@ -8887,7 +9259,7 @@ pub fn getEnumType(
88879259}
88889260
88899261const GeneratedTagEnumTypeInit = struct {
8890 decl: DeclIndex,
9262 name: NullTerminatedString,
88919263 owner_union_ty: Index,
88929264 tag_ty: Index,
88939265 names: []const NullTerminatedString,
......@@ -8928,7 +9300,7 @@ pub fn getGeneratedTagEnumType(
89289300 items.appendAssumeCapacity(.{
89299301 .tag = .type_enum_auto,
89309302 .data = addExtraAssumeCapacity(extra, EnumAuto{
8931 .decl = ini.decl,
9303 .name = ini.name,
89329304 .captures_len = 0,
89339305 .namespace = .none,
89349306 .int_tag_type = ini.tag_ty,
......@@ -8961,7 +9333,7 @@ pub fn getGeneratedTagEnumType(
89619333 .auto => unreachable,
89629334 },
89639335 .data = addExtraAssumeCapacity(extra, EnumExplicit{
8964 .decl = ini.decl,
9336 .name = ini.name,
89659337 .captures_len = 0,
89669338 .namespace = .none,
89679339 .int_tag_type = ini.tag_ty,
......@@ -9034,7 +9406,7 @@ pub fn getOpaqueType(
90349406 .reified => 0,
90359407 });
90369408 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
9037 .decl = undefined, // set by `finish`
9409 .name = undefined, // set by `finish`
90389410 .namespace = .none,
90399411 .zir_index = switch (ini.key) {
90409412 inline else => |x| x.zir_index,
......@@ -9052,15 +9424,18 @@ pub fn getOpaqueType(
90529424 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
90539425 .reified => {},
90549426 }
9055 return .{ .wip = .{
9056 .tid = tid,
9057 .index = gop.put(),
9058 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,
9059 .namespace_extra_index = if (ini.has_namespace)
9060 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?
9061 else
9062 null,
9063 } };
9427 return .{
9428 .wip = .{
9429 .tid = tid,
9430 .index = gop.put(),
9431 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
9432 .cau_extra_index = null, // opaques do not undergo type resolution
9433 .namespace_extra_index = if (ini.has_namespace)
9434 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?
9435 else
9436 null,
9437 },
9438 };
90649439}
90659440
90669441pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
......@@ -9181,7 +9556,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
91819556 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
91829557 extra.appendAssumeCapacity(.{switch (field.type) {
91839558 Index,
9184 DeclIndex,
9559 Cau.Index,
9560 Nav.Index,
91859561 NamespaceIndex,
91869562 OptionalNamespaceIndex,
91879563 MapIndex,
......@@ -9244,7 +9620,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
92449620 const extra_item = extra_items[extra_index];
92459621 @field(result, field.name) = switch (field.type) {
92469622 Index,
9247 DeclIndex,
9623 Cau.Index,
9624 Nav.Index,
92489625 NamespaceIndex,
92499626 OptionalNamespaceIndex,
92509627 MapIndex,
......@@ -9436,12 +9813,6 @@ pub fn getCoerced(
94369813
94379814 switch (ip.indexToKey(val)) {
94389815 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
9439 .extern_func => |extern_func| if (ip.isFunctionType(new_ty))
9440 return ip.getExternFunc(gpa, tid, .{
9441 .ty = new_ty,
9442 .decl = extern_func.decl,
9443 .lib_name = extern_func.lib_name,
9444 }),
94459816 .func => unreachable,
94469817
94479818 .int => |int| switch (ip.indexToKey(new_ty)) {
......@@ -9858,27 +10229,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
985810229 var items_len: usize = 0;
985910230 var extra_len: usize = 0;
986010231 var limbs_len: usize = 0;
9861 var decls_len: usize = 0;
986210232 for (ip.locals) |*local| {
986310233 items_len += local.mutate.items.len;
986410234 extra_len += local.mutate.extra.len;
986510235 limbs_len += local.mutate.limbs.len;
9866 decls_len += local.mutate.decls.buckets_list.len;
986710236 }
986810237 const items_size = (1 + 4) * items_len;
986910238 const extra_size = 4 * extra_len;
987010239 const limbs_size = 8 * limbs_len;
9871 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
987210240
987310241 // TODO: map overhead size is not taken into account
9874 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;
10242 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size;
987510243
987610244 std.debug.print(
987710245 \\InternPool size: {d} bytes
987810246 \\ {d} items: {d} bytes
987910247 \\ {d} extra: {d} bytes
988010248 \\ {d} limbs: {d} bytes
9881 \\ {d} decls: {d} bytes
988210249 \\
988310250 , .{
988410251 total_size,
......@@ -9888,8 +10255,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
988810255 extra_size,
988910256 limbs_len,
989010257 limbs_size,
9891 decls_len,
9892 decls_size,
989310258 });
989410259
989510260 const TagStats = struct {
......@@ -10034,10 +10399,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1003410399 .undef => 0,
1003510400 .simple_type => 0,
1003610401 .simple_value => 0,
10037 .ptr_decl => @sizeOf(PtrDecl),
10402 .ptr_nav => @sizeOf(PtrNav),
1003810403 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
10039 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
10040 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
10404 .ptr_uav => @sizeOf(PtrUav),
10405 .ptr_uav_aligned => @sizeOf(PtrUavAligned),
1004110406 .ptr_comptime_field => @sizeOf(PtrComptimeField),
1004210407 .ptr_int => @sizeOf(PtrInt),
1004310408 .ptr_eu_payload => @sizeOf(PtrBase),
......@@ -10092,7 +10457,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1009210457 .float_c_longdouble_f128 => @sizeOf(Float128),
1009310458 .float_comptime_float => @sizeOf(Float128),
1009410459 .variable => @sizeOf(Tag.Variable),
10095 .extern_func => @sizeOf(Tag.ExternFunc),
10460 .@"extern" => @sizeOf(Tag.Extern),
1009610461 .func_decl => @sizeOf(Tag.FuncDecl),
1009710462 .func_instance => b: {
1009810463 const info = extraData(extra_list, Tag.FuncInstance, data);
......@@ -10171,10 +10536,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1017110536 .type_union,
1017210537 .type_function,
1017310538 .undef,
10174 .ptr_decl,
10539 .ptr_nav,
1017510540 .ptr_comptime_alloc,
10176 .ptr_anon_decl,
10177 .ptr_anon_decl_aligned,
10541 .ptr_uav,
10542 .ptr_uav_aligned,
1017810543 .ptr_comptime_field,
1017910544 .ptr_int,
1018010545 .ptr_eu_payload,
......@@ -10212,7 +10577,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1021210577 .float_c_longdouble_f128,
1021310578 .float_comptime_float,
1021410579 .variable,
10215 .extern_func,
10580 .@"extern",
1021610581 .func_decl,
1021710582 .func_instance,
1021810583 .func_coerced,
......@@ -10275,13 +10640,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1027510640 instances.sort(SortContext{ .values = instances.values() });
1027610641 var it = instances.iterator();
1027710642 while (it.next()) |entry| {
10278 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
10279 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
10643 const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);
10644 try w.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
1028010645 for (entry.value_ptr.items) |index| {
1028110646 const unwrapped_index = index.unwrap(ip);
1028210647 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
10283 const owner_decl = ip.declPtrConst(func.owner_decl);
10284 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
10648 const owner_nav = ip.getNav(func.owner_nav);
10649 try w.print(" {}: (", .{owner_nav.name.fmt(ip)});
1028510650 for (func.comptime_args.get(ip)) |arg| {
1028610651 if (arg != .none) {
1028710652 const key = ip.indexToKey(arg);
......@@ -10295,66 +10660,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1029510660 try bw.flush();
1029610661}
1029710662
10298pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {
10299 return @constCast(ip.declPtrConst(decl_index));
10663pub fn getCau(ip: *const InternPool, index: Cau.Index) Cau {
10664 const unwrapped = index.unwrap(ip);
10665 const caus = ip.getLocalShared(unwrapped.tid).caus.acquire();
10666 return caus.view().items(.@"0")[unwrapped.index];
10667}
10668
10669pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav {
10670 const unwrapped = index.unwrap(ip);
10671 const navs = ip.getLocalShared(unwrapped.tid).navs.acquire();
10672 return navs.view().get(unwrapped.index).unpack();
1030010673}
1030110674
10302pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl {
10303 const unwrapped_decl_index = decl_index.unwrap(ip);
10304 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();
10305 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];
10306 return &decls_bucket[unwrapped_decl_index.index];
10675pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
10676 const unwrapped_namespace_index = namespace_index.unwrap(ip);
10677 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
10678 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
10679 return &namespaces_bucket[unwrapped_namespace_index.index];
1030710680}
1030810681
10309pub fn createDecl(
10682/// Create a `Cau` associated with the type at the given `InternPool.Index`.
10683pub fn createTypeCau(
1031010684 ip: *InternPool,
1031110685 gpa: Allocator,
1031210686 tid: Zcu.PerThread.Id,
10313 initialization: Zcu.Decl,
10314) Allocator.Error!DeclIndex {
10315 const local = ip.getLocal(tid);
10316 const free_list_next = local.mutate.decls.free_list;
10317 if (free_list_next != Local.BucketListMutate.free_list_sentinel) {
10318 const reused_decl_index: DeclIndex = @enumFromInt(free_list_next);
10319 const reused_decl = ip.declPtr(reused_decl_index);
10320 local.mutate.decls.free_list = @intFromEnum(@field(reused_decl, Local.decl_next_free_field));
10321 reused_decl.* = initialization;
10322 return reused_decl_index;
10323 }
10324 const decls = local.getMutableDecls(gpa);
10325 if (local.mutate.decls.last_bucket_len == 0) {
10326 try decls.ensureUnusedCapacity(1);
10327 var arena = decls.arena.promote(decls.gpa);
10328 defer decls.arena.* = arena.state;
10329 decls.appendAssumeCapacity(.{try arena.allocator().create(
10330 [1 << Local.decls_bucket_width]Zcu.Decl,
10331 )});
10332 }
10333 const unwrapped_decl_index: DeclIndex.Unwrapped = .{
10687 zir_index: TrackedInst.Index,
10688 namespace: NamespaceIndex,
10689 owner_type: InternPool.Index,
10690) Allocator.Error!Cau.Index {
10691 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10692 const index_unwrapped: Cau.Index.Unwrapped = .{
1033410693 .tid = tid,
10335 .bucket_index = decls.mutate.len - 1,
10336 .index = local.mutate.decls.last_bucket_len,
10694 .index = caus.mutate.len,
1033710695 };
10338 local.mutate.decls.last_bucket_len =
10339 (unwrapped_decl_index.index + 1) & Local.namespaces_bucket_mask;
10340 const decl_index = unwrapped_decl_index.wrap(ip);
10341 ip.declPtr(decl_index).* = initialization;
10342 return decl_index;
10696 try caus.append(.{.{
10697 .zir_index = zir_index,
10698 .namespace = namespace,
10699 .owner = Cau.Owner.wrap(.{ .type = owner_type }),
10700 }});
10701 return index_unwrapped.wrap(ip);
1034310702}
1034410703
10345pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex) void {
10346 const local = ip.getLocal(tid);
10347 const decl = ip.declPtr(decl_index);
10348 decl.* = undefined;
10349 @field(decl, Local.decl_next_free_field) = @enumFromInt(local.mutate.decls.free_list);
10350 local.mutate.decls.free_list = @intFromEnum(decl_index);
10704/// Create a `Cau` for a `comptime` declaration.
10705pub fn createComptimeCau(
10706 ip: *InternPool,
10707 gpa: Allocator,
10708 tid: Zcu.PerThread.Id,
10709 zir_index: TrackedInst.Index,
10710 namespace: NamespaceIndex,
10711) Allocator.Error!Cau.Index {
10712 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10713 const index_unwrapped: Cau.Index.Unwrapped = .{
10714 .tid = tid,
10715 .index = caus.mutate.len,
10716 };
10717 try caus.append(.{.{
10718 .zir_index = zir_index,
10719 .namespace = namespace,
10720 .owner = Cau.Owner.wrap(.none),
10721 }});
10722 return index_unwrapped.wrap(ip);
1035110723}
1035210724
10353pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
10354 const unwrapped_namespace_index = namespace_index.unwrap(ip);
10355 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
10356 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
10357 return &namespaces_bucket[unwrapped_namespace_index.index];
10725/// Create a `Nav` not associated with any `Cau`.
10726/// Since there is no analysis owner, the `Nav`'s value must be known at creation time.
10727pub fn createNav(
10728 ip: *InternPool,
10729 gpa: Allocator,
10730 tid: Zcu.PerThread.Id,
10731 opts: struct {
10732 name: NullTerminatedString,
10733 fqn: NullTerminatedString,
10734 val: InternPool.Index,
10735 alignment: Alignment,
10736 @"linksection": OptionalNullTerminatedString,
10737 @"addrspace": std.builtin.AddressSpace,
10738 },
10739) Allocator.Error!Nav.Index {
10740 const navs = ip.getLocal(tid).getMutableNavs(gpa);
10741 const index_unwrapped: Nav.Index.Unwrapped = .{
10742 .tid = tid,
10743 .index = navs.mutate.len,
10744 };
10745 try navs.append(Nav.pack(.{
10746 .name = opts.name,
10747 .fqn = opts.fqn,
10748 .analysis_owner = .none,
10749 .status = .{ .resolved = .{
10750 .val = opts.val,
10751 .alignment = opts.alignment,
10752 .@"linksection" = opts.@"linksection",
10753 .@"addrspace" = opts.@"addrspace",
10754 } },
10755 .is_usingnamespace = false,
10756 }));
10757 return index_unwrapped.wrap(ip);
10758}
10759
10760/// Create a `Cau` and `Nav` which are paired. The value of the `Nav` is
10761/// determined by semantic analysis of the `Cau`. The value of the `Nav`
10762/// is initially unresolved.
10763pub fn createPairedCauNav(
10764 ip: *InternPool,
10765 gpa: Allocator,
10766 tid: Zcu.PerThread.Id,
10767 name: NullTerminatedString,
10768 fqn: NullTerminatedString,
10769 zir_index: TrackedInst.Index,
10770 namespace: NamespaceIndex,
10771 /// TODO: this is hacky! See `Nav.is_usingnamespace`.
10772 is_usingnamespace: bool,
10773) Allocator.Error!struct { Cau.Index, Nav.Index } {
10774 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10775 const navs = ip.getLocal(tid).getMutableNavs(gpa);
10776
10777 try caus.ensureUnusedCapacity(1);
10778 try navs.ensureUnusedCapacity(1);
10779
10780 const cau = Cau.Index.Unwrapped.wrap(.{
10781 .tid = tid,
10782 .index = caus.mutate.len,
10783 }, ip);
10784 const nav = Nav.Index.Unwrapped.wrap(.{
10785 .tid = tid,
10786 .index = navs.mutate.len,
10787 }, ip);
10788
10789 caus.appendAssumeCapacity(.{.{
10790 .zir_index = zir_index,
10791 .namespace = namespace,
10792 .owner = Cau.Owner.wrap(.{ .nav = nav }),
10793 }});
10794 navs.appendAssumeCapacity(Nav.pack(.{
10795 .name = name,
10796 .fqn = fqn,
10797 .analysis_owner = cau.toOptional(),
10798 .status = .unresolved,
10799 .is_usingnamespace = is_usingnamespace,
10800 }));
10801
10802 return .{ cau, nav };
10803}
10804
10805/// Resolve the value of a `Nav` with an analysis owner.
10806/// If its status is already `resolved`, the old value is discarded.
10807pub fn resolveNavValue(
10808 ip: *InternPool,
10809 nav: Nav.Index,
10810 resolved: struct {
10811 val: InternPool.Index,
10812 alignment: Alignment,
10813 @"linksection": OptionalNullTerminatedString,
10814 @"addrspace": std.builtin.AddressSpace,
10815 },
10816) void {
10817 const unwrapped = nav.unwrap(ip);
10818
10819 const local = ip.getLocal(unwrapped.tid);
10820 local.mutate.extra.mutex.lock();
10821 defer local.mutate.extra.mutex.unlock();
10822
10823 const navs = local.shared.navs.view();
10824
10825 const nav_analysis_owners = navs.items(.analysis_owner);
10826 const nav_vals = navs.items(.val);
10827 const nav_linksections = navs.items(.@"linksection");
10828 const nav_bits = navs.items(.bits);
10829
10830 assert(nav_analysis_owners[unwrapped.index] != .none);
10831
10832 @atomicStore(InternPool.Index, &nav_vals[unwrapped.index], resolved.val, .release);
10833 @atomicStore(OptionalNullTerminatedString, &nav_linksections[unwrapped.index], resolved.@"linksection", .release);
10834
10835 var bits = nav_bits[unwrapped.index];
10836 bits.status = .resolved;
10837 bits.alignment = resolved.alignment;
10838 bits.@"addrspace" = resolved.@"addrspace";
10839 @atomicStore(Nav.Repr.Bits, &nav_bits[unwrapped.index], bits, .release);
1035810840}
1035910841
1036010842pub fn createNamespace(
......@@ -10404,7 +10886,7 @@ pub fn destroyNamespace(
1040410886 namespace.* = .{
1040510887 .parent = undefined,
1040610888 .file_scope = undefined,
10407 .decl_index = undefined,
10889 .owner_type = undefined,
1040810890 };
1040910891 @field(namespace, Local.namespace_next_free_field) =
1041010892 @enumFromInt(local.mutate.namespaces.free_list);
......@@ -10750,10 +11232,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1075011232
1075111233 .simple_type, .simple_value => unreachable, // handled via Index above
1075211234
10753 inline .ptr_decl,
11235 inline .ptr_nav,
1075411236 .ptr_comptime_alloc,
10755 .ptr_anon_decl,
10756 .ptr_anon_decl_aligned,
11237 .ptr_uav,
11238 .ptr_uav_aligned,
1075711239 .ptr_comptime_field,
1075811240 .ptr_int,
1075911241 .ptr_eu_payload,
......@@ -10770,7 +11252,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1077011252 .error_union_error,
1077111253 .enum_tag,
1077211254 .variable,
10773 .extern_func,
11255 .@"extern",
1077411256 .func_decl,
1077511257 .func_instance,
1077611258 .func_coerced,
......@@ -10892,14 +11374,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool {
1089211374 return val.unwrap(ip).getTag(ip) == .variable;
1089311375}
1089411376
10895pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
11377pub fn getBackingNav(ip: *const InternPool, val: Index) Nav.Index.Optional {
1089611378 var base = val;
1089711379 while (true) {
1089811380 const unwrapped_base = base.unwrap(ip);
1089911381 const base_item = unwrapped_base.getItem(ip);
1090011382 switch (base_item.tag) {
10901 .ptr_decl => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
10902 base_item.data + std.meta.fieldIndex(PtrDecl, "decl").?
11383 .ptr_nav => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
11384 base_item.data + std.meta.fieldIndex(PtrNav, "nav").?
1090311385 ]),
1090411386 inline .ptr_eu_payload,
1090511387 .ptr_opt_payload,
......@@ -10922,11 +11404,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
1092211404 const unwrapped_base = base.unwrap(ip);
1092311405 const base_item = unwrapped_base.getItem(ip);
1092411406 switch (base_item.tag) {
10925 .ptr_decl => return .decl,
11407 .ptr_nav => return .nav,
1092611408 .ptr_comptime_alloc => return .comptime_alloc,
10927 .ptr_anon_decl,
10928 .ptr_anon_decl_aligned,
10929 => return .anon_decl,
11409 .ptr_uav,
11410 .ptr_uav_aligned,
11411 => return .uav,
1093011412 .ptr_comptime_field => return .comptime_field,
1093111413 .ptr_int => return .int,
1093211414 inline .ptr_eu_payload,
......@@ -11098,10 +11580,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1109811580 // values, not types
1109911581 .undef,
1110011582 .simple_value,
11101 .ptr_decl,
11583 .ptr_nav,
1110211584 .ptr_comptime_alloc,
11103 .ptr_anon_decl,
11104 .ptr_anon_decl_aligned,
11585 .ptr_uav,
11586 .ptr_uav_aligned,
1110511587 .ptr_comptime_field,
1110611588 .ptr_int,
1110711589 .ptr_eu_payload,
......@@ -11137,7 +11619,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1113711619 .float_c_longdouble_f128,
1113811620 .float_comptime_float,
1113911621 .variable,
11140 .extern_func,
11622 .@"extern",
1114111623 .func_decl,
1114211624 .func_instance,
1114311625 .func_coerced,
......@@ -11190,18 +11672,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
1119011672 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
1119111673}
1119211674
11193pub fn funcSetAnalysisState(ip: *InternPool, func: Index, state: FuncAnalysis.State) void {
11194 const unwrapped_func = func.unwrap(ip);
11195 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11196 extra_mutex.lock();
11197 defer extra_mutex.unlock();
11198
11199 const analysis_ptr = ip.funcAnalysisPtr(func);
11200 var analysis = analysis_ptr.*;
11201 analysis.state = state;
11202 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11203}
11204
1120511675pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
1120611676 const unwrapped_func = func.unwrap(ip);
1120711677 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
......@@ -11349,10 +11819,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
1134911819 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
1135011820}
1135111821
11352pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
11353 return funcDeclInfo(ip, index).owner_decl;
11354}
11355
1135611822pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
1135711823 const unwrapped_index = index.unwrap(ip);
1135811824 const extra_list = unwrapped_index.getExtra(ip);
......@@ -11409,14 +11875,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {
1140911875 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);
1141011876}
1141111877
11412/// Asserts the type is a struct.
11413pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {
11414 return switch (ip.indexToKey(i)) {
11415 .struct_type => |t| t.decl,
11416 else => unreachable,
11417 };
11418}
11419
1142011878/// Returns the already-existing field with the same name, if any.
1142111879pub fn addFieldName(
1142211880 ip: *InternPool,
......@@ -11436,8 +11894,8 @@ pub fn addFieldName(
1143611894 return null;
1143711895}
1143811896
11439/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_anon_decl`
11440/// encoding instead of `Tag.ptr_anon_decl_aligned` when possible.
11897/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_uav`
11898/// encoding instead of `Tag.ptr_uav_aligned` when possible.
1144111899fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
1144211900 if (a_ty == b_ty) return true;
1144311901 const b_info = ip.indexToKey(b_ty).ptr_type;
......@@ -11607,3 +12065,7 @@ pub fn getErrorValue(
1160712065pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
1160812066 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
1160912067}
12068
12069pub fn isRemoved(ip: *const InternPool, ty: Index) bool {
12070 return ty.unwrap(ip).getTag(ip) == .removed;
12071}
src/Sema.zig+1014-1056
......@@ -16,16 +16,14 @@ air_instructions: std.MultiArrayList(Air.Inst) = .{},
1616air_extra: std.ArrayListUnmanaged(u32) = .{},
1717/// Maps ZIR to AIR.
1818inst_map: InstMap = .{},
19/// When analyzing an inline function call, owner_decl is the Decl of the caller.
20owner_decl: *Decl,
21owner_decl_index: InternPool.DeclIndex,
22/// For an inline or comptime function call, this will be the root parent function
23/// which contains the callsite. Corresponds to `owner_decl`.
24/// This could be `none`, a `func_decl`, or a `func_instance`.
25owner_func_index: InternPool.Index,
19/// The "owner" of a `Sema` represents the root "thing" that is being analyzed.
20/// This does not change throughout the entire lifetime of a `Sema`. For instance,
21/// when analyzing a runtime function body, this is always `func` of that function,
22/// even if an inline/comptime function call is being analyzed.
23owner: AnalUnit,
2624/// The function this ZIR code is the body of, according to the source code.
27/// This starts out the same as `owner_func_index` and then diverges in the case of
28/// an inline or comptime function call.
25/// This starts out the same as `sema.owner.func` if applicable, and then diverges
26/// in the case of an inline or comptime function call.
2927/// This could be `none`, a `func_decl`, or a `func_instance`.
3028func_index: InternPool.Index,
3129/// Whether the type of func_index has a calling convention of `.Naked`.
......@@ -48,7 +46,6 @@ branch_count: u32 = 0,
4846/// Populated when returning `error.ComptimeBreak`. Used to communicate the
4947/// break instruction up the stack to find the corresponding Block.
5048comptime_break_inst: Zir.Inst.Index = undefined,
51decl_val_table: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Air.Inst.Ref) = .{},
5249/// When doing a generic function instantiation, this array collects a value
5350/// for each parameter of the generic owner. `none` for non-comptime parameters.
5451/// This is a separate array from `block.params` so that it can be passed
......@@ -79,10 +76,6 @@ no_partial_func_ty: bool = false,
7976/// here so the values can be dropped without any cleanup.
8077unresolved_inferred_allocs: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{},
8178
82/// This is populated when `@setAlignStack` occurs so that if there is a duplicate
83/// one encountered, the conflicting source location can be shown.
84prev_stack_alignment_src: ?LazySrcLoc = null,
85
8679/// While analyzing a type which has a special InternPool index, this is set to the index at which
8780/// the struct/enum/union type created should be placed. Otherwise, it is `.none`.
8881builtin_type_target_index: InternPool.Index = .none,
......@@ -177,7 +170,6 @@ const trace = @import("tracy.zig").trace;
177170const Namespace = Module.Namespace;
178171const CompileError = Module.CompileError;
179172const SemaError = Module.SemaError;
180const Decl = Module.Decl;
181173const LazySrcLoc = Zcu.LazySrcLoc;
182174const RangeSet = @import("RangeSet.zig");
183175const target_util = @import("target.zig");
......@@ -394,7 +386,7 @@ pub const Block = struct {
394386 /// The name of the current "context" for naming namespace types.
395387 /// The interpretation of this depends on the name strategy in ZIR, but the name
396388 /// is always incorporated into the type name somehow.
397 /// See `Sema.createAnonymousDeclTypeNamed`.
389 /// See `Sema.createTypeName`.
398390 type_name_ctx: InternPool.NullTerminatedString,
399391
400392 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.
......@@ -440,8 +432,8 @@ pub const Block = struct {
440432 try sema.errNote(ci.src, parent, prefix ++ "it is inside a @cImport", .{});
441433 },
442434 .comptime_ret_ty => |rt| {
443 const ret_ty_src: LazySrcLoc = if (try sema.funcDeclSrc(rt.func)) |fn_decl| .{
444 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
435 const ret_ty_src: LazySrcLoc = if (try sema.funcDeclSrcInst(rt.func)) |fn_decl_inst| .{
436 .base_node_inst = fn_decl_inst,
445437 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
446438 } else rt.func_src;
447439 if (rt.return_ty.isGenericPoison()) {
......@@ -871,7 +863,6 @@ pub fn deinit(sema: *Sema) void {
871863 sema.air_instructions.deinit(gpa);
872864 sema.air_extra.deinit(gpa);
873865 sema.inst_map.deinit(gpa);
874 sema.decl_val_table.deinit(gpa);
875866 {
876867 var it = sema.post_hoc_blocks.iterator();
877868 while (it.next()) |entry| {
......@@ -2170,7 +2161,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value
21702161fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
21712162 const val = (try sema.resolveValue(inst)) orelse return null;
21722163 if (sema.pt.zcu.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {
2173 .decl, .anon_decl, .comptime_alloc, .comptime_field => return null,
2164 .nav, .uav, .comptime_alloc, .comptime_field => return null,
21742165 .int => {},
21752166 .eu_payload, .opt_payload, .arr_elem, .field => unreachable,
21762167 };
......@@ -2503,7 +2494,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
25032494 @setCold(true);
25042495 const gpa = sema.gpa;
25052496 const mod = sema.pt.zcu;
2506 const ip = &mod.intern_pool;
25072497
25082498 if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) {
25092499 var all_references = mod.resolveReferences() catch @panic("out of memory");
......@@ -2531,10 +2521,10 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
25312521
25322522 const use_ref_trace = if (mod.comp.reference_trace) |n| n > 0 else mod.failed_analysis.count() == 0;
25332523 if (use_ref_trace) {
2534 err_msg.reference_trace_root = sema.ownerUnit().toOptional();
2524 err_msg.reference_trace_root = sema.owner.toOptional();
25352525 }
25362526
2537 const gop = try mod.failed_analysis.getOrPut(gpa, sema.ownerUnit());
2527 const gop = try mod.failed_analysis.getOrPut(gpa, sema.owner);
25382528 if (gop.found_existing) {
25392529 // If there are multiple errors for the same Decl, prefer the first one added.
25402530 sema.err = null;
......@@ -2544,16 +2534,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
25442534 gop.value_ptr.* = err_msg;
25452535 }
25462536
2547 if (sema.owner_func_index != .none) {
2548 ip.funcSetAnalysisState(sema.owner_func_index, .sema_failure);
2549 } else {
2550 sema.owner_decl.analysis = .sema_failure;
2551 }
2552
2553 if (sema.func_index != .none) {
2554 ip.funcSetAnalysisState(sema.func_index, .sema_failure);
2555 }
2556
25572537 return error.AnalysisFail;
25582538}
25592539
......@@ -2662,7 +2642,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
26622642 const pt = sema.pt;
26632643 const zcu = pt.zcu;
26642644 const ip = &zcu.intern_pool;
2665 const parent_captures: InternPool.CaptureValue.Slice = zcu.namespacePtr(block.namespace).getType(zcu).getCaptures(zcu);
2645 const parent_ty = Type.fromInterned(zcu.namespacePtr(block.namespace).owner_type);
2646 const parent_captures: InternPool.CaptureValue.Slice = parent_ty.getCaptures(zcu);
26662647
26672648 const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len);
26682649
......@@ -2704,8 +2685,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
27042685 sema.code.nullTerminatedString(str),
27052686 .no_embedded_nulls,
27062687 );
2707 const decl = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
2708 break :capture InternPool.CaptureValue.wrap(.{ .decl_val = decl });
2688 const nav = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
2689 break :capture InternPool.CaptureValue.wrap(.{ .nav_val = nav });
27092690 },
27102691 .decl_ref => |str| capture: {
27112692 const decl_name = try ip.getOrPutString(
......@@ -2714,8 +2695,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
27142695 sema.code.nullTerminatedString(str),
27152696 .no_embedded_nulls,
27162697 );
2717 const decl = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
2718 break :capture InternPool.CaptureValue.wrap(.{ .decl_ref = decl });
2698 const nav = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
2699 break :capture InternPool.CaptureValue.wrap(.{ .nav_ref = nav });
27192700 },
27202701 };
27212702 }
......@@ -2740,19 +2721,24 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
27402721fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
27412722 const pt = sema.pt;
27422723 const zcu = pt.zcu;
2724 const ip = &zcu.intern_pool;
27432725
27442726 if (!zcu.comp.incremental) return false;
27452727
2746 const decl_index = Type.fromInterned(ty).getOwnerDecl(zcu);
2747 const decl_as_depender = AnalUnit.wrap(.{ .decl = decl_index });
2748 const was_outdated = zcu.outdated.swapRemove(decl_as_depender) or
2749 zcu.potentially_outdated.swapRemove(decl_as_depender);
2728 const cau_index = switch (ip.indexToKey(ty)) {
2729 .struct_type => ip.loadStructType(ty).cau.unwrap().?,
2730 .union_type => ip.loadUnionType(ty).cau,
2731 .enum_type => ip.loadEnumType(ty).cau.unwrap().?,
2732 else => unreachable,
2733 };
2734 const cau_unit = AnalUnit.wrap(.{ .cau = cau_index });
2735 const was_outdated = zcu.outdated.swapRemove(cau_unit) or
2736 zcu.potentially_outdated.swapRemove(cau_unit);
27502737 if (!was_outdated) return false;
2751 _ = zcu.outdated_ready.swapRemove(decl_as_depender);
2752 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
2738 _ = zcu.outdated_ready.swapRemove(cau_unit);
2739 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, cau_unit);
27532740 zcu.intern_pool.remove(pt.tid, ty);
2754 zcu.declPtr(decl_index).analysis = .dependency_failure;
2755 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
2741 try zcu.markDependeeOutdated(.{ .interned = ty });
27562742 return true;
27572743}
27582744
......@@ -2831,73 +2817,68 @@ fn zirStructDecl(
28312817 });
28322818 errdefer wip_ty.cancel(ip, pt.tid);
28332819
2834 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2820 wip_ty.setName(ip, try sema.createTypeName(
28352821 block,
2836 Value.fromInterned(wip_ty.index),
28372822 small.name_strategy,
28382823 "struct",
28392824 inst,
2840 );
2841 mod.declPtr(new_decl_index).owns_tv = true;
2842 errdefer pt.abortAnonDecl(new_decl_index);
2843
2844 if (pt.zcu.comp.incremental) {
2845 try ip.addDependency(
2846 sema.gpa,
2847 AnalUnit.wrap(.{ .decl = new_decl_index }),
2848 .{ .src_hash = try block.trackZir(inst) },
2849 );
2850 }
2825 wip_ty.index,
2826 ));
28512827
28522828 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
28532829 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
28542830 .parent = block.namespace.toOptional(),
2855 .decl_index = new_decl_index,
2831 .owner_type = wip_ty.index,
28562832 .file_scope = block.getFileScopeIndex(mod),
28572833 })).toOptional() else .none;
28582834 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
28592835
2836 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index.unwrap() orelse block.namespace, wip_ty.index);
2837
2838 if (pt.zcu.comp.incremental) {
2839 try ip.addDependency(
2840 sema.gpa,
2841 AnalUnit.wrap(.{ .cau = new_cau_index }),
2842 .{ .src_hash = tracked_inst },
2843 );
2844 }
2845
28602846 if (new_namespace_index.unwrap()) |ns| {
28612847 const decls = sema.code.bodySlice(extra_index, decls_len);
2862 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
2848 try pt.scanNamespace(ns, decls);
28632849 }
28642850
2865 try pt.finalizeAnonDecl(new_decl_index);
28662851 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
2867 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
2868 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
2852 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
2853 try sema.declareDependency(.{ .interned = wip_ty.index });
2854 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
28692855}
28702856
2871fn createAnonymousDeclTypeNamed(
2857fn createTypeName(
28722858 sema: *Sema,
28732859 block: *Block,
2874 val: Value,
28752860 name_strategy: Zir.Inst.NameStrategy,
28762861 anon_prefix: []const u8,
28772862 inst: ?Zir.Inst.Index,
2878) !InternPool.DeclIndex {
2863 /// This is used purely to give the type a unique name in the `anon` case.
2864 type_index: InternPool.Index,
2865) !InternPool.NullTerminatedString {
28792866 const pt = sema.pt;
28802867 const zcu = pt.zcu;
2868 const gpa = zcu.gpa;
28812869 const ip = &zcu.intern_pool;
2882 const gpa = sema.gpa;
2883 const namespace = block.namespace;
2884 const new_decl_index = try pt.allocateNewDecl(namespace);
2885 errdefer pt.destroyDecl(new_decl_index);
28862870
28872871 switch (name_strategy) {
28882872 .anon => {}, // handled after switch
2889 .parent => {
2890 try pt.initNewAnonDecl(new_decl_index, val, block.type_name_ctx, .none);
2891 return new_decl_index;
2892 },
2873 .parent => return block.type_name_ctx,
28932874 .func => func_strat: {
28942875 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));
28952876 const zir_tags = sema.code.instructions.items(.tag);
28962877
2897 var buf = std.ArrayList(u8).init(gpa);
2898 defer buf.deinit();
2878 var buf: std.ArrayListUnmanaged(u8) = .{};
2879 defer buf.deinit(gpa);
28992880
2900 const writer = buf.writer();
2881 const writer = buf.writer(gpa);
29012882 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});
29022883
29032884 var arg_i: usize = 0;
......@@ -2931,23 +2912,18 @@ fn createAnonymousDeclTypeNamed(
29312912 };
29322913
29332914 try writer.writeByte(')');
2934 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
2935 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2936 return new_decl_index;
2915 return ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
29372916 },
29382917 .dbg_var => {
2918 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
29392919 const ref = inst.?.toRef();
29402920 const zir_tags = sema.code.instructions.items(.tag);
29412921 const zir_data = sema.code.instructions.items(.data);
29422922 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
2943 .dbg_var_ptr, .dbg_var_val => {
2944 if (zir_data[i].str_op.operand != ref) continue;
2945
2946 const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
2923 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
2924 return ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
29472925 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
29482926 }, .no_embedded_nulls);
2949 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2950 return new_decl_index;
29512927 },
29522928 else => {},
29532929 };
......@@ -2955,20 +2931,19 @@ fn createAnonymousDeclTypeNamed(
29552931 },
29562932 }
29572933
2958 // anon strat handling.
2934 // anon strat handling
29592935
29602936 // It would be neat to have "struct:line:column" but this name has
29612937 // to survive incremental updates, where it may have been shifted down
29622938 // or up to a different line, but unchanged, and thus not unnecessarily
29632939 // semantically analyzed.
2964 // This name is also used as the key in the parent namespace so it cannot be
2965 // renamed.
2940 // TODO: that would be possible, by detecting line number changes and renaming
2941 // types appropriately. However, `@typeName` becomes a problem then. If we remove
2942 // that builtin from the language, we can consider this.
29662943
2967 const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2968 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
2969 }, .no_embedded_nulls) catch unreachable;
2970 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2971 return new_decl_index;
2944 return ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2945 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
2946 }, .no_embedded_nulls);
29722947}
29732948
29742949fn zirEnumDecl(
......@@ -3068,60 +3043,53 @@ fn zirEnumDecl(
30683043
30693044 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
30703045
3071 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3046 const type_name = try sema.createTypeName(
30723047 block,
3073 Value.fromInterned(wip_ty.index),
30743048 small.name_strategy,
30753049 "enum",
30763050 inst,
3051 wip_ty.index,
30773052 );
3078 const new_decl = mod.declPtr(new_decl_index);
3079 new_decl.owns_tv = true;
3080 errdefer if (!done) pt.abortAnonDecl(new_decl_index);
3081
3082 if (pt.zcu.comp.incremental) {
3083 try mod.intern_pool.addDependency(
3084 gpa,
3085 AnalUnit.wrap(.{ .decl = new_decl_index }),
3086 .{ .src_hash = try block.trackZir(inst) },
3087 );
3088 }
3053 wip_ty.setName(ip, type_name);
30893054
30903055 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
30913056 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
30923057 .parent = block.namespace.toOptional(),
3093 .decl_index = new_decl_index,
3058 .owner_type = wip_ty.index,
30943059 .file_scope = block.getFileScopeIndex(mod),
30953060 })).toOptional() else .none;
30963061 errdefer if (!done) if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
30973062
3063 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index.unwrap() orelse block.namespace, wip_ty.index);
3064
3065 if (pt.zcu.comp.incremental) {
3066 try mod.intern_pool.addDependency(
3067 gpa,
3068 AnalUnit.wrap(.{ .cau = new_cau_index }),
3069 .{ .src_hash = try block.trackZir(inst) },
3070 );
3071 }
3072
30983073 if (new_namespace_index.unwrap()) |ns| {
3099 try pt.scanNamespace(ns, decls, new_decl);
3074 try pt.scanNamespace(ns, decls);
31003075 }
31013076
3077 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3078 try sema.declareDependency(.{ .interned = wip_ty.index });
3079
31023080 // We've finished the initial construction of this type, and are about to perform analysis.
3103 // Set the decl and namespace appropriately, and don't destroy anything on failure.
3104 wip_ty.prepare(ip, new_decl_index, new_namespace_index);
3081 // Set the Cau and namespace appropriately, and don't destroy anything on failure.
3082 wip_ty.prepare(ip, new_cau_index, new_namespace_index);
31053083 done = true;
31063084
31073085 const int_tag_ty = ty: {
31083086 // We create a block for the field type instructions because they
31093087 // may need to reference Decls from inside the enum namespace.
3110 // Within the field type, default value, and alignment expressions, the "owner decl"
3111 // should be the enum itself.
3088 // Within the field type, default value, and alignment expressions, the owner should be the enum's `Cau`.
31123089
3113 const prev_owner_decl = sema.owner_decl;
3114 const prev_owner_decl_index = sema.owner_decl_index;
3115 sema.owner_decl = new_decl;
3116 sema.owner_decl_index = new_decl_index;
3117 defer {
3118 sema.owner_decl = prev_owner_decl;
3119 sema.owner_decl_index = prev_owner_decl_index;
3120 }
3121
3122 const prev_owner_func_index = sema.owner_func_index;
3123 sema.owner_func_index = .none;
3124 defer sema.owner_func_index = prev_owner_func_index;
3090 const prev_owner = sema.owner;
3091 sema.owner = AnalUnit.wrap(.{ .cau = new_cau_index });
3092 defer sema.owner = prev_owner;
31253093
31263094 const prev_func_index = sema.func_index;
31273095 sema.func_index = .none;
......@@ -3135,7 +3103,7 @@ fn zirEnumDecl(
31353103 .inlining = null,
31363104 .is_comptime = true,
31373105 .src_base_inst = tracked_inst,
3138 .type_name_ctx = new_decl.name,
3106 .type_name_ctx = type_name,
31393107 };
31403108 defer enum_block.instructions.deinit(sema.gpa);
31413109
......@@ -3253,7 +3221,6 @@ fn zirEnumDecl(
32533221 }
32543222 }
32553223
3256 try pt.finalizeAnonDecl(new_decl_index);
32573224 return Air.internedToRef(wip_ty.index);
32583225}
32593226
......@@ -3336,41 +3303,41 @@ fn zirUnionDecl(
33363303 });
33373304 errdefer wip_ty.cancel(ip, pt.tid);
33383305
3339 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3306 wip_ty.setName(ip, try sema.createTypeName(
33403307 block,
3341 Value.fromInterned(wip_ty.index),
33423308 small.name_strategy,
33433309 "union",
33443310 inst,
3345 );
3346 mod.declPtr(new_decl_index).owns_tv = true;
3347 errdefer pt.abortAnonDecl(new_decl_index);
3348
3349 if (pt.zcu.comp.incremental) {
3350 try mod.intern_pool.addDependency(
3351 gpa,
3352 AnalUnit.wrap(.{ .decl = new_decl_index }),
3353 .{ .src_hash = try block.trackZir(inst) },
3354 );
3355 }
3311 wip_ty.index,
3312 ));
33563313
33573314 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
33583315 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
33593316 .parent = block.namespace.toOptional(),
3360 .decl_index = new_decl_index,
3317 .owner_type = wip_ty.index,
33613318 .file_scope = block.getFileScopeIndex(mod),
33623319 })).toOptional() else .none;
33633320 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
33643321
3322 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index.unwrap() orelse block.namespace, wip_ty.index);
3323
3324 if (pt.zcu.comp.incremental) {
3325 try mod.intern_pool.addDependency(
3326 gpa,
3327 AnalUnit.wrap(.{ .cau = new_cau_index }),
3328 .{ .src_hash = try block.trackZir(inst) },
3329 );
3330 }
3331
33653332 if (new_namespace_index.unwrap()) |ns| {
33663333 const decls = sema.code.bodySlice(extra_index, decls_len);
3367 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3334 try pt.scanNamespace(ns, decls);
33683335 }
33693336
3370 try pt.finalizeAnonDecl(new_decl_index);
33713337 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
3372 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
3373 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3338 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3339 try sema.declareDependency(.{ .interned = wip_ty.index });
3340 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
33743341}
33753342
33763343fn zirOpaqueDecl(
......@@ -3418,47 +3385,33 @@ fn zirOpaqueDecl(
34183385 };
34193386 // No `wrapWipTy` needed as no std.builtin types are opaque.
34203387 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {
3421 .existing => |ty| wip: {
3422 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);
3423 break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip;
3424 },
3388 // No `maybeRemoveOutdatedType` as opaque types are never outdated.
3389 .existing => |ty| return Air.internedToRef(ty),
34253390 .wip => |wip| wip,
34263391 };
34273392 errdefer wip_ty.cancel(ip, pt.tid);
34283393
3429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3394 wip_ty.setName(ip, try sema.createTypeName(
34303395 block,
3431 Value.fromInterned(wip_ty.index),
34323396 small.name_strategy,
34333397 "opaque",
34343398 inst,
3435 );
3436 mod.declPtr(new_decl_index).owns_tv = true;
3437 errdefer pt.abortAnonDecl(new_decl_index);
3438
3439 if (pt.zcu.comp.incremental) {
3440 try ip.addDependency(
3441 gpa,
3442 AnalUnit.wrap(.{ .decl = new_decl_index }),
3443 .{ .src_hash = try block.trackZir(inst) },
3444 );
3445 }
3399 wip_ty.index,
3400 ));
34463401
34473402 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try pt.createNamespace(.{
34483403 .parent = block.namespace.toOptional(),
3449 .decl_index = new_decl_index,
3404 .owner_type = wip_ty.index,
34503405 .file_scope = block.getFileScopeIndex(mod),
34513406 })).toOptional() else .none;
34523407 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
34533408
34543409 if (new_namespace_index.unwrap()) |ns| {
34553410 const decls = sema.code.bodySlice(extra_index, decls_len);
3456 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3411 try pt.scanNamespace(ns, decls);
34573412 }
34583413
3459 try pt.finalizeAnonDecl(new_decl_index);
3460
3461 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3414 return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index));
34623415}
34633416
34643417fn zirErrorSetDecl(
......@@ -3774,7 +3727,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
37743727 // might have already done our job and created an anon decl ref.
37753728 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
37763729 .ptr => |ptr| switch (ptr.base_addr) {
3777 .anon_decl => {
3730 .uav => {
37783731 // The comptime-ification was already done for us.
37793732 // Just make sure the pointer is const.
37803733 return sema.makePtrConst(block, alloc);
......@@ -3799,7 +3752,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
37993752 // Promote the constant to an anon decl.
38003753 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{
38013754 .ty = alloc_ty.toIntern(),
3802 .base_addr = .{ .anon_decl = .{
3755 .base_addr = .{ .uav = .{
38033756 .val = interned.toIntern(),
38043757 .orig_ty = alloc_ty.toIntern(),
38053758 } },
......@@ -4097,7 +4050,7 @@ fn finishResolveComptimeKnownAllocPtr(
40974050 } else {
40984051 return try pt.intern(.{ .ptr = .{
40994052 .ty = alloc_ty.toIntern(),
4100 .base_addr = .{ .anon_decl = .{
4053 .base_addr = .{ .uav = .{
41014054 .orig_ty = alloc_ty.toIntern(),
41024055 .val = result_val,
41034056 } },
......@@ -4250,7 +4203,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
42504203 }
42514204
42524205 const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) {
4253 .anon_decl => |a| a.val,
4206 .uav => |a| a.val,
42544207 .comptime_alloc => |i| val: {
42554208 const alloc = sema.getComptimeAlloc(i);
42564209 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();
......@@ -5505,22 +5458,23 @@ fn failWithBadMemberAccess(
55055458 field_name: InternPool.NullTerminatedString,
55065459) CompileError {
55075460 const pt = sema.pt;
5508 const mod = pt.zcu;
5509 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
5461 const zcu = pt.zcu;
5462 const ip = &zcu.intern_pool;
5463 const kw_name = switch (agg_ty.zigTypeTag(zcu)) {
55105464 .Union => "union",
55115465 .Struct => "struct",
55125466 .Opaque => "opaque",
55135467 .Enum => "enum",
55145468 else => unreachable,
55155469 };
5516 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
5470 if (agg_ty.typeDeclInst(zcu)) |inst| if (inst.resolve(ip) == .main_struct_inst) {
55175471 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{
5518 agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5472 agg_ty.fmt(pt), field_name.fmt(ip),
55195473 });
55205474 };
55215475
55225476 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5523 kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5477 kw_name, agg_ty.fmt(pt), field_name.fmt(ip),
55245478 });
55255479}
55265480
......@@ -5535,13 +5489,12 @@ fn failWithBadStructFieldAccess(
55355489 const pt = sema.pt;
55365490 const zcu = pt.zcu;
55375491 const ip = &zcu.intern_pool;
5538 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
55395492
55405493 const msg = msg: {
55415494 const msg = try sema.errMsg(
55425495 field_src,
55435496 "no field named '{}' in struct '{}'",
5544 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
5497 .{ field_name.fmt(ip), struct_type.name.fmt(ip) },
55455498 );
55465499 errdefer msg.destroy(sema.gpa);
55475500 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
......@@ -5562,13 +5515,12 @@ fn failWithBadUnionFieldAccess(
55625515 const zcu = pt.zcu;
55635516 const ip = &zcu.intern_pool;
55645517 const gpa = sema.gpa;
5565 const decl = zcu.declPtr(union_obj.decl);
55665518
55675519 const msg = msg: {
55685520 const msg = try sema.errMsg(
55695521 field_src,
55705522 "no field named '{}' in union '{}'",
5571 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
5523 .{ field_name.fmt(ip), union_obj.name.fmt(ip) },
55725524 );
55735525 errdefer msg.destroy(gpa);
55745526 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
......@@ -5659,7 +5611,7 @@ fn storeToInferredAllocComptime(
56595611 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
56605612 iac.ptr = try pt.intern(.{ .ptr = .{
56615613 .ty = alloc_ty.toIntern(),
5662 .base_addr = .{ .anon_decl = .{
5614 .base_addr = .{ .uav = .{
56635615 .val = operand_val.toIntern(),
56645616 .orig_ty = alloc_ty.toIntern(),
56655617 } },
......@@ -5748,11 +5700,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.
57485700 .ty = array_ty.toIntern(),
57495701 .storage = .{ .bytes = string },
57505702 } });
5751 return anonDeclRef(sema, val);
5703 return sema.uavRef(val);
57525704}
57535705
5754fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5755 return Air.internedToRef(try refValue(sema, val));
5706fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5707 return Air.internedToRef(try sema.refValue(val));
57565708}
57575709
57585710fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
......@@ -5767,7 +5719,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
57675719 })).toIntern();
57685720 return pt.intern(.{ .ptr = .{
57695721 .ty = ptr_ty,
5770 .base_addr = .{ .anon_decl = .{
5722 .base_addr = .{ .uav = .{
57715723 .val = val,
57725724 .orig_ty = ptr_ty,
57735725 } },
......@@ -5866,7 +5818,7 @@ fn zirCompileLog(
58665818 }
58675819 try writer.print("\n", .{});
58685820
5869 const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.ownerUnit());
5821 const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.owner);
58705822 if (!gop.found_existing) gop.value_ptr.* = .{
58715823 .base_node_inst = block.src_base_inst,
58725824 .node_offset = src_node,
......@@ -6021,7 +5973,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60215973 if (!comp.config.link_libc)
60225974 try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});
60235975
6024 const gop = try zcu.cimport_errors.getOrPut(gpa, sema.ownerUnit());
5976 const gop = try zcu.cimport_errors.getOrPut(gpa, sema.owner);
60255977 if (!gop.found_existing) {
60265978 gop.value_ptr.* = c_import_res.errors;
60275979 c_import_res.errors = std.zig.ErrorBundle.empty;
......@@ -6069,13 +6021,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60696021 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60706022
60716023 const path_digest = zcu.filePathDigest(result.file_index);
6072 const root_decl = zcu.fileRootDecl(result.file_index);
6073 pt.astGenFile(result.file, path_digest, root_decl) catch |err|
6024 const old_root_type = zcu.fileRootType(result.file_index);
6025 pt.astGenFile(result.file, path_digest, old_root_type) catch |err|
60746026 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60756027
6028 // TODO: register some kind of dependency on the file.
6029 // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to
6030 // trigger re-analysis later.
60766031 try pt.ensureFileAnalyzed(result.file_index);
6077 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;
6078 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);
6032 return Air.internedToRef(zcu.fileRootType(result.file_index));
60796033}
60806034
60816035fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -6423,36 +6377,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
64236377 defer tracy.end();
64246378
64256379 const pt = sema.pt;
6426 const mod = pt.zcu;
6380 const zcu = pt.zcu;
6381 const ip = &zcu.intern_pool;
64276382 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
64286383 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
64296384 const src = block.nodeOffset(inst_data.src_node);
64306385 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
64316386 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
6432 const decl_name = try mod.intern_pool.getOrPutString(
6433 mod.gpa,
6387 const decl_name = try ip.getOrPutString(
6388 zcu.gpa,
64346389 pt.tid,
64356390 sema.code.nullTerminatedString(extra.decl_name),
64366391 .no_embedded_nulls,
64376392 );
6438 const decl_index = if (extra.namespace != .none) index_blk: {
6393 const nav_index = if (extra.namespace != .none) index_blk: {
64396394 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);
6440 const container_namespace = container_ty.getNamespaceIndex(mod);
6395 const container_namespace = container_ty.getNamespaceIndex(zcu);
64416396
6442 const maybe_index = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false);
6443 break :index_blk maybe_index orelse
6397 const lookup = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false) orelse
64446398 return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name);
6399
6400 break :index_blk lookup.nav;
64456401 } else try sema.lookupIdentifier(block, operand_src, decl_name);
64466402 const options = try sema.resolveExportOptions(block, options_src, extra.options);
6447 {
6448 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));
6449 try sema.ensureDeclAnalyzed(decl_index);
6450 const exported_decl = mod.declPtr(decl_index);
6451 if (exported_decl.val.getFunction(mod)) |function| {
6452 return sema.analyzeExport(block, src, options, function.owner_decl);
6453 }
6454 }
6455 try sema.analyzeExport(block, src, options, decl_index);
6403
6404 try sema.ensureNavResolved(src, nav_index);
6405
6406 // Make sure to export the owner Nav if applicable.
6407 const exported_nav = switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) {
6408 .variable => |v| v.owner_nav,
6409 .@"extern" => |e| e.owner_nav,
6410 .func => |f| f.owner_nav,
6411 else => nav_index,
6412 };
6413 try sema.analyzeExport(block, src, options, exported_nav);
64566414}
64576415
64586416fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -6460,7 +6418,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
64606418 defer tracy.end();
64616419
64626420 const pt = sema.pt;
6463 const mod = pt.zcu;
6421 const zcu = pt.zcu;
6422 const ip = &zcu.intern_pool;
64646423 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
64656424 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
64666425 const src = block.nodeOffset(inst_data.src_node);
......@@ -6472,17 +6431,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
64726431 const options = try sema.resolveExportOptions(block, options_src, extra.options);
64736432 if (options.linkage == .internal)
64746433 return;
6475 if (operand.getFunction(mod)) |function| {
6476 const decl_index = function.owner_decl;
6477 return sema.analyzeExport(block, src, options, decl_index);
6478 }
64796434
6480 try sema.exports.append(mod.gpa, .{
6481 .opts = options,
6482 .src = src,
6483 .exported = .{ .value = operand.toIntern() },
6484 .status = .in_progress,
6485 });
6435 // If the value has an owner Nav, export that instead.
6436 const maybe_owner_nav = switch (ip.indexToKey(operand.toIntern())) {
6437 .variable => |v| v.owner_nav,
6438 .@"extern" => |e| e.owner_nav,
6439 .func => |f| f.owner_nav,
6440 else => null,
6441 };
6442 if (maybe_owner_nav) |owner_nav| {
6443 return sema.analyzeExport(block, src, options, owner_nav);
6444 } else {
6445 try sema.exports.append(zcu.gpa, .{
6446 .opts = options,
6447 .src = src,
6448 .exported = .{ .uav = operand.toIntern() },
6449 .status = .in_progress,
6450 });
6451 }
64866452}
64876453
64886454pub fn analyzeExport(
......@@ -6490,22 +6456,22 @@ pub fn analyzeExport(
64906456 block: *Block,
64916457 src: LazySrcLoc,
64926458 options: Module.Export.Options,
6493 exported_decl_index: InternPool.DeclIndex,
6459 exported_nav_index: InternPool.Nav.Index,
64946460) !void {
64956461 const gpa = sema.gpa;
64966462 const pt = sema.pt;
6497 const mod = pt.zcu;
6463 const zcu = pt.zcu;
6464 const ip = &zcu.intern_pool;
64986465
64996466 if (options.linkage == .internal)
65006467 return;
65016468
6502 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = exported_decl_index }));
6503 try sema.ensureDeclAnalyzed(exported_decl_index);
6504 const exported_decl = mod.declPtr(exported_decl_index);
6505 const export_ty = exported_decl.typeOf(mod);
6469 try sema.ensureNavResolved(src, exported_nav_index);
6470 const exported_nav = ip.getNav(exported_nav_index);
6471 const export_ty = Type.fromInterned(exported_nav.typeOf(ip));
65066472
65076473 if (!try sema.validateExternType(export_ty, .other)) {
6508 const msg = msg: {
6474 return sema.failWithOwnedErrorMsg(block, msg: {
65096475 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
65106476 errdefer msg.destroy(gpa);
65116477
......@@ -6513,59 +6479,50 @@ pub fn analyzeExport(
65136479
65146480 try sema.addDeclaredHereNote(msg, export_ty);
65156481 break :msg msg;
6516 };
6517 return sema.failWithOwnedErrorMsg(block, msg);
6482 });
65186483 }
65196484
65206485 // TODO: some backends might support re-exporting extern decls
6521 if (exported_decl.isExtern(mod)) {
6486 if (exported_nav.isExtern(ip)) {
65226487 return sema.fail(block, src, "export target cannot be extern", .{});
65236488 }
65246489
6525 try sema.maybeQueueFuncBodyAnalysis(src, exported_decl_index);
6490 try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index);
65266491
65276492 try sema.exports.append(gpa, .{
65286493 .opts = options,
65296494 .src = src,
6530 .exported = .{ .decl_index = exported_decl_index },
6495 .exported = .{ .nav = exported_nav_index },
65316496 .status = .in_progress,
65326497 });
65336498}
65346499
65356500fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
65366501 const pt = sema.pt;
6537 const mod = pt.zcu;
6502 const zcu = pt.zcu;
65386503 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
65396504 const operand_src = block.builtinCallArgSrc(extra.node, 0);
65406505 const src = block.nodeOffset(extra.node);
65416506 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
6507
6508 const func = switch (sema.owner.unwrap()) {
6509 .func => |func| func,
6510 .cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}),
6511 };
6512
65426513 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
65436514 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
65446515 alignment.toByteUnits().?,
65456516 });
65466517 }
65476518
6548 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
6549 switch (fn_owner_decl.typeOf(mod).fnCallingConvention(mod)) {
6519 switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) {
65506520 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
65516521 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
6552 else => if (block.inlining != null) {
6553 return sema.fail(block, src, "@setAlignStack in inline call", .{});
6554 },
6555 }
6556
6557 if (sema.prev_stack_alignment_src) |prev_src| {
6558 const msg = msg: {
6559 const msg = try sema.errMsg(src, "multiple @setAlignStack in the same function body", .{});
6560 errdefer msg.destroy(sema.gpa);
6561 try sema.errNote(prev_src, msg, "other instance here", .{});
6562 break :msg msg;
6563 };
6564 return sema.failWithOwnedErrorMsg(block, msg);
6522 else => {},
65656523 }
6566 sema.prev_stack_alignment_src = src;
65676524
6568 mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
6525 zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
65696526}
65706527
65716528fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
......@@ -6577,16 +6534,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
65776534 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{
65786535 .needed_comptime_reason = "operand to @setCold must be comptime-known",
65796536 });
6580 if (sema.func_index == .none) return; // does nothing outside a function
6581 ip.funcSetCold(sema.func_index, is_cold);
6537 // TODO: should `@setCold` apply to the parent in an inline call?
6538 // See also #20642 and friends.
6539 const func = switch (sema.owner.unwrap()) {
6540 .func => |func| func,
6541 .cau => return, // does nothing outside a function
6542 };
6543 ip.funcSetCold(func, is_cold);
65826544}
65836545
65846546fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
65856547 const pt = sema.pt;
65866548 const mod = pt.zcu;
65876549 const ip = &mod.intern_pool;
6588 if (sema.func_index == .none) return; // does nothing outside a function
6589 ip.funcSetDisableInstrumentation(sema.func_index);
6550 const func = switch (sema.owner.unwrap()) {
6551 .func => |func| func,
6552 .cau => return, // does nothing outside a function
6553 };
6554 ip.funcSetDisableInstrumentation(func);
65906555}
65916556
65926557fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
......@@ -6760,8 +6725,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
67606725 inst_data.get(sema.code),
67616726 .no_embedded_nulls,
67626727 );
6763 const decl_index = try sema.lookupIdentifier(block, src, decl_name);
6764 return sema.analyzeDeclRef(src, decl_index);
6728 const nav_index = try sema.lookupIdentifier(block, src, decl_name);
6729 return sema.analyzeNavRef(src, nav_index);
67656730}
67666731
67676732fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -6775,17 +6740,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
67756740 inst_data.get(sema.code),
67766741 .no_embedded_nulls,
67776742 );
6778 const decl = try sema.lookupIdentifier(block, src, decl_name);
6779 return sema.analyzeDeclVal(block, src, decl);
6743 const nav = try sema.lookupIdentifier(block, src, decl_name);
6744 return sema.analyzeNavVal(block, src, nav);
67806745}
67816746
6782fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {
6747fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.Nav.Index {
67836748 const pt = sema.pt;
67846749 const mod = pt.zcu;
67856750 var namespace = block.namespace;
67866751 while (true) {
6787 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {
6788 return decl_index;
6752 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |lookup| {
6753 assert(lookup.accessible);
6754 return lookup.nav;
67896755 }
67906756 namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break;
67916757 }
......@@ -6801,66 +6767,72 @@ fn lookupInNamespace(
68016767 opt_namespace_index: InternPool.OptionalNamespaceIndex,
68026768 ident_name: InternPool.NullTerminatedString,
68036769 observe_usingnamespace: bool,
6804) CompileError!?InternPool.DeclIndex {
6770) CompileError!?struct {
6771 nav: InternPool.Nav.Index,
6772 /// If `false`, the declaration is in a different file and is not `pub`.
6773 /// We still return the declaration for better error reporting.
6774 accessible: bool,
6775} {
68056776 const pt = sema.pt;
6806 const mod = pt.zcu;
6777 const zcu = pt.zcu;
6778 const ip = &zcu.intern_pool;
68076779
68086780 const namespace_index = opt_namespace_index.unwrap() orelse return null;
6809 const namespace = mod.namespacePtr(namespace_index);
6810 const namespace_decl = mod.declPtr(namespace.decl_index);
6811 if (namespace_decl.analysis == .file_failure) {
6812 return error.AnalysisFail;
6813 }
6781 const namespace = zcu.namespacePtr(namespace_index);
6782
6783 const adapter: Zcu.Namespace.NameAdapter = .{ .zcu = zcu };
68146784
6815 if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) {
6816 const src_file = mod.namespacePtr(block.namespace).file_scope;
6785 const src_file = zcu.namespacePtr(block.namespace).file_scope;
68176786
6787 if (observe_usingnamespace and (namespace.pub_usingnamespace.items.len != 0 or namespace.priv_usingnamespace.items.len != 0)) {
68186788 const gpa = sema.gpa;
6819 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{};
6789 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{};
68206790 defer checked_namespaces.deinit(gpa);
68216791
68226792 // Keep track of name conflicts for error notes.
6823 var candidates: std.ArrayListUnmanaged(InternPool.DeclIndex) = .{};
6793 var candidates: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{};
68246794 defer candidates.deinit(gpa);
68256795
6826 try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file);
6796 try checked_namespaces.put(gpa, namespace, {});
68276797 var check_i: usize = 0;
68286798
68296799 while (check_i < checked_namespaces.count()) : (check_i += 1) {
68306800 const check_ns = checked_namespaces.keys()[check_i];
6831 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {
6832 // Skip decls which are not marked pub, which are in a different
6833 // file than the `a.b`/`@hasDecl` syntax.
6834 const decl = mod.declPtr(decl_index);
6835 if (decl.is_pub or (src_file == decl.getFileScopeIndex(mod) and
6836 checked_namespaces.values()[check_i]))
6837 {
6838 try candidates.append(gpa, decl_index);
6839 }
6840 }
6841 var it = check_ns.usingnamespace_set.iterator();
6842 while (it.next()) |entry| {
6843 const sub_usingnamespace_decl_index = entry.key_ptr.*;
6844 // Skip the decl we're currently analysing.
6845 if (sub_usingnamespace_decl_index == sema.owner_decl_index) continue;
6846 const sub_usingnamespace_decl = mod.declPtr(sub_usingnamespace_decl_index);
6847 const sub_is_pub = entry.value_ptr.*;
6848 if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScopeIndex(mod)) {
6849 // Skip usingnamespace decls which are not marked pub, which are in
6850 // a different file than the `a.b`/`@hasDecl` syntax.
6801 const Pass = enum { @"pub", priv };
6802 for ([2]Pass{ .@"pub", .priv }) |pass| {
6803 if (pass == .priv and src_file != check_ns.file_scope) {
68516804 continue;
68526805 }
6853 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index);
6854 const ns_ty = sub_usingnamespace_decl.val.toType();
6855 const sub_ns = mod.namespacePtrUnwrap(ns_ty.getNamespaceIndex(mod)) orelse continue;
6856 try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScopeIndex(mod));
6806
6807 const decls, const usingnamespaces = switch (pass) {
6808 .@"pub" => .{ &check_ns.pub_decls, &check_ns.pub_usingnamespace },
6809 .priv => .{ &check_ns.priv_decls, &check_ns.priv_usingnamespace },
6810 };
6811
6812 if (decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6813 try candidates.append(gpa, nav_index);
6814 }
6815
6816 for (usingnamespaces.items) |sub_ns_nav| {
6817 try sema.ensureNavResolved(src, sub_ns_nav);
6818 const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.resolved.val);
6819 const sub_ns = zcu.namespacePtrUnwrap(sub_ns_ty.getNamespaceIndex(zcu)) orelse continue;
6820 try checked_namespaces.put(gpa, sub_ns, {});
6821 }
68576822 }
68586823 }
68596824
6860 {
6825 ignore_self: {
6826 const skip_nav = switch (sema.owner.unwrap()) {
6827 .func => break :ignore_self,
6828 .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
6829 .none, .type => break :ignore_self,
6830 .nav => |nav| nav,
6831 },
6832 };
68616833 var i: usize = 0;
68626834 while (i < candidates.items.len) {
6863 if (candidates.items[i] == sema.owner_decl_index) {
6835 if (candidates.items[i] == skip_nav) {
68646836 _ = candidates.orderedRemove(i);
68656837 } else {
68666838 i += 1;
......@@ -6870,48 +6842,50 @@ fn lookupInNamespace(
68706842
68716843 switch (candidates.items.len) {
68726844 0 => {},
6873 1 => {
6874 const decl_index = candidates.items[0];
6875 return decl_index;
6876 },
6877 else => {
6878 const msg = msg: {
6879 const msg = try sema.errMsg(src, "ambiguous reference", .{});
6880 errdefer msg.destroy(gpa);
6881 for (candidates.items) |candidate_index| {
6882 const candidate = mod.declPtr(candidate_index);
6883 try sema.errNote(.{
6884 .base_node_inst = candidate.zir_decl_index.unwrap().?,
6885 .offset = LazySrcLoc.Offset.nodeOffset(0),
6886 }, msg, "declared here", .{});
6887 }
6888 break :msg msg;
6889 };
6890 return sema.failWithOwnedErrorMsg(block, msg);
6845 1 => return .{
6846 .nav = candidates.items[0],
6847 .accessible = true,
68916848 },
6849 else => return sema.failWithOwnedErrorMsg(block, msg: {
6850 const msg = try sema.errMsg(src, "ambiguous reference", .{});
6851 errdefer msg.destroy(gpa);
6852 for (candidates.items) |candidate| {
6853 try sema.errNote(zcu.navSrcLoc(candidate), msg, "declared here", .{});
6854 }
6855 break :msg msg;
6856 }),
68926857 }
6893 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {
6894 return decl_index;
6858 } else if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6859 return .{
6860 .nav = nav_index,
6861 .accessible = true,
6862 };
6863 } else if (namespace.priv_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6864 return .{
6865 .nav = nav_index,
6866 .accessible = src_file == namespace.file_scope,
6867 };
68956868 }
68966869
68976870 return null;
68986871}
68996872
6900fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6873fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedInst.Index {
69016874 const pt = sema.pt;
6902 const mod = pt.zcu;
6903 const func_val = (try sema.resolveValue(func_inst)) orelse return null;
6904 if (func_val.isUndef(mod)) return null;
6905 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
6906 .extern_func => |extern_func| extern_func.decl,
6907 .func => |func| func.owner_decl,
6875 const zcu = pt.zcu;
6876 const ip = &zcu.intern_pool;
6877 const func_val = try sema.resolveValue(func_inst) orelse return null;
6878 if (func_val.isUndef(zcu)) return null;
6879 const nav = switch (ip.indexToKey(func_val.toIntern())) {
6880 .@"extern" => |e| e.owner_nav,
6881 .func => |f| f.owner_nav,
69086882 .ptr => |ptr| switch (ptr.base_addr) {
6909 .decl => |decl| if (ptr.byte_offset == 0) mod.declPtr(decl).val.getFunction(mod).?.owner_decl else return null,
6883 .nav => |nav| if (ptr.byte_offset == 0) nav else return null,
69106884 else => return null,
69116885 },
69126886 else => return null,
69136887 };
6914 return mod.declPtr(owner_decl_index);
6888 return ip.getNav(nav).srcInst(ip);
69156889}
69166890
69176891pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
......@@ -7100,11 +7074,12 @@ fn zirCall(
71007074 const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1);
71017075 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
71027076
7103 if (sema.owner_func_index == .none or
7104 !mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn)
7105 {
7106 // No errorable fn actually called; we have no error return trace
7107 input_is_error = false;
7077 switch (sema.owner.unwrap()) {
7078 .cau => input_is_error = false,
7079 .func => |owner_func| if (!mod.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) {
7080 // No errorable fn actually called; we have no error return trace
7081 input_is_error = false;
7082 },
71087083 }
71097084
71107085 if (block.ownerModule().error_tracing and
......@@ -7199,7 +7174,7 @@ fn checkCallArgumentCount(
71997174 return func_ty;
72007175 }
72017176
7202 const maybe_decl = try sema.funcDeclSrc(func);
7177 const maybe_func_inst = try sema.funcDeclSrcInst(func);
72037178 const member_str = if (member_fn) "member function " else "";
72047179 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
72057180 const msg = msg: {
......@@ -7215,9 +7190,9 @@ fn checkCallArgumentCount(
72157190 );
72167191 errdefer msg.destroy(sema.gpa);
72177192
7218 if (maybe_decl) |fn_decl| {
7193 if (maybe_func_inst) |func_inst| {
72197194 try sema.errNote(.{
7220 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
7195 .base_node_inst = func_inst,
72217196 .offset = LazySrcLoc.Offset.nodeOffset(0),
72227197 }, msg, "function declared here", .{});
72237198 }
......@@ -7544,7 +7519,7 @@ fn analyzeCall(
75447519 if (func_val.isUndef(mod))
75457520 return sema.failWithUseOfUndef(block, call_src);
75467521 if (cc == .Naked) {
7547 const maybe_decl = try sema.funcDeclSrc(func);
7522 const maybe_func_inst = try sema.funcDeclSrcInst(func);
75487523 const msg = msg: {
75497524 const msg = try sema.errMsg(
75507525 func_src,
......@@ -7553,8 +7528,8 @@ fn analyzeCall(
75537528 );
75547529 errdefer msg.destroy(sema.gpa);
75557530
7556 if (maybe_decl) |fn_decl| try sema.errNote(.{
7557 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
7531 if (maybe_func_inst) |func_inst| try sema.errNote(.{
7532 .base_node_inst = func_inst,
75587533 .offset = LazySrcLoc.Offset.nodeOffset(0),
75597534 }, msg, "function declared here", .{});
75607535 break :msg msg;
......@@ -7654,33 +7629,32 @@ fn analyzeCall(
76547629 .block_comptime_reason = comptime_reason,
76557630 });
76567631 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
7657 .extern_func => return sema.fail(block, call_src, "{s} call of extern function", .{
7632 .@"extern" => return sema.fail(block, call_src, "{s} call of extern function", .{
76587633 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
76597634 }),
76607635 .func => func_val.toIntern(),
76617636 .ptr => |ptr| blk: {
76627637 switch (ptr.base_addr) {
7663 .decl => |decl| if (ptr.byte_offset == 0) {
7664 const func_val_ptr = mod.declPtr(decl).val.toIntern();
7665 const intern_index = mod.intern_pool.indexToKey(func_val_ptr);
7666 if (intern_index == .extern_func or (intern_index == .variable and intern_index.variable.is_extern))
7638 .nav => |nav_index| if (ptr.byte_offset == 0) {
7639 const nav = ip.getNav(nav_index);
7640 if (nav.isExtern(ip))
76677641 return sema.fail(block, call_src, "{s} call of extern function pointer", .{
7668 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7642 if (is_comptime_call) "comptime" else "inline",
76697643 });
7670 break :blk func_val_ptr;
7644 break :blk nav.status.resolved.val;
76717645 },
76727646 else => {},
76737647 }
76747648 assert(callee_ty.isPtrAtRuntime(mod));
76757649 return sema.fail(block, call_src, "{s} call of function pointer", .{
7676 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7650 if (is_comptime_call) "comptime" else "inline",
76777651 });
76787652 },
76797653 else => unreachable,
76807654 };
76817655 if (func_ty_info.is_var_args) {
76827656 return sema.fail(block, call_src, "{s} call of variadic function", .{
7683 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7657 if (is_comptime_call) "comptime" else "inline",
76847658 });
76857659 }
76867660
......@@ -7712,7 +7686,12 @@ fn analyzeCall(
77127686 };
77137687
77147688 const module_fn = mod.funcInfo(module_fn_index);
7715 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
7689
7690 // This is not a function instance, so the function's `Nav` has a
7691 // `Cau` -- we don't need to check `generic_owner`.
7692 const fn_nav = ip.getNav(module_fn.owner_nav);
7693 const fn_cau_index = fn_nav.analysis_owner.unwrap().?;
7694 const fn_cau = ip.getCau(fn_cau_index);
77167695
77177696 // We effectively want a child Sema here, but can't literally do that, because we need AIR
77187697 // to be shared. InlineCallSema is a wrapper which handles this for us. While `ics` is in
......@@ -7720,7 +7699,7 @@ fn analyzeCall(
77207699 // whenever performing an operation where the difference matters.
77217700 var ics = InlineCallSema.init(
77227701 sema,
7723 fn_owner_decl.getFileScope(mod).zir,
7702 mod.cauFileScope(fn_cau_index).zir,
77247703 module_fn_index,
77257704 block.error_return_trace_index,
77267705 );
......@@ -7729,7 +7708,8 @@ fn analyzeCall(
77297708 var child_block: Block = .{
77307709 .parent = null,
77317710 .sema = sema,
7732 .namespace = fn_owner_decl.src_namespace,
7711 // The function body exists in the same namespace as the corresponding function declaration.
7712 .namespace = fn_cau.namespace,
77337713 .instructions = .{},
77347714 .label = null,
77357715 .inlining = &inlining,
......@@ -7740,8 +7720,8 @@ fn analyzeCall(
77407720 .runtime_cond = block.runtime_cond,
77417721 .runtime_loop = block.runtime_loop,
77427722 .runtime_index = block.runtime_index,
7743 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,
7744 .type_name_ctx = fn_owner_decl.name,
7723 .src_base_inst = fn_cau.zir_index,
7724 .type_name_ctx = fn_nav.fqn,
77457725 };
77467726
77477727 const merges = &child_block.inlining.?.merges;
......@@ -7759,7 +7739,7 @@ fn analyzeCall(
77597739 // comptime memory is mutated.
77607740 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
77617741
7762 const owner_info = mod.typeToFunc(fn_owner_decl.typeOf(mod)).?;
7742 const owner_info = mod.typeToFunc(Type.fromInterned(module_fn.ty)).?;
77637743 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);
77647744 var new_fn_info: InternPool.GetFuncTypeKey = .{
77657745 .param_types = new_param_types,
......@@ -7809,9 +7789,6 @@ fn analyzeCall(
78097789 _ = ics.callee();
78107790
78117791 if (!inlining.has_comptime_args) {
7812 if (module_fn.analysisUnordered(ip).state == .sema_failure)
7813 return error.AnalysisFail;
7814
78157792 var block_it = block;
78167793 while (block_it.inlining) |parent_inlining| {
78177794 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {
......@@ -7957,8 +7934,11 @@ fn analyzeCall(
79577934
79587935 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
79597936
7960 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7961 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
7937 switch (sema.owner.unwrap()) {
7938 .cau => {},
7939 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7940 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
7941 },
79627942 }
79637943
79647944 if (try sema.resolveValue(func)) |func_val| {
......@@ -7994,7 +7974,7 @@ fn analyzeCall(
79947974 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
79957975 .func => break :skip_safety,
79967976 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
7997 .decl => |decl| if (!mod.declPtr(decl).isExtern(mod)) break :skip_safety,
7977 .nav => |nav| if (!ip.getNav(nav).isExtern(ip)) break :skip_safety,
79987978 else => {},
79997979 },
80007980 else => {},
......@@ -8018,18 +7998,18 @@ fn analyzeCall(
80187998
80197999fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
80208000 const pt = sema.pt;
8021 const mod = pt.zcu;
8022 const target = mod.getTarget();
8023 const backend = mod.comp.getZigBackend();
8001 const zcu = pt.zcu;
8002 const target = zcu.getTarget();
8003 const backend = zcu.comp.getZigBackend();
80248004 if (!target_util.supportsTailCall(target, backend)) {
80258005 return sema.fail(block, call_src, "unable to perform tail call: compiler backend '{s}' does not support tail calls on target architecture '{s}' with the selected CPU feature flags", .{
80268006 @tagName(backend), @tagName(target.cpu.arch),
80278007 });
80288008 }
8029 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);
8030 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {
8009 const owner_func_ty = Type.fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty);
8010 if (owner_func_ty.toIntern() != func_ty.toIntern()) {
80318011 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
8032 func_ty.fmt(pt), func_decl.typeOf(mod).fmt(pt),
8012 func_ty.fmt(pt), owner_func_ty.fmt(pt),
80338013 });
80348014 }
80358015 _ = try block.addUnOp(.ret, result);
......@@ -8191,7 +8171,7 @@ fn instantiateGenericCall(
81918171 });
81928172 const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {
81938173 .func => func_val.toIntern(),
8194 .ptr => |ptr| zcu.declPtr(ptr.base_addr.decl).val.toIntern(),
8174 .ptr => |ptr| ip.getNav(ptr.base_addr.nav).status.resolved.val,
81958175 else => unreachable,
81968176 };
81978177 const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func;
......@@ -8207,10 +8187,10 @@ fn instantiateGenericCall(
82078187 // The actual monomorphization happens via adding `func_instance` to
82088188 // `InternPool`.
82098189
8210 const fn_owner_decl = zcu.declPtr(generic_owner_func.owner_decl);
8211 const namespace_index = fn_owner_decl.src_namespace;
8212 const namespace = zcu.namespacePtr(namespace_index);
8213 const fn_zir = namespace.fileScope(zcu).zir;
8190 // Since we are looking at the generic owner here, it has a `Cau`.
8191 const fn_nav = ip.getNav(generic_owner_func.owner_nav);
8192 const fn_cau = ip.getCau(fn_nav.analysis_owner.unwrap().?);
8193 const fn_zir = zcu.namespacePtr(fn_cau.namespace).fileScope(zcu).zir;
82148194 const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip));
82158195
82168196 const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());
......@@ -8232,15 +8212,13 @@ fn instantiateGenericCall(
82328212 // We pass the generic callsite's owner decl here because whatever `Decl`
82338213 // dependencies are chased at this point should be attached to the
82348214 // callsite, not the `Decl` associated with the `func_instance`.
8235 .owner_decl = sema.owner_decl,
8236 .owner_decl_index = sema.owner_decl_index,
8237 .func_index = sema.owner_func_index,
8215 .owner = sema.owner,
8216 .func_index = sema.func_index,
82388217 // This may not be known yet, since the calling convention could be generic, but there
82398218 // should be no illegal instructions encountered while creating the function anyway.
82408219 .func_is_naked = false,
82418220 .fn_ret_ty = Type.void,
82428221 .fn_ret_ty_ies = null,
8243 .owner_func_index = .none,
82448222 .comptime_args = comptime_args,
82458223 .generic_owner = generic_owner,
82468224 .generic_call_src = call_src,
......@@ -8253,12 +8231,12 @@ fn instantiateGenericCall(
82538231 var child_block: Block = .{
82548232 .parent = null,
82558233 .sema = &child_sema,
8256 .namespace = namespace_index,
8234 .namespace = fn_cau.namespace,
82578235 .instructions = .{},
82588236 .inlining = null,
82598237 .is_comptime = true,
8260 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,
8261 .type_name_ctx = fn_owner_decl.name,
8238 .src_base_inst = fn_cau.zir_index,
8239 .type_name_ctx = fn_nav.fqn,
82628240 };
82638241 defer child_block.instructions.deinit(gpa);
82648242
......@@ -8421,10 +8399,11 @@ fn instantiateGenericCall(
84218399
84228400 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
84238401
8424 if (sema.owner_func_index != .none and
8425 Type.fromInterned(func_ty_info.return_type).isError(zcu))
8426 {
8427 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
8402 switch (sema.owner.unwrap()) {
8403 .cau => {},
8404 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
8405 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
8406 },
84288407 }
84298408
84308409 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));
......@@ -9366,10 +9345,11 @@ fn zirFunc(
93669345 inferred_error_set: bool,
93679346) CompileError!Air.Inst.Ref {
93689347 const pt = sema.pt;
9369 const mod = pt.zcu;
9348 const zcu = pt.zcu;
9349 const ip = &zcu.intern_pool;
93709350 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
93719351 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9372 const target = mod.getTarget();
9352 const target = zcu.getTarget();
93739353 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
93749354
93759355 var extra_index = extra.end;
......@@ -9410,11 +9390,17 @@ fn zirFunc(
94109390 // the callconv based on whether it is exported. Otherwise, the callconv defaults
94119391 // to `.Unspecified`.
94129392 const cc: std.builtin.CallingConvention = if (has_body) cc: {
9413 const fn_is_exported = if (sema.generic_owner != .none) exported: {
9414 const generic_owner_fn = mod.funcInfo(sema.generic_owner);
9415 const generic_owner_decl = mod.declPtr(generic_owner_fn.owner_decl);
9416 break :exported generic_owner_decl.is_exported;
9417 } else sema.owner_decl.is_exported;
9393 const func_decl_cau = if (sema.generic_owner != .none) cau: {
9394 const generic_owner_fn = zcu.funcInfo(sema.generic_owner);
9395 // The generic owner definitely has a `Cau` for the corresponding function declaration.
9396 const generic_owner_nav = ip.getNav(generic_owner_fn.owner_nav);
9397 break :cau generic_owner_nav.analysis_owner.unwrap().?;
9398 } else sema.owner.unwrap().cau;
9399 const fn_is_exported = exported: {
9400 const decl_inst = ip.getCau(func_decl_cau).zir_index.resolve(ip);
9401 const zir_decl = sema.code.getDeclaration(decl_inst)[0];
9402 break :exported zir_decl.flags.is_export;
9403 };
94189404 break :cc if (fn_is_exported) .C else .Unspecified;
94199405 } else .Unspecified;
94209406
......@@ -9613,10 +9599,10 @@ fn funcCommon(
96139599 is_noinline: bool,
96149600) CompileError!Air.Inst.Ref {
96159601 const pt = sema.pt;
9616 const mod = pt.zcu;
9602 const zcu = pt.zcu;
96179603 const gpa = sema.gpa;
9618 const target = mod.getTarget();
9619 const ip = &mod.intern_pool;
9604 const target = zcu.getTarget();
9605 const ip = &zcu.intern_pool;
96209606 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
96219607 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
96229608 const func_src = block.nodeOffset(src_node_offset);
......@@ -9664,8 +9650,8 @@ fn funcCommon(
96649650 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) {
96659651 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});
96669652 }
9667 if (!param_ty.isValidParamType(mod)) {
9668 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
9653 if (!param_ty.isValidParamType(zcu)) {
9654 const opaque_str = if (param_ty.zigTypeTag(zcu) == .Opaque) "opaque " else "";
96699655 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
96709656 opaque_str, param_ty.fmt(pt),
96719657 });
......@@ -9699,7 +9685,7 @@ fn funcCommon(
96999685 return sema.failWithOwnedErrorMsg(block, msg);
97009686 }
97019687 if (is_source_decl and !this_generic and is_noalias and
9702 !(param_ty.zigTypeTag(mod) == .Pointer or param_ty.isPtrLikeOptional(mod)))
9688 !(param_ty.zigTypeTag(zcu) == .Pointer or param_ty.isPtrLikeOptional(zcu)))
97039689 {
97049690 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
97059691 }
......@@ -9707,7 +9693,7 @@ fn funcCommon(
97079693 .Interrupt => if (target.cpu.arch.isX86()) {
97089694 const err_code_size = target.ptrBitWidth();
97099695 switch (i) {
9710 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}),
9696 0 => if (param_ty.zigTypeTag(zcu) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}),
97119697 1 => if (param_ty.bitSize(pt) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}),
97129698 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),
97139699 }
......@@ -9769,14 +9755,11 @@ fn funcCommon(
97699755 );
97709756 }
97719757
9772 // extern_func and func_decl functions take ownership of `sema.owner_decl`.
9773 sema.owner_decl.@"linksection" = switch (section) {
9758 const section_name: InternPool.OptionalNullTerminatedString = switch (section) {
97749759 .generic => .none,
97759760 .default => .none,
9776 .explicit => |section_name| section_name.toOptional(),
9761 .explicit => |name| name.toOptional(),
97779762 };
9778 sema.owner_decl.alignment = alignment orelse .none;
9779 sema.owner_decl.@"addrspace" = address_space orelse .generic;
97809763
97819764 if (inferred_error_set) {
97829765 assert(!is_extern);
......@@ -9784,7 +9767,7 @@ fn funcCommon(
97849767 if (!ret_poison)
97859768 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
97869769 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9787 .owner_decl = sema.owner_decl_index,
9770 .owner_nav = sema.getOwnerCauNav(),
97889771
97899772 .param_types = param_types,
97909773 .noalias_bits = noalias_bits,
......@@ -9804,6 +9787,13 @@ fn funcCommon(
98049787 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
98059788 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
98069789 });
9790 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
9791 ip.resolveNavValue(sema.getOwnerCauNav(), .{
9792 .val = func_index,
9793 .alignment = alignment orelse .none,
9794 .@"linksection" = section_name,
9795 .@"addrspace" = address_space orelse .generic,
9796 });
98079797 return finishFunc(
98089798 sema,
98099799 block,
......@@ -9846,11 +9836,20 @@ fn funcCommon(
98469836 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
98479837 .node_offset_lib_name = src_node_offset,
98489838 }), lib_name);
9849 const func_index = try ip.getExternFunc(gpa, pt.tid, .{
9839 const func_index = try pt.getExtern(.{
9840 .name = sema.getOwnerCauNavName(),
98509841 .ty = func_ty,
9851 .decl = sema.owner_decl_index,
9852 .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
9842 .lib_name = try ip.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
9843 .is_const = true,
9844 .is_threadlocal = false,
9845 .is_weak_linkage = false,
9846 .alignment = alignment orelse .none,
9847 .@"addrspace" = address_space orelse .generic,
9848 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
9849 .owner_nav = undefined, // ignored by `getExtern`
98539850 });
9851 // Note that unlike function declaration, extern functions don't touch the
9852 // Sema's owner Cau's owner Nav. The alignment etc were passed above.
98549853 return finishFunc(
98559854 sema,
98569855 block,
......@@ -9872,7 +9871,7 @@ fn funcCommon(
98729871
98739872 if (has_body) {
98749873 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9875 .owner_decl = sema.owner_decl_index,
9874 .owner_nav = sema.getOwnerCauNav(),
98769875 .ty = func_ty,
98779876 .cc = cc,
98789877 .is_noinline = is_noinline,
......@@ -9882,6 +9881,13 @@ fn funcCommon(
98829881 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
98839882 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
98849883 });
9884 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
9885 ip.resolveNavValue(sema.getOwnerCauNav(), .{
9886 .val = func_index,
9887 .alignment = alignment orelse .none,
9888 .@"linksection" = section_name,
9889 .@"addrspace" = address_space orelse .generic,
9890 });
98859891 return finishFunc(
98869892 sema,
98879893 block,
......@@ -11179,7 +11185,7 @@ const SwitchProngAnalysis = struct {
1117911185 return block.addStructFieldVal(spa.operand, field_index, field_ty);
1118011186 }
1118111187 } else if (capture_byref) {
11182 return anonDeclRef(sema, item_val.toIntern());
11188 return sema.uavRef(item_val.toIntern());
1118311189 } else {
1118411190 return inline_case_capture;
1118511191 }
......@@ -13947,9 +13953,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1394713953 }
1394813954
1394913955 const namespace = container_type.getNamespaceIndex(mod);
13950 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl_index| {
13951 const decl = mod.declPtr(decl_index);
13952 if (decl.is_pub or decl.getFileScope(mod) == block.getFileScope(mod)) {
13956 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
13957 if (lookup.accessible) {
1395313958 return .bool_true;
1395413959 }
1395513960 }
......@@ -13981,9 +13986,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1398113986 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
1398213987 },
1398313988 };
13989 // TODO: register some kind of dependency on the file.
13990 // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to
13991 // trigger re-analysis later.
1398413992 try pt.ensureFileAnalyzed(result.file_index);
13985 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;
13986 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);
13993 return Air.internedToRef(zcu.fileRootType(result.file_index));
1398713994}
1398813995
1398913996fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -16970,7 +16977,7 @@ fn analyzeArithmetic(
1697016977 if (block.wantSafety() and want_safety and scalar_tag == .Int) {
1697116978 if (mod.backendSupportsFeature(.safety_checked_instructions)) {
1697216979 if (air_tag != air_tag_safe) {
16973 _ = try sema.preparePanicId(block, .integer_overflow);
16980 _ = try sema.preparePanicId(block, src, .integer_overflow);
1697416981 }
1697516982 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
1697616983 } else {
......@@ -17158,13 +17165,11 @@ fn zirAsm(
1715817165 if (is_volatile) {
1715917166 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});
1716017167 }
17161 try mod.addGlobalAssembly(sema.owner_decl_index, asm_source);
17168 try mod.addGlobalAssembly(sema.owner.unwrap().cau, asm_source);
1716217169 return .void_value;
1716317170 }
1716417171
17165 if (block.is_comptime) {
17166 try sema.requireRuntimeBlock(block, src, null);
17167 }
17172 try sema.requireRuntimeBlock(block, src, null);
1716817173
1716917174 var extra_i = extra.end;
1717017175 var output_type_bits = extra.data.output_type_bits;
......@@ -17646,18 +17651,17 @@ fn zirThis(
1764617651 block: *Block,
1764717652 extended: Zir.Inst.Extended.InstData,
1764817653) CompileError!Air.Inst.Ref {
17654 _ = extended;
1764917655 const pt = sema.pt;
17650 const mod = pt.zcu;
17651 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;
17652 const src = block.nodeOffset(@bitCast(extended.operand));
17653 return sema.analyzeDeclVal(block, src, this_decl_index);
17656 const namespace = pt.zcu.namespacePtr(block.namespace);
17657 return Air.internedToRef(namespace.owner_type);
1765417658}
1765517659
1765617660fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
1765717661 const pt = sema.pt;
1765817662 const mod = pt.zcu;
1765917663 const ip = &mod.intern_pool;
17660 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);
17664 const captures = Type.fromInterned(mod.namespacePtr(block.namespace).owner_type).getCaptures(mod);
1766117665
1766217666 const src_node: i32 = @bitCast(extended.operand);
1766317667 const src = block.nodeOffset(src_node);
......@@ -17665,8 +17669,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
1766517669 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {
1766617670 .@"comptime" => |index| return Air.internedToRef(index),
1766717671 .runtime => |index| index,
17668 .decl_val => |decl_index| return sema.analyzeDeclVal(block, src, decl_index),
17669 .decl_ref => |decl_index| return sema.analyzeDeclRef(src, decl_index),
17672 .nav_val => |nav| return sema.analyzeNavVal(block, src, nav),
17673 .nav_ref => |nav| return sema.analyzeNavRef(src, nav),
1767017674 };
1767117675
1767217676 // The comptime case is handled already above. Runtime case below.
......@@ -17764,20 +17768,19 @@ fn zirBuiltinSrc(
1776417768 block: *Block,
1776517769 extended: Zir.Inst.Extended.InstData,
1776617770) CompileError!Air.Inst.Ref {
17767 _ = block;
1776817771 const tracy = trace(@src());
1776917772 defer tracy.end();
1777017773
1777117774 const pt = sema.pt;
1777217775 const zcu = pt.zcu;
17773 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
17774 const fn_owner_decl = zcu.funcOwnerDeclPtr(sema.func_index);
1777517776 const ip = &zcu.intern_pool;
17777 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
17778 const fn_name = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).name;
1777617779 const gpa = sema.gpa;
17777 const file_scope = fn_owner_decl.getFileScope(zcu);
17780 const file_scope = block.getFileScope(zcu);
1777817781
1777917782 const func_name_val = v: {
17780 const func_name_len = fn_owner_decl.name.length(ip);
17783 const func_name_len = fn_name.length(ip);
1778117784 const array_ty = try pt.intern(.{ .array_type = .{
1778217785 .len = func_name_len,
1778317786 .sentinel = .zero_u8,
......@@ -17787,11 +17790,11 @@ fn zirBuiltinSrc(
1778717790 .ty = .slice_const_u8_sentinel_0_type,
1778817791 .ptr = try pt.intern(.{ .ptr = .{
1778917792 .ty = .manyptr_const_u8_sentinel_0_type,
17790 .base_addr = .{ .anon_decl = .{
17793 .base_addr = .{ .uav = .{
1779117794 .orig_ty = .slice_const_u8_sentinel_0_type,
1779217795 .val = try pt.intern(.{ .aggregate = .{
1779317796 .ty = array_ty,
17794 .storage = .{ .bytes = fn_owner_decl.name.toString() },
17797 .storage = .{ .bytes = fn_name.toString() },
1779517798 } }),
1779617799 } },
1779717800 .byte_offset = 0,
......@@ -17811,7 +17814,7 @@ fn zirBuiltinSrc(
1781117814 .ty = .slice_const_u8_sentinel_0_type,
1781217815 .ptr = try pt.intern(.{ .ptr = .{
1781317816 .ty = .manyptr_const_u8_sentinel_0_type,
17814 .base_addr = .{ .anon_decl = .{
17817 .base_addr = .{ .uav = .{
1781517818 .orig_ty = .slice_const_u8_sentinel_0_type,
1781617819 .val = try pt.intern(.{ .aggregate = .{
1781717820 .ty = array_ty,
......@@ -17837,7 +17840,7 @@ fn zirBuiltinSrc(
1783717840 .ty = .slice_const_u8_sentinel_0_type,
1783817841 .ptr = try pt.intern(.{ .ptr = .{
1783917842 .ty = .manyptr_const_u8_sentinel_0_type,
17840 .base_addr = .{ .anon_decl = .{
17843 .base_addr = .{ .uav = .{
1784117844 .orig_ty = .slice_const_u8_sentinel_0_type,
1784217845 .val = try pt.intern(.{ .aggregate = .{
1784317846 .ty = array_ty,
......@@ -17902,25 +17905,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1790217905 .val = .void_value,
1790317906 } }))),
1790417907 .Fn => {
17905 const fn_info_decl_index = (try sema.namespaceLookup(
17908 const fn_info_nav = try sema.namespaceLookup(
1790617909 block,
1790717910 src,
1790817911 type_info_ty.getNamespaceIndex(mod),
1790917912 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),
17910 )).?;
17911 try sema.ensureDeclAnalyzed(fn_info_decl_index);
17912 const fn_info_decl = mod.declPtr(fn_info_decl_index);
17913 const fn_info_ty = fn_info_decl.val.toType();
17913 ) orelse @panic("std.builtin.Type is corrupt");
17914 try sema.ensureNavResolved(src, fn_info_nav);
17915 const fn_info_ty = Type.fromInterned(ip.getNav(fn_info_nav).status.resolved.val);
1791417916
17915 const param_info_decl_index = (try sema.namespaceLookup(
17917 const param_info_nav = try sema.namespaceLookup(
1791617918 block,
1791717919 src,
1791817920 fn_info_ty.getNamespaceIndex(mod),
1791917921 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),
17920 )).?;
17921 try sema.ensureDeclAnalyzed(param_info_decl_index);
17922 const param_info_decl = mod.declPtr(param_info_decl_index);
17923 const param_info_ty = param_info_decl.val.toType();
17922 ) orelse @panic("std.builtin.Type is corrupt");
17923 try sema.ensureNavResolved(src, param_info_nav);
17924 const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val);
1792417925
1792517926 const func_ty_info = mod.typeToFunc(ty).?;
1792617927 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
......@@ -17972,7 +17973,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1797217973 .ty = slice_ty,
1797317974 .ptr = try pt.intern(.{ .ptr = .{
1797417975 .ty = manyptr_ty,
17975 .base_addr = .{ .anon_decl = .{
17976 .base_addr = .{ .uav = .{
1797617977 .orig_ty = manyptr_ty,
1797717978 .val = new_decl_val,
1797817979 } },
......@@ -18014,15 +18015,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1801418015 } })));
1801518016 },
1801618017 .Int => {
18017 const int_info_decl_index = (try sema.namespaceLookup(
18018 const int_info_nav = try sema.namespaceLookup(
1801818019 block,
1801918020 src,
1802018021 type_info_ty.getNamespaceIndex(mod),
1802118022 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),
18022 )).?;
18023 try sema.ensureDeclAnalyzed(int_info_decl_index);
18024 const int_info_decl = mod.declPtr(int_info_decl_index);
18025 const int_info_ty = int_info_decl.val.toType();
18023 ) orelse @panic("std.builtin.Type is corrupt");
18024 try sema.ensureNavResolved(src, int_info_nav);
18025 const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val);
1802618026
1802718027 const signedness_ty = try pt.getBuiltinType("Signedness");
1802818028 const info = ty.intInfo(mod);
......@@ -18042,15 +18042,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1804218042 } })));
1804318043 },
1804418044 .Float => {
18045 const float_info_decl_index = (try sema.namespaceLookup(
18045 const float_info_nav = try sema.namespaceLookup(
1804618046 block,
1804718047 src,
1804818048 type_info_ty.getNamespaceIndex(mod),
1804918049 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),
18050 )).?;
18051 try sema.ensureDeclAnalyzed(float_info_decl_index);
18052 const float_info_decl = mod.declPtr(float_info_decl_index);
18053 const float_info_ty = float_info_decl.val.toType();
18050 ) orelse @panic("std.builtin.Type is corrupt");
18051 try sema.ensureNavResolved(src, float_info_nav);
18052 const float_info_ty = Type.fromInterned(ip.getNav(float_info_nav).status.resolved.val);
1805418053
1805518054 const field_vals = .{
1805618055 // bits: u16,
......@@ -18074,26 +18073,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1807418073
1807518074 const addrspace_ty = try pt.getBuiltinType("AddressSpace");
1807618075 const pointer_ty = t: {
18077 const decl_index = (try sema.namespaceLookup(
18076 const nav = try sema.namespaceLookup(
1807818077 block,
1807918078 src,
1808018079 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
1808118080 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),
18082 )).?;
18083 try sema.ensureDeclAnalyzed(decl_index);
18084 const decl = mod.declPtr(decl_index);
18085 break :t decl.val.toType();
18081 ) orelse @panic("std.builtin.Type is corrupt");
18082 try sema.ensureNavResolved(src, nav);
18083 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1808618084 };
1808718085 const ptr_size_ty = t: {
18088 const decl_index = (try sema.namespaceLookup(
18086 const nav = try sema.namespaceLookup(
1808918087 block,
1809018088 src,
1809118089 pointer_ty.getNamespaceIndex(mod),
1809218090 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),
18093 )).?;
18094 try sema.ensureDeclAnalyzed(decl_index);
18095 const decl = mod.declPtr(decl_index);
18096 break :t decl.val.toType();
18091 ) orelse @panic("std.builtin.Type is corrupt");
18092 try sema.ensureNavResolved(src, nav);
18093 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1809718094 };
1809818095
1809918096 const field_values = .{
......@@ -18128,15 +18125,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1812818125 },
1812918126 .Array => {
1813018127 const array_field_ty = t: {
18131 const array_field_ty_decl_index = (try sema.namespaceLookup(
18128 const nav = try sema.namespaceLookup(
1813218129 block,
1813318130 src,
1813418131 type_info_ty.getNamespaceIndex(mod),
1813518132 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),
18136 )).?;
18137 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);
18138 const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index);
18139 break :t array_field_ty_decl.val.toType();
18133 ) orelse @panic("std.builtin.Type is corrupt");
18134 try sema.ensureNavResolved(src, nav);
18135 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1814018136 };
1814118137
1814218138 const info = ty.arrayInfo(mod);
......@@ -18159,15 +18155,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1815918155 },
1816018156 .Vector => {
1816118157 const vector_field_ty = t: {
18162 const vector_field_ty_decl_index = (try sema.namespaceLookup(
18158 const nav = try sema.namespaceLookup(
1816318159 block,
1816418160 src,
1816518161 type_info_ty.getNamespaceIndex(mod),
1816618162 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),
18167 )).?;
18168 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);
18169 const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index);
18170 break :t vector_field_ty_decl.val.toType();
18163 ) orelse @panic("std.builtin.Type is corrupt");
18164 try sema.ensureNavResolved(src, nav);
18165 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1817118166 };
1817218167
1817318168 const info = ty.arrayInfo(mod);
......@@ -18188,15 +18183,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1818818183 },
1818918184 .Optional => {
1819018185 const optional_field_ty = t: {
18191 const optional_field_ty_decl_index = (try sema.namespaceLookup(
18186 const nav = try sema.namespaceLookup(
1819218187 block,
1819318188 src,
1819418189 type_info_ty.getNamespaceIndex(mod),
1819518190 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),
18196 )).?;
18197 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);
18198 const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index);
18199 break :t optional_field_ty_decl.val.toType();
18191 ) orelse @panic("std.builtin.Type is corrupt");
18192 try sema.ensureNavResolved(src, nav);
18193 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1820018194 };
1820118195
1820218196 const field_values = .{
......@@ -18215,15 +18209,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1821518209 .ErrorSet => {
1821618210 // Get the Error type
1821718211 const error_field_ty = t: {
18218 const set_field_ty_decl_index = (try sema.namespaceLookup(
18212 const nav = try sema.namespaceLookup(
1821918213 block,
1822018214 src,
1822118215 type_info_ty.getNamespaceIndex(mod),
1822218216 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),
18223 )).?;
18224 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
18225 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);
18226 break :t set_field_ty_decl.val.toType();
18217 ) orelse @panic("std.builtin.Type is corrupt");
18218 try sema.ensureNavResolved(src, nav);
18219 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1822718220 };
1822818221
1822918222 // Build our list of Error values
......@@ -18251,7 +18244,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1825118244 .ty = .slice_const_u8_sentinel_0_type,
1825218245 .ptr = try pt.intern(.{ .ptr = .{
1825318246 .ty = .manyptr_const_u8_sentinel_0_type,
18254 .base_addr = .{ .anon_decl = .{
18247 .base_addr = .{ .uav = .{
1825518248 .val = new_decl_val,
1825618249 .orig_ty = .slice_const_u8_sentinel_0_type,
1825718250 } },
......@@ -18298,7 +18291,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1829818291 .ty = slice_errors_ty.toIntern(),
1829918292 .ptr = try pt.intern(.{ .ptr = .{
1830018293 .ty = manyptr_errors_ty,
18301 .base_addr = .{ .anon_decl = .{
18294 .base_addr = .{ .uav = .{
1830218295 .orig_ty = manyptr_errors_ty,
1830318296 .val = new_decl_val,
1830418297 } },
......@@ -18321,15 +18314,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1832118314 },
1832218315 .ErrorUnion => {
1832318316 const error_union_field_ty = t: {
18324 const error_union_field_ty_decl_index = (try sema.namespaceLookup(
18317 const nav = try sema.namespaceLookup(
1832518318 block,
1832618319 src,
1832718320 type_info_ty.getNamespaceIndex(mod),
1832818321 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),
18329 )).?;
18330 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);
18331 const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index);
18332 break :t error_union_field_ty_decl.val.toType();
18322 ) orelse @panic("std.builtin.Type is corrupt");
18323 try sema.ensureNavResolved(src, nav);
18324 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1833318325 };
1833418326
1833518327 const field_values = .{
......@@ -18351,15 +18343,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1835118343 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1835218344
1835318345 const enum_field_ty = t: {
18354 const enum_field_ty_decl_index = (try sema.namespaceLookup(
18346 const nav = try sema.namespaceLookup(
1835518347 block,
1835618348 src,
1835718349 type_info_ty.getNamespaceIndex(mod),
1835818350 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),
18359 )).?;
18360 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
18361 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);
18362 break :t enum_field_ty_decl.val.toType();
18351 ) orelse @panic("std.builtin.Type is corrupt");
18352 try sema.ensureNavResolved(src, nav);
18353 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1836318354 };
1836418355
1836518356 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
......@@ -18392,7 +18383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1839218383 .ty = .slice_const_u8_sentinel_0_type,
1839318384 .ptr = try pt.intern(.{ .ptr = .{
1839418385 .ty = .manyptr_const_u8_sentinel_0_type,
18395 .base_addr = .{ .anon_decl = .{
18386 .base_addr = .{ .uav = .{
1839618387 .val = new_decl_val,
1839718388 .orig_ty = .slice_const_u8_sentinel_0_type,
1839818389 } },
......@@ -18435,7 +18426,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1843518426 .ty = slice_ty,
1843618427 .ptr = try pt.intern(.{ .ptr = .{
1843718428 .ty = manyptr_ty,
18438 .base_addr = .{ .anon_decl = .{
18429 .base_addr = .{ .uav = .{
1843918430 .val = new_decl_val,
1844018431 .orig_ty = manyptr_ty,
1844118432 } },
......@@ -18448,15 +18439,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1844818439 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace);
1844918440
1845018441 const type_enum_ty = t: {
18451 const type_enum_ty_decl_index = (try sema.namespaceLookup(
18442 const nav = try sema.namespaceLookup(
1845218443 block,
1845318444 src,
1845418445 type_info_ty.getNamespaceIndex(mod),
1845518446 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),
18456 )).?;
18457 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);
18458 const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index);
18459 break :t type_enum_ty_decl.val.toType();
18447 ) orelse @panic("std.builtin.Type is corrupt");
18448 try sema.ensureNavResolved(src, nav);
18449 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1846018450 };
1846118451
1846218452 const field_values = .{
......@@ -18480,27 +18470,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1848018470 },
1848118471 .Union => {
1848218472 const type_union_ty = t: {
18483 const type_union_ty_decl_index = (try sema.namespaceLookup(
18473 const nav = try sema.namespaceLookup(
1848418474 block,
1848518475 src,
1848618476 type_info_ty.getNamespaceIndex(mod),
1848718477 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),
18488 )).?;
18489 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);
18490 const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index);
18491 break :t type_union_ty_decl.val.toType();
18478 ) orelse @panic("std.builtin.Type is corrupt");
18479 try sema.ensureNavResolved(src, nav);
18480 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1849218481 };
1849318482
1849418483 const union_field_ty = t: {
18495 const union_field_ty_decl_index = (try sema.namespaceLookup(
18484 const nav = try sema.namespaceLookup(
1849618485 block,
1849718486 src,
1849818487 type_info_ty.getNamespaceIndex(mod),
1849918488 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),
18500 )).?;
18501 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
18502 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);
18503 break :t union_field_ty_decl.val.toType();
18489 ) orelse @panic("std.builtin.Type is corrupt");
18490 try sema.ensureNavResolved(src, nav);
18491 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1850418492 };
1850518493
1850618494 try ty.resolveLayout(pt); // Getting alignment requires type layout
......@@ -18528,7 +18516,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1852818516 .ty = .slice_const_u8_sentinel_0_type,
1852918517 .ptr = try pt.intern(.{ .ptr = .{
1853018518 .ty = .manyptr_const_u8_sentinel_0_type,
18531 .base_addr = .{ .anon_decl = .{
18519 .base_addr = .{ .uav = .{
1853218520 .val = new_decl_val,
1853318521 .orig_ty = .slice_const_u8_sentinel_0_type,
1853418522 } },
......@@ -18579,7 +18567,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1857918567 .ty = slice_ty,
1858018568 .ptr = try pt.intern(.{ .ptr = .{
1858118569 .ty = manyptr_ty,
18582 .base_addr = .{ .anon_decl = .{
18570 .base_addr = .{ .uav = .{
1858318571 .orig_ty = manyptr_ty,
1858418572 .val = new_decl_val,
1858518573 } },
......@@ -18597,15 +18585,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1859718585 } });
1859818586
1859918587 const container_layout_ty = t: {
18600 const decl_index = (try sema.namespaceLookup(
18588 const nav = try sema.namespaceLookup(
1860118589 block,
1860218590 src,
1860318591 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
1860418592 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18605 )).?;
18606 try sema.ensureDeclAnalyzed(decl_index);
18607 const decl = mod.declPtr(decl_index);
18608 break :t decl.val.toType();
18593 ) orelse @panic("std.builtin.Type is corrupt");
18594 try sema.ensureNavResolved(src, nav);
18595 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1860918596 };
1861018597
1861118598 const field_values = .{
......@@ -18630,27 +18617,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1863018617 },
1863118618 .Struct => {
1863218619 const type_struct_ty = t: {
18633 const type_struct_ty_decl_index = (try sema.namespaceLookup(
18620 const nav = try sema.namespaceLookup(
1863418621 block,
1863518622 src,
1863618623 type_info_ty.getNamespaceIndex(mod),
1863718624 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),
18638 )).?;
18639 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);
18640 const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index);
18641 break :t type_struct_ty_decl.val.toType();
18625 ) orelse @panic("std.builtin.Type is corrupt");
18626 try sema.ensureNavResolved(src, nav);
18627 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1864218628 };
1864318629
1864418630 const struct_field_ty = t: {
18645 const struct_field_ty_decl_index = (try sema.namespaceLookup(
18631 const nav = try sema.namespaceLookup(
1864618632 block,
1864718633 src,
1864818634 type_info_ty.getNamespaceIndex(mod),
1864918635 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),
18650 )).?;
18651 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
18652 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);
18653 break :t struct_field_ty_decl.val.toType();
18636 ) orelse @panic("std.builtin.Type is corrupt");
18637 try sema.ensureNavResolved(src, nav);
18638 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1865418639 };
1865518640
1865618641 try ty.resolveLayout(pt); // Getting alignment requires type layout
......@@ -18683,7 +18668,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1868318668 .ty = .slice_const_u8_sentinel_0_type,
1868418669 .ptr = try pt.intern(.{ .ptr = .{
1868518670 .ty = .manyptr_const_u8_sentinel_0_type,
18686 .base_addr = .{ .anon_decl = .{
18671 .base_addr = .{ .uav = .{
1868718672 .val = new_decl_val,
1868818673 .orig_ty = .slice_const_u8_sentinel_0_type,
1868918674 } },
......@@ -18747,7 +18732,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1874718732 .ty = .slice_const_u8_sentinel_0_type,
1874818733 .ptr = try pt.intern(.{ .ptr = .{
1874918734 .ty = .manyptr_const_u8_sentinel_0_type,
18750 .base_addr = .{ .anon_decl = .{
18735 .base_addr = .{ .uav = .{
1875118736 .val = new_decl_val,
1875218737 .orig_ty = .slice_const_u8_sentinel_0_type,
1875318738 } },
......@@ -18809,7 +18794,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1880918794 .ty = slice_ty,
1881018795 .ptr = try pt.intern(.{ .ptr = .{
1881118796 .ty = manyptr_ty,
18812 .base_addr = .{ .anon_decl = .{
18797 .base_addr = .{ .uav = .{
1881318798 .orig_ty = manyptr_ty,
1881418799 .val = new_decl_val,
1881518800 } },
......@@ -18830,15 +18815,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1883018815 } });
1883118816
1883218817 const container_layout_ty = t: {
18833 const decl_index = (try sema.namespaceLookup(
18818 const nav = try sema.namespaceLookup(
1883418819 block,
1883518820 src,
1883618821 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
1883718822 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18838 )).?;
18839 try sema.ensureDeclAnalyzed(decl_index);
18840 const decl = mod.declPtr(decl_index);
18841 break :t decl.val.toType();
18823 ) orelse @panic("std.builtin.Type is corrupt");
18824 try sema.ensureNavResolved(src, nav);
18825 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1884218826 };
1884318827
1884418828 const layout = ty.containerLayout(mod);
......@@ -18866,15 +18850,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1886618850 },
1886718851 .Opaque => {
1886818852 const type_opaque_ty = t: {
18869 const type_opaque_ty_decl_index = (try sema.namespaceLookup(
18853 const nav = try sema.namespaceLookup(
1887018854 block,
1887118855 src,
1887218856 type_info_ty.getNamespaceIndex(mod),
1887318857 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),
18874 )).?;
18875 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);
18876 const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index);
18877 break :t type_opaque_ty_decl.val.toType();
18858 ) orelse @panic("std.builtin.Type is corrupt");
18859 try sema.ensureNavResolved(src, nav);
18860 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1887818861 };
1887918862
1888018863 try ty.resolveFields(pt);
......@@ -18906,19 +18889,19 @@ fn typeInfoDecls(
1890618889 opt_namespace: InternPool.OptionalNamespaceIndex,
1890718890) CompileError!InternPool.Index {
1890818891 const pt = sema.pt;
18909 const mod = pt.zcu;
18892 const zcu = pt.zcu;
18893 const ip = &zcu.intern_pool;
1891018894 const gpa = sema.gpa;
1891118895
1891218896 const declaration_ty = t: {
18913 const declaration_ty_decl_index = (try sema.namespaceLookup(
18897 const nav = try sema.namespaceLookup(
1891418898 block,
1891518899 src,
18916 type_info_ty.getNamespaceIndex(mod),
18917 try mod.intern_pool.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
18918 )).?;
18919 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
18920 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
18921 break :t declaration_ty_decl.val.toType();
18900 type_info_ty.getNamespaceIndex(zcu),
18901 try ip.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
18902 ) orelse @panic("std.builtin.Type is corrupt");
18903 try sema.ensureNavResolved(src, nav);
18904 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1892218905 };
1892318906
1892418907 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
......@@ -18927,7 +18910,7 @@ fn typeInfoDecls(
1892718910 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
1892818911 defer seen_namespaces.deinit();
1892918912
18930 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
18913 try sema.typeInfoNamespaceDecls(block, src, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
1893118914
1893218915 const array_decl_ty = try pt.arrayType(.{
1893318916 .len = decl_vals.items.len,
......@@ -18944,12 +18927,12 @@ fn typeInfoDecls(
1894418927 .is_const = true,
1894518928 },
1894618929 })).toIntern();
18947 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18930 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern();
1894818931 return try pt.intern(.{ .slice = .{
1894918932 .ty = slice_ty,
1895018933 .ptr = try pt.intern(.{ .ptr = .{
1895118934 .ty = manyptr_ty,
18952 .base_addr = .{ .anon_decl = .{
18935 .base_addr = .{ .uav = .{
1895318936 .orig_ty = manyptr_ty,
1895418937 .val = new_decl_val,
1895518938 } },
......@@ -18962,59 +18945,54 @@ fn typeInfoDecls(
1896218945fn typeInfoNamespaceDecls(
1896318946 sema: *Sema,
1896418947 block: *Block,
18948 src: LazySrcLoc,
1896518949 opt_namespace_index: InternPool.OptionalNamespaceIndex,
1896618950 declaration_ty: Type,
1896718951 decl_vals: *std.ArrayList(InternPool.Index),
1896818952 seen_namespaces: *std.AutoHashMap(*Namespace, void),
1896918953) !void {
1897018954 const pt = sema.pt;
18971 const mod = pt.zcu;
18972 const ip = &mod.intern_pool;
18955 const zcu = pt.zcu;
18956 const ip = &zcu.intern_pool;
1897318957
1897418958 const namespace_index = opt_namespace_index.unwrap() orelse return;
18975 const namespace = mod.namespacePtr(namespace_index);
18959 const namespace = zcu.namespacePtr(namespace_index);
1897618960
1897718961 const gop = try seen_namespaces.getOrPut(namespace);
1897818962 if (gop.found_existing) return;
1897918963
18980 const decls = namespace.decls.keys();
18981 for (decls) |decl_index| {
18982 const decl = mod.declPtr(decl_index);
18983 if (!decl.is_pub) continue;
18984 if (decl.kind == .@"usingnamespace") {
18985 if (decl.analysis == .in_progress) continue;
18986 try sema.ensureDeclAnalyzed(decl_index);
18987 try sema.typeInfoNamespaceDecls(block, decl.val.toType().getNamespaceIndex(mod), declaration_ty, decl_vals, seen_namespaces);
18988 continue;
18989 }
18990 if (decl.kind != .named) continue;
18991 const name_val = v: {
18992 const decl_name_len = decl.name.length(ip);
18993 const new_decl_ty = try pt.arrayType(.{
18994 .len = decl_name_len,
18964 for (namespace.pub_decls.keys()) |nav| {
18965 const name = ip.getNav(nav).name;
18966 const name_val = name_val: {
18967 const name_len = name.length(ip);
18968 const array_ty = try pt.arrayType(.{
18969 .len = name_len,
1899518970 .sentinel = .zero_u8,
1899618971 .child = .u8_type,
1899718972 });
18998 const new_decl_val = try pt.intern(.{ .aggregate = .{
18999 .ty = new_decl_ty.toIntern(),
19000 .storage = .{ .bytes = decl.name.toString() },
19001 } });
19002 break :v try pt.intern(.{ .slice = .{
19003 .ty = .slice_const_u8_sentinel_0_type,
19004 .ptr = try pt.intern(.{ .ptr = .{
19005 .ty = .manyptr_const_u8_sentinel_0_type,
19006 .base_addr = .{ .anon_decl = .{
19007 .orig_ty = .slice_const_u8_sentinel_0_type,
19008 .val = new_decl_val,
19009 } },
19010 .byte_offset = 0,
19011 } }),
19012 .len = (try pt.intValue(Type.usize, decl_name_len)).toIntern(),
18973 const array_val = try pt.intern(.{ .aggregate = .{
18974 .ty = array_ty.toIntern(),
18975 .storage = .{ .bytes = name.toString() },
1901318976 } });
18977 break :name_val try pt.intern(.{
18978 .slice = .{
18979 .ty = .slice_const_u8_sentinel_0_type, // [:0]const u8
18980 .ptr = try pt.intern(.{
18981 .ptr = .{
18982 .ty = .manyptr_const_u8_sentinel_0_type, // [*:0]const u8
18983 .base_addr = .{ .uav = .{
18984 .orig_ty = .slice_const_u8_sentinel_0_type,
18985 .val = array_val,
18986 } },
18987 .byte_offset = 0,
18988 },
18989 }),
18990 .len = (try pt.intValue(Type.usize, name_len)).toIntern(),
18991 },
18992 });
1901418993 };
19015
19016 const fields = .{
19017 //name: [:0]const u8,
18994 const fields = [_]InternPool.Index{
18995 // name: [:0]const u8,
1901818996 name_val,
1901918997 };
1902018998 try decl_vals.append(try pt.intern(.{ .aggregate = .{
......@@ -19022,6 +19000,17 @@ fn typeInfoNamespaceDecls(
1902219000 .storage = .{ .elems = &fields },
1902319001 } }));
1902419002 }
19003
19004 for (namespace.pub_usingnamespace.items) |nav| {
19005 if (ip.getNav(nav).analysis_owner.unwrap()) |cau| {
19006 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .cau = cau }))) {
19007 continue;
19008 }
19009 }
19010 try sema.ensureNavResolved(src, nav);
19011 const namespace_ty = Type.fromInterned(ip.getNav(nav).status.resolved.val);
19012 try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu), declaration_ty, decl_vals, seen_namespaces);
19013 }
1902519014}
1902619015
1902719016fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -19906,7 +19895,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
1990619895 return;
1990719896 }
1990819897
19909 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
19898 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return;
1991019899 if (!start_block.ownerModule().error_tracing) return;
1991119900
1991219901 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
......@@ -19928,7 +19917,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
1992819917 },
1992919918 else => if (ip.isInferredErrorSetType(err_set_ty)) {
1993019919 const ies = sema.fn_ret_ty_ies.?;
19931 assert(ies.func == sema.func_index);
19920 assert(ies.func == sema.owner.unwrap().func);
1993219921 try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand));
1993319922 },
1993419923 }
......@@ -20232,7 +20221,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
2023220221
2023320222 if (is_byref) {
2023420223 const init_val = (try sema.resolveValue(init_ref)).?;
20235 return anonDeclRef(sema, init_val.toIntern());
20224 return sema.uavRef(init_val.toIntern());
2023620225 } else {
2023720226 return init_ref;
2023820227 }
......@@ -21056,7 +21045,7 @@ fn arrayInitAnon(
2105621045}
2105721046
2105821047fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
21059 return if (is_ref) anonDeclRef(sema, val) else Air.internedToRef(val);
21048 return if (is_ref) sema.uavRef(val) else Air.internedToRef(val);
2106021049}
2106121050
2106221051fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -21163,16 +21152,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2116321152 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2116421153 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2116521154
21166 if (sema.owner_func_index != .none and
21167 ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and
21168 block.ownerModule().error_tracing)
21169 {
21170 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21155 switch (sema.owner.unwrap()) {
21156 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
21157 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21158 },
21159 .cau => {},
2117121160 }
21172 return Air.internedToRef((try pt.intern(.{ .opt = .{
21161 return Air.internedToRef(try pt.intern(.{ .opt = .{
2117321162 .ty = opt_ptr_stack_trace_ty.toIntern(),
2117421163 .val = .none,
21175 } })));
21164 } }));
2117621165}
2117721166
2117821167fn zirFrame(
......@@ -21369,24 +21358,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2136921358 const operand = try sema.resolveInst(inst_data.operand);
2137021359 const operand_ty = sema.typeOf(operand);
2137121360 const pt = sema.pt;
21372 const mod = pt.zcu;
21373 const ip = &mod.intern_pool;
21361 const zcu = pt.zcu;
21362 const ip = &zcu.intern_pool;
2137421363
2137521364 try operand_ty.resolveLayout(pt);
21376 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
21365 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
2137721366 .EnumLiteral => {
2137821367 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
2137921368 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
2138021369 return sema.addNullTerminatedStrLit(tag_name);
2138121370 },
2138221371 .Enum => operand_ty,
21383 .Union => operand_ty.unionTagType(mod) orelse
21372 .Union => operand_ty.unionTagType(zcu) orelse
2138421373 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),
2138521374 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
2138621375 operand_ty.fmt(pt),
2138721376 }),
2138821377 };
21389 if (enum_ty.enumFieldCount(mod) == 0) {
21378 if (enum_ty.enumFieldCount(zcu) == 0) {
2139021379 // TODO I don't think this is the correct way to handle this but
2139121380 // it prevents a crash.
2139221381 // https://github.com/ziglang/zig/issues/15909
......@@ -21394,26 +21383,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2139421383 enum_ty.fmt(pt),
2139521384 });
2139621385 }
21397 const enum_decl_index = enum_ty.getOwnerDecl(mod);
2139821386 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
2139921387 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
21400 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
21388 const field_index = enum_ty.enumTagFieldIndex(val, zcu) orelse {
2140121389 const msg = msg: {
2140221390 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{
21403 val.fmtValueSema(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip),
21391 val.fmtValueSema(pt, sema), enum_ty.fmt(pt),
2140421392 });
2140521393 errdefer msg.destroy(sema.gpa);
21406 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});
21394 try sema.errNote(enum_ty.srcLoc(zcu), msg, "declared here", .{});
2140721395 break :msg msg;
2140821396 };
2140921397 return sema.failWithOwnedErrorMsg(block, msg);
2141021398 };
2141121399 // TODO: write something like getCoercedInts to avoid needing to dupe
21412 const field_name = enum_ty.enumFieldName(field_index, mod);
21400 const field_name = enum_ty.enumFieldName(field_index, zcu);
2141321401 return sema.addNullTerminatedStrLit(field_name);
2141421402 }
2141521403 try sema.requireRuntimeBlock(block, src, operand_src);
21416 if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) {
21404 if (block.wantSafety() and zcu.backendSupportsFeature(.is_named_enum_value)) {
2141721405 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
2141821406 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
2141921407 }
......@@ -21820,19 +21808,15 @@ fn zirReify(
2182021808 };
2182121809 errdefer wip_ty.cancel(ip, pt.tid);
2182221810
21823 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21811 wip_ty.setName(ip, try sema.createTypeName(
2182421812 block,
21825 Value.fromInterned(wip_ty.index),
2182621813 name_strategy,
2182721814 "opaque",
2182821815 inst,
21829 );
21830 mod.declPtr(new_decl_index).owns_tv = true;
21831 errdefer pt.abortAnonDecl(new_decl_index);
21832
21833 try pt.finalizeAnonDecl(new_decl_index);
21816 wip_ty.index,
21817 ));
2183421818
21835 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
21819 return Air.internedToRef(wip_ty.finish(ip, .none, .none));
2183621820 },
2183721821 .Union => {
2183821822 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
......@@ -22001,13 +21985,15 @@ fn reifyEnum(
2200121985 });
2200221986 }
2200321987
21988 const tracked_inst = try block.trackZir(inst);
21989
2200421990 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
2200521991 .has_namespace = false,
2200621992 .has_values = true,
2200721993 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
2200821994 .fields_len = fields_len,
2200921995 .key = .{ .reified = .{
22010 .zir_index = try block.trackZir(inst),
21996 .zir_index = tracked_inst,
2201121997 .type_hash = hasher.final(),
2201221998 } },
2201321999 })) {
......@@ -22020,17 +22006,17 @@ fn reifyEnum(
2202022006 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
2202122007 }
2202222008
22023 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22009 wip_ty.setName(ip, try sema.createTypeName(
2202422010 block,
22025 Value.fromInterned(wip_ty.index),
2202622011 name_strategy,
2202722012 "enum",
2202822013 inst,
22029 );
22030 mod.declPtr(new_decl_index).owns_tv = true;
22031 errdefer pt.abortAnonDecl(new_decl_index);
22014 wip_ty.index,
22015 ));
22016
22017 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, block.namespace, wip_ty.index);
2203222018
22033 wip_ty.prepare(ip, new_decl_index, .none);
22019 wip_ty.prepare(ip, new_cau_index, .none);
2203422020 wip_ty.setTagTy(ip, tag_ty.toIntern());
2203522021
2203622022 for (0..fields_len) |field_idx| {
......@@ -22076,7 +22062,6 @@ fn reifyEnum(
2207622062 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
2207722063 }
2207822064
22079 try pt.finalizeAnonDecl(new_decl_index);
2208022065 return Air.internedToRef(wip_ty.index);
2208122066}
2208222067
......@@ -22134,6 +22119,8 @@ fn reifyUnion(
2213422119 }
2213522120 }
2213622121
22122 const tracked_inst = try block.trackZir(inst);
22123
2213722124 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
2213822125 .flags = .{
2213922126 .layout = layout,
......@@ -22158,7 +22145,7 @@ fn reifyUnion(
2215822145 .field_types = &.{}, // set later
2215922146 .field_aligns = &.{}, // set later
2216022147 .key = .{ .reified = .{
22161 .zir_index = try block.trackZir(inst),
22148 .zir_index = tracked_inst,
2216222149 .type_hash = hasher.final(),
2216322150 } },
2216422151 })) {
......@@ -22167,15 +22154,14 @@ fn reifyUnion(
2216722154 };
2216822155 errdefer wip_ty.cancel(ip, pt.tid);
2216922156
22170 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22157 const type_name = try sema.createTypeName(
2217122158 block,
22172 Value.fromInterned(wip_ty.index),
2217322159 name_strategy,
2217422160 "union",
2217522161 inst,
22162 wip_ty.index,
2217622163 );
22177 mod.declPtr(new_decl_index).owns_tv = true;
22178 errdefer pt.abortAnonDecl(new_decl_index);
22164 wip_ty.setName(ip, type_name);
2217922165
2218022166 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
2218122167 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
......@@ -22268,7 +22254,7 @@ fn reifyUnion(
2226822254 }
2226922255 }
2227022256
22271 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));
22257 const enum_tag_ty = try sema.generateUnionTagTypeSimple(field_names.keys(), wip_ty.index, type_name);
2227222258 break :tag_ty .{ enum_tag_ty, false };
2227322259 };
2227422260 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
......@@ -22315,10 +22301,11 @@ fn reifyUnion(
2231522301 loaded_union.setTagType(ip, enum_tag_ty);
2231622302 loaded_union.setStatus(ip, .have_field_types);
2231722303
22318 try pt.finalizeAnonDecl(new_decl_index);
22304 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, block.namespace, wip_ty.index);
22305
2231922306 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22320 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
22321 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22307 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22308 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), .none));
2232222309}
2232322310
2232422311fn reifyStruct(
......@@ -22399,6 +22386,8 @@ fn reifyStruct(
2239922386 }
2240022387 }
2240122388
22389 const tracked_inst = try block.trackZir(inst);
22390
2240222391 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
2240322392 .layout = layout,
2240422393 .fields_len = fields_len,
......@@ -22411,7 +22400,7 @@ fn reifyStruct(
2241122400 .inits_resolved = true,
2241222401 .has_namespace = false,
2241322402 .key = .{ .reified = .{
22414 .zir_index = try block.trackZir(inst),
22403 .zir_index = tracked_inst,
2241522404 .type_hash = hasher.final(),
2241622405 } },
2241722406 })) {
......@@ -22426,15 +22415,13 @@ fn reifyStruct(
2242622415 .auto => {},
2242722416 };
2242822417
22429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22418 wip_ty.setName(ip, try sema.createTypeName(
2243022419 block,
22431 Value.fromInterned(wip_ty.index),
2243222420 name_strategy,
2243322421 "struct",
2243422422 inst,
22435 );
22436 mod.declPtr(new_decl_index).owns_tv = true;
22437 errdefer pt.abortAnonDecl(new_decl_index);
22423 wip_ty.index,
22424 ));
2243822425
2243922426 const struct_type = ip.loadStructType(wip_ty.index);
2244022427
......@@ -22582,10 +22569,11 @@ fn reifyStruct(
2258222569 }
2258322570 }
2258422571
22585 try pt.finalizeAnonDecl(new_decl_index);
22572 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, block.namespace, wip_ty.index);
22573
2258622574 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22587 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));
22588 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22575 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22576 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), .none));
2258922577}
2259022578
2259122579fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
......@@ -26028,7 +26016,8 @@ fn zirVarExtended(
2602826016 extended: Zir.Inst.Extended.InstData,
2602926017) CompileError!Air.Inst.Ref {
2603026018 const pt = sema.pt;
26031 const mod = pt.zcu;
26019 const zcu = pt.zcu;
26020 const ip = &zcu.intern_pool;
2603226021 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
2603326022 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
2603426023 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
......@@ -26075,16 +26064,62 @@ fn zirVarExtended(
2607526064
2607626065 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
2607726066
26078 return Air.internedToRef((try pt.intern(.{ .variable = .{
26067 if (small.is_extern) {
26068 // We need to resolve the alignment and addrspace early.
26069 // Keep in sync with logic in `Zcu.PerThread.semaCau`.
26070 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
26071 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
26072
26073 const decl_inst, const decl_bodies = decl: {
26074 const decl_inst = sema.getOwnerCauDeclInst().resolve(ip);
26075 const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst);
26076 break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) };
26077 };
26078
26079 const alignment: InternPool.Alignment = a: {
26080 const align_body = decl_bodies.align_body orelse break :a .none;
26081 const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst);
26082 break :a try sema.analyzeAsAlign(block, align_src, align_ref);
26083 };
26084
26085 const @"addrspace": std.builtin.AddressSpace = as: {
26086 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(var_ty.toIntern())) {
26087 .func_type => .function,
26088 else => .variable,
26089 };
26090 const target = zcu.getTarget();
26091 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
26092 .function => target_util.defaultAddressSpace(target, .function),
26093 .variable => target_util.defaultAddressSpace(target, .global_mutable),
26094 .constant => target_util.defaultAddressSpace(target, .global_constant),
26095 else => unreachable,
26096 };
26097 const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst);
26098 break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx);
26099 };
26100
26101 return Air.internedToRef(try pt.getExtern(.{
26102 .name = sema.getOwnerCauNavName(),
26103 .ty = var_ty.toIntern(),
26104 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
26105 .is_const = small.is_const,
26106 .is_threadlocal = small.is_threadlocal,
26107 .is_weak_linkage = false,
26108 .alignment = alignment,
26109 .@"addrspace" = @"addrspace",
26110 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
26111 .owner_nav = undefined, // ignored by `getExtern`
26112 }));
26113 }
26114 assert(!small.is_const); // non-const non-extern variable is not legal
26115 return Air.internedToRef(try pt.intern(.{ .variable = .{
2607926116 .ty = var_ty.toIntern(),
2608026117 .init = init_val,
26081 .decl = sema.owner_decl_index,
26082 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
26083 .is_extern = small.is_extern,
26084 .is_const = small.is_const,
26118 .owner_nav = sema.getOwnerCauNav(),
26119 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
2608526120 .is_threadlocal = small.is_threadlocal,
2608626121 .is_weak_linkage = false,
26087 } })));
26122 } }));
2608826123}
2608926124
2609026125fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -26255,10 +26290,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2625526290 else => |e| return e,
2625626291 };
2625726292 break :blk mod.toEnum(std.builtin.CallingConvention, cc_val);
26258 } else if (sema.owner_decl.is_exported and has_body)
26259 .C
26260 else
26261 .Unspecified;
26293 } else cc: {
26294 if (has_body) {
26295 const decl_inst = if (sema.generic_owner != .none) decl_inst: {
26296 // Generic instance -- use the original function declaration to
26297 // look for the `export` syntax.
26298 const nav = mod.intern_pool.getNav(mod.funcInfo(sema.generic_owner).owner_nav);
26299 const cau = mod.intern_pool.getCau(nav.analysis_owner.unwrap().?);
26300 break :decl_inst cau.zir_index;
26301 } else sema.getOwnerCauDeclInst(); // not an instantiation so we're analyzing a function declaration Cau
26302
26303 const zir_decl = sema.code.getDeclaration(decl_inst.resolve(&mod.intern_pool))[0];
26304 if (zir_decl.flags.is_export) {
26305 break :cc .C;
26306 }
26307 }
26308 break :cc .Unspecified;
26309 };
2626226310
2626326311 const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: {
2626426312 const body_len = sema.code.extra[extra_index];
......@@ -26600,42 +26648,32 @@ fn zirBuiltinExtern(
2660026648
2660126649 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
2660226650
26651 // TODO: error for threadlocal functions, non-const functions, etc
26652
2660326653 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
2660426654 ty = try pt.optionalType(ty.toIntern());
2660526655 }
2660626656 const ptr_info = ty.ptrInfo(mod);
2660726657
26608 const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);
26609 errdefer pt.destroyDecl(new_decl_index);
26610 const new_decl = mod.declPtr(new_decl_index);
26611 try pt.initNewAnonDecl(
26612 new_decl_index,
26613 Value.fromInterned(
26614 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
26615 try ip.getExternFunc(sema.gpa, pt.tid, .{
26616 .ty = ptr_info.child,
26617 .decl = new_decl_index,
26618 .lib_name = options.library_name,
26619 })
26620 else
26621 try pt.intern(.{ .variable = .{
26622 .ty = ptr_info.child,
26623 .init = .none,
26624 .decl = new_decl_index,
26625 .lib_name = options.library_name,
26626 .is_extern = true,
26627 .is_const = ptr_info.flags.is_const,
26628 .is_threadlocal = options.is_thread_local,
26629 .is_weak_linkage = options.linkage == .weak,
26630 } }),
26631 ),
26632 options.name,
26633 .none,
26634 );
26635 new_decl.owns_tv = true;
26636 // Note that this will queue the anon decl for codegen, so that the backend can
26637 // correctly handle the extern, including duplicate detection.
26638 try pt.finalizeAnonDecl(new_decl_index);
26658 const extern_val = try pt.getExtern(.{
26659 .name = options.name,
26660 .ty = ptr_info.child,
26661 .lib_name = options.library_name,
26662 .is_const = ptr_info.flags.is_const,
26663 .is_threadlocal = options.is_thread_local,
26664 .is_weak_linkage = options.linkage == .weak,
26665 .alignment = ptr_info.flags.alignment,
26666 .@"addrspace" = ptr_info.flags.address_space,
26667 // This instruction is just for source locations.
26668 // `builtin_extern` doesn't provide enough information, and isn't currently tracked.
26669 // So, for now, just use our containing `declaration`.
26670 .zir_index = switch (sema.owner.unwrap()) {
26671 .cau => sema.getOwnerCauDeclInst(),
26672 .func => sema.getOwnerFuncDeclInst(),
26673 },
26674 .owner_nav = undefined, // ignored by `getExtern`
26675 });
26676 const extern_nav = ip.indexToKey(extern_val).@"extern".owner_nav;
2663926677
2664026678 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{
2664126679 .ty = switch (ip.indexToKey(ty.toIntern())) {
......@@ -26643,7 +26681,7 @@ fn zirBuiltinExtern(
2664326681 .opt_type => |child_type| child_type,
2664426682 else => unreachable,
2664526683 },
26646 .base_addr = .{ .decl = new_decl_index },
26684 .base_addr = .{ .nav = extern_nav },
2664726685 .byte_offset = 0,
2664826686 } })), ty)).toIntern());
2664926687}
......@@ -27129,17 +27167,15 @@ fn explainWhyTypeIsNotPacked(
2712927167 }
2713027168}
2713127169
27132fn prepareSimplePanic(sema: *Sema) !void {
27170fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
2713327171 const pt = sema.pt;
2713427172 const mod = pt.zcu;
2713527173
2713627174 if (mod.panic_func_index == .none) {
27137 const decl_index = (try pt.getBuiltinDecl("panic"));
27138 // decl_index may be an alias; we must find the decl that actually
27139 // owns the function.
27140 try sema.ensureDeclAnalyzed(decl_index);
27141 const fn_val = try mod.declPtr(decl_index).valueOrFail();
27142 try sema.declareDependency(.{ .decl_val = decl_index });
27175 const fn_ref = try sema.analyzeNavVal(block, src, try pt.getBuiltinNav("panic"));
27176 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{
27177 .needed_comptime_reason = "panic handler must be comptime-known",
27178 });
2714327179 assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn);
2714427180 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));
2714527181 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());
......@@ -27167,16 +27203,16 @@ fn prepareSimplePanic(sema: *Sema) !void {
2716727203/// Backends depend on panic decls being available when lowering safety-checked
2716827204/// instructions. This function ensures the panic function will be available to
2716927205/// be called during that time.
27170fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {
27206fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) !InternPool.Nav.Index {
2717127207 const pt = sema.pt;
2717227208 const mod = pt.zcu;
2717327209 const gpa = sema.gpa;
2717427210 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2717527211
27176 try sema.prepareSimplePanic();
27212 try sema.prepareSimplePanic(block, src);
2717727213
2717827214 const panic_messages_ty = try pt.getBuiltinType("panic_messages");
27179 const msg_decl_index = (sema.namespaceLookup(
27215 const msg_nav_index = (sema.namespaceLookup(
2718027216 block,
2718127217 LazySrcLoc.unneeded,
2718227218 panic_messages_ty.getNamespaceIndex(mod),
......@@ -27186,9 +27222,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
2718627222 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
2718727223 error.OutOfMemory => |e| return e,
2718827224 }).?;
27189 try sema.ensureDeclAnalyzed(msg_decl_index);
27190 mod.panic_messages[@intFromEnum(panic_id)] = msg_decl_index.toOptional();
27191 return msg_decl_index;
27225 try sema.ensureNavResolved(src, msg_nav_index);
27226 mod.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27227 return msg_nav_index;
2719227228}
2719327229
2719427230fn addSafetyCheck(
......@@ -27282,10 +27318,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
2728227318 return;
2728327319 }
2728427320
27285 try sema.prepareSimplePanic();
27321 try sema.prepareSimplePanic(block, src);
2728627322
2728727323 const panic_func = mod.funcInfo(mod.panic_func_index);
27288 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);
27324 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
2728927325 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);
2729027326
2729127327 const opt_usize_ty = try pt.optionalType(.usize_type);
......@@ -27455,8 +27491,8 @@ fn safetyCheckFormatted(
2745527491}
2745627492
2745727493fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void {
27458 const msg_decl_index = try sema.preparePanicId(block, panic_id);
27459 const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index);
27494 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);
27495 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);
2746027496 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
2746127497}
2746227498
......@@ -27628,21 +27664,21 @@ fn fieldVal(
2762827664 return Air.internedToRef(enum_val.toIntern());
2762927665 },
2763027666 .Struct, .Opaque => {
27631 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27632 return inst;
27667 switch (child_type.toIntern()) {
27668 .empty_struct_type, .anyopaque_type => {}, // no namespace
27669 else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27670 return inst;
27671 },
2763327672 }
2763427673 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
2763527674 },
27636 else => {
27637 const msg = msg: {
27638 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27639 errdefer msg.destroy(sema.gpa);
27640 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
27641 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});
27642 break :msg msg;
27643 };
27644 return sema.failWithOwnedErrorMsg(block, msg);
27645 },
27675 else => return sema.failWithOwnedErrorMsg(block, msg: {
27676 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27677 errdefer msg.destroy(sema.gpa);
27678 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
27679 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});
27680 break :msg msg;
27681 }),
2764627682 }
2764727683 },
2764827684 .Struct => if (is_pointer_to) {
......@@ -27700,7 +27736,7 @@ fn fieldPtr(
2770027736 .Array => {
2770127737 if (field_name.eqlSlice("len", ip)) {
2770227738 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));
27703 return anonDeclRef(sema, int_val.toIntern());
27739 return uavRef(sema, int_val.toIntern());
2770427740 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2770527741 const ptr_info = object_ty.ptrInfo(mod);
2770627742 const new_ptr_ty = try pt.ptrTypeSema(.{
......@@ -27839,7 +27875,7 @@ fn fieldPtr(
2783927875 child_type
2784027876 else
2784127877 try pt.singleErrorSetType(field_name);
27842 return anonDeclRef(sema, try pt.intern(.{ .err = .{
27878 return uavRef(sema, try pt.intern(.{ .err = .{
2784327879 .ty = error_set_type.toIntern(),
2784427880 .name = field_name,
2784527881 } }));
......@@ -27853,7 +27889,7 @@ fn fieldPtr(
2785327889 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
2785427890 const field_index_u32: u32 = @intCast(field_index);
2785527891 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
27856 return anonDeclRef(sema, idx_val.toIntern());
27892 return uavRef(sema, idx_val.toIntern());
2785727893 }
2785827894 }
2785927895 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
......@@ -27867,7 +27903,7 @@ fn fieldPtr(
2786727903 };
2786827904 const field_index_u32: u32 = @intCast(field_index);
2786927905 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
27870 return anonDeclRef(sema, idx_val.toIntern());
27906 return uavRef(sema, idx_val.toIntern());
2787127907 },
2787227908 .Struct, .Opaque => {
2787327909 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
......@@ -27923,18 +27959,18 @@ fn fieldCallBind(
2792327959 // in `fieldVal`. This function takes a pointer and returns a pointer.
2792427960
2792527961 const pt = sema.pt;
27926 const mod = pt.zcu;
27927 const ip = &mod.intern_pool;
27962 const zcu = pt.zcu;
27963 const ip = &zcu.intern_pool;
2792827964 const raw_ptr_src = src; // TODO better source location
2792927965 const raw_ptr_ty = sema.typeOf(raw_ptr);
27930 const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C))
27931 raw_ptr_ty.childType(mod)
27966 const inner_ty = if (raw_ptr_ty.zigTypeTag(zcu) == .Pointer and (raw_ptr_ty.ptrSize(zcu) == .One or raw_ptr_ty.ptrSize(zcu) == .C))
27967 raw_ptr_ty.childType(zcu)
2793227968 else
2793327969 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
2793427970
2793527971 // Optionally dereference a second pointer to get the concrete type.
27936 const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One;
27937 const concrete_ty = if (is_double_ptr) inner_ty.childType(mod) else inner_ty;
27972 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .Pointer and inner_ty.ptrSize(zcu) == .One;
27973 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;
2793827974 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
2793927975 const object_ptr = if (is_double_ptr)
2794027976 try sema.analyzeLoad(block, src, raw_ptr, src)
......@@ -27942,36 +27978,36 @@ fn fieldCallBind(
2794227978 raw_ptr;
2794327979
2794427980 find_field: {
27945 switch (concrete_ty.zigTypeTag(mod)) {
27981 switch (concrete_ty.zigTypeTag(zcu)) {
2794627982 .Struct => {
2794727983 try concrete_ty.resolveFields(pt);
27948 if (mod.typeToStruct(concrete_ty)) |struct_type| {
27984 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
2794927985 const field_index = struct_type.nameIndex(ip, field_name) orelse
2795027986 break :find_field;
2795127987 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2795227988
2795327989 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
27954 } else if (concrete_ty.isTuple(mod)) {
27990 } else if (concrete_ty.isTuple(zcu)) {
2795527991 if (field_name.eqlSlice("len", ip)) {
27956 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };
27992 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(zcu)) };
2795727993 }
2795827994 if (field_name.toUnsigned(ip)) |field_index| {
27959 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;
27960 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, mod), field_index, object_ptr);
27995 if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field;
27996 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, zcu), field_index, object_ptr);
2796127997 }
2796227998 } else {
27963 const max = concrete_ty.structFieldCount(mod);
27999 const max = concrete_ty.structFieldCount(zcu);
2796428000 for (0..max) |i_usize| {
2796528001 const i: u32 = @intCast(i_usize);
27966 if (field_name == concrete_ty.structFieldName(i, mod).unwrap().?) {
27967 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, mod), i, object_ptr);
28002 if (field_name == concrete_ty.structFieldName(i, zcu).unwrap().?) {
28003 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, zcu), i, object_ptr);
2796828004 }
2796928005 }
2797028006 }
2797128007 },
2797228008 .Union => {
2797328009 try concrete_ty.resolveFields(pt);
27974 const union_obj = mod.typeToUnion(concrete_ty).?;
28010 const union_obj = zcu.typeToUnion(concrete_ty).?;
2797528011 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
2797628012 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
2797728013 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };
......@@ -27985,23 +28021,23 @@ fn fieldCallBind(
2798528021 }
2798628022
2798728023 // If we get here, we need to look for a decl in the struct type instead.
27988 const found_decl = found_decl: {
27989 const namespace = concrete_ty.getNamespace(mod) orelse
27990 break :found_decl null;
27991 const decl_idx = (try sema.namespaceLookup(block, src, namespace, field_name)) orelse
27992 break :found_decl null;
28024 const found_nav = found_nav: {
28025 const namespace = concrete_ty.getNamespace(zcu) orelse
28026 break :found_nav null;
28027 const nav_index = try sema.namespaceLookup(block, src, namespace, field_name) orelse
28028 break :found_nav null;
2799328029
27994 const decl_val = try sema.analyzeDeclVal(block, src, decl_idx);
28030 const decl_val = try sema.analyzeNavVal(block, src, nav_index);
2799528031 const decl_type = sema.typeOf(decl_val);
27996 if (mod.typeToFunc(decl_type)) |func_type| f: {
28032 if (zcu.typeToFunc(decl_type)) |func_type| f: {
2799728033 if (func_type.param_types.len == 0) break :f;
2799828034
2799928035 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);
2800028036 if (first_param_type.isGenericPoison() or
28001 (first_param_type.zigTypeTag(mod) == .Pointer and
28002 (first_param_type.ptrSize(mod) == .One or
28003 first_param_type.ptrSize(mod) == .C) and
28004 first_param_type.childType(mod).eql(concrete_ty, mod)))
28037 (first_param_type.zigTypeTag(zcu) == .Pointer and
28038 (first_param_type.ptrSize(zcu) == .One or
28039 first_param_type.ptrSize(zcu) == .C) and
28040 first_param_type.childType(zcu).eql(concrete_ty, zcu)))
2800528041 {
2800628042 // Note that if the param type is generic poison, we know that it must
2800728043 // specifically be `anytype` since it's the first parameter, meaning we
......@@ -28012,31 +28048,31 @@ fn fieldCallBind(
2801228048 .func_inst = decl_val,
2801328049 .arg0_inst = object_ptr,
2801428050 } };
28015 } else if (first_param_type.eql(concrete_ty, mod)) {
28051 } else if (first_param_type.eql(concrete_ty, zcu)) {
2801628052 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2801728053 return .{ .method = .{
2801828054 .func_inst = decl_val,
2801928055 .arg0_inst = deref,
2802028056 } };
28021 } else if (first_param_type.zigTypeTag(mod) == .Optional) {
28022 const child = first_param_type.optionalChild(mod);
28023 if (child.eql(concrete_ty, mod)) {
28057 } else if (first_param_type.zigTypeTag(zcu) == .Optional) {
28058 const child = first_param_type.optionalChild(zcu);
28059 if (child.eql(concrete_ty, zcu)) {
2802428060 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2802528061 return .{ .method = .{
2802628062 .func_inst = decl_val,
2802728063 .arg0_inst = deref,
2802828064 } };
28029 } else if (child.zigTypeTag(mod) == .Pointer and
28030 child.ptrSize(mod) == .One and
28031 child.childType(mod).eql(concrete_ty, mod))
28065 } else if (child.zigTypeTag(zcu) == .Pointer and
28066 child.ptrSize(zcu) == .One and
28067 child.childType(zcu).eql(concrete_ty, zcu))
2803228068 {
2803328069 return .{ .method = .{
2803428070 .func_inst = decl_val,
2803528071 .arg0_inst = object_ptr,
2803628072 } };
2803728073 }
28038 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and
28039 first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod))
28074 } else if (first_param_type.zigTypeTag(zcu) == .ErrorUnion and
28075 first_param_type.errorUnionPayload(zcu).eql(concrete_ty, zcu))
2804028076 {
2804128077 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2804228078 return .{ .method = .{
......@@ -28045,7 +28081,7 @@ fn fieldCallBind(
2804528081 } };
2804628082 }
2804728083 }
28048 break :found_decl decl_idx;
28084 break :found_nav nav_index;
2804928085 };
2805028086
2805128087 const msg = msg: {
......@@ -28055,14 +28091,15 @@ fn fieldCallBind(
2805528091 });
2805628092 errdefer msg.destroy(sema.gpa);
2805728093 try sema.addDeclaredHereNote(msg, concrete_ty);
28058 if (found_decl) |decl_idx| {
28059 const decl = mod.declPtr(decl_idx);
28060 try sema.errNote(.{
28061 .base_node_inst = decl.zir_decl_index.unwrap().?,
28062 .offset = LazySrcLoc.Offset.nodeOffset(0),
28063 }, msg, "'{}' is not a member function", .{field_name.fmt(ip)});
28094 if (found_nav) |nav_index| {
28095 try sema.errNote(
28096 zcu.navSrcLoc(nav_index),
28097 msg,
28098 "'{}' is not a member function",
28099 .{field_name.fmt(ip)},
28100 );
2806428101 }
28065 if (concrete_ty.zigTypeTag(mod) == .ErrorUnion) {
28102 if (concrete_ty.zigTypeTag(zcu) == .ErrorUnion) {
2806628103 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
2806728104 }
2806828105 if (is_double_ptr) {
......@@ -28119,27 +28156,22 @@ fn namespaceLookup(
2811928156 src: LazySrcLoc,
2812028157 opt_namespace: InternPool.OptionalNamespaceIndex,
2812128158 decl_name: InternPool.NullTerminatedString,
28122) CompileError!?InternPool.DeclIndex {
28159) CompileError!?InternPool.Nav.Index {
2812328160 const pt = sema.pt;
28124 const mod = pt.zcu;
28161 const zcu = pt.zcu;
2812528162 const gpa = sema.gpa;
28126 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {
28127 const decl = mod.declPtr(decl_index);
28128 if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {
28129 const msg = msg: {
28163 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |lookup| {
28164 if (!lookup.accessible) {
28165 return sema.failWithOwnedErrorMsg(block, msg: {
2813028166 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
28131 decl_name.fmt(&mod.intern_pool),
28167 decl_name.fmt(&zcu.intern_pool),
2813228168 });
2813328169 errdefer msg.destroy(gpa);
28134 try sema.errNote(.{
28135 .base_node_inst = decl.zir_decl_index.unwrap().?,
28136 .offset = LazySrcLoc.Offset.nodeOffset(0),
28137 }, msg, "declared here", .{});
28170 try sema.errNote(zcu.navSrcLoc(lookup.nav), msg, "declared here", .{});
2813828171 break :msg msg;
28139 };
28140 return sema.failWithOwnedErrorMsg(block, msg);
28172 });
2814128173 }
28142 return decl_index;
28174 return lookup.nav;
2814328175 }
2814428176 return null;
2814528177}
......@@ -28151,8 +28183,8 @@ fn namespaceLookupRef(
2815128183 opt_namespace: InternPool.OptionalNamespaceIndex,
2815228184 decl_name: InternPool.NullTerminatedString,
2815328185) CompileError!?Air.Inst.Ref {
28154 const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null;
28155 return try sema.analyzeDeclRef(src, decl);
28186 const nav = try sema.namespaceLookup(block, src, opt_namespace, decl_name) orelse return null;
28187 return try sema.analyzeNavRef(src, nav);
2815628188}
2815728189
2815828190fn namespaceLookupVal(
......@@ -28162,8 +28194,8 @@ fn namespaceLookupVal(
2816228194 opt_namespace: InternPool.OptionalNamespaceIndex,
2816328195 decl_name: InternPool.NullTerminatedString,
2816428196) CompileError!?Air.Inst.Ref {
28165 const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null;
28166 return try sema.analyzeDeclVal(block, src, decl);
28197 const nav = try sema.namespaceLookup(block, src, opt_namespace, decl_name) orelse return null;
28198 return try sema.analyzeNavVal(block, src, nav);
2816728199}
2816828200
2816928201fn structFieldPtr(
......@@ -29200,9 +29232,9 @@ const CoerceOpts = struct {
2920029232
2920129233 fn get(info: @This(), sema: *Sema) !?LazySrcLoc {
2920229234 if (info.func_inst == .none) return null;
29203 const fn_decl = try sema.funcDeclSrc(info.func_inst) orelse return null;
29235 const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null;
2920429236 return .{
29205 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
29237 .base_node_inst = func_inst,
2920629238 .offset = .{ .fn_proto_param_type = .{
2920729239 .fn_proto_node_offset = 0,
2920829240 .param_index = info.param_i,
......@@ -29303,8 +29335,12 @@ fn coerceExtra(
2930329335 // Function body to function pointer.
2930429336 if (inst_ty.zigTypeTag(zcu) == .Fn) {
2930529337 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
29306 const fn_decl = fn_val.pointerDecl(zcu).?;
29307 const inst_as_ptr = try sema.analyzeDeclRef(inst_src, fn_decl);
29338 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
29339 .func => |f| f.owner_nav,
29340 .@"extern" => |e| e.owner_nav,
29341 else => unreachable,
29342 };
29343 const inst_as_ptr = try sema.analyzeNavRef(inst_src, fn_nav);
2930829344 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
2930929345 }
2931029346
......@@ -29846,7 +29882,7 @@ fn coerceExtra(
2984629882 errdefer msg.destroy(sema.gpa);
2984729883
2984829884 const ret_ty_src: LazySrcLoc = .{
29849 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,
29885 .base_node_inst = sema.getOwnerFuncDeclInst(),
2985029886 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
2985129887 };
2985229888 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
......@@ -29879,10 +29915,10 @@ fn coerceExtra(
2987929915
2988029916 // Add notes about function return type
2988129917 if (opts.is_ret and
29882 zcu.test_functions.get(zcu.funcOwnerDeclIndex(sema.func_index)) == null)
29918 !zcu.test_functions.contains(zcu.funcInfo(sema.owner.unwrap().func).owner_nav))
2988329919 {
2988429920 const ret_ty_src: LazySrcLoc = .{
29885 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,
29921 .base_node_inst = sema.getOwnerFuncDeclInst(),
2988629922 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
2988729923 };
2988829924 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
......@@ -30885,9 +30921,9 @@ fn coerceVarArgParam(
3088530921 if (block.is_typeof) return inst;
3088630922
3088730923 const pt = sema.pt;
30888 const mod = pt.zcu;
30924 const zcu = pt.zcu;
3088930925 const uncasted_ty = sema.typeOf(inst);
30890 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {
30926 const coerced = switch (uncasted_ty.zigTypeTag(zcu)) {
3089130927 // TODO consider casting to c_int/f64 if they fit
3089230928 .ComptimeInt, .ComptimeFloat => return sema.fail(
3089330929 block,
......@@ -30897,12 +30933,12 @@ fn coerceVarArgParam(
3089730933 ),
3089830934 .Fn => fn_ptr: {
3089930935 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
30900 const fn_decl = fn_val.pointerDecl(mod).?;
30901 break :fn_ptr try sema.analyzeDeclRef(inst_src, fn_decl);
30936 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
30937 break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav);
3090230938 },
3090330939 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
3090430940 .Float => float: {
30905 const target = mod.getTarget();
30941 const target = zcu.getTarget();
3090630942 const double_bits = target.c_type_bit_size(.double);
3090730943 const inst_bits = uncasted_ty.floatBits(target);
3090830944 if (inst_bits >= double_bits) break :float inst;
......@@ -30912,10 +30948,10 @@ fn coerceVarArgParam(
3091230948 else => unreachable,
3091330949 }
3091430950 },
30915 else => if (uncasted_ty.isAbiInt(mod)) int: {
30951 else => if (uncasted_ty.isAbiInt(zcu)) int: {
3091630952 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
30917 const target = mod.getTarget();
30918 const uncasted_info = uncasted_ty.intInfo(mod);
30953 const target = zcu.getTarget();
30954 const uncasted_info = uncasted_ty.intInfo(zcu);
3091930955 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {
3092030956 .signed => .int,
3092130957 .unsigned => .uint,
......@@ -32117,23 +32153,14 @@ fn coerceTupleToTuple(
3211732153 } })));
3211832154}
3211932155
32120fn analyzeDeclVal(
32156fn analyzeNavVal(
3212132157 sema: *Sema,
3212232158 block: *Block,
3212332159 src: LazySrcLoc,
32124 decl_index: InternPool.DeclIndex,
32160 nav_index: InternPool.Nav.Index,
3212532161) CompileError!Air.Inst.Ref {
32126 if (sema.decl_val_table.get(decl_index)) |result| {
32127 return result;
32128 }
32129 const decl_ref = try sema.analyzeDeclRefInner(src, decl_index, false);
32130 const result = try sema.analyzeLoad(block, src, decl_ref, src);
32131 if (result.toInterned() != null) {
32132 if (!block.is_typeof) {
32133 try sema.decl_val_table.put(sema.gpa, decl_index, result);
32134 }
32135 }
32136 return result;
32162 const ref = try sema.analyzeNavRefInner(src, nav_index, false);
32163 return sema.analyzeLoad(block, src, ref, src);
3213732164}
3213832165
3213932166fn addReferenceEntry(
......@@ -32148,44 +32175,37 @@ fn addReferenceEntry(
3214832175 // TODO: we need to figure out how to model inline calls here.
3214932176 // They aren't references in the analysis sense, but ought to show up in the reference trace!
3215032177 // Would representing inline calls in the reference table cause excessive memory usage?
32151 try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src);
32178 try zcu.addUnitReference(sema.owner, referenced_unit, src);
3215232179}
3215332180
32154pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {
32181pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!void {
3215532182 const pt = sema.pt;
32156 const mod = pt.zcu;
32157 const ip = &mod.intern_pool;
32158 const decl = mod.declPtr(decl_index);
32159 if (decl.analysis == .in_progress) {
32160 const msg = try sema.errMsg(.{
32161 .base_node_inst = decl.zir_decl_index.unwrap().?,
32162 .offset = LazySrcLoc.Offset.nodeOffset(0),
32163 }, "dependency loop detected", .{});
32164 return sema.failWithOwnedErrorMsg(null, msg);
32165 }
32183 const zcu = pt.zcu;
32184 const ip = &zcu.intern_pool;
3216632185
32167 pt.ensureDeclAnalyzed(decl_index) catch |err| {
32168 if (sema.owner_func_index != .none) {
32169 ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
32170 } else {
32171 sema.owner_decl.analysis = .dependency_failure;
32172 }
32173 return err;
32174 };
32175}
32186 const nav = ip.getNav(nav_index);
3217632187
32177fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {
32178 const pt = sema.pt;
32179 const mod = pt.zcu;
32180 const ip = &mod.intern_pool;
32181 pt.ensureFuncBodyAnalyzed(func) catch |err| {
32182 if (sema.owner_func_index != .none) {
32183 ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
32184 } else {
32185 sema.owner_decl.analysis = .dependency_failure;
32186 }
32187 return err;
32188 const cau_index = nav.analysis_owner.unwrap() orelse {
32189 assert(nav.status == .resolved);
32190 return;
3218832191 };
32192
32193 // Note that even if `nav.status == .resolved`, we must still trigger `ensureCauAnalyzed`
32194 // to make sure the value is up-to-date on incremental updates.
32195
32196 assert(ip.getCau(cau_index).owner.unwrap().nav == nav_index);
32197
32198 const anal_unit = AnalUnit.wrap(.{ .cau = cau_index });
32199 try sema.addReferenceEntry(src, anal_unit);
32200
32201 if (zcu.analysis_in_progress.contains(anal_unit)) {
32202 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{
32203 .base_node_inst = ip.getCau(cau_index).zir_index,
32204 .offset = LazySrcLoc.Offset.nodeOffset(0),
32205 }, "dependency loop detected", .{}));
32206 }
32207
32208 return pt.ensureCauAnalyzed(cau_index);
3218932209}
3219032210
3219132211fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
......@@ -32200,55 +32220,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
3220032220 } }));
3220132221}
3220232222
32203fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {
32204 return sema.analyzeDeclRefInner(src, decl_index, true);
32223fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref {
32224 return sema.analyzeNavRefInner(src, nav_index, true);
3220532225}
3220632226
32207/// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but
32227/// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed, but
3220832228/// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a
32209/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps
32229/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeNavRef` wraps
3221032230/// this function with `analyze_fn_body` set to true.
32211fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
32231fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
3221232232 const pt = sema.pt;
32213 const mod = pt.zcu;
32214 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));
32215 try sema.ensureDeclAnalyzed(decl_index);
32233 const zcu = pt.zcu;
32234 const ip = &zcu.intern_pool;
3221632235
32217 const decl_val = try mod.declPtr(decl_index).valueOrFail();
32218 const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_val.toIntern())) {
32219 .variable => |variable| variable.decl,
32220 .extern_func => |extern_func| extern_func.decl,
32221 .func => |func| func.owner_decl,
32222 else => decl_index,
32223 });
32224 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type
32225 try sema.declareDependency(.{ .decl_val = decl_index });
32236 // TODO: if this is a `decl_ref` of a non-variable Nav, only depend on Nav type
32237 try sema.declareDependency(.{ .nav_val = orig_nav_index });
32238 try sema.ensureNavResolved(src, orig_nav_index);
32239
32240 const nav_val = zcu.navValue(orig_nav_index);
32241 const nav_index, const is_const = switch (ip.indexToKey(nav_val.toIntern())) {
32242 .variable => |v| .{ v.owner_nav, false },
32243 .func => |f| .{ f.owner_nav, true },
32244 .@"extern" => |e| .{ e.owner_nav, e.is_const },
32245 else => .{ orig_nav_index, true },
32246 };
32247 const nav_info = ip.getNav(nav_index).status.resolved;
3222632248 const ptr_ty = try pt.ptrTypeSema(.{
32227 .child = decl_val.typeOf(mod).toIntern(),
32249 .child = nav_val.typeOf(zcu).toIntern(),
3222832250 .flags = .{
32229 .alignment = owner_decl.alignment,
32230 .is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true,
32231 .address_space = owner_decl.@"addrspace",
32251 .alignment = nav_info.alignment,
32252 .is_const = is_const,
32253 .address_space = nav_info.@"addrspace",
3223232254 },
3223332255 });
3223432256 if (analyze_fn_body) {
32235 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);
32257 try sema.maybeQueueFuncBodyAnalysis(src, nav_index);
3223632258 }
3223732259 return Air.internedToRef((try pt.intern(.{ .ptr = .{
3223832260 .ty = ptr_ty.toIntern(),
32239 .base_addr = .{ .decl = decl_index },
32261 .base_addr = .{ .nav = nav_index },
3224032262 .byte_offset = 0,
3224132263 } })));
3224232264}
3224332265
32244fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {
32245 const mod = sema.pt.zcu;
32246 const decl = mod.declPtr(decl_index);
32247 const decl_val = try decl.valueOrFail();
32248 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;
32249 if (!try sema.fnHasRuntimeBits(decl_val.typeOf(mod))) return;
32250 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = decl_val.toIntern() }));
32251 try mod.ensureFuncBodyAnalysisQueued(decl_val.toIntern());
32266fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void {
32267 const zcu = sema.pt.zcu;
32268 const ip = &zcu.intern_pool;
32269 const nav_val = zcu.navValue(nav_index);
32270 if (!ip.isFuncBody(nav_val.toIntern())) return;
32271 if (!try sema.fnHasRuntimeBits(nav_val.typeOf(zcu))) return;
32272 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() }));
32273 try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
3225232274}
3225332275
3225432276fn analyzeRef(
......@@ -32263,9 +32285,9 @@ fn analyzeRef(
3226332285
3226432286 if (try sema.resolveValue(operand)) |val| {
3226532287 switch (mod.intern_pool.indexToKey(val.toIntern())) {
32266 .extern_func => |extern_func| return sema.analyzeDeclRef(src, extern_func.decl),
32267 .func => |func| return sema.analyzeDeclRef(src, func.owner_decl),
32268 else => return anonDeclRef(sema, val.toIntern()),
32288 .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav),
32289 .func => |f| return sema.analyzeNavRef(src, f.owner_nav),
32290 else => return uavRef(sema, val.toIntern()),
3226932291 }
3227032292 }
3227132293
......@@ -35198,7 +35220,7 @@ pub fn resolveStructAlignment(
3519835220 const ip = &mod.intern_pool;
3519935221 const target = mod.getTarget();
3520035222
35201 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35223 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3520235224
3520335225 assert(struct_type.layout != .@"packed");
3520435226 assert(struct_type.flagsUnordered(ip).alignment == .none);
......@@ -35242,7 +35264,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3524235264 const ip = &zcu.intern_pool;
3524335265 const struct_type = zcu.typeToStruct(ty) orelse return;
3524435266
35245 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35267 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3524635268
3524735269 if (struct_type.haveLayout(ip))
3524835270 return;
......@@ -35384,8 +35406,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
3538435406 const gpa = zcu.gpa;
3538535407 const ip = &zcu.intern_pool;
3538635408
35387 const decl_index = struct_type.decl.unwrap().?;
35388 const decl = zcu.declPtr(decl_index);
35409 const cau_index = struct_type.cau.unwrap().?;
3538935410
3539035411 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;
3539135412
......@@ -35400,13 +35421,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
3540035421 .gpa = gpa,
3540135422 .arena = analysis_arena.allocator(),
3540235423 .code = zir,
35403 .owner_decl = decl,
35404 .owner_decl_index = decl_index,
35424 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3540535425 .func_index = .none,
3540635426 .func_is_naked = false,
3540735427 .fn_ret_ty = Type.void,
3540835428 .fn_ret_ty_ies = null,
35409 .owner_func_index = .none,
3541035429 .comptime_err_ret_trace = &comptime_err_ret_trace,
3541135430 };
3541235431 defer sema.deinit();
......@@ -35414,12 +35433,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
3541435433 var block: Block = .{
3541535434 .parent = null,
3541635435 .sema = &sema,
35417 .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,
35436 .namespace = ip.getCau(cau_index).namespace,
3541835437 .instructions = .{},
3541935438 .inlining = null,
3542035439 .is_comptime = true,
3542135440 .src_base_inst = struct_type.zir_index.unwrap().?,
35422 .type_name_ctx = decl.name,
35441 .type_name_ctx = struct_type.name,
3542335442 };
3542435443 defer assert(block.instructions.items.len == 0);
3542535444
......@@ -35544,7 +35563,7 @@ pub fn resolveUnionAlignment(
3554435563 const ip = &zcu.intern_pool;
3554535564 const target = zcu.getTarget();
3554635565
35547 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35566 assert(sema.owner.unwrap().cau == union_type.cau);
3554835567
3554935568 assert(!union_type.haveLayout(ip));
3555035569
......@@ -35584,7 +35603,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3558435603 // Load again, since the tag type might have changed due to resolution.
3558535604 const union_type = ip.loadUnionType(ty.ip_index);
3558635605
35587 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35606 assert(sema.owner.unwrap().cau == union_type.cau);
3558835607
3558935608 const old_flags = union_type.flagsUnordered(ip);
3559035609 switch (old_flags.status) {
......@@ -35697,7 +35716,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3569735716 const ip = &mod.intern_pool;
3569835717 const struct_type = mod.typeToStruct(ty).?;
3569935718
35700 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35719 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3570135720
3570235721 if (struct_type.setFullyResolved(ip)) return;
3570335722 errdefer struct_type.clearFullyResolved(ip);
......@@ -35720,7 +35739,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
3572035739 const ip = &mod.intern_pool;
3572135740 const union_obj = mod.typeToUnion(ty).?;
3572235741
35723 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);
35742 assert(sema.owner.unwrap().cau == union_obj.cau);
3572435743
3572535744 switch (union_obj.flagsUnordered(ip).status) {
3572635745 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
......@@ -35754,21 +35773,8 @@ pub fn resolveTypeFieldsStruct(
3575435773 const pt = sema.pt;
3575535774 const zcu = pt.zcu;
3575635775 const ip = &zcu.intern_pool;
35757 // If there is no owner decl it means the struct has no fields.
35758 const owner_decl = struct_type.decl.unwrap() orelse return;
3575935776
35760 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35761
35762 switch (zcu.declPtr(owner_decl).analysis) {
35763 .file_failure,
35764 .dependency_failure,
35765 .sema_failure,
35766 => {
35767 sema.owner_decl.analysis = .dependency_failure;
35768 return error.AnalysisFail;
35769 },
35770 else => {},
35771 }
35777 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3577235778
3577335779 if (struct_type.haveFieldTypes(ip)) return;
3577435780
......@@ -35783,13 +35789,7 @@ pub fn resolveTypeFieldsStruct(
3578335789 defer struct_type.clearFieldTypesWip(ip);
3578435790
3578535791 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
35786 error.AnalysisFail => {
35787 if (zcu.declPtr(owner_decl).analysis == .complete) {
35788 zcu.declPtr(owner_decl).analysis = .dependency_failure;
35789 }
35790 return error.AnalysisFail;
35791 },
35792 error.OutOfMemory => return error.OutOfMemory,
35792 error.AnalysisFail, error.OutOfMemory => |e| return e,
3579335793 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3579435794 };
3579535795}
......@@ -35799,9 +35799,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3579935799 const zcu = pt.zcu;
3580035800 const ip = &zcu.intern_pool;
3580135801 const struct_type = zcu.typeToStruct(ty) orelse return;
35802 const owner_decl = struct_type.decl.unwrap() orelse return;
3580335802
35804 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35803 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3580535804
3580635805 // Inits can start as resolved
3580735806 if (struct_type.haveFieldInits(ip)) return;
......@@ -35819,13 +35818,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3581935818 defer struct_type.clearInitsWip(ip);
3582035819
3582135820 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {
35822 error.AnalysisFail => {
35823 if (zcu.declPtr(owner_decl).analysis == .complete) {
35824 zcu.declPtr(owner_decl).analysis = .dependency_failure;
35825 }
35826 return error.AnalysisFail;
35827 },
35828 error.OutOfMemory => return error.OutOfMemory,
35821 error.AnalysisFail, error.OutOfMemory => |e| return e,
3582935822 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3583035823 };
3583135824 struct_type.setHaveFieldInits(ip);
......@@ -35835,20 +35828,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3583535828 const pt = sema.pt;
3583635829 const zcu = pt.zcu;
3583735830 const ip = &zcu.intern_pool;
35838 const owner_decl = zcu.declPtr(union_type.decl);
3583935831
35840 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35832 assert(sema.owner.unwrap().cau == union_type.cau);
3584135833
35842 switch (owner_decl.analysis) {
35843 .file_failure,
35844 .dependency_failure,
35845 .sema_failure,
35846 => {
35847 sema.owner_decl.analysis = .dependency_failure;
35848 return error.AnalysisFail;
35849 },
35850 else => {},
35851 }
3585235834 switch (union_type.flagsUnordered(ip).status) {
3585335835 .none => {},
3585435836 .field_types_wip => {
......@@ -35869,14 +35851,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3586935851
3587035852 union_type.setStatus(ip, .field_types_wip);
3587135853 errdefer union_type.setStatus(ip, .none);
35872 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {
35873 error.AnalysisFail => {
35874 if (owner_decl.analysis == .complete) {
35875 owner_decl.analysis = .dependency_failure;
35876 }
35877 return error.AnalysisFail;
35878 },
35879 error.OutOfMemory => return error.OutOfMemory,
35854 semaUnionFields(pt, sema.arena, ty.toIntern(), union_type) catch |err| switch (err) {
35855 error.AnalysisFail, error.OutOfMemory => |e| return e,
3588035856 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3588135857 };
3588235858 union_type.setStatus(ip, .have_field_types);
......@@ -35891,28 +35867,28 @@ fn resolveInferredErrorSet(
3589135867 ies_index: InternPool.Index,
3589235868) CompileError!InternPool.Index {
3589335869 const pt = sema.pt;
35894 const mod = pt.zcu;
35895 const ip = &mod.intern_pool;
35870 const zcu = pt.zcu;
35871 const ip = &zcu.intern_pool;
3589635872 const func_index = ip.iesFuncIndex(ies_index);
35897 const func = mod.funcInfo(func_index);
35873 const func = zcu.funcInfo(func_index);
3589835874
35899 try sema.declareDependency(.{ .func_ies = func_index });
35875 try sema.declareDependency(.{ .interned = func_index }); // resolved IES
3590035876
3590135877 // TODO: during an incremental update this might not be `.none`, but the
3590235878 // function might be out-of-date!
3590335879 const resolved_ty = func.resolvedErrorSetUnordered(ip);
3590435880 if (resolved_ty != .none) return resolved_ty;
3590535881
35906 if (func.analysisUnordered(ip).state == .in_progress)
35882 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .func = func_index }))) {
3590735883 return sema.fail(block, src, "unable to resolve inferred error set", .{});
35884 }
3590835885
3590935886 // In order to ensure that all dependencies are properly added to the set,
3591035887 // we need to ensure the function body is analyzed of the inferred error
3591135888 // set. However, in the case of comptime/inline function calls with
3591235889 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
3591335890 // has no corresponding function body.
35914 const ies_func_owner_decl = mod.declPtr(func.owner_decl);
35915 const ies_func_info = mod.typeToFunc(ies_func_owner_decl.typeOf(mod)).?;
35891 const ies_func_info = zcu.typeToFunc(Type.fromInterned(func.ty)).?;
3591635892 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
3591735893 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
3591835894 // so here we can simply skip this case.
......@@ -35920,22 +35896,17 @@ fn resolveInferredErrorSet(
3592035896 assert(ies_func_info.cc == .Inline);
3592135897 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {
3592235898 if (ies_func_info.is_generic) {
35923 const msg = msg: {
35899 return sema.failWithOwnedErrorMsg(block, msg: {
3592435900 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});
3592535901 errdefer msg.destroy(sema.gpa);
35926
35927 try sema.errNote(.{
35928 .base_node_inst = ies_func_owner_decl.zir_decl_index.unwrap().?,
35929 .offset = LazySrcLoc.Offset.nodeOffset(0),
35930 }, msg, "generic function declared here", .{});
35902 try sema.errNote(zcu.navSrcLoc(func.owner_nav), msg, "generic function declared here", .{});
3593135903 break :msg msg;
35932 };
35933 return sema.failWithOwnedErrorMsg(block, msg);
35904 });
3593435905 }
3593535906 // In this case we are dealing with the actual InferredErrorSet object that
3593635907 // corresponds to the function, not one created to track an inline/comptime call.
3593735908 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));
35938 try sema.ensureFuncBodyAnalyzed(func_index);
35909 try pt.ensureFuncBodyAnalyzed(func_index);
3593935910 }
3594035911
3594135912 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`
......@@ -36092,9 +36063,8 @@ fn semaStructFields(
3609236063 const zcu = pt.zcu;
3609336064 const gpa = zcu.gpa;
3609436065 const ip = &zcu.intern_pool;
36095 const decl_index = struct_type.decl.unwrap() orelse return;
36096 const decl = zcu.declPtr(decl_index);
36097 const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
36066 const cau_index = struct_type.cau.unwrap().?;
36067 const namespace_index = ip.getCau(cau_index).namespace;
3609836068 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
3609936069 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
3610036070
......@@ -36119,13 +36089,11 @@ fn semaStructFields(
3611936089 .gpa = gpa,
3612036090 .arena = arena,
3612136091 .code = zir,
36122 .owner_decl = decl,
36123 .owner_decl_index = decl_index,
36092 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3612436093 .func_index = .none,
3612536094 .func_is_naked = false,
3612636095 .fn_ret_ty = Type.void,
3612736096 .fn_ret_ty_ies = null,
36128 .owner_func_index = .none,
3612936097 .comptime_err_ret_trace = &comptime_err_ret_trace,
3613036098 };
3613136099 defer sema.deinit();
......@@ -36138,7 +36106,7 @@ fn semaStructFields(
3613836106 .inlining = null,
3613936107 .is_comptime = true,
3614036108 .src_base_inst = struct_type.zir_index.unwrap().?,
36141 .type_name_ctx = decl.name,
36109 .type_name_ctx = struct_type.name,
3614236110 };
3614336111 defer assert(block_scope.instructions.items.len == 0);
3614436112
......@@ -36318,9 +36286,8 @@ fn semaStructFieldInits(
3631836286
3631936287 assert(!struct_type.haveFieldInits(ip));
3632036288
36321 const decl_index = struct_type.decl.unwrap() orelse return;
36322 const decl = zcu.declPtr(decl_index);
36323 const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
36289 const cau_index = struct_type.cau.unwrap().?;
36290 const namespace_index = ip.getCau(cau_index).namespace;
3632436291 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
3632536292 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
3632636293 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
......@@ -36333,13 +36300,11 @@ fn semaStructFieldInits(
3633336300 .gpa = gpa,
3633436301 .arena = arena,
3633536302 .code = zir,
36336 .owner_decl = decl,
36337 .owner_decl_index = decl_index,
36303 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3633836304 .func_index = .none,
3633936305 .func_is_naked = false,
3634036306 .fn_ret_ty = Type.void,
3634136307 .fn_ret_ty_ies = null,
36342 .owner_func_index = .none,
3634336308 .comptime_err_ret_trace = &comptime_err_ret_trace,
3634436309 };
3634536310 defer sema.deinit();
......@@ -36352,7 +36317,7 @@ fn semaStructFieldInits(
3635236317 .inlining = null,
3635336318 .is_comptime = true,
3635436319 .src_base_inst = struct_type.zir_index.unwrap().?,
36355 .type_name_ctx = decl.name,
36320 .type_name_ctx = struct_type.name,
3635636321 };
3635736322 defer assert(block_scope.instructions.items.len == 0);
3635836323
......@@ -36449,14 +36414,14 @@ fn semaStructFieldInits(
3644936414 try sema.flushExports();
3645036415}
3645136416
36452fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {
36417fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_ty: InternPool.Index, union_type: InternPool.LoadedUnionType) CompileError!void {
3645336418 const tracy = trace(@src());
3645436419 defer tracy.end();
3645536420
3645636421 const zcu = pt.zcu;
3645736422 const gpa = zcu.gpa;
3645836423 const ip = &zcu.intern_pool;
36459 const decl_index = union_type.decl;
36424 const cau_index = union_type.cau;
3646036425 const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir;
3646136426 const zir_index = union_type.zir_index.resolve(ip);
3646236427 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
......@@ -36501,8 +36466,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3650136466 const body = zir.bodySlice(extra_index, body_len);
3650236467 extra_index += body.len;
3650336468
36504 const decl = zcu.declPtr(decl_index);
36505
3650636469 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
3650736470 defer comptime_err_ret_trace.deinit();
3650836471
......@@ -36511,13 +36474,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3651136474 .gpa = gpa,
3651236475 .arena = arena,
3651336476 .code = zir,
36514 .owner_decl = decl,
36515 .owner_decl_index = decl_index,
36477 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3651636478 .func_index = .none,
3651736479 .func_is_naked = false,
3651836480 .fn_ret_ty = Type.void,
3651936481 .fn_ret_ty_ies = null,
36520 .owner_func_index = .none,
3652136482 .comptime_err_ret_trace = &comptime_err_ret_trace,
3652236483 };
3652336484 defer sema.deinit();
......@@ -36530,7 +36491,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3653036491 .inlining = null,
3653136492 .is_comptime = true,
3653236493 .src_base_inst = union_type.zir_index,
36533 .type_name_ctx = decl.name,
36494 .type_name_ctx = union_type.name,
3653436495 };
3653536496 defer assert(block_scope.instructions.items.len == 0);
3653636497
......@@ -36817,10 +36778,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3681736778 return sema.failWithOwnedErrorMsg(&block_scope, msg);
3681836779 }
3681936780 } else if (enum_field_vals.count() > 0) {
36820 const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl));
36781 const enum_ty = try sema.generateUnionTagTypeNumbered(enum_field_names, enum_field_vals.keys(), union_ty, union_type.name);
3682136782 union_type.setTagType(ip, enum_ty);
3682236783 } else {
36823 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl));
36784 const enum_ty = try sema.generateUnionTagTypeSimple(enum_field_names, union_ty, union_type.name);
3682436785 union_type.setTagType(ip, enum_ty);
3682536786 }
3682636787
......@@ -36836,39 +36797,27 @@ fn semaUnionFieldVal(sema: *Sema, block: *Block, src: LazySrcLoc, int_tag_ty: Ty
3683636797
3683736798fn generateUnionTagTypeNumbered(
3683836799 sema: *Sema,
36839 block: *Block,
3684036800 enum_field_names: []const InternPool.NullTerminatedString,
3684136801 enum_field_vals: []const InternPool.Index,
36842 union_owner_decl: *Module.Decl,
36802 union_type: InternPool.Index,
36803 union_name: InternPool.NullTerminatedString,
3684336804) !InternPool.Index {
3684436805 const pt = sema.pt;
3684536806 const mod = pt.zcu;
3684636807 const gpa = sema.gpa;
3684736808 const ip = &mod.intern_pool;
3684836809
36849 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36850 errdefer pt.destroyDecl(new_decl_index);
3685136810 const name = try ip.getOrPutStringFmt(
3685236811 gpa,
3685336812 pt.tid,
3685436813 "@typeInfo({}).Union.tag_type.?",
36855 .{union_owner_decl.fqn.fmt(ip)},
36814 .{union_name.fmt(ip)},
3685636815 .no_embedded_nulls,
3685736816 );
36858 try pt.initNewAnonDecl(
36859 new_decl_index,
36860 Value.@"unreachable",
36861 name,
36862 name.toOptional(),
36863 );
36864 errdefer pt.abortAnonDecl(new_decl_index);
36865
36866 const new_decl = mod.declPtr(new_decl_index);
36867 new_decl.owns_tv = true;
3686836817
3686936818 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36870 .decl = new_decl_index,
36871 .owner_union_ty = union_owner_decl.val.toIntern(),
36819 .name = name,
36820 .owner_union_ty = union_type,
3687236821 .tag_ty = if (enum_field_vals.len == 0)
3687336822 (try pt.intType(.unsigned, 0)).toIntern()
3687436823 else
......@@ -36878,46 +36827,31 @@ fn generateUnionTagTypeNumbered(
3687836827 .tag_mode = .explicit,
3687936828 });
3688036829
36881 new_decl.val = Value.fromInterned(enum_ty);
36882
36883 try pt.finalizeAnonDecl(new_decl_index);
3688436830 return enum_ty;
3688536831}
3688636832
3688736833fn generateUnionTagTypeSimple(
3688836834 sema: *Sema,
36889 block: *Block,
3689036835 enum_field_names: []const InternPool.NullTerminatedString,
36891 union_owner_decl: *Module.Decl,
36836 union_type: InternPool.Index,
36837 union_name: InternPool.NullTerminatedString,
3689236838) !InternPool.Index {
3689336839 const pt = sema.pt;
3689436840 const mod = pt.zcu;
3689536841 const ip = &mod.intern_pool;
3689636842 const gpa = sema.gpa;
3689736843
36898 const new_decl_index = new_decl_index: {
36899 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36900 errdefer pt.destroyDecl(new_decl_index);
36901 const name = try ip.getOrPutStringFmt(
36902 gpa,
36903 pt.tid,
36904 "@typeInfo({}).Union.tag_type.?",
36905 .{union_owner_decl.fqn.fmt(ip)},
36906 .no_embedded_nulls,
36907 );
36908 try pt.initNewAnonDecl(
36909 new_decl_index,
36910 Value.@"unreachable",
36911 name,
36912 name.toOptional(),
36913 );
36914 break :new_decl_index new_decl_index;
36915 };
36916 errdefer pt.abortAnonDecl(new_decl_index);
36844 const name = try ip.getOrPutStringFmt(
36845 gpa,
36846 pt.tid,
36847 "@typeInfo({}).Union.tag_type.?",
36848 .{union_name.fmt(ip)},
36849 .no_embedded_nulls,
36850 );
3691736851
3691836852 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36919 .decl = new_decl_index,
36920 .owner_union_ty = union_owner_decl.val.toIntern(),
36853 .name = name,
36854 .owner_union_ty = union_type,
3692136855 .tag_ty = if (enum_field_names.len == 0)
3692236856 (try pt.intType(.unsigned, 0)).toIntern()
3692336857 else
......@@ -36927,11 +36861,6 @@ fn generateUnionTagTypeSimple(
3692736861 .tag_mode = .auto,
3692836862 });
3692936863
36930 const new_decl = mod.declPtr(new_decl_index);
36931 new_decl.owns_tv = true;
36932 new_decl.val = Value.fromInterned(enum_ty);
36933
36934 try pt.finalizeAnonDecl(new_decl_index);
3693536864 return enum_ty;
3693636865}
3693736866
......@@ -37057,9 +36986,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3705736986 // values, not types
3705836987 .undef,
3705936988 .simple_value,
37060 .ptr_decl,
37061 .ptr_anon_decl,
37062 .ptr_anon_decl_aligned,
36989 .ptr_nav,
36990 .ptr_uav,
36991 .ptr_uav_aligned,
3706336992 .ptr_comptime_alloc,
3706436993 .ptr_comptime_field,
3706536994 .ptr_int,
......@@ -37096,7 +37025,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3709637025 .float_c_longdouble_f128,
3709737026 .float_comptime_float,
3709837027 .variable,
37099 .extern_func,
37028 .@"extern",
3710037029 .func_decl,
3710137030 .func_instance,
3710237031 .func_coerced,
......@@ -37965,7 +37894,7 @@ fn intFitsInType(
3796537894 .zero_usize, .zero_u8 => return true,
3796637895 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
3796737896 .undef => return true,
37968 .variable, .extern_func, .func, .ptr => {
37897 .variable, .@"extern", .func, .ptr => {
3796937898 const target = mod.getTarget();
3797037899 const ptr_bits = target.ptrBitWidth();
3797137900 return switch (info.signedness) {
......@@ -38240,24 +38169,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
3824038169 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
3824138170 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
3824238171 // the loop.
38243 if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) {
38244 return;
38172 switch (sema.owner.unwrap()) {
38173 .cau => |cau| switch (dependee) {
38174 .nav_val => |nav| if (zcu.intern_pool.getNav(nav).analysis_owner == cau.toOptional()) {
38175 return;
38176 },
38177 else => {},
38178 },
38179 .func => {},
3824538180 }
3824638181
38247 const depender = AnalUnit.wrap(
38248 if (sema.owner_func_index != .none)
38249 .{ .func = sema.owner_func_index }
38250 else
38251 .{ .decl = sema.owner_decl_index },
38252 );
38253 try zcu.intern_pool.addDependency(sema.gpa, depender, dependee);
38182 try zcu.intern_pool.addDependency(sema.gpa, sema.owner, dependee);
3825438183}
3825538184
3825638185fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
3825738186 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
3825838187 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),
3825938188 .ptr => |ptr| switch (ptr.base_addr) {
38260 .anon_decl, .decl, .int => false,
38189 .uav, .nav, .int => false,
3826138190 .comptime_field => true,
3826238191 .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const,
3826338192 .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)),
......@@ -38388,19 +38317,17 @@ pub fn flushExports(sema: *Sema) !void {
3838838317 const zcu = sema.pt.zcu;
3838938318 const gpa = zcu.gpa;
3839038319
38391 const unit = sema.ownerUnit();
38392
3839338320 // There may be existing exports. For instance, a struct may export
3839438321 // things during both field type resolution and field default resolution.
3839538322 //
3839638323 // So, pick up and delete any existing exports. This strategy performs
3839738324 // redundant work, but that's okay, because this case is exceedingly rare.
38398 if (zcu.single_exports.get(unit)) |export_idx| {
38325 if (zcu.single_exports.get(sema.owner)) |export_idx| {
3839938326 try sema.exports.append(gpa, zcu.all_exports.items[export_idx]);
38400 } else if (zcu.multi_exports.get(unit)) |info| {
38327 } else if (zcu.multi_exports.get(sema.owner)) |info| {
3840138328 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
3840238329 }
38403 zcu.deleteUnitExports(unit);
38330 zcu.deleteUnitExports(sema.owner);
3840438331
3840538332 // `sema.exports` is completed; store the data into the `Zcu`.
3840638333 if (sema.exports.items.len == 1) {
......@@ -38410,24 +38337,55 @@ pub fn flushExports(sema: *Sema) !void {
3841038337 break :idx zcu.all_exports.items.len - 1;
3841138338 };
3841238339 zcu.all_exports.items[export_idx] = sema.exports.items[0];
38413 zcu.single_exports.putAssumeCapacityNoClobber(unit, @intCast(export_idx));
38340 zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, @intCast(export_idx));
3841438341 } else {
3841538342 try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);
3841638343 const exports_base = zcu.all_exports.items.len;
3841738344 try zcu.all_exports.appendSlice(gpa, sema.exports.items);
38418 zcu.multi_exports.putAssumeCapacityNoClobber(unit, .{
38345 zcu.multi_exports.putAssumeCapacityNoClobber(sema.owner, .{
3841938346 .index = @intCast(exports_base),
3842038347 .len = @intCast(sema.exports.items.len),
3842138348 });
3842238349 }
3842338350}
3842438351
38425pub fn ownerUnit(sema: Sema) AnalUnit {
38426 if (sema.owner_func_index != .none) {
38427 return AnalUnit.wrap(.{ .func = sema.owner_func_index });
38428 } else {
38429 return AnalUnit.wrap(.{ .decl = sema.owner_decl_index });
38430 }
38352/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38353/// the corresponding `Nav`.
38354fn getOwnerCauNav(sema: *Sema) InternPool.Nav.Index {
38355 const cau = sema.owner.unwrap().cau;
38356 return sema.pt.zcu.intern_pool.getCau(cau).owner.unwrap().nav;
38357}
38358
38359/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38360/// the declaration name from its corresponding `Nav`.
38361fn getOwnerCauNavName(sema: *Sema) InternPool.NullTerminatedString {
38362 const nav = sema.getOwnerCauNav();
38363 return sema.pt.zcu.intern_pool.getNav(nav).name;
38364}
38365
38366/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38367/// the `TrackedInst` corresponding to this `declaration` instruction.
38368fn getOwnerCauDeclInst(sema: *Sema) InternPool.TrackedInst.Index {
38369 const ip = &sema.pt.zcu.intern_pool;
38370 const cau = ip.getCau(sema.owner.unwrap().cau);
38371 assert(cau.owner.unwrap() == .nav);
38372 return cau.zir_index;
38373}
38374
38375/// Given that this `Sema` is owned by a runtime function, fetches the
38376/// `TrackedInst` corresponding to its `declaration` instruction.
38377fn getOwnerFuncDeclInst(sema: *Sema) InternPool.TrackedInst.Index {
38378 const zcu = sema.pt.zcu;
38379 const ip = &zcu.intern_pool;
38380 const func = sema.owner.unwrap().func;
38381 const func_info = zcu.funcInfo(func);
38382 const cau = if (func_info.generic_owner == .none) cau: {
38383 break :cau ip.getNav(func_info.owner_nav).analysis_owner.unwrap().?;
38384 } else cau: {
38385 const generic_owner = zcu.funcInfo(func_info.generic_owner);
38386 break :cau ip.getNav(generic_owner.owner_nav).analysis_owner.unwrap().?;
38387 };
38388 return ip.getCau(cau).zir_index;
3843138389}
3843238390
3843338391pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;
src/Sema/bitcast.zig+1-1
......@@ -254,7 +254,7 @@ const UnpackValueBits = struct {
254254 .error_set_type,
255255 .inferred_error_set_type,
256256 .variable,
257 .extern_func,
257 .@"extern",
258258 .func,
259259 .err,
260260 .error_union,
src/Sema/comptime_ptr_access.zig+16-8
......@@ -217,15 +217,23 @@ fn loadComptimePtrInner(
217217 };
218218
219219 const base_val: MutableValue = switch (ptr.base_addr) {
220 .decl => |decl_index| val: {
221 try sema.declareDependency(.{ .decl_val = decl_index });
222 try sema.ensureDeclAnalyzed(decl_index);
223 const decl = zcu.declPtr(decl_index);
224 if (decl.val.getVariable(zcu) != null) return .runtime_load;
225 break :val .{ .interned = decl.val.toIntern() };
220 .nav => |nav| val: {
221 try sema.declareDependency(.{ .nav_val = nav });
222 try sema.ensureNavResolved(src, nav);
223 const val = ip.getNav(nav).status.resolved.val;
224 switch (ip.indexToKey(val)) {
225 .variable => return .runtime_load,
226 // We let `.@"extern"` through here if it's a function.
227 // This allows you to alias `extern fn`s.
228 .@"extern" => |e| if (Type.fromInterned(e.ty).zigTypeTag(zcu) == .Fn)
229 break :val .{ .interned = val }
230 else
231 return .runtime_load,
232 else => break :val .{ .interned = val },
233 }
226234 },
227235 .comptime_alloc => |alloc_index| sema.getComptimeAlloc(alloc_index).val,
228 .anon_decl => |anon_decl| .{ .interned = anon_decl.val },
236 .uav => |uav| .{ .interned = uav.val },
229237 .comptime_field => |val| .{ .interned = val },
230238 .int => return .runtime_load,
231239 .eu_payload => |base_ptr_ip| val: {
......@@ -580,7 +588,7 @@ fn prepareComptimePtrStore(
580588
581589 // `base_strat` will not be an error case.
582590 const base_strat: ComptimeStoreStrategy = switch (ptr.base_addr) {
583 .decl, .anon_decl, .int => return .runtime_store,
591 .nav, .uav, .int => return .runtime_store,
584592 .comptime_field => return .comptime_field,
585593 .comptime_alloc => |alloc_index| .{ .direct = .{
586594 .alloc = alloc_index,
src/Type.zig+110-64
......@@ -268,9 +268,9 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
268268 return;
269269 },
270270 .inferred_error_set_type => |func_index| {
271 const owner_decl = mod.funcOwnerDeclPtr(func_index);
271 const func_nav = ip.getNav(mod.funcInfo(func_index).owner_nav);
272272 try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{
273 owner_decl.fqn.fmt(ip),
273 func_nav.fqn.fmt(ip),
274274 });
275275 },
276276 .error_set_type => |error_set_type| {
......@@ -331,15 +331,11 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
331331 .generic_poison => unreachable,
332332 },
333333 .struct_type => {
334 const struct_type = ip.loadStructType(ty.toIntern());
335 if (struct_type.decl.unwrap()) |decl_index| {
336 const decl = mod.declPtr(decl_index);
337 try writer.print("{}", .{decl.fqn.fmt(ip)});
338 } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {
339 const namespace = mod.namespacePtr(namespace_index);
340 try namespace.renderFullyQualifiedName(ip, .empty, writer);
341 } else {
334 const name = ip.loadStructType(ty.toIntern()).name;
335 if (name == .empty) {
342336 try writer.writeAll("@TypeOf(.{})");
337 } else {
338 try writer.print("{}", .{name.fmt(ip)});
343339 }
344340 },
345341 .anon_struct_type => |anon_struct| {
......@@ -366,16 +362,16 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
366362 },
367363
368364 .union_type => {
369 const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl);
370 try writer.print("{}", .{decl.fqn.fmt(ip)});
365 const name = ip.loadUnionType(ty.toIntern()).name;
366 try writer.print("{}", .{name.fmt(ip)});
371367 },
372368 .opaque_type => {
373 const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl);
374 try writer.print("{}", .{decl.fqn.fmt(ip)});
369 const name = ip.loadOpaqueType(ty.toIntern()).name;
370 try writer.print("{}", .{name.fmt(ip)});
375371 },
376372 .enum_type => {
377 const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl);
378 try writer.print("{}", .{decl.fqn.fmt(ip)});
373 const name = ip.loadEnumType(ty.toIntern()).name;
374 try writer.print("{}", .{name.fmt(ip)});
379375 },
380376 .func_type => |fn_info| {
381377 if (fn_info.is_noinline) {
......@@ -427,7 +423,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
427423 .undef,
428424 .simple_value,
429425 .variable,
430 .extern_func,
426 .@"extern",
431427 .func,
432428 .int,
433429 .err,
......@@ -645,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced(
645641 .undef,
646642 .simple_value,
647643 .variable,
648 .extern_func,
644 .@"extern",
649645 .func,
650646 .int,
651647 .err,
......@@ -757,7 +753,7 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
757753 .undef,
758754 .simple_value,
759755 .variable,
760 .extern_func,
756 .@"extern",
761757 .func,
762758 .int,
763759 .err,
......@@ -1108,7 +1104,7 @@ pub fn abiAlignmentAdvanced(
11081104 .undef,
11091105 .simple_value,
11101106 .variable,
1111 .extern_func,
1107 .@"extern",
11121108 .func,
11131109 .int,
11141110 .err,
......@@ -1483,7 +1479,7 @@ pub fn abiSizeAdvanced(
14831479 .undef,
14841480 .simple_value,
14851481 .variable,
1486 .extern_func,
1482 .@"extern",
14871483 .func,
14881484 .int,
14891485 .err,
......@@ -1813,7 +1809,7 @@ pub fn bitSizeAdvanced(
18131809 .undef,
18141810 .simple_value,
18151811 .variable,
1816 .extern_func,
1812 .@"extern",
18171813 .func,
18181814 .int,
18191815 .err,
......@@ -2351,7 +2347,7 @@ pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType {
23512347 .undef,
23522348 .simple_value,
23532349 .variable,
2354 .extern_func,
2350 .@"extern",
23552351 .func,
23562352 .int,
23572353 .err,
......@@ -2700,7 +2696,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
27002696 .undef,
27012697 .simple_value,
27022698 .variable,
2703 .extern_func,
2699 .@"extern",
27042700 .func,
27052701 .int,
27062702 .err,
......@@ -2899,7 +2895,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve
28992895 .undef,
29002896 .simple_value,
29012897 .variable,
2902 .extern_func,
2898 .@"extern",
29032899 .func,
29042900 .int,
29052901 .err,
......@@ -3007,6 +3003,26 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {
30073003 };
30083004}
30093005
3006// TODO: new dwarf structure will also need the enclosing code block for types created in imperative scopes
3007pub fn getParentNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {
3008 const ip = &zcu.intern_pool;
3009 const cau = switch (ip.indexToKey(ty.toIntern())) {
3010 .struct_type => ip.loadStructType(ty.toIntern()).cau,
3011 .union_type => ip.loadUnionType(ty.toIntern()).cau.toOptional(),
3012 .enum_type => |e| switch (e) {
3013 .declared, .reified => ip.loadEnumType(ty.toIntern()).cau,
3014 .generated_tag => |gt| ip.loadUnionType(gt.union_type).cau.toOptional(),
3015 .empty_struct => unreachable,
3016 },
3017 // TODO: this doesn't handle opaque types with empty namespaces
3018 .opaque_type => return ip.namespacePtr(ip.loadOpaqueType(ty.toIntern()).namespace.unwrap().?).parent,
3019 else => return null,
3020 };
3021 return ip.namespacePtr(ip.getCau(cau.unwrap() orelse return .none).namespace)
3022 // TODO: I thought the cau contained the parent namespace based on "analyzed within" but alas
3023 .parent;
3024}
3025
30103026// Works for vectors and vectors of integers.
30113027pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
30123028 const mod = pt.zcu;
......@@ -3321,21 +3337,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {
33213337 }
33223338}
33233339
3324pub fn getOwnerDecl(ty: Type, mod: *Module) InternPool.DeclIndex {
3325 return ty.getOwnerDeclOrNull(mod) orelse unreachable;
3326}
3327
3328pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?InternPool.DeclIndex {
3329 const ip = &mod.intern_pool;
3330 return switch (ip.indexToKey(ty.toIntern())) {
3331 .struct_type => ip.loadStructType(ty.toIntern()).decl.unwrap(),
3332 .union_type => ip.loadUnionType(ty.toIntern()).decl,
3333 .opaque_type => ip.loadOpaqueType(ty.toIntern()).decl,
3334 .enum_type => ip.loadEnumType(ty.toIntern()).decl,
3335 else => null,
3336 };
3337}
3338
33393340pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {
33403341 const ip = &zcu.intern_pool;
33413342 return .{
......@@ -3366,7 +3367,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {
33663367 .struct_type => {
33673368 const struct_type = ip.loadStructType(ty.toIntern());
33683369 if (struct_type.layout == .@"packed") return false;
3369 if (struct_type.decl == .none) return false;
3370 if (struct_type.cau == .none) return false;
33703371 return struct_type.flagsUnordered(ip).is_tuple;
33713372 },
33723373 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,
......@@ -3388,7 +3389,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {
33883389 .struct_type => {
33893390 const struct_type = ip.loadStructType(ty.toIntern());
33903391 if (struct_type.layout == .@"packed") return false;
3391 if (struct_type.decl == .none) return false;
3392 if (struct_type.cau == .none) return false;
33923393 return struct_type.flagsUnordered(ip).is_tuple;
33933394 },
33943395 .anon_struct_type => true,
......@@ -3444,6 +3445,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
34443445 };
34453446}
34463447
3448pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3449 const ip = &zcu.intern_pool;
3450 return switch (ip.indexToKey(ty.toIntern())) {
3451 .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(),
3452 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3453 .enum_type => |e| switch (e) {
3454 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3455 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3456 .empty_struct => unreachable,
3457 },
3458 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
3459 else => null,
3460 };
3461}
3462
34473463pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
34483464 const ip = &zcu.intern_pool;
34493465 const tracked = switch (ip.indexToKey(ty.toIntern())) {
......@@ -3471,7 +3487,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
34713487 };
34723488}
34733489
3474/// Given a namespace type, returns its list of caotured values.
3490/// Given a namespace type, returns its list of captured values.
34753491pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
34763492 const ip = &zcu.intern_pool;
34773493 return switch (ip.indexToKey(ty.toIntern())) {
......@@ -3773,7 +3789,11 @@ fn resolveStructInner(
37733789 const gpa = zcu.gpa;
37743790
37753791 const struct_obj = zcu.typeToStruct(ty).?;
3776 const owner_decl_index = struct_obj.decl.unwrap() orelse return;
3792 const owner = InternPool.AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap() orelse return });
3793
3794 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3795 return error.AnalysisFail;
3796 }
37773797
37783798 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
37793799 defer analysis_arena.deinit();
......@@ -3786,24 +3806,30 @@ fn resolveStructInner(
37863806 .gpa = gpa,
37873807 .arena = analysis_arena.allocator(),
37883808 .code = undefined, // This ZIR will not be used.
3789 .owner_decl = zcu.declPtr(owner_decl_index),
3790 .owner_decl_index = owner_decl_index,
3809 .owner = owner,
37913810 .func_index = .none,
37923811 .func_is_naked = false,
37933812 .fn_ret_ty = Type.void,
37943813 .fn_ret_ty_ies = null,
3795 .owner_func_index = .none,
37963814 .comptime_err_ret_trace = &comptime_err_ret_trace,
37973815 };
37983816 defer sema.deinit();
37993817
3800 switch (resolution) {
3801 .fields => return sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),
3802 .inits => return sema.resolveStructFieldInits(ty),
3803 .alignment => return sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3804 .layout => return sema.resolveStructLayout(ty),
3805 .full => return sema.resolveStructFully(ty),
3806 }
3818 (switch (resolution) {
3819 .fields => sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),
3820 .inits => sema.resolveStructFieldInits(ty),
3821 .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3822 .layout => sema.resolveStructLayout(ty),
3823 .full => sema.resolveStructFully(ty),
3824 }) catch |err| switch (err) {
3825 error.AnalysisFail => {
3826 if (!zcu.failed_analysis.contains(owner)) {
3827 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3828 }
3829 return error.AnalysisFail;
3830 },
3831 error.OutOfMemory => |e| return e,
3832 };
38073833}
38083834
38093835/// `ty` must be a union.
......@@ -3816,7 +3842,11 @@ fn resolveUnionInner(
38163842 const gpa = zcu.gpa;
38173843
38183844 const union_obj = zcu.typeToUnion(ty).?;
3819 const owner_decl_index = union_obj.decl;
3845 const owner = InternPool.AnalUnit.wrap(.{ .cau = union_obj.cau });
3846
3847 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3848 return error.AnalysisFail;
3849 }
38203850
38213851 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
38223852 defer analysis_arena.deinit();
......@@ -3829,23 +3859,29 @@ fn resolveUnionInner(
38293859 .gpa = gpa,
38303860 .arena = analysis_arena.allocator(),
38313861 .code = undefined, // This ZIR will not be used.
3832 .owner_decl = zcu.declPtr(owner_decl_index),
3833 .owner_decl_index = owner_decl_index,
3862 .owner = owner,
38343863 .func_index = .none,
38353864 .func_is_naked = false,
38363865 .fn_ret_ty = Type.void,
38373866 .fn_ret_ty_ies = null,
3838 .owner_func_index = .none,
38393867 .comptime_err_ret_trace = &comptime_err_ret_trace,
38403868 };
38413869 defer sema.deinit();
38423870
3843 switch (resolution) {
3844 .fields => return sema.resolveTypeFieldsUnion(ty, union_obj),
3845 .alignment => return sema.resolveUnionAlignment(ty, union_obj),
3846 .layout => return sema.resolveUnionLayout(ty),
3847 .full => return sema.resolveUnionFully(ty),
3848 }
3871 (switch (resolution) {
3872 .fields => sema.resolveTypeFieldsUnion(ty, union_obj),
3873 .alignment => sema.resolveUnionAlignment(ty, union_obj),
3874 .layout => sema.resolveUnionLayout(ty),
3875 .full => sema.resolveUnionFully(ty),
3876 }) catch |err| switch (err) {
3877 error.AnalysisFail => {
3878 if (!zcu.failed_analysis.contains(owner)) {
3879 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3880 }
3881 return error.AnalysisFail;
3882 },
3883 error.OutOfMemory => |e| return e,
3884 };
38493885}
38503886
38513887/// Fully resolves a simple type. This is usually a nop, but for builtin types with
......@@ -3945,6 +3981,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {
39453981 });
39463982}
39473983
3984pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
3985 return switch (ip.indexToKey(ty.toIntern())) {
3986 .struct_type => ip.loadStructType(ty.toIntern()).name,
3987 .union_type => ip.loadUnionType(ty.toIntern()).name,
3988 .enum_type => ip.loadEnumType(ty.toIntern()).name,
3989 .opaque_type => ip.loadOpaqueType(ty.toIntern()).name,
3990 else => unreachable,
3991 };
3992}
3993
39483994pub const @"u1": Type = .{ .ip_index = .u1_type };
39493995pub const @"u8": Type = .{ .ip_index = .u8_type };
39503996pub const @"u16": Type = .{ .ip_index = .u16_type };
src/Value.zig+37-48
......@@ -227,13 +227,6 @@ pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func {
227227 };
228228}
229229
230pub fn getExternFunc(val: Value, mod: *Module) ?InternPool.Key.ExternFunc {
231 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
232 .extern_func => |extern_func| extern_func,
233 else => null,
234 };
235}
236
237230pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
238231 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
239232 .variable => |variable| variable,
......@@ -319,17 +312,8 @@ pub fn toBool(val: Value) bool {
319312 };
320313}
321314
322fn ptrHasIntAddr(val: Value, mod: *Module) bool {
323 var check = val;
324 while (true) switch (mod.intern_pool.indexToKey(check.toIntern())) {
325 .ptr => |ptr| switch (ptr.base_addr) {
326 .decl, .comptime_alloc, .comptime_field, .anon_decl => return false,
327 .int => return true,
328 .eu_payload, .opt_payload => |base| check = Value.fromInterned(base),
329 .arr_elem, .field => |base_index| check = Value.fromInterned(base_index.base),
330 },
331 else => unreachable,
332 };
315fn ptrHasIntAddr(val: Value, zcu: *Zcu) bool {
316 return zcu.intern_pool.getBackingAddrTag(val.toIntern()).? == .int;
333317}
334318
335319/// Write a Value's contents to `buffer`.
......@@ -1058,7 +1042,7 @@ pub fn orderAgainstZeroAdvanced(
10581042 .bool_true => .gt,
10591043 else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) {
10601044 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {
1061 .decl, .comptime_alloc, .comptime_field => .gt,
1045 .nav, .comptime_alloc, .comptime_field => .gt,
10621046 .int => .eq,
10631047 else => unreachable,
10641048 },
......@@ -1130,11 +1114,11 @@ pub fn compareHeteroAdvanced(
11301114 pt: Zcu.PerThread,
11311115 comptime strat: ResolveStrat,
11321116) !bool {
1133 if (lhs.pointerDecl(pt.zcu)) |lhs_decl| {
1134 if (rhs.pointerDecl(pt.zcu)) |rhs_decl| {
1117 if (lhs.pointerNav(pt.zcu)) |lhs_nav| {
1118 if (rhs.pointerNav(pt.zcu)) |rhs_nav| {
11351119 switch (op) {
1136 .eq => return lhs_decl == rhs_decl,
1137 .neq => return lhs_decl != rhs_decl,
1120 .eq => return lhs_nav == rhs_nav,
1121 .neq => return lhs_nav != rhs_nav,
11381122 else => {},
11391123 }
11401124 } else {
......@@ -1144,7 +1128,7 @@ pub fn compareHeteroAdvanced(
11441128 else => {},
11451129 }
11461130 }
1147 } else if (rhs.pointerDecl(pt.zcu)) |_| {
1131 } else if (rhs.pointerNav(pt.zcu)) |_| {
11481132 switch (op) {
11491133 .eq => return false,
11501134 .neq => return true,
......@@ -1252,12 +1236,12 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {
12521236 .payload => |payload| Value.fromInterned(payload).canMutateComptimeVarState(zcu),
12531237 },
12541238 .ptr => |ptr| switch (ptr.base_addr) {
1255 .decl => false, // The value of a Decl can never reference a comptime alloc.
1239 .nav => false, // The value of a Nav can never reference a comptime alloc.
12561240 .int => false,
12571241 .comptime_alloc => true, // A comptime alloc is either mutable or references comptime-mutable memory.
12581242 .comptime_field => true, // Comptime field pointers are comptime-mutable, albeit only to the "correct" value.
12591243 .eu_payload, .opt_payload => |base| Value.fromInterned(base).canMutateComptimeVarState(zcu),
1260 .anon_decl => |anon_decl| Value.fromInterned(anon_decl.val).canMutateComptimeVarState(zcu),
1244 .uav => |uav| Value.fromInterned(uav.val).canMutateComptimeVarState(zcu),
12611245 .arr_elem, .field => |base_index| Value.fromInterned(base_index.base).canMutateComptimeVarState(zcu),
12621246 },
12631247 .slice => |slice| return Value.fromInterned(slice.ptr).canMutateComptimeVarState(zcu),
......@@ -1273,16 +1257,17 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {
12731257 };
12741258}
12751259
1276/// Gets the decl referenced by this pointer. If the pointer does not point
1277/// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),
1278/// this function returns null.
1279pub fn pointerDecl(val: Value, mod: *Module) ?InternPool.DeclIndex {
1260/// Gets the `Nav` referenced by this pointer. If the pointer does not point
1261/// to a `Nav`, or if it points to some part of one (like a field or element),
1262/// returns null.
1263pub fn pointerNav(val: Value, mod: *Module) ?InternPool.Nav.Index {
12801264 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1281 .variable => |variable| variable.decl,
1282 .extern_func => |extern_func| extern_func.decl,
1283 .func => |func| func.owner_decl,
1265 // TODO: these 3 cases are weird; these aren't pointer values!
1266 .variable => |v| v.owner_nav,
1267 .@"extern" => |e| e.owner_nav,
1268 .func => |func| func.owner_nav,
12841269 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1285 .decl => |decl| decl,
1270 .nav => |nav| nav,
12861271 else => null,
12871272 } else null,
12881273 else => null,
......@@ -1341,10 +1326,14 @@ pub fn isLazySize(val: Value, mod: *Module) bool {
13411326 };
13421327}
13431328
1344pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {
1345 const backing_decl = mod.intern_pool.getBackingDecl(val.toIntern()).unwrap() orelse return false;
1346 const variable = mod.declPtr(backing_decl).getOwnedVariable(mod) orelse return false;
1347 return variable.is_threadlocal;
1329pub fn isPtrToThreadLocal(val: Value, zcu: *Zcu) bool {
1330 const ip = &zcu.intern_pool;
1331 const nav = ip.getBackingNav(val.toIntern()).unwrap() orelse return false;
1332 return switch (ip.indexToKey(ip.getNav(nav).status.resolved.val)) {
1333 .@"extern" => |e| e.is_threadlocal,
1334 .variable => |v| v.is_threadlocal,
1335 else => false,
1336 };
13481337}
13491338
13501339// Asserts that the provided start/end are in-bounds.
......@@ -4031,8 +4020,8 @@ pub const PointerDeriveStep = union(enum) {
40314020 addr: u64,
40324021 ptr_ty: Type,
40334022 },
4034 decl_ptr: InternPool.DeclIndex,
4035 anon_decl_ptr: InternPool.Key.Ptr.BaseAddr.AnonDecl,
4023 nav_ptr: InternPool.Nav.Index,
4024 uav_ptr: InternPool.Key.Ptr.BaseAddr.Uav,
40364025 comptime_alloc_ptr: struct {
40374026 val: Value,
40384027 ptr_ty: Type,
......@@ -4069,8 +4058,8 @@ pub const PointerDeriveStep = union(enum) {
40694058 pub fn ptrType(step: PointerDeriveStep, pt: Zcu.PerThread) !Type {
40704059 return switch (step) {
40714060 .int => |int| int.ptr_ty,
4072 .decl_ptr => |decl| try pt.zcu.declPtr(decl).declPtrType(pt),
4073 .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty),
4061 .nav_ptr => |nav| try pt.navPtrType(nav),
4062 .uav_ptr => |uav| Type.fromInterned(uav.orig_ty),
40744063 .comptime_alloc_ptr => |info| info.ptr_ty,
40754064 .comptime_field_ptr => |val| try pt.singleConstPtrType(val.typeOf(pt.zcu)),
40764065 .offset_and_cast => |oac| oac.new_ptr_ty,
......@@ -4098,17 +4087,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
40984087 .addr = ptr.byte_offset,
40994088 .ptr_ty = Type.fromInterned(ptr.ty),
41004089 } },
4101 .decl => |decl| .{ .decl_ptr = decl },
4102 .anon_decl => |ad| base: {
4090 .nav => |nav| .{ .nav_ptr = nav },
4091 .uav => |uav| base: {
41034092 // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be.
41044093 // TODO: fix this in the sites interning anon decls!
41054094 const const_ty = try pt.ptrType(info: {
4106 var info = Type.fromInterned(ad.orig_ty).ptrInfo(zcu);
4095 var info = Type.fromInterned(uav.orig_ty).ptrInfo(zcu);
41074096 info.flags.is_const = true;
41084097 break :info info;
41094098 });
4110 break :base .{ .anon_decl_ptr = .{
4111 .val = ad.val,
4099 break :base .{ .uav_ptr = .{
4100 .val = uav.val,
41124101 .orig_ty = const_ty.toIntern(),
41134102 } };
41144103 },
......@@ -4357,7 +4346,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaErro
43574346 },
43584347 .ptr => |ptr| {
43594348 switch (ptr.base_addr) {
4360 .decl, .comptime_alloc, .anon_decl, .int => return val,
4349 .nav, .comptime_alloc, .uav, .int => return val,
43614350 .comptime_field => |field_val| {
43624351 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern();
43634352 return if (resolved_field_val == field_val)
src/Zcu.zig+143-521
......@@ -118,8 +118,15 @@ embed_table: std.StringArrayHashMapUnmanaged(*EmbedFile) = .{},
118118/// is not yet implemented.
119119intern_pool: InternPool = .{},
120120
121analysis_in_progress: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{},
121122/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.
122123failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .{},
124/// This `AnalUnit` failed semantic analysis because it required analysis of another `AnalUnit` which itself failed.
125transitive_failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{},
126/// This `Nav` succeeded analysis, but failed codegen.
127/// This may be a simple "value" `Nav`, or it may be a function.
128/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.
129failed_codegen: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, *ErrorMsg) = .{},
123130/// Keep track of one `@compileLog` callsite per `AnalUnit`.
124131/// The value is the source location of the `@compileLog` call, convertible to a `LazySrcLoc`.
125132compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
......@@ -155,12 +162,12 @@ outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .{},
155162/// Such `AnalUnit`s are ready for immediate re-analysis.
156163/// See `findOutdatedToAnalyze` for details.
157164outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{},
158/// This contains a set of Decls which may not be in `outdated`, but are the
159/// root Decls of files which have updated source and thus must be re-analyzed.
160/// If such a Decl is only in this set, the struct type index may be preserved
161/// (only the namespace might change). If such a Decl is also `outdated`, the
162/// struct type index must be recreated.
163outdated_file_root: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
165/// This contains a set of struct types whose corresponding `Cau` may not be in
166/// `outdated`, but are the root types of files which have updated source and
167/// thus must be re-analyzed. If such a type is only in this set, the struct type
168/// index may be preserved (only the namespace might change). If its owned `Cau`
169/// is also outdated, the struct type index must be recreated.
170outdated_file_root: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{},
164171/// This contains a list of AnalUnit whose analysis or codegen failed, but the
165172/// failure was something like running out of disk space, and trying again may
166173/// succeed. On the next update, we will flush this list, marking all members of
......@@ -179,12 +186,9 @@ stage1_flags: packed struct {
179186
180187compile_log_text: std.ArrayListUnmanaged(u8) = .{},
181188
182emit_h: ?*GlobalEmitH,
183
184test_functions: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
189test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .{},
185190
186/// TODO: the key here will be a `Cau.Index`.
187global_assembly: std.AutoArrayHashMapUnmanaged(Decl.Index, []u8) = .{},
191global_assembly: std.AutoArrayHashMapUnmanaged(InternPool.Cau.Index, []u8) = .{},
188192
189193/// Key is the `AnalUnit` *performing* the reference. This representation allows
190194/// incremental updates to quickly delete references caused by a specific `AnalUnit`.
......@@ -196,7 +200,7 @@ all_references: std.ArrayListUnmanaged(Reference) = .{},
196200/// Freelist of indices in `all_references`.
197201free_references: std.ArrayListUnmanaged(u32) = .{},
198202
199panic_messages: [PanicId.len]Decl.OptionalIndex = .{.none} ** PanicId.len,
203panic_messages: [PanicId.len]InternPool.Nav.Index.Optional = .{.none} ** PanicId.len,
200204/// The panic function body.
201205panic_func_index: InternPool.Index = .none,
202206null_stack_trace: InternPool.Index = .none,
......@@ -250,45 +254,25 @@ pub const CImportError = struct {
250254 }
251255};
252256
253/// A `Module` has zero or one of these depending on whether `-femit-h` is enabled.
254pub const GlobalEmitH = struct {
255 /// Where to put the output.
256 loc: Compilation.EmitLoc,
257 /// When emit_h is non-null, each Decl gets one more compile error slot for
258 /// emit-h failing for that Decl. This table is also how we tell if a Decl has
259 /// failed emit-h or succeeded.
260 failed_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, *ErrorMsg) = .{},
261 /// Tracks all decls in order to iterate over them and emit .h code for them.
262 decl_table: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
263 /// Similar to the allocated_decls field of Module, this is where `EmitH` objects
264 /// are allocated. There will be exactly one EmitH object per Decl object, with
265 /// identical indexes.
266 allocated_emit_h: std.SegmentedList(EmitH, 0) = .{},
267
268 pub fn declPtr(global_emit_h: *GlobalEmitH, decl_index: Decl.Index) *EmitH {
269 return global_emit_h.allocated_emit_h.at(@intFromEnum(decl_index));
270 }
271};
272
273257pub const ErrorInt = u32;
274258
275259pub const Exported = union(enum) {
276 /// The Decl being exported. Note this is *not* the Decl performing the export.
277 decl_index: Decl.Index,
260 /// The Nav being exported. Note this is *not* the Nav corresponding to the AnalUnit performing the export.
261 nav: InternPool.Nav.Index,
278262 /// Constant value being exported.
279 value: InternPool.Index,
263 uav: InternPool.Index,
280264
281265 pub fn getValue(exported: Exported, zcu: *Zcu) Value {
282266 return switch (exported) {
283 .decl_index => |decl_index| zcu.declPtr(decl_index).val,
284 .value => |value| Value.fromInterned(value),
267 .nav => |nav| zcu.navValue(nav),
268 .uav => |uav| Value.fromInterned(uav),
285269 };
286270 }
287271
288272 pub fn getAlign(exported: Exported, zcu: *Zcu) Alignment {
289273 return switch (exported) {
290 .decl_index => |decl_index| zcu.declPtr(decl_index).alignment,
291 .value => .none,
274 .nav => |nav| zcu.intern_pool.getNav(nav).status.resolved.alignment,
275 .uav => .none,
292276 };
293277 }
294278};
......@@ -324,302 +308,54 @@ pub const Reference = struct {
324308 src: LazySrcLoc,
325309};
326310
327pub const Decl = struct {
328 /// Equal to `fqn` if already fully qualified.
329 name: InternPool.NullTerminatedString,
330 /// Fully qualified name.
331 fqn: InternPool.NullTerminatedString,
332 /// The most recent Value of the Decl after a successful semantic analysis.
333 /// Populated when `has_tv`.
334 val: Value,
335 /// Populated when `has_tv`.
336 @"linksection": InternPool.OptionalNullTerminatedString,
337 /// Populated when `has_tv`.
338 alignment: Alignment,
339 /// Populated when `has_tv`.
340 @"addrspace": std.builtin.AddressSpace,
341 /// The direct parent namespace of the Decl. In the case of the Decl
342 /// corresponding to a file, this is the namespace of the struct, since
343 /// there is no parent.
344 src_namespace: Namespace.Index,
345
346 /// Index of the ZIR `declaration` instruction from which this `Decl` was created.
347 /// For the root `Decl` of a `File` and legacy anonymous decls, this is `.none`.
348 zir_decl_index: InternPool.TrackedInst.Index.Optional,
349
350 /// Represents the "shallow" analysis status. For example, for decls that are functions,
351 /// the function type is analyzed with this set to `in_progress`, however, the semantic
352 /// analysis of the function body is performed with this value set to `success`. Functions
353 /// have their own analysis status field.
354 analysis: enum {
355 /// This Decl corresponds to an AST Node that has not been referenced yet, and therefore
356 /// because of Zig's lazy declaration analysis, it will remain unanalyzed until referenced.
357 unreferenced,
358 /// Semantic analysis for this Decl is running right now.
359 /// This state detects dependency loops.
360 in_progress,
361 /// The file corresponding to this Decl had a parse error or ZIR error.
362 /// There will be a corresponding ErrorMsg in Zcu.failed_files.
363 file_failure,
364 /// This Decl might be OK but it depends on another one which did not
365 /// successfully complete semantic analysis.
366 dependency_failure,
367 /// Semantic analysis failure.
368 /// There will be a corresponding ErrorMsg in Zcu.failed_analysis.
369 sema_failure,
370 /// There will be a corresponding ErrorMsg in Zcu.failed_analysis.
371 codegen_failure,
372 /// Sematic analysis and constant value codegen of this Decl has
373 /// succeeded. However, the Decl may be outdated due to an in-progress
374 /// update. Note that for a function, this does not mean codegen of the
375 /// function body succeded: that state is indicated by the function's
376 /// `analysis` field.
377 complete,
378 },
379 /// Whether `typed_value`, `align`, `linksection` and `addrspace` are populated.
380 has_tv: bool,
381 /// If `true` it means the `Decl` is the resource owner of the type/value associated
382 /// with it. That means when `Decl` is destroyed, the cleanup code should additionally
383 /// check if the value owns a `Namespace`, and destroy that too.
384 owns_tv: bool,
385 /// Whether the corresponding AST decl has a `pub` keyword.
386 is_pub: bool,
387 /// Whether the corresponding AST decl has a `export` keyword.
388 is_exported: bool,
389 /// What kind of a declaration is this.
390 kind: Kind,
391
392 pub const Kind = enum {
393 @"usingnamespace",
394 @"test",
395 @"comptime",
396 named,
397 anon,
398 };
399
400 pub const Index = InternPool.DeclIndex;
401 pub const OptionalIndex = InternPool.OptionalDeclIndex;
402
403 pub fn zirBodies(decl: Decl, zcu: *Zcu) Zir.Inst.Declaration.Bodies {
404 const zir = decl.getFileScope(zcu).zir;
405 const zir_index = decl.zir_decl_index.unwrap().?.resolve(&zcu.intern_pool);
406 const declaration = zir.instructions.items(.data)[@intFromEnum(zir_index)].declaration;
407 const extra = zir.extraData(Zir.Inst.Declaration, declaration.payload_index);
408 return extra.data.getBodies(@intCast(extra.end), zir);
409 }
410
411 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
412 assert(decl.has_tv);
413 return decl.val.typeOf(zcu);
414 }
415
416 /// Small wrapper for Sema to use over direct access to the `val` field.
417 /// If the value is not populated, instead returns `error.AnalysisFail`.
418 pub fn valueOrFail(decl: Decl) error{AnalysisFail}!Value {
419 if (!decl.has_tv) return error.AnalysisFail;
420 return decl.val;
421 }
422
423 pub fn getOwnedFunction(decl: Decl, zcu: *Zcu) ?InternPool.Key.Func {
424 const i = decl.getOwnedFunctionIndex();
425 if (i == .none) return null;
426 return switch (zcu.intern_pool.indexToKey(i)) {
427 .func => |func| func,
428 else => null,
429 };
430 }
431
432 /// This returns an InternPool.Index even when the value is not a function.
433 pub fn getOwnedFunctionIndex(decl: Decl) InternPool.Index {
434 return if (decl.owns_tv) decl.val.toIntern() else .none;
435 }
436
437 /// If the Decl owns its value and it is an extern function, returns it,
438 /// otherwise null.
439 pub fn getOwnedExternFunc(decl: Decl, zcu: *Zcu) ?InternPool.Key.ExternFunc {
440 return if (decl.owns_tv) decl.val.getExternFunc(zcu) else null;
441 }
442
443 /// If the Decl owns its value and it is a variable, returns it,
444 /// otherwise null.
445 pub fn getOwnedVariable(decl: Decl, zcu: *Zcu) ?InternPool.Key.Variable {
446 return if (decl.owns_tv) decl.val.getVariable(zcu) else null;
447 }
448
449 /// Gets the namespace that this Decl creates by being a struct, union,
450 /// enum, or opaque.
451 pub fn getInnerNamespaceIndex(decl: Decl, zcu: *Zcu) Namespace.OptionalIndex {
452 if (!decl.has_tv) return .none;
453 const ip = &zcu.intern_pool;
454 return switch (decl.val.ip_index) {
455 .empty_struct_type => .none,
456 .none => .none,
457 else => switch (ip.indexToKey(decl.val.toIntern())) {
458 .opaque_type => ip.loadOpaqueType(decl.val.toIntern()).namespace,
459 .struct_type => ip.loadStructType(decl.val.toIntern()).namespace,
460 .union_type => ip.loadUnionType(decl.val.toIntern()).namespace,
461 .enum_type => ip.loadEnumType(decl.val.toIntern()).namespace,
462 else => .none,
463 },
464 };
465 }
466
467 /// Like `getInnerNamespaceIndex`, but only returns it if the Decl is the owner.
468 pub fn getOwnedInnerNamespaceIndex(decl: Decl, zcu: *Zcu) Namespace.OptionalIndex {
469 if (!decl.owns_tv) return .none;
470 return decl.getInnerNamespaceIndex(zcu);
471 }
472
473 /// Same as `getOwnedInnerNamespaceIndex` but additionally obtains the pointer.
474 pub fn getOwnedInnerNamespace(decl: Decl, zcu: *Zcu) ?*Namespace {
475 return zcu.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(zcu));
476 }
477
478 /// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.
479 pub fn getInnerNamespace(decl: Decl, zcu: *Zcu) ?*Namespace {
480 return zcu.namespacePtrUnwrap(decl.getInnerNamespaceIndex(zcu));
481 }
482
483 pub fn getFileScope(decl: Decl, zcu: *Zcu) *File {
484 return zcu.fileByIndex(getFileScopeIndex(decl, zcu));
485 }
486
487 pub fn getFileScopeIndex(decl: Decl, zcu: *Zcu) File.Index {
488 return zcu.namespacePtr(decl.src_namespace).file_scope;
489 }
490
491 pub fn getExternDecl(decl: Decl, zcu: *Zcu) OptionalIndex {
492 assert(decl.has_tv);
493 return switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {
494 .variable => |variable| if (variable.is_extern) variable.decl.toOptional() else .none,
495 .extern_func => |extern_func| extern_func.decl.toOptional(),
496 else => .none,
497 };
498 }
499
500 pub fn isExtern(decl: Decl, zcu: *Zcu) bool {
501 return decl.getExternDecl(zcu) != .none;
502 }
503
504 pub fn getAlignment(decl: Decl, pt: Zcu.PerThread) Alignment {
505 assert(decl.has_tv);
506 if (decl.alignment != .none) return decl.alignment;
507 return decl.typeOf(pt.zcu).abiAlignment(pt);
508 }
509
510 pub fn declPtrType(decl: Decl, pt: Zcu.PerThread) !Type {
511 assert(decl.has_tv);
512 const decl_ty = decl.typeOf(pt.zcu);
513 return pt.ptrType(.{
514 .child = decl_ty.toIntern(),
515 .flags = .{
516 .alignment = if (decl.alignment == decl_ty.abiAlignment(pt))
517 .none
518 else
519 decl.alignment,
520 .address_space = decl.@"addrspace",
521 .is_const = decl.getOwnedVariable(pt.zcu) == null,
522 },
523 });
524 }
525
526 /// Returns the source location of this `Decl`.
527 /// Asserts that this `Decl` corresponds to what will in future be a `Nav` (Named
528 /// Addressable Value): a source-level declaration or generic instantiation.
529 pub fn navSrcLoc(decl: Decl, zcu: *Zcu) LazySrcLoc {
530 return .{
531 .base_node_inst = decl.zir_decl_index.unwrap() orelse inst: {
532 // generic instantiation
533 assert(decl.has_tv);
534 assert(decl.owns_tv);
535 const owner = zcu.funcInfo(decl.val.toIntern()).generic_owner;
536 const generic_owner_decl = zcu.declPtr(zcu.funcInfo(owner).owner_decl);
537 break :inst generic_owner_decl.zir_decl_index.unwrap().?;
538 },
539 .offset = LazySrcLoc.Offset.nodeOffset(0),
540 };
541 }
542
543 pub fn navSrcLine(decl: Decl, zcu: *Zcu) u32 {
544 const ip = &zcu.intern_pool;
545 const tracked = decl.zir_decl_index.unwrap() orelse inst: {
546 // generic instantiation
547 assert(decl.has_tv);
548 assert(decl.owns_tv);
549 const generic_owner_func = switch (ip.indexToKey(decl.val.toIntern())) {
550 .func => |func| func.generic_owner,
551 else => return 0, // TODO: this is probably a `variable` or something; figure this out when we finish sorting out `Decl`.
552 };
553 const generic_owner_decl = zcu.declPtr(zcu.funcInfo(generic_owner_func).owner_decl);
554 break :inst generic_owner_decl.zir_decl_index.unwrap().?;
555 };
556 const info = tracked.resolveFull(ip);
557 const file = zcu.fileByIndex(info.file);
558 assert(file.zir_loaded);
559 const zir = file.zir;
560 const inst = zir.instructions.get(@intFromEnum(info.inst));
561 assert(inst.tag == .declaration);
562 return zir.extraData(Zir.Inst.Declaration, inst.data.declaration.payload_index).data.src_line;
563 }
564
565 pub fn typeSrcLine(decl: Decl, zcu: *Zcu) u32 {
566 assert(decl.has_tv);
567 assert(decl.owns_tv);
568 return decl.val.toType().typeDeclSrcLine(zcu).?;
569 }
570};
571
572/// This state is attached to every Decl when Module emit_h is non-null.
573pub const EmitH = struct {
574 fwd_decl: std.ArrayListUnmanaged(u8) = .{},
575};
576
577pub const DeclAdapter = struct {
578 zcu: *Zcu,
579
580 pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {
581 _ = self;
582 return std.hash.uint32(@intFromEnum(s));
583 }
584
585 pub fn eql(self: @This(), a: InternPool.NullTerminatedString, b_decl_index: Decl.Index, b_index: usize) bool {
586 _ = b_index;
587 return a == self.zcu.declPtr(b_decl_index).name;
588 }
589};
590
591311/// The container that structs, enums, unions, and opaques have.
592312pub const Namespace = struct {
593313 parent: OptionalIndex,
594314 file_scope: File.Index,
595315 /// Will be a struct, enum, union, or opaque.
596 decl_index: Decl.Index,
597 /// Direct children of the namespace.
598 /// Declaration order is preserved via entry order.
599 /// These are only declarations named directly by the AST; anonymous
600 /// declarations are not stored here.
601 decls: std.ArrayHashMapUnmanaged(Decl.Index, void, DeclContext, true) = .{},
602 /// Key is usingnamespace Decl itself. To find the namespace being included,
603 /// the Decl Value has to be resolved as a Type which has a Namespace.
604 /// Value is whether the usingnamespace decl is marked `pub`.
605 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},
316 owner_type: InternPool.Index,
317 /// Members of the namespace which are marked `pub`.
318 pub_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .{},
319 /// Members of the namespace which are *not* marked `pub`.
320 priv_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .{},
321 /// All `usingnamespace` declarations in this namespace which are marked `pub`.
322 pub_usingnamespace: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{},
323 /// All `usingnamespace` declarations in this namespace which are *not* marked `pub`.
324 priv_usingnamespace: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{},
325 /// All `comptime` and `test` declarations in this namespace. We store these purely so that
326 /// incremental compilation can re-use the existing `Cau`s when a namespace changes.
327 other_decls: std.ArrayListUnmanaged(InternPool.Cau.Index) = .{},
606328
607329 pub const Index = InternPool.NamespaceIndex;
608330 pub const OptionalIndex = InternPool.OptionalNamespaceIndex;
609331
610 const DeclContext = struct {
332 const NavNameContext = struct {
611333 zcu: *Zcu,
612334
613 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
614 const decl = ctx.zcu.declPtr(decl_index);
615 return std.hash.uint32(@intFromEnum(decl.name));
335 pub fn hash(ctx: NavNameContext, nav: InternPool.Nav.Index) u32 {
336 const name = ctx.zcu.intern_pool.getNav(nav).name;
337 return std.hash.uint32(@intFromEnum(name));
616338 }
617339
618 pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
340 pub fn eql(ctx: NavNameContext, a_nav: InternPool.Nav.Index, b_nav: InternPool.Nav.Index, b_index: usize) bool {
619341 _ = b_index;
620 const a_decl = ctx.zcu.declPtr(a_decl_index);
621 const b_decl = ctx.zcu.declPtr(b_decl_index);
622 return a_decl.name == b_decl.name;
342 const a_name = ctx.zcu.intern_pool.getNav(a_nav).name;
343 const b_name = ctx.zcu.intern_pool.getNav(b_nav).name;
344 return a_name == b_name;
345 }
346 };
347
348 pub const NameAdapter = struct {
349 zcu: *Zcu,
350
351 pub fn hash(ctx: NameAdapter, s: InternPool.NullTerminatedString) u32 {
352 _ = ctx;
353 return std.hash.uint32(@intFromEnum(s));
354 }
355
356 pub fn eql(ctx: NameAdapter, a: InternPool.NullTerminatedString, b_nav: InternPool.Nav.Index, b_index: usize) bool {
357 _ = b_index;
358 return a == ctx.zcu.intern_pool.getNav(b_nav).name;
623359 }
624360 };
625361
......@@ -631,25 +367,6 @@ pub const Namespace = struct {
631367 return ip.filePtr(ns.file_scope);
632368 }
633369
634 // This renders e.g. "std.fs.Dir.OpenOptions"
635 pub fn renderFullyQualifiedName(
636 ns: Namespace,
637 ip: *InternPool,
638 name: InternPool.NullTerminatedString,
639 writer: anytype,
640 ) @TypeOf(writer).Error!void {
641 if (ns.parent.unwrap()) |parent| {
642 try ip.namespacePtr(parent).renderFullyQualifiedName(
643 ip,
644 ip.declPtr(ns.decl_index).name,
645 writer,
646 );
647 } else {
648 try ns.fileScopeIp(ip).renderFullyQualifiedName(writer);
649 }
650 if (name != .empty) try writer.print(".{}", .{name.fmt(ip)});
651 }
652
653370 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
654371 pub fn renderFullyQualifiedDebugName(
655372 ns: Namespace,
......@@ -678,44 +395,9 @@ pub const Namespace = struct {
678395 tid: Zcu.PerThread.Id,
679396 name: InternPool.NullTerminatedString,
680397 ) !InternPool.NullTerminatedString {
681 const strings = ip.getLocal(tid).getMutableStrings(gpa);
682 // Protects reads of interned strings from being reallocated during the call to
683 // renderFullyQualifiedName.
684 const slice = try strings.addManyAsSlice(count: {
685 var count: usize = name.length(ip) + 1;
686 var cur_ns = &ns;
687 while (true) {
688 const decl = ip.declPtr(cur_ns.decl_index);
689 cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse {
690 count += ns.fileScopeIp(ip).fullyQualifiedNameLen();
691 break :count count;
692 });
693 count += decl.name.length(ip) + 1;
694 }
695 });
696 var fbs = std.io.fixedBufferStream(slice[0]);
697 ns.renderFullyQualifiedName(ip, name, fbs.writer()) catch unreachable;
698 assert(fbs.pos == slice[0].len);
699
700 // Sanitize the name for nvptx which is more restrictive.
701 // TODO This should be handled by the backend, not the frontend. Have a
702 // look at how the C backend does it for inspiration.
703 // FIXME This has bitrotted and is no longer able to be implemented here.
704 //const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
705 //if (cpu_arch.isNvptx()) {
706 // for (slice[0]) |*byte| switch (byte.*) {
707 // '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
708 // else => {},
709 // };
710 //}
711
712 return ip.getOrPutTrailingString(gpa, tid, @intCast(slice[0].len), .no_embedded_nulls);
713 }
714
715 pub fn getType(ns: Namespace, zcu: *Zcu) Type {
716 const decl = zcu.declPtr(ns.decl_index);
717 assert(decl.has_tv);
718 return decl.val.toType();
398 const ns_name = Type.fromInterned(ns.owner_type).containerTypeName(ip);
399 if (name == .empty) return ns_name;
400 return ip.getOrPutStringFmt(gpa, tid, "{}.{}", .{ ns_name.fmt(ip), name.fmt(ip) }, .no_embedded_nulls);
719401 }
720402};
721403
......@@ -2428,16 +2110,13 @@ pub fn deinit(zcu: *Zcu) void {
24282110 for (zcu.failed_analysis.values()) |value| {
24292111 value.destroy(gpa);
24302112 }
2431 zcu.failed_analysis.deinit(gpa);
2432
2433 if (zcu.emit_h) |emit_h| {
2434 for (emit_h.failed_decls.values()) |value| {
2435 value.destroy(gpa);
2436 }
2437 emit_h.failed_decls.deinit(gpa);
2438 emit_h.decl_table.deinit(gpa);
2439 emit_h.allocated_emit_h.deinit(gpa);
2113 for (zcu.failed_codegen.values()) |value| {
2114 value.destroy(gpa);
24402115 }
2116 zcu.analysis_in_progress.deinit(gpa);
2117 zcu.failed_analysis.deinit(gpa);
2118 zcu.transitive_failed_analysis.deinit(gpa);
2119 zcu.failed_codegen.deinit(gpa);
24412120
24422121 for (zcu.failed_files.values()) |value| {
24432122 if (value) |msg| msg.destroy(gpa);
......@@ -2486,26 +2165,14 @@ pub fn deinit(zcu: *Zcu) void {
24862165 zcu.intern_pool.deinit(gpa);
24872166}
24882167
2489pub fn declPtr(mod: *Zcu, index: Decl.Index) *Decl {
2490 return mod.intern_pool.declPtr(index);
2491}
2492
2493pub fn namespacePtr(mod: *Zcu, index: Namespace.Index) *Namespace {
2494 return mod.intern_pool.namespacePtr(index);
2168pub fn namespacePtr(zcu: *Zcu, index: Namespace.Index) *Namespace {
2169 return zcu.intern_pool.namespacePtr(index);
24952170}
24962171
24972172pub fn namespacePtrUnwrap(mod: *Zcu, index: Namespace.OptionalIndex) ?*Namespace {
24982173 return mod.namespacePtr(index.unwrap() orelse return null);
24992174}
25002175
2501/// Returns true if and only if the Decl is the top level struct associated with a File.
2502pub fn declIsRoot(mod: *Zcu, decl_index: Decl.Index) bool {
2503 const decl = mod.declPtr(decl_index);
2504 const namespace = mod.namespacePtr(decl.src_namespace);
2505 if (namespace.parent != .none) return false;
2506 return decl_index == namespace.decl_index;
2507}
2508
25092176// TODO https://github.com/ziglang/zig/issues/8643
25102177pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;
25112178pub const HackDataLayout = extern struct {
......@@ -2642,8 +2309,12 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
26422309 // If this is a Decl, we must recursively mark dependencies on its tyval
26432310 // as no longer PO.
26442311 switch (depender.unwrap()) {
2645 .decl => |decl_index| try zcu.markPoDependeeUpToDate(.{ .decl_val = decl_index }),
2646 .func => |func_index| try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index }),
2312 .cau => |cau| switch (zcu.intern_pool.getCau(cau).owner.unwrap()) {
2313 .nav => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_val = nav }),
2314 .type => |ty| try zcu.markPoDependeeUpToDate(.{ .interned = ty }),
2315 .none => {},
2316 },
2317 .func => |func| try zcu.markPoDependeeUpToDate(.{ .interned = func }),
26472318 }
26482319 }
26492320}
......@@ -2651,9 +2322,13 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
26512322/// Given a AnalUnit which is newly outdated or PO, mark all AnalUnits which may
26522323/// in turn be PO, due to a dependency on the original AnalUnit's tyval or IES.
26532324fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUnit) !void {
2654 var it = zcu.intern_pool.dependencyIterator(switch (maybe_outdated.unwrap()) {
2655 .decl => |decl_index| .{ .decl_val = decl_index }, // TODO: also `decl_ref` deps when introduced
2656 .func => |func_index| .{ .func_ies = func_index },
2325 const ip = &zcu.intern_pool;
2326 var it = ip.dependencyIterator(switch (maybe_outdated.unwrap()) {
2327 .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
2328 .nav => |nav| .{ .nav_val = nav }, // TODO: also `nav_ref` deps when introduced
2329 .none, .type => return, // analysis of this `Cau` can't outdate any dependencies
2330 },
2331 .func => |func_index| .{ .interned = func_index }, // IES
26572332 });
26582333
26592334 while (it.next()) |po| {
......@@ -2680,6 +2355,8 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
26802355pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
26812356 if (!zcu.comp.incremental) return null;
26822357
2358 if (true) @panic("TODO: findOutdatedToAnalyze");
2359
26832360 if (zcu.outdated.count() == 0 and zcu.potentially_outdated.count() == 0) {
26842361 log.debug("findOutdatedToAnalyze: no outdated depender", .{});
26852362 return null;
......@@ -2742,6 +2419,8 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
27422419 zcu.potentially_outdated.count(),
27432420 });
27442421
2422 const Decl = {};
2423
27452424 var chosen_decl_idx: ?Decl.Index = null;
27462425 var chosen_decl_dependers: u32 = undefined;
27472426
......@@ -2939,65 +2618,20 @@ pub fn mapOldZirToNew(
29392618/// analyzed, and for ensuring it can exist at runtime (see
29402619/// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body
29412620/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.
2942pub fn ensureFuncBodyAnalysisQueued(mod: *Zcu, func_index: InternPool.Index) !void {
2943 const ip = &mod.intern_pool;
2944 const func = mod.funcInfo(func_index);
2945 const decl_index = func.owner_decl;
2946 const decl = mod.declPtr(decl_index);
2947
2948 switch (decl.analysis) {
2949 .unreferenced => unreachable,
2950 .in_progress => unreachable,
2951
2952 .file_failure,
2953 .sema_failure,
2954 .codegen_failure,
2955 .dependency_failure,
2956 // Analysis of the function Decl itself failed, but we've already
2957 // emitted an error for that. The callee doesn't need the function to be
2958 // analyzed right now, so its analysis can safely continue.
2959 => return,
2960
2961 .complete => {},
2962 }
2963
2964 assert(decl.has_tv);
2965
2966 const func_as_depender = AnalUnit.wrap(.{ .func = func_index });
2967 const is_outdated = mod.outdated.contains(func_as_depender) or
2968 mod.potentially_outdated.contains(func_as_depender);
2621pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void {
2622 const ip = &zcu.intern_pool;
2623 const func = zcu.funcInfo(func_index);
29692624
29702625 switch (func.analysisUnordered(ip).state) {
2971 .none => {},
2972 .queued => return,
2973 // As above, we don't need to forward errors here.
2974 .sema_failure,
2975 .dependency_failure,
2976 .codegen_failure,
2977 .success,
2978 => if (!is_outdated) return,
2979 .in_progress => return,
2980 .inline_only => unreachable, // don't queue work for this
2981 }
2982
2983 // Decl itself is safely analyzed, and body analysis is not yet queued
2984
2985 try mod.comp.queueJob(.{ .analyze_func = func_index });
2986 if (mod.emit_h != null) {
2987 // TODO: we ideally only want to do this if the function's type changed
2988 // since the last update
2989 try mod.comp.queueJob(.{ .emit_h_decl = decl_index });
2626 .unreferenced => {}, // We're the first reference!
2627 .queued => return, // Analysis is already queued.
2628 .analyzed => return, // Analysis is complete; if it's out-of-date, it'll be re-analyzed later this update.
29902629 }
2630
2631 try zcu.comp.queueJob(.{ .analyze_func = func_index });
29912632 func.setAnalysisState(ip, .queued);
29922633}
29932634
2994pub const SemaDeclResult = packed struct {
2995 /// Whether the value of a `decl_val` of this Decl changed.
2996 invalidate_decl_val: bool,
2997 /// Whether the type of a `decl_ref` of this Decl changed.
2998 invalidate_decl_ref: bool,
2999};
3000
30012635pub const ImportFileResult = struct {
30022636 file: *File,
30032637 file_index: File.Index,
......@@ -3171,14 +2805,15 @@ pub fn handleUpdateExports(
31712805 };
31722806}
31732807
3174pub fn addGlobalAssembly(mod: *Zcu, decl_index: Decl.Index, source: []const u8) !void {
3175 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);
2808pub fn addGlobalAssembly(zcu: *Zcu, cau: InternPool.Cau.Index, source: []const u8) !void {
2809 const gpa = zcu.gpa;
2810 const gop = try zcu.global_assembly.getOrPut(gpa, cau);
31762811 if (gop.found_existing) {
3177 const new_value = try std.fmt.allocPrint(mod.gpa, "{s}\n{s}", .{ gop.value_ptr.*, source });
3178 mod.gpa.free(gop.value_ptr.*);
2812 const new_value = try std.fmt.allocPrint(gpa, "{s}\n{s}", .{ gop.value_ptr.*, source });
2813 gpa.free(gop.value_ptr.*);
31792814 gop.value_ptr.* = new_value;
31802815 } else {
3181 gop.value_ptr.* = try mod.gpa.dupe(u8, source);
2816 gop.value_ptr.* = try gpa.dupe(u8, source);
31822817 }
31832818}
31842819
......@@ -3315,10 +2950,6 @@ pub fn atomicPtrAlignment(
33152950 return error.BadType;
33162951}
33172952
3318pub fn declFileScope(mod: *Zcu, decl_index: Decl.Index) *File {
3319 return mod.declPtr(decl_index).getFileScope(mod);
3320}
3321
33222953/// Returns null in the following cases:
33232954/// * `@TypeOf(.{})`
33242955/// * A struct which has no fields (`struct {}`).
......@@ -3352,16 +2983,8 @@ pub fn typeToFunc(mod: *Zcu, ty: Type) ?InternPool.Key.FuncType {
33522983 return mod.intern_pool.indexToFuncType(ty.toIntern());
33532984}
33542985
3355pub fn funcOwnerDeclPtr(mod: *Zcu, func_index: InternPool.Index) *Decl {
3356 return mod.declPtr(mod.funcOwnerDeclIndex(func_index));
3357}
3358
3359pub fn funcOwnerDeclIndex(mod: *Zcu, func_index: InternPool.Index) Decl.Index {
3360 return mod.funcInfo(func_index).owner_decl;
3361}
3362
3363pub fn iesFuncIndex(mod: *const Zcu, ies_index: InternPool.Index) InternPool.Index {
3364 return mod.intern_pool.iesFuncIndex(ies_index);
2986pub fn iesFuncIndex(zcu: *const Zcu, ies_index: InternPool.Index) InternPool.Index {
2987 return zcu.intern_pool.iesFuncIndex(ies_index);
33652988}
33662989
33672990pub fn funcInfo(mod: *Zcu, func_index: InternPool.Index) InternPool.Key.Func {
......@@ -3372,44 +2995,6 @@ pub fn toEnum(mod: *Zcu, comptime E: type, val: Value) E {
33722995 return mod.intern_pool.toEnum(E, val.toIntern());
33732996}
33742997
3375pub fn isAnytypeParam(mod: *Zcu, func: InternPool.Index, index: u32) bool {
3376 const file = mod.declPtr(func.owner_decl).getFileScope(mod);
3377
3378 const tags = file.zir.instructions.items(.tag);
3379
3380 const param_body = file.zir.getParamBody(func.zir_body_inst);
3381 const param = param_body[index];
3382
3383 return switch (tags[param]) {
3384 .param, .param_comptime => false,
3385 .param_anytype, .param_anytype_comptime => true,
3386 else => unreachable,
3387 };
3388}
3389
3390pub fn getParamName(mod: *Zcu, func_index: InternPool.Index, index: u32) [:0]const u8 {
3391 const func = mod.funcInfo(func_index);
3392 const file = mod.declPtr(func.owner_decl).getFileScope(mod);
3393
3394 const tags = file.zir.instructions.items(.tag);
3395 const data = file.zir.instructions.items(.data);
3396
3397 const param_body = file.zir.getParamBody(func.zir_body_inst.resolve(&mod.intern_pool));
3398 const param = param_body[index];
3399
3400 return switch (tags[@intFromEnum(param)]) {
3401 .param, .param_comptime => blk: {
3402 const extra = file.zir.extraData(Zir.Inst.Param, data[@intFromEnum(param)].pl_tok.payload_index);
3403 break :blk file.zir.nullTerminatedString(extra.data.name);
3404 },
3405 .param_anytype, .param_anytype_comptime => blk: {
3406 const param_data = data[@intFromEnum(param)].str_tok;
3407 break :blk param_data.get(file.zir);
3408 },
3409 else => unreachable,
3410 };
3411}
3412
34132998pub const UnionLayout = struct {
34142999 abi_size: u64,
34153000 abi_align: Alignment,
......@@ -3468,19 +3053,20 @@ pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File {
34683053 return zcu.intern_pool.filePtr(file_index);
34693054}
34703055
3471/// Returns the `Decl` of the struct that represents this `File`.
3472pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex {
3056/// Returns the struct that represents this `File`.
3057/// If the struct has not been created, returns `.none`.
3058pub fn fileRootType(zcu: *const Zcu, file_index: File.Index) InternPool.Index {
34733059 const ip = &zcu.intern_pool;
34743060 const file_index_unwrapped = file_index.unwrap(ip);
34753061 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3476 return files.view().items(.root_decl)[file_index_unwrapped.index];
3062 return files.view().items(.root_type)[file_index_unwrapped.index];
34773063}
34783064
3479pub fn setFileRootDecl(zcu: *Zcu, file_index: File.Index, root_decl: Decl.OptionalIndex) void {
3065pub fn setFileRootType(zcu: *Zcu, file_index: File.Index, root_type: InternPool.Index) void {
34803066 const ip = &zcu.intern_pool;
34813067 const file_index_unwrapped = file_index.unwrap(ip);
34823068 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3483 files.view().items(.root_decl)[file_index_unwrapped.index] = root_decl;
3069 files.view().items(.root_type)[file_index_unwrapped.index] = root_type;
34843070}
34853071
34863072pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {
......@@ -3489,3 +3075,39 @@ pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {
34893075 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
34903076 return files.view().items(.bin_digest)[file_index_unwrapped.index];
34913077}
3078
3079pub fn navSrcLoc(zcu: *const Zcu, nav_index: InternPool.Nav.Index) LazySrcLoc {
3080 const ip = &zcu.intern_pool;
3081 return .{
3082 .base_node_inst = ip.getNav(nav_index).srcInst(ip),
3083 .offset = LazySrcLoc.Offset.nodeOffset(0),
3084 };
3085}
3086
3087pub fn navSrcLine(zcu: *Zcu, nav_index: InternPool.Nav.Index) u32 {
3088 const ip = &zcu.intern_pool;
3089 const inst_info = ip.getNav(nav_index).srcInst(ip).resolveFull(ip);
3090 const zir = zcu.fileByIndex(inst_info.file).zir;
3091 const inst = zir.instructions.get(@intFromEnum(inst_info.inst));
3092 assert(inst.tag == .declaration);
3093 return zir.extraData(Zir.Inst.Declaration, inst.data.declaration.payload_index).data.src_line;
3094}
3095
3096pub fn navValue(zcu: *const Zcu, nav_index: InternPool.Nav.Index) Value {
3097 return Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.resolved.val);
3098}
3099
3100pub fn navFileScopeIndex(zcu: *Zcu, nav: InternPool.Nav.Index) File.Index {
3101 const ip = &zcu.intern_pool;
3102 return ip.getNav(nav).srcInst(ip).resolveFull(ip).file;
3103}
3104
3105pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File {
3106 return zcu.fileByIndex(zcu.navFileScopeIndex(nav));
3107}
3108
3109pub fn cauFileScope(zcu: *Zcu, cau: InternPool.Cau.Index) *File {
3110 const ip = &zcu.intern_pool;
3111 const file_index = ip.getCau(cau).zir_index.resolveFull(ip).file;
3112 return zcu.fileByIndex(file_index);
3113}
src/Zcu/PerThread.zig+835-843
......@@ -6,26 +6,6 @@ tid: Id,
66pub const IdBacking = u7;
77pub const Id = if (InternPool.single_threaded) enum { main } else enum(IdBacking) { main, _ };
88
9pub fn destroyDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
10 const zcu = pt.zcu;
11 const gpa = zcu.gpa;
12
13 {
14 _ = zcu.test_functions.swapRemove(decl_index);
15 if (zcu.global_assembly.fetchSwapRemove(decl_index)) |kv| {
16 gpa.free(kv.value);
17 }
18 }
19
20 pt.zcu.intern_pool.destroyDecl(pt.tid, decl_index);
21
22 if (zcu.emit_h) |zcu_emit_h| {
23 const decl_emit_h = zcu_emit_h.declPtr(decl_index);
24 decl_emit_h.fwd_decl.deinit(gpa);
25 decl_emit_h.* = undefined;
26 }
27}
28
299fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
3010 const zcu = pt.zcu;
3111 const gpa = zcu.gpa;
......@@ -40,9 +20,6 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
4020 file.unload(gpa);
4121 }
4222 file.references.deinit(gpa);
43 if (zcu.fileRootDecl(file_index).unwrap()) |root_decl| {
44 pt.zcu.intern_pool.destroyDecl(pt.tid, root_decl);
45 }
4623 if (file.prev_zir) |prev_zir| {
4724 prev_zir.deinit(gpa);
4825 gpa.destroy(prev_zir);
......@@ -62,7 +39,7 @@ pub fn astGenFile(
6239 pt: Zcu.PerThread,
6340 file: *Zcu.File,
6441 path_digest: Cache.BinDigest,
65 opt_root_decl: Zcu.Decl.OptionalIndex,
42 old_root_type: InternPool.Index,
6643) !void {
6744 dev.check(.ast_gen);
6845 assert(!file.mod.isBuiltin());
......@@ -323,13 +300,13 @@ pub fn astGenFile(
323300 return error.AnalysisFail;
324301 }
325302
326 if (opt_root_decl.unwrap()) |root_decl| {
303 if (old_root_type != .none) {
327304 // The root of this file must be re-analyzed, since the file has changed.
328305 comp.mutex.lock();
329306 defer comp.mutex.unlock();
330307
331 log.debug("outdated root Decl: {}", .{root_decl});
332 try zcu.outdated_file_root.put(gpa, root_decl, {});
308 log.debug("outdated file root type: {}", .{old_root_type});
309 try zcu.outdated_file_root.put(gpa, old_root_type, {});
333310 }
334311}
335312
......@@ -491,137 +468,171 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
491468 }
492469}
493470
494/// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl.
471/// Ensures that `zcu.fileRootType` on this `file_index` gives an up-to-date answer.
472/// Returns `error.AnalysisFail` if the file has an error.
495473pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
496 if (pt.zcu.fileRootDecl(file_index).unwrap()) |existing_root| {
497 return pt.ensureDeclAnalyzed(existing_root);
474 const file_root_type = pt.zcu.fileRootType(file_index);
475 if (file_root_type != .none) {
476 const file_root_type_cau = pt.zcu.intern_pool.loadStructType(file_root_type).cau.unwrap().?;
477 return pt.ensureCauAnalyzed(file_root_type_cau);
498478 } else {
499479 return pt.semaFile(file_index);
500480 }
501481}
502482
503/// This ensures that the Decl will have an up-to-date Type and Value populated.
504/// However the resolution status of the Type may not be fully resolved.
505/// For example an inferred error set is not resolved until after `analyzeFnBody`.
506/// is called.
507pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.SemaError!void {
508 dev.check(.sema);
509
483/// This ensures that the state of the `Cau`, and of its corresponding `Nav` or type,
484/// is fully up-to-date. Note that the type of the `Nav` may not be fully resolved.
485/// Returns `error.AnalysisFail` if the `Cau` has an error.
486pub fn ensureCauAnalyzed(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) Zcu.SemaError!void {
510487 const tracy = trace(@src());
511488 defer tracy.end();
512489
513 const mod = pt.zcu;
514 const ip = &mod.intern_pool;
515 const decl = mod.declPtr(decl_index);
490 const zcu = pt.zcu;
491 const gpa = zcu.gpa;
492 const ip = &zcu.intern_pool;
516493
517 log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{
518 @intFromEnum(decl_index),
519 decl.name.fmt(ip),
520 });
494 const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index });
495 const cau = ip.getCau(cau_index);
496 const inst_info = cau.zir_index.resolveFull(ip);
497
498 log.debug("ensureCauAnalyzed {d}", .{@intFromEnum(cau_index)});
499
500 assert(!zcu.analysis_in_progress.contains(anal_unit));
521501
522 // Determine whether or not this Decl is outdated, i.e. requires re-analysis
523 // even if `complete`. If a Decl is PO, we pessismistically assume that it
524 // *does* require re-analysis, to ensure that the Decl is definitely
502 // Determine whether or not this Cau is outdated, i.e. requires re-analysis
503 // even if `complete`. If a Cau is PO, we pessismistically assume that it
504 // *does* require re-analysis, to ensure that the Cau is definitely
525505 // up-to-date when this function returns.
526506
527507 // If analysis occurs in a poor order, this could result in over-analysis.
528508 // We do our best to avoid this by the other dependency logic in this file
529 // which tries to limit re-analysis to Decls whose previously listed
509 // which tries to limit re-analysis to Caus whose previously listed
530510 // dependencies are all up-to-date.
531511
532 const decl_as_depender = InternPool.AnalUnit.wrap(.{ .decl = decl_index });
533 const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or
534 mod.potentially_outdated.swapRemove(decl_as_depender);
512 const cau_outdated = zcu.outdated.swapRemove(anal_unit) or
513 zcu.potentially_outdated.swapRemove(anal_unit);
514
515 if (cau_outdated) {
516 _ = zcu.outdated_ready.swapRemove(anal_unit);
517 }
518
519 // TODO: this only works if namespace lookups in Sema trigger `ensureCauAnalyzed`, because
520 // `outdated_file_root` information is not "viral", so we need that a namespace lookup first
521 // handles the case where the file root is not an outdated *type* but does have an outdated
522 // *namespace*. A more logically simple alternative may be for a file's root struct to register
523 // a dependency on the file's entire source code (hash). Alternatively, we could make sure that
524 // these are always handled first in an update. Actually, that's probably the best option.
525 // For my own benefit, here's how a namespace update for a normal (non-file-root) type works:
526 // `const S = struct { ... };`
527 // We are adding or removing a declaration within this `struct`.
528 // * `S` registers a dependency on `.{ .src_hash = (declaration of S) }`
529 // * Any change to the `struct` body -- including changing a declaration -- invalidates this
530 // * `S` is re-analyzed, but notes:
531 // * there is an existing struct instance (at this `TrackedInst` with these captures)
532 // * the struct's `Cau` is up-to-date (because nothing about the fields changed)
533 // * so, it uses the same `struct`
534 // * but this doesn't stop it from updating the namespace!
535 // * we basically do `scanDecls`, updating the namespace as needed
536 // * TODO: optimize this to make sure we only do it once a generation i guess?
537 // * so everyone lived happily ever after
538 const file_root_outdated = switch (cau.owner.unwrap()) {
539 .type => |ty| zcu.outdated_file_root.swapRemove(ty),
540 .nav, .none => false,
541 };
535542
536 if (decl_was_outdated) {
537 _ = mod.outdated_ready.swapRemove(decl_as_depender);
543 if (zcu.fileByIndex(inst_info.file).status != .success_zir) {
544 return error.AnalysisFail;
538545 }
539546
540 const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated;
541
542 switch (decl.analysis) {
543 .in_progress => unreachable,
544
545 .file_failure => return error.AnalysisFail,
546
547 .sema_failure,
548 .dependency_failure,
549 .codegen_failure,
550 => if (!was_outdated) return error.AnalysisFail,
551
552 .complete => if (!was_outdated) return,
553
554 .unreferenced => {},
547 if (!cau_outdated and !file_root_outdated) {
548 // We can trust the current information about this `Cau`.
549 if (zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit)) {
550 return error.AnalysisFail;
551 }
552 // If it wasn't failed and wasn't marked outdated, then either...
553 // * it is a type and is up-to-date, or
554 // * it is a `comptime` decl and is up-to-date, or
555 // * it is another decl and is EITHER up-to-date OR never-referenced (so unresolved)
556 // We just need to check for that last case.
557 switch (cau.owner.unwrap()) {
558 .type, .none => return,
559 .nav => |nav| if (ip.getNav(nav).status == .resolved) return,
560 }
555561 }
556562
557 if (was_outdated) {
558 dev.check(.incremental);
559 // The exports this Decl performs will be re-discovered, so we remove them here
563 // `cau_outdated` can be true in the initial update for `comptime` declarations,
564 // so this isn't a `dev.check`.
565 if (cau_outdated and dev.env.supports(.incremental)) {
566 // The exports this `Cau` performs will be re-discovered, so we remove them here
560567 // prior to re-analysis.
561 mod.deleteUnitExports(decl_as_depender);
562 mod.deleteUnitReferences(decl_as_depender);
568 zcu.deleteUnitExports(anal_unit);
569 zcu.deleteUnitReferences(anal_unit);
563570 }
564571
565 const sema_result: Zcu.SemaDeclResult = blk: {
566 if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) {
567 // Anonymous decl. We don't semantically analyze these.
568 break :blk .{
569 .invalidate_decl_val = false,
570 .invalidate_decl_ref = false,
571 };
572 }
573
574 if (mod.declIsRoot(decl_index)) {
575 const changed = try pt.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated);
576 break :blk .{
572 const sema_result: SemaCauResult = res: {
573 if (inst_info.inst == .main_struct_inst) {
574 const changed = try pt.semaFileUpdate(inst_info.file, cau_outdated);
575 break :res .{
577576 .invalidate_decl_val = changed,
578577 .invalidate_decl_ref = changed,
579578 };
580579 }
581580
582 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
581 const decl_prog_node = zcu.sema_prog_node.start(switch (cau.owner.unwrap()) {
582 .nav => |nav| ip.getNav(nav).fqn.toSlice(ip),
583 .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
584 .none => "comptime",
585 }, 0);
583586 defer decl_prog_node.end();
584587
585 break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
588 break :res pt.semaCau(cau_index) catch |err| switch (err) {
586589 error.AnalysisFail => {
587 if (decl.analysis == .in_progress) {
588 // If this decl caused the compile error, the analysis field would
589 // be changed to indicate it was this Decl's fault. Because this
590 // did not happen, we infer here that it was a dependency failure.
591 decl.analysis = .dependency_failure;
590 if (!zcu.failed_analysis.contains(anal_unit)) {
591 // If this `Cau` caused the error, it would have an entry in `failed_analysis`.
592 // Since it does not, this must be a transitive failure.
593 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
592594 }
593595 return error.AnalysisFail;
594596 },
595597 error.GenericPoison => unreachable,
596 else => |e| {
597 decl.analysis = .sema_failure;
598 try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1);
599 try mod.retryable_failures.append(mod.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
600 mod.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(
601 mod.gpa,
602 decl.navSrcLoc(mod),
603 "unable to analyze: {s}",
604 .{@errorName(e)},
598 error.ComptimeBreak => unreachable,
599 error.ComptimeReturn => unreachable,
600 error.OutOfMemory => {
601 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
602 try zcu.retryable_failures.append(gpa, anal_unit);
603 zcu.failed_analysis.putAssumeCapacityNoClobber(anal_unit, try Zcu.ErrorMsg.create(
604 gpa,
605 .{ .base_node_inst = cau.zir_index, .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0) },
606 "unable to analyze: OutOfMemory",
607 .{},
605608 ));
606609 return error.AnalysisFail;
607610 },
608611 };
609612 };
610613
614 if (!cau_outdated) {
615 // We definitely don't need to do any dependency tracking, so our work is done.
616 return;
617 }
618
611619 // TODO: we do not yet have separate dependencies for decl values vs types.
612 if (decl_was_outdated) {
613 if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {
614 log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});
615 // This dependency was marked as PO, meaning dependees were waiting
616 // on its analysis result, and it has turned out to be outdated.
617 // Update dependees accordingly.
618 try mod.markDependeeOutdated(.{ .decl_val = decl_index });
619 } else {
620 log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});
621 // This dependency was previously PO, but turned out to be up-to-date.
622 // We do not need to queue successive analysis.
623 try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });
624 }
620 const invalidate = sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref;
621 const dependee: InternPool.Dependee = switch (cau.owner.unwrap()) {
622 .none => return, // there are no dependencies on a `comptime` decl!
623 .nav => |nav_index| .{ .nav_val = nav_index },
624 .type => |ty| .{ .interned = ty },
625 };
626
627 if (invalidate) {
628 // This dependency was marked as PO, meaning dependees were waiting
629 // on its analysis result, and it has turned out to be outdated.
630 // Update dependees accordingly.
631 try zcu.markDependeeOutdated(dependee);
632 } else {
633 // This dependency was previously PO, but turned out to be up-to-date.
634 // We do not need to queue successive analysis.
635 try zcu.markPoDependeeUpToDate(dependee);
625636 }
626637}
627638
......@@ -636,28 +647,32 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
636647 const ip = &zcu.intern_pool;
637648
638649 // We only care about the uncoerced function.
639 // We need to do this for the "orphaned function" check below to be valid.
640650 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
641651
642652 const func = zcu.funcInfo(maybe_coerced_func_index);
643 const decl_index = func.owner_decl;
644 const decl = zcu.declPtr(decl_index);
645653
646 log.debug("ensureFuncBodyAnalyzed '{d}' (instance of '{}')", .{
647 @intFromEnum(func_index),
648 decl.name.fmt(ip),
649 });
654 log.debug("ensureFuncBodyAnalyzed {d}", .{@intFromEnum(func_index)});
650655
651 // First, our owner decl must be up-to-date. This will always be the case
652 // during the first update, but may not on successive updates if we happen
653 // to get analyzed before our parent decl.
654 try pt.ensureDeclAnalyzed(decl_index);
656 // Here's an interesting question: is this function actually valid?
657 // Maybe the signature changed, so we'll end up creating a whole different `func`
658 // in the InternPool, and this one is a waste of time to analyze. Worse, we'd be
659 // analyzing new ZIR with old data, and get bogus errors. They would be unused,
660 // but they would still hang around internally! So, let's detect this case.
661 // For function decls, we must ensure the declaration's `Cau` is up-to-date, and
662 // check if `func_index` was removed by that update.
663 // For function instances, we do that process on the generic owner.
655664
656 // On an update, it's possible this function changed such that our owner
657 // decl now refers to a different function, making this one orphaned. If
658 // that's the case, we should remove this function from the binary.
659 if (decl.val.ip_index != func_index) {
660 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
665 try pt.ensureCauAnalyzed(cau: {
666 const func_nav = if (func.generic_owner == .none)
667 func.owner_nav
668 else
669 zcu.funcInfo(func.generic_owner).owner_nav;
670
671 break :cau ip.getNav(func_nav).analysis_owner.unwrap().?;
672 });
673
674 if (ip.isRemoved(func_index) or (func.generic_owner != .none and ip.isRemoved(func.generic_owner))) {
675 try zcu.markDependeeOutdated(.{ .interned = func_index }); // IES
661676 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
662677 ip.remove(pt.tid, func_index);
663678 @panic("TODO: remove orphaned function from binary");
......@@ -670,58 +685,40 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
670685 else
671686 .none;
672687
673 switch (decl.analysis) {
674 .unreferenced => unreachable,
675 .in_progress => unreachable,
676
677 .codegen_failure => unreachable, // functions do not perform constant value generation
688 const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index });
689 const func_outdated = zcu.outdated.swapRemove(anal_unit) or
690 zcu.potentially_outdated.swapRemove(anal_unit);
678691
679 .file_failure,
680 .sema_failure,
681 .dependency_failure,
682 => return error.AnalysisFail,
683
684 .complete => {},
685 }
686
687 const func_as_depender = InternPool.AnalUnit.wrap(.{ .func = func_index });
688 const was_outdated = zcu.outdated.swapRemove(func_as_depender) or
689 zcu.potentially_outdated.swapRemove(func_as_depender);
690
691 if (was_outdated) {
692 if (func_outdated) {
692693 dev.check(.incremental);
693 _ = zcu.outdated_ready.swapRemove(func_as_depender);
694 zcu.deleteUnitExports(func_as_depender);
695 zcu.deleteUnitReferences(func_as_depender);
694 _ = zcu.outdated_ready.swapRemove(anal_unit);
695 zcu.deleteUnitExports(anal_unit);
696 zcu.deleteUnitReferences(anal_unit);
696697 }
697698
698 switch (func.analysisUnordered(ip).state) {
699 .success => if (!was_outdated) return,
700 .sema_failure,
701 .dependency_failure,
702 .codegen_failure,
703 => if (!was_outdated) return error.AnalysisFail,
704 .none, .queued => {},
705 .in_progress => unreachable,
706 .inline_only => unreachable, // don't queue work for this
699 if (!func_outdated) {
700 // We can trust the current information about this function.
701 if (zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit)) {
702 return error.AnalysisFail;
703 }
704 switch (func.analysisUnordered(ip).state) {
705 .unreferenced => {}, // this is the first reference
706 .queued => {}, // we're waiting on first-time analysis
707 .analyzed => return, // up-to-date
708 }
707709 }
708710
709711 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
710712 @intFromEnum(func_index),
711 if (was_outdated) "outdated" else "never analyzed",
713 if (func_outdated) "outdated" else "never analyzed",
712714 });
713715
714 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
715 defer tmp_arena.deinit();
716 const sema_arena = tmp_arena.allocator();
717
718 var air = pt.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
716 var air = pt.analyzeFnBody(func_index) catch |err| switch (err) {
719717 error.AnalysisFail => {
720 if (func.analysisUnordered(ip).state == .in_progress) {
721 // If this decl caused the compile error, the analysis field would
722 // be changed to indicate it was this Decl's fault. Because this
723 // did not happen, we infer here that it was a dependency failure.
724 func.setAnalysisState(ip, .dependency_failure);
718 if (!zcu.failed_analysis.contains(anal_unit)) {
719 // If this function caused the error, it would have an entry in `failed_analysis`.
720 // Since it does not, this must be a transitive failure.
721 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
725722 }
726723 return error.AnalysisFail;
727724 },
......@@ -729,18 +726,14 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
729726 };
730727 errdefer air.deinit(gpa);
731728
732 const invalidate_ies_deps = i: {
733 if (!was_outdated) break :i false;
734 if (!func.analysisUnordered(ip).inferred_error_set) break :i true;
735 const new_resolved_ies = func.resolvedErrorSetUnordered(ip);
736 break :i new_resolved_ies != old_resolved_ies;
737 };
738 if (invalidate_ies_deps) {
739 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});
740 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
741 } else if (was_outdated) {
742 log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)});
743 try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index });
729 if (func_outdated) {
730 if (!func.analysisUnordered(ip).inferred_error_set or func.resolvedErrorSetUnordered(ip) != old_resolved_ies) {
731 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});
732 try zcu.markDependeeOutdated(.{ .interned = func_index });
733 } else {
734 log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)});
735 try zcu.markPoDependeeUpToDate(.{ .interned = func_index });
736 }
744737 }
745738
746739 const comp = zcu.comp;
......@@ -773,16 +766,16 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
773766 }
774767
775768 const func = zcu.funcInfo(func_index);
776 const decl_index = func.owner_decl;
777 const decl = zcu.declPtr(decl_index);
769 const nav_index = func.owner_nav;
770 const nav = ip.getNav(nav_index);
778771
779772 var liveness = try Liveness.analyze(gpa, air, ip);
780773 defer liveness.deinit(gpa);
781774
782775 if (build_options.enable_debug_extensions and comp.verbose_air) {
783 std.debug.print("# Begin Function AIR: {}:\n", .{decl.fqn.fmt(ip)});
776 std.debug.print("# Begin Function AIR: {}:\n", .{nav.fqn.fmt(ip)});
784777 @import("../print_air.zig").dump(pt, air, liveness);
785 std.debug.print("# End Function AIR: {}\n\n", .{decl.fqn.fmt(ip)});
778 std.debug.print("# End Function AIR: {}\n\n", .{nav.fqn.fmt(ip)});
786779 }
787780
788781 if (std.debug.runtime_safety) {
......@@ -797,23 +790,18 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
797790 verify.verify() catch |err| switch (err) {
798791 error.OutOfMemory => return error.OutOfMemory,
799792 else => {
800 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
801 zcu.failed_analysis.putAssumeCapacityNoClobber(
802 InternPool.AnalUnit.wrap(.{ .func = func_index }),
803 try Zcu.ErrorMsg.create(
804 gpa,
805 decl.navSrcLoc(zcu),
806 "invalid liveness: {s}",
807 .{@errorName(err)},
808 ),
809 );
810 func.setAnalysisState(ip, .codegen_failure);
793 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
794 gpa,
795 zcu.navSrcLoc(nav_index),
796 "invalid liveness: {s}",
797 .{@errorName(err)},
798 ));
811799 return;
812800 },
813801 };
814802 }
815803
816 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(ip), 0);
804 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0);
817805 defer codegen_prog_node.end();
818806
819807 if (!air.typesFullyResolved(zcu)) {
......@@ -821,22 +809,21 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
821809 // Correcting this failure will involve changing a type this function
822810 // depends on, hence triggering re-analysis of this function, so this
823811 // interacts correctly with incremental compilation.
824 func.setAnalysisState(ip, .codegen_failure);
812 // TODO: do we need to mark this failure anywhere? I don't think so, since compilation
813 // will fail due to the type error anyway.
825814 } else if (comp.bin_file) |lf| {
826815 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
827816 error.OutOfMemory => return error.OutOfMemory,
828817 error.AnalysisFail => {
829 func.setAnalysisState(ip, .codegen_failure);
818 assert(zcu.failed_codegen.contains(nav_index));
830819 },
831820 else => {
832 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
833 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .func = func_index }), try Zcu.ErrorMsg.create(
821 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
834822 gpa,
835 decl.navSrcLoc(zcu),
823 zcu.navSrcLoc(nav_index),
836824 "unable to codegen: {s}",
837825 .{@errorName(err)},
838826 ));
839 func.setAnalysisState(ip, .codegen_failure);
840827 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
841828 },
842829 };
......@@ -851,17 +838,16 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
851838pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
852839 dev.check(.sema);
853840 const import_file_result = try pt.importPkg(pkg);
854 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
855 if (root_decl_index == .none) {
841 const root_type = pt.zcu.fileRootType(import_file_result.file_index);
842 if (root_type == .none) {
856843 return pt.semaFile(import_file_result.file_index);
857844 }
858845}
859846
860fn getFileRootStruct(
847fn createFileRootStruct(
861848 pt: Zcu.PerThread,
862 decl_index: Zcu.Decl.Index,
863 namespace_index: Zcu.Namespace.Index,
864849 file_index: Zcu.File.Index,
850 namespace_index: Zcu.Namespace.Index,
865851) Allocator.Error!InternPool.Index {
866852 const zcu = pt.zcu;
867853 const gpa = zcu.gpa;
......@@ -912,34 +898,37 @@ fn getFileRootStruct(
912898 };
913899 errdefer wip_ty.cancel(ip, pt.tid);
914900
901 wip_ty.setName(ip, try file.internFullyQualifiedName(pt));
902 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;
903 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, namespace_index, wip_ty.index);
904
915905 if (zcu.comp.incremental) {
916906 try ip.addDependency(
917907 gpa,
918 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
908 InternPool.AnalUnit.wrap(.{ .cau = new_cau_index }),
919909 .{ .src_hash = tracked_inst },
920910 );
921911 }
922912
923 const decl = zcu.declPtr(decl_index);
924 decl.val = Value.fromInterned(wip_ty.index);
925 decl.has_tv = true;
926 decl.owns_tv = true;
927 decl.analysis = .complete;
928
929 try pt.scanNamespace(namespace_index, decls, decl);
913 try pt.scanNamespace(namespace_index, decls);
930914 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
931 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
915 zcu.setFileRootType(file_index, wip_ty.index);
916 return wip_ty.finish(ip, new_cau_index.toOptional(), namespace_index.toOptional());
932917}
933918
934/// Re-analyze the root Decl of a file on an incremental update.
919/// Re-analyze the root type of a file on an incremental update.
935920/// If `type_outdated`, the struct type itself is considered outdated and is
936921/// reconstructed at a new InternPool index. Otherwise, the namespace is just
937922/// re-analyzed. Returns whether the decl's tyval was invalidated.
923/// Returns `error.AnalysisFail` if the file has an error.
938924fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {
939925 const zcu = pt.zcu;
940926 const ip = &zcu.intern_pool;
941927 const file = zcu.fileByIndex(file_index);
942 const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?);
928 const file_root_type = zcu.fileRootType(file_index);
929 const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu).unwrap().?;
930
931 assert(file_root_type != .none);
943932
944933 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
945934 file.mod.fully_qualified_name,
......@@ -948,33 +937,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
948937 });
949938
950939 if (file.status != .success_zir) {
951 if (decl.analysis == .file_failure) {
952 return false;
953 } else {
954 decl.analysis = .file_failure;
955 return true;
956 }
957 }
958
959 if (decl.analysis == .file_failure) {
960 // No struct type currently exists. Create one!
961 const root_decl = zcu.fileRootDecl(file_index);
962 _ = try pt.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index);
963 return true;
940 return error.AnalysisFail;
964941 }
965942
966 assert(decl.has_tv);
967 assert(decl.owns_tv);
968
969943 if (type_outdated) {
970 // Invalidate the existing type, reusing the decl and namespace.
971 const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?;
972 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{
973 .decl = file_root_decl,
974 }));
975 ip.remove(pt.tid, decl.val.toIntern());
976 decl.val = undefined;
977 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);
944 // Invalidate the existing type, reusing its namespace.
945 const file_root_type_cau = ip.loadStructType(file_root_type).cau.unwrap().?;
946 ip.removeDependenciesForDepender(
947 zcu.gpa,
948 InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }),
949 );
950 ip.remove(pt.tid, file_root_type);
951 _ = try pt.createFileRootStruct(file_index, namespace_index);
978952 return true;
979953 }
980954
......@@ -994,7 +968,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
994968 const decls = file.zir.bodySlice(extra_index, decls_len);
995969
996970 if (!type_outdated) {
997 try pt.scanNamespace(decl.src_namespace, decls, decl);
971 try pt.scanNamespace(namespace_index, decls);
998972 }
999973
1000974 return false;
......@@ -1009,43 +983,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1009983 const zcu = pt.zcu;
1010984 const gpa = zcu.gpa;
1011985 const file = zcu.fileByIndex(file_index);
1012 assert(zcu.fileRootDecl(file_index) == .none);
1013 log.debug("semaFile zcu={s} sub_file_path={s}", .{
1014 file.mod.fully_qualified_name, file.sub_file_path,
1015 });
1016
1017 // Because these three things each reference each other, `undefined`
1018 // placeholders are used before being set after the struct type gains an
1019 // InternPool index.
1020 const new_namespace_index = try pt.createNamespace(.{
1021 .parent = .none,
1022 .decl_index = undefined,
1023 .file_scope = file_index,
1024 });
1025 errdefer pt.destroyNamespace(new_namespace_index);
1026
1027 const new_decl_index = try pt.allocateNewDecl(new_namespace_index);
1028 const new_decl = zcu.declPtr(new_decl_index);
1029 errdefer @panic("TODO error handling");
1030
1031 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
1032 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
1033
1034 new_decl.fqn = try file.internFullyQualifiedName(pt);
1035 new_decl.name = new_decl.fqn;
1036 new_decl.is_pub = true;
1037 new_decl.is_exported = false;
1038 new_decl.alignment = .none;
1039 new_decl.@"linksection" = .none;
1040 new_decl.analysis = .in_progress;
986 assert(zcu.fileRootType(file_index) == .none);
1041987
1042988 if (file.status != .success_zir) {
1043 new_decl.analysis = .file_failure;
1044 return;
989 return error.AnalysisFail;
1045990 }
1046991 assert(file.zir_loaded);
1047992
1048 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
993 const new_namespace_index = try pt.createNamespace(.{
994 .parent = .none,
995 .owner_type = undefined, // set in `createFileRootStruct`
996 .file_scope = file_index,
997 });
998 const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index);
1049999 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
10501000
10511001 switch (zcu.comp.cache_use) {
......@@ -1067,98 +1017,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10671017
10681018 whole.cache_manifest_mutex.lock();
10691019 defer whole.cache_manifest_mutex.unlock();
1070 try man.addFilePostContents(resolved_path, source.bytes, source.stat);
1020 man.addFilePostContents(resolved_path, source.bytes, source.stat) catch |err| switch (err) {
1021 error.OutOfMemory => |e| return e,
1022 else => {
1023 try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)});
1024 return error.AnalysisFail;
1025 },
1026 };
10711027 },
10721028 .incremental => {},
10731029 }
10741030}
10751031
1076fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1077 const tracy = trace(@src());
1078 defer tracy.end();
1032const SemaCauResult = packed struct {
1033 /// Whether the value of a `decl_val` of the corresponding Nav changed.
1034 invalidate_decl_val: bool,
1035 /// Whether the type of a `decl_ref` of the corresponding Nav changed.
1036 invalidate_decl_ref: bool,
1037};
10791038
1039/// Performs semantic analysis on the given `Cau`, storing results to its owner `Nav` if needed.
1040/// If analysis fails, returns `error.AnalysisFail`, storing an error in `zcu.failed_analysis` unless
1041/// the error is transitive.
1042/// On success, returns information about whether the `Nav` value changed.
1043fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
10801044 const zcu = pt.zcu;
1081 const decl = zcu.declPtr(decl_index);
1045 const gpa = zcu.gpa;
10821046 const ip = &zcu.intern_pool;
10831047
1084 if (decl.getFileScope(zcu).status != .success_zir) {
1085 return error.AnalysisFail;
1086 }
1048 const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index });
10871049
1088 assert(!zcu.declIsRoot(decl_index));
1050 const cau = ip.getCau(cau_index);
1051 const inst_info = cau.zir_index.resolveFull(ip);
1052 const file = zcu.fileByIndex(inst_info.file);
1053 const zir = file.zir;
10891054
1090 if (decl.zir_decl_index == .none and decl.owns_tv) {
1091 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
1092 return pt.semaAnonOwnerDecl(decl_index);
1055 if (file.status != .success_zir) {
1056 return error.AnalysisFail;
10931057 }
10941058
1095 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
1096 log.debug("decl name '{}'", .{decl.fqn.fmt(ip)});
1097 defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)});
1059 // We are about to re-analyze this `Cau`; drop its depenndencies.
1060 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
10981061
1099 const old_has_tv = decl.has_tv;
1100 // The following values are ignored if `!old_has_tv`
1101 const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined;
1102 const old_val = decl.val;
1103 const old_align = decl.alignment;
1104 const old_linksection = decl.@"linksection";
1105 const old_addrspace = decl.@"addrspace";
1106 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|
1107 prev_func.analysisUnordered(ip).state == .inline_only
1108 else
1109 false;
1110
1111 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);
1062 const builtin_type_target_index: InternPool.Index = switch (cau.owner.unwrap()) {
1063 .none => ip_index: {
1064 // `comptime` decl -- we will re-analyze its body.
1065 // This declaration has no value so is definitely not a std.builtin type.
1066 break :ip_index .none;
1067 },
1068 .type => |ty| {
1069 // This is an incremental update, and this type is being re-analyzed because it is outdated.
1070 // The type must be recreated at a new `InternPool.Index`.
1071 // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed.
1072 ip.remove(pt.tid, ty);
1073 return .{
1074 .invalidate_decl_val = true,
1075 .invalidate_decl_ref = true,
1076 };
1077 },
1078 .nav => |nav| ip_index: {
1079 // Other decl -- we will re-analyze its value.
1080 // This might be a type in `builtin.zig` -- check.
1081 if (file.mod != zcu.std_mod) break :ip_index .none;
1082 // We're in the std module.
1083 const nav_name = ip.getNav(nav).name;
1084 const std_file_imported = try pt.importPkg(zcu.std_mod);
1085 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
1086 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).?.unwrap().?);
1087 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
1088 const builtin_nav = ip.getNav(std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse break :ip_index .none);
1089 const builtin_namespace = switch (builtin_nav.status) {
1090 .unresolved => break :ip_index .none,
1091 .resolved => |r| Type.fromInterned(r.val).getNamespace(zcu).?.unwrap().?,
1092 };
1093 if (cau.namespace != builtin_namespace) break :ip_index .none;
1094 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
1095 for ([_][]const u8{
1096 "AtomicOrder",
1097 "AtomicRmwOp",
1098 "CallingConvention",
1099 "AddressSpace",
1100 "FloatMode",
1101 "ReduceOp",
1102 "CallModifier",
1103 "PrefetchOptions",
1104 "ExportOptions",
1105 "ExternOptions",
1106 "Type",
1107 }, [_]InternPool.Index{
1108 .atomic_order_type,
1109 .atomic_rmw_op_type,
1110 .calling_convention_type,
1111 .address_space_type,
1112 .float_mode_type,
1113 .reduce_op_type,
1114 .call_modifier_type,
1115 .prefetch_options_type,
1116 .export_options_type,
1117 .extern_options_type,
1118 .type_info_type,
1119 }) |type_name, type_ip| {
1120 if (nav_name.eqlSlice(type_name, ip)) break :ip_index type_ip;
1121 }
1122 break :ip_index .none;
1123 },
1124 };
11121125
1113 const gpa = zcu.gpa;
1114 const zir = decl.getFileScope(zcu).zir;
1115
1116 const builtin_type_target_index: InternPool.Index = ip_index: {
1117 const std_mod = zcu.std_mod;
1118 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
1119 // We're in the std module.
1120 const std_file_imported = try pt.importPkg(std_mod);
1121 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
1122 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
1123 const std_namespace = std_decl.getInnerNamespace(zcu).?;
1124 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
1125 const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none);
1126 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none;
1127 if (decl.src_namespace != builtin_namespace) break :ip_index .none;
1128 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
1129 for ([_][]const u8{
1130 "AtomicOrder",
1131 "AtomicRmwOp",
1132 "CallingConvention",
1133 "AddressSpace",
1134 "FloatMode",
1135 "ReduceOp",
1136 "CallModifier",
1137 "PrefetchOptions",
1138 "ExportOptions",
1139 "ExternOptions",
1140 "Type",
1141 }, [_]InternPool.Index{
1142 .atomic_order_type,
1143 .atomic_rmw_op_type,
1144 .calling_convention_type,
1145 .address_space_type,
1146 .float_mode_type,
1147 .reduce_op_type,
1148 .call_modifier_type,
1149 .prefetch_options_type,
1150 .export_options_type,
1151 .extern_options_type,
1152 .type_info_type,
1153 }) |type_name, type_ip| {
1154 if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip;
1155 }
1156 break :ip_index .none;
1126 const is_usingnamespace = switch (cau.owner.unwrap()) {
1127 .nav => |nav| ip.getNav(nav).is_usingnamespace,
1128 .none, .type => false,
11571129 };
11581130
1159 zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1131 log.debug("semaCau '{d}'", .{@intFromEnum(cau_index)});
11601132
1161 decl.analysis = .in_progress;
1133 try zcu.analysis_in_progress.put(gpa, anal_unit, {});
1134 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
11621135
11631136 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
11641137 defer analysis_arena.deinit();
......@@ -1171,224 +1144,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
11711144 .gpa = gpa,
11721145 .arena = analysis_arena.allocator(),
11731146 .code = zir,
1174 .owner_decl = decl,
1175 .owner_decl_index = decl_index,
1147 .owner = anal_unit,
11761148 .func_index = .none,
11771149 .func_is_naked = false,
11781150 .fn_ret_ty = Type.void,
11791151 .fn_ret_ty_ies = null,
1180 .owner_func_index = .none,
11811152 .comptime_err_ret_trace = &comptime_err_ret_trace,
11821153 .builtin_type_target_index = builtin_type_target_index,
11831154 };
11841155 defer sema.deinit();
11851156
1186 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
1187 try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{
1188 .file = decl.getFileScopeIndex(zcu),
1189 .inst = decl_inst,
1190 }) });
1157 // Every `Cau` has a dependency on the source of its own ZIR instruction.
1158 try sema.declareDependency(.{ .src_hash = cau.zir_index });
11911159
1192 var block_scope: Sema.Block = .{
1160 var block: Sema.Block = .{
11931161 .parent = null,
11941162 .sema = &sema,
1195 .namespace = decl.src_namespace,
1163 .namespace = cau.namespace,
11961164 .instructions = .{},
11971165 .inlining = null,
11981166 .is_comptime = true,
1199 .src_base_inst = decl.zir_decl_index.unwrap().?,
1200 .type_name_ctx = decl.name,
1167 .src_base_inst = cau.zir_index,
1168 .type_name_ctx = switch (cau.owner.unwrap()) {
1169 .nav => |nav| ip.getNav(nav).fqn,
1170 .type => |ty| Type.fromInterned(ty).containerTypeName(ip),
1171 .none => try ip.getOrPutStringFmt(gpa, pt.tid, "{}.comptime", .{
1172 Type.fromInterned(zcu.namespacePtr(cau.namespace).owner_type).containerTypeName(ip).fmt(ip),
1173 }, .no_embedded_nulls),
1174 },
1175 };
1176 defer block.instructions.deinit(gpa);
1177
1178 const zir_decl: Zir.Inst.Declaration, const decl_bodies: Zir.Inst.Declaration.Bodies = decl: {
1179 const decl, const extra_end = zir.getDeclaration(inst_info.inst);
1180 break :decl .{ decl, decl.getBodies(extra_end, zir) };
1181 };
1182
1183 // We have to fetch this state before resolving the body because of the `nav_already_populated`
1184 // case below. We might change the language in future so that align/linksection/etc for functions
1185 // work in a way more in line with other declarations, in which case that logic will go away.
1186 const old_nav_info = switch (cau.owner.unwrap()) {
1187 .none, .type => undefined, // we'll never use `old_nav_info`
1188 .nav => |nav| ip.getNav(nav),
12011189 };
1202 defer block_scope.instructions.deinit(gpa);
12031190
1204 const decl_bodies = decl.zirBodies(zcu);
1191 const result_ref = try sema.resolveInlineBody(&block, decl_bodies.value_body, inst_info.inst);
12051192
1206 const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);
1207 // We'll do some other bits with the Sema. Clear the type target index just
1208 // in case they analyze any type.
1193 const nav_index = switch (cau.owner.unwrap()) {
1194 .none => {
1195 // This is a `comptime` decl, so we are done -- the side effects are all we care about.
1196 // Just make sure to `flushExports`.
1197 try sema.flushExports();
1198 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1199 return .{
1200 .invalidate_decl_val = false,
1201 .invalidate_decl_ref = false,
1202 };
1203 },
1204 .nav => |nav| nav, // We will resolve this `Nav` below.
1205 .type => unreachable, // Handled at top of function.
1206 };
1207
1208 // We'll do more work with the Sema. Clear the target type index just in case we analyze any type.
12091209 sema.builtin_type_target_index = .none;
1210 const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 });
1211 const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 });
1212 const address_space_src = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 });
1213 const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 });
1214 const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 });
1215 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
1210
1211 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
1212 const section_src = block.src(.{ .node_offset_var_decl_section = 0 });
1213 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
1214 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
1215 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
1216
1217 const decl_val = try sema.resolveFinalDeclValue(&block, init_src, result_ref);
12161218 const decl_ty = decl_val.typeOf(zcu);
12171219
1218 // Note this resolves the type of the Decl, not the value; if this Decl
1219 // is a struct, for example, this resolves `type` (which needs no resolution),
1220 // not the struct itself.
1220 switch (decl_val.toIntern()) {
1221 .generic_poison => unreachable, // assertion failure
1222 .unreachable_value => unreachable, // assertion failure
1223 else => {},
1224 }
1225
1226 // This resolves the type of the resolved value, not that value itself. If `decl_val` is a struct type,
1227 // this resolves the type `type` (which needs no resolution), not the struct itself.
12211228 try decl_ty.resolveLayout(pt);
12221229
1223 if (decl.kind == .@"usingnamespace") {
1224 if (!decl_ty.eql(Type.type, zcu)) {
1225 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
1230 // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`.
1231 if (is_usingnamespace) {
1232 if (decl_ty.toIntern() != .type_type) {
1233 return sema.fail(&block, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
12261234 }
1227 const ty = decl_val.toType();
1228 if (ty.getNamespace(zcu) == null) {
1229 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(pt)});
1235 if (decl_val.toType().getNamespace(zcu) == null) {
1236 return sema.fail(&block, ty_src, "type {} has no namespace", .{decl_val.toType().fmt(pt)});
12301237 }
1231
1232 decl.val = ty.toValue();
1233 decl.alignment = .none;
1234 decl.@"linksection" = .none;
1235 decl.has_tv = true;
1236 decl.owns_tv = false;
1237 decl.analysis = .complete;
1238
1239 // TODO: usingnamespace cannot currently participate in incremental compilation
1238 ip.resolveNavValue(nav_index, .{
1239 .val = decl_val.toIntern(),
1240 .alignment = .none,
1241 .@"linksection" = .none,
1242 .@"addrspace" = .generic,
1243 });
1244 // TODO: usingnamespace cannot participate in incremental compilation
1245 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
12401246 return .{
12411247 .invalidate_decl_val = true,
12421248 .invalidate_decl_ref = true,
12431249 };
12441250 }
12451251
1246 var queue_linker_work = true;
1247 var is_func = false;
1248 var is_inline = false;
1249 switch (decl_val.toIntern()) {
1250 .generic_poison => unreachable,
1251 .unreachable_value => unreachable,
1252 else => switch (ip.indexToKey(decl_val.toIntern())) {
1253 .variable => |variable| {
1254 decl.owns_tv = variable.decl == decl_index;
1255 queue_linker_work = decl.owns_tv;
1256 },
1257
1258 .extern_func => |extern_func| {
1259 decl.owns_tv = extern_func.decl == decl_index;
1260 queue_linker_work = decl.owns_tv;
1261 is_func = decl.owns_tv;
1262 },
1263
1264 .func => |func| {
1265 decl.owns_tv = func.owner_decl == decl_index;
1266 queue_linker_work = false;
1267 is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline;
1268 is_func = decl.owns_tv;
1269 },
1270
1271 else => {},
1272 },
1273 }
1252 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
1253 .func => |f| .{ f.owner_nav == nav_index, false },
1254 .variable => |v| .{ false, v.owner_nav == nav_index },
1255 .@"extern" => .{ false, false },
1256 else => .{ false, true },
1257 };
12741258
1275 decl.val = decl_val;
1276 // Function linksection, align, and addrspace were already set by Sema
1277 if (!is_func) {
1278 decl.alignment = blk: {
1279 const align_body = decl_bodies.align_body orelse break :blk .none;
1280 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);
1281 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
1259 if (nav_already_populated) {
1260 // This is a function declaration.
1261 // Logic in `Sema.funcCommon` has already populated the `Nav` for us.
1262 assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern());
1263 } else {
1264 // Keep in sync with logic in `Sema.zirVarExtended`.
1265 const alignment: InternPool.Alignment = a: {
1266 const align_body = decl_bodies.align_body orelse break :a .none;
1267 const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst);
1268 break :a try sema.analyzeAsAlign(&block, align_src, align_ref);
12821269 };
1283 decl.@"linksection" = blk: {
1284 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;
1285 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);
1286 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{
1270
1271 const @"linksection": InternPool.OptionalNullTerminatedString = ls: {
1272 const linksection_body = decl_bodies.linksection_body orelse break :ls .none;
1273 const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst);
1274 const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{
12871275 .needed_comptime_reason = "linksection must be comptime-known",
12881276 });
12891277 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {
1290 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
1278 return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{});
12911279 } else if (bytes.len == 0) {
1292 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
1280 return sema.fail(&block, section_src, "linksection cannot be empty", .{});
12931281 }
1294 break :blk try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
1282 break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
12951283 };
1296 decl.@"addrspace" = blk: {
1284
1285 const @"addrspace": std.builtin.AddressSpace = as: {
12971286 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
1287 .func => .function,
12981288 .variable => .variable,
1299 .extern_func, .func => .function,
1289 .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type)
1290 .function
1291 else
1292 .variable,
13001293 else => .constant,
13011294 };
1302
13031295 const target = zcu.getTarget();
1304
1305 const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) {
1296 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
13061297 .function => target_util.defaultAddressSpace(target, .function),
13071298 .variable => target_util.defaultAddressSpace(target, .global_mutable),
13081299 .constant => target_util.defaultAddressSpace(target, .global_constant),
13091300 else => unreachable,
13101301 };
1311 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);
1312 break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);
1302 const addrspace_ref = try sema.resolveInlineBody(&block, addrspace_body, inst_info.inst);
1303 break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx);
13131304 };
1314 }
1315 decl.has_tv = true;
1316 decl.analysis = .complete;
1317
1318 const result: Zcu.SemaDeclResult = if (old_has_tv) .{
1319 .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or
1320 !decl.val.eql(old_val, decl_ty, zcu) or
1321 is_inline != old_is_inline,
1322 .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or
1323 decl.alignment != old_align or
1324 decl.@"linksection" != old_linksection or
1325 decl.@"addrspace" != old_addrspace or
1326 is_inline != old_is_inline,
1327 } else .{
1328 .invalidate_decl_val = true,
1329 .invalidate_decl_ref = true,
1330 };
1331
1332 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty));
1333 if (has_runtime_bits) {
1334 // Needed for codegen_decl which will call updateDecl and then the
1335 // codegen backend wants full access to the Decl Type.
1336 try decl_ty.resolveFully(pt);
1337
1338 try zcu.comp.queueJob(.{ .codegen_decl = decl_index });
13391305
1340 if (result.invalidate_decl_ref and zcu.emit_h != null) {
1341 try zcu.comp.queueJob(.{ .emit_h_decl = decl_index });
1342 }
1306 ip.resolveNavValue(nav_index, .{
1307 .val = decl_val.toIntern(),
1308 .alignment = alignment,
1309 .@"linksection" = @"linksection",
1310 .@"addrspace" = @"addrspace",
1311 });
13431312 }
13441313
1345 if (decl.is_exported) {
1346 const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });
1347 if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});
1348 // The scope needs to have the decl in it.
1349 try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
1314 // Mark the `Cau` as completed before evaluating the export!
1315 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1316
1317 if (zir_decl.flags.is_export) {
1318 const export_src = block.src(.{ .token_offset = @intFromBool(zir_decl.flags.is_pub) });
1319 const name_slice = zir.nullTerminatedString(zir_decl.name.toString(zir).?);
1320 const name_ip = try ip.getOrPutString(gpa, pt.tid, name_slice, .no_embedded_nulls);
1321 try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_index);
13501322 }
13511323
13521324 try sema.flushExports();
13531325
1354 return result;
1355}
1356
1357pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1358 const zcu = pt.zcu;
1359 const decl = zcu.declPtr(decl_index);
1326 queue_codegen: {
1327 if (!queue_linker_work) break :queue_codegen;
13601328
1361 assert(decl.has_tv);
1362 assert(decl.owns_tv);
1329 // Needed for codegen_nav which will call updateDecl and then the
1330 // codegen backend wants full access to the Decl Type.
1331 // We also need this for the `isFnOrHasRuntimeBits` check below.
1332 // TODO: we could make the language more lenient by deferring this work
1333 // to the `codegen_nav` job.
1334 try decl_ty.resolveFully(pt);
13631335
1364 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
1336 if (!decl_ty.isFnOrHasRuntimeBits(pt)) break :queue_codegen;
13651337
1366 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
1367 .Fn => @panic("TODO: update fn instance"),
1368 .Type => {},
1369 else => unreachable,
1338 try zcu.comp.queueJob(.{ .codegen_nav = nav_index });
13701339 }
13711340
1372 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
1373 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
1374 //
1375 // However, as soon as we make that, the context that created us will require re-analysis anyway
1376 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
1377 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
1378 // why should we bother implementing it here too when the Sema logic will be hit right after?
1379 //
1380 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
1381 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
1382 // with a new Decl.
1383 //
1384 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
1385 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1386 zcu.intern_pool.remove(pt.tid, decl.val.toIntern());
1387 decl.analysis = .dependency_failure;
1388 return .{
1389 .invalidate_decl_val = true,
1390 .invalidate_decl_ref = true,
1391 };
1341 switch (old_nav_info.status) {
1342 .unresolved => return .{
1343 .invalidate_decl_val = true,
1344 .invalidate_decl_ref = true,
1345 },
1346 .resolved => |old| {
1347 const new = ip.getNav(nav_index).status.resolved;
1348 return .{
1349 .invalidate_decl_val = new.val != old.val,
1350 .invalidate_decl_ref = ip.typeOf(new.val) != ip.typeOf(old.val) or
1351 new.alignment != old.alignment or
1352 new.@"linksection" != old.@"linksection" or
1353 new.@"addrspace" != old.@"addrspace",
1354 };
1355 },
1356 }
13921357}
13931358
13941359pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
......@@ -1426,7 +1391,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
14261391 const file_index = try ip.createFile(gpa, pt.tid, .{
14271392 .bin_digest = path_digest,
14281393 .file = builtin_file,
1429 .root_decl = .none,
1394 .root_type = .none,
14301395 });
14311396 keep_resolved_path = true; // It's now owned by import_table.
14321397 gop.value_ptr.* = file_index;
......@@ -1453,7 +1418,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
14531418 const new_file_index = try ip.createFile(gpa, pt.tid, .{
14541419 .bin_digest = path_digest,
14551420 .file = new_file,
1456 .root_decl = .none,
1421 .root_type = .none,
14571422 });
14581423 keep_resolved_path = true; // It's now owned by import_table.
14591424 gop.value_ptr.* = new_file_index;
......@@ -1563,7 +1528,7 @@ pub fn importFile(
15631528 const new_file_index = try ip.createFile(gpa, pt.tid, .{
15641529 .bin_digest = path_digest,
15651530 .file = new_file,
1566 .root_decl = .none,
1531 .root_type = .none,
15671532 });
15681533 keep_resolved_path = true; // It's now owned by import_table.
15691534 gop.value_ptr.* = new_file_index;
......@@ -1726,7 +1691,7 @@ fn newEmbedFile(
17261691 })).toIntern();
17271692 const ptr_val = try pt.intern(.{ .ptr = .{
17281693 .ty = ptr_ty,
1729 .base_addr = .{ .anon_decl = .{
1694 .base_addr = .{ .uav = .{
17301695 .val = array_val,
17311696 .orig_ty = ptr_ty,
17321697 } },
......@@ -1748,39 +1713,70 @@ pub fn scanNamespace(
17481713 pt: Zcu.PerThread,
17491714 namespace_index: Zcu.Namespace.Index,
17501715 decls: []const Zir.Inst.Index,
1751 parent_decl: *Zcu.Decl,
17521716) Allocator.Error!void {
17531717 const tracy = trace(@src());
17541718 defer tracy.end();
17551719
17561720 const zcu = pt.zcu;
1721 const ip = &zcu.intern_pool;
17571722 const gpa = zcu.gpa;
17581723 const namespace = zcu.namespacePtr(namespace_index);
17591724
17601725 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
17611726 // than their name. We'll build an efficient mapping now, then discard the current `decls`.
1762 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index) = .{};
1727 // We map to the `Cau`, since not every declaration has a `Nav`.
1728 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index) = .{};
17631729 defer existing_by_inst.deinit(gpa);
17641730
1765 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));
1766
1767 for (namespace.decls.keys()) |decl_index| {
1768 const decl = zcu.declPtr(decl_index);
1769 existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);
1731 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(
1732 namespace.pub_decls.count() + namespace.priv_decls.count() +
1733 namespace.pub_usingnamespace.items.len + namespace.priv_usingnamespace.items.len +
1734 namespace.other_decls.items.len,
1735 ));
1736
1737 for (namespace.pub_decls.keys()) |nav| {
1738 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1739 const zir_index = ip.getCau(cau_index).zir_index;
1740 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1741 }
1742 for (namespace.priv_decls.keys()) |nav| {
1743 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1744 const zir_index = ip.getCau(cau_index).zir_index;
1745 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1746 }
1747 for (namespace.pub_usingnamespace.items) |nav| {
1748 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1749 const zir_index = ip.getCau(cau_index).zir_index;
1750 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1751 }
1752 for (namespace.priv_usingnamespace.items) |nav| {
1753 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1754 const zir_index = ip.getCau(cau_index).zir_index;
1755 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1756 }
1757 for (namespace.other_decls.items) |cau_index| {
1758 const cau = ip.getCau(cau_index);
1759 existing_by_inst.putAssumeCapacityNoClobber(cau.zir_index, cau_index);
1760 // If this is a test, it'll be re-added to `test_functions` later on
1761 // if still alive. Remove it for now.
1762 switch (cau.owner.unwrap()) {
1763 .none, .type => {},
1764 .nav => |nav| _ = zcu.test_functions.swapRemove(nav),
1765 }
17701766 }
17711767
17721768 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
17731769 defer seen_decls.deinit(gpa);
17741770
1775 namespace.decls.clearRetainingCapacity();
1776 try namespace.decls.ensureTotalCapacity(gpa, decls.len);
1777
1778 namespace.usingnamespace_set.clearRetainingCapacity();
1771 namespace.pub_decls.clearRetainingCapacity();
1772 namespace.priv_decls.clearRetainingCapacity();
1773 namespace.pub_usingnamespace.clearRetainingCapacity();
1774 namespace.priv_usingnamespace.clearRetainingCapacity();
1775 namespace.other_decls.clearRetainingCapacity();
17791776
17801777 var scan_decl_iter: ScanDeclIter = .{
17811778 .pt = pt,
17821779 .namespace_index = namespace_index,
1783 .parent_decl = parent_decl,
17841780 .seen_decls = &seen_decls,
17851781 .existing_by_inst = &existing_by_inst,
17861782 .pass = .named,
......@@ -1792,34 +1788,17 @@ pub fn scanNamespace(
17921788 for (decls) |decl_inst| {
17931789 try scan_decl_iter.scanDecl(decl_inst);
17941790 }
1795
1796 if (seen_decls.count() != namespace.decls.count()) {
1797 // Do a pass over the namespace contents and remove any decls from the last update
1798 // which were removed in this one.
1799 var i: usize = 0;
1800 while (i < namespace.decls.count()) {
1801 const decl_index = namespace.decls.keys()[i];
1802 const decl = zcu.declPtr(decl_index);
1803 if (!seen_decls.contains(decl.name)) {
1804 // We must preserve namespace ordering for @typeInfo.
1805 namespace.decls.orderedRemoveAt(i);
1806 i -= 1;
1807 }
1808 }
1809 }
18101791}
18111792
18121793const ScanDeclIter = struct {
18131794 pt: Zcu.PerThread,
18141795 namespace_index: Zcu.Namespace.Index,
1815 parent_decl: *Zcu.Decl,
18161796 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
1817 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index),
1797 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index),
18181798 /// Decl scanning is run in two passes, so that we can detect when a generated
18191799 /// name would clash with an explicit name and use a different one.
18201800 pass: enum { named, unnamed },
18211801 usingnamespace_index: usize = 0,
1822 comptime_index: usize = 0,
18231802 unnamed_test_index: usize = 0,
18241803
18251804 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
......@@ -1843,37 +1822,35 @@ const ScanDeclIter = struct {
18431822
18441823 const pt = iter.pt;
18451824 const zcu = pt.zcu;
1825 const comp = zcu.comp;
18461826 const namespace_index = iter.namespace_index;
18471827 const namespace = zcu.namespacePtr(namespace_index);
18481828 const gpa = zcu.gpa;
1849 const zir = namespace.fileScope(zcu).zir;
1829 const file = namespace.fileScope(zcu);
1830 const zir = file.zir;
18501831 const ip = &zcu.intern_pool;
18511832
18521833 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
18531834 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
18541835 const declaration = extra.data;
18551836
1856 // Every Decl needs a name.
1857 const decl_name: InternPool.NullTerminatedString, const kind: Zcu.Decl.Kind, const is_named_test: bool = switch (declaration.name) {
1837 const Kind = enum { @"comptime", @"usingnamespace", @"test", named };
1838
1839 const maybe_name: InternPool.OptionalNullTerminatedString, const kind: Kind, const is_named_test: bool = switch (declaration.name) {
18581840 .@"comptime" => info: {
18591841 if (iter.pass != .unnamed) return;
1860 const i = iter.comptime_index;
1861 iter.comptime_index += 1;
18621842 break :info .{
1863 try iter.avoidNameConflict("comptime_{d}", .{i}),
1843 .none,
18641844 .@"comptime",
18651845 false,
18661846 };
18671847 },
18681848 .@"usingnamespace" => info: {
1869 // TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.
1870 // The problem is, we need to preserve the decl ordering for `@typeInfo`.
1871 // I'm not bothering to fix this now, since some upcoming changes will change this code significantly anyway.
1872 if (iter.pass != .named) return;
1849 if (iter.pass != .unnamed) return;
18731850 const i = iter.usingnamespace_index;
18741851 iter.usingnamespace_index += 1;
18751852 break :info .{
1876 try iter.avoidNameConflict("usingnamespace_{d}", .{i}),
1853 (try iter.avoidNameConflict("usingnamespace_{d}", .{i})).toOptional(),
18771854 .@"usingnamespace",
18781855 false,
18791856 };
......@@ -1883,7 +1860,7 @@ const ScanDeclIter = struct {
18831860 const i = iter.unnamed_test_index;
18841861 iter.unnamed_test_index += 1;
18851862 break :info .{
1886 try iter.avoidNameConflict("test_{d}", .{i}),
1863 (try iter.avoidNameConflict("test_{d}", .{i})).toOptional(),
18871864 .@"test",
18881865 false,
18891866 };
......@@ -1894,7 +1871,7 @@ const ScanDeclIter = struct {
18941871 assert(declaration.flags.has_doc_comment);
18951872 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
18961873 break :info .{
1897 try iter.avoidNameConflict("decltest.{s}", .{name}),
1874 (try iter.avoidNameConflict("decltest.{s}", .{name})).toOptional(),
18981875 .@"test",
18991876 true,
19001877 };
......@@ -1903,7 +1880,7 @@ const ScanDeclIter = struct {
19031880 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
19041881 if (iter.pass != .unnamed) return;
19051882 break :info .{
1906 try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),
1883 (try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)})).toOptional(),
19071884 .@"test",
19081885 true,
19091886 };
......@@ -1917,132 +1894,144 @@ const ScanDeclIter = struct {
19171894 );
19181895 try iter.seen_decls.putNoClobber(gpa, name, {});
19191896 break :info .{
1920 name,
1897 name.toOptional(),
19211898 .named,
19221899 false,
19231900 };
19241901 },
19251902 };
19261903
1927 switch (kind) {
1928 .@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1),
1929 .@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1),
1930 else => {},
1931 }
1932
1933 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
19341904 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
1935 .file = parent_file_scope_index,
1905 .file = namespace.file_scope,
19361906 .inst = decl_inst,
19371907 });
19381908
1939 // We create a Decl for it regardless of analysis status.
1940
1941 const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {
1942 // We need only update this existing Decl.
1943 const decl = zcu.declPtr(decl_index);
1944 const was_exported = decl.is_exported;
1945 assert(decl.kind == kind); // ZIR tracking should preserve this
1946 decl.name = decl_name;
1947 decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
1948 decl.is_pub = declaration.flags.is_pub;
1949 decl.is_exported = declaration.flags.is_export;
1950 break :decl_index .{ was_exported, decl_index };
1951 } else decl_index: {
1952 // Create and set up a new Decl.
1953 const new_decl_index = try pt.allocateNewDecl(namespace_index);
1954 const new_decl = zcu.declPtr(new_decl_index);
1955 new_decl.kind = kind;
1956 new_decl.name = decl_name;
1957 new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
1958 new_decl.is_pub = declaration.flags.is_pub;
1959 new_decl.is_exported = declaration.flags.is_export;
1960 new_decl.zir_decl_index = tracked_inst.toOptional();
1961 break :decl_index .{ false, new_decl_index };
1962 };
1963
1964 const decl = zcu.declPtr(decl_index);
1965
1966 namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu });
1909 const existing_cau = iter.existing_by_inst.get(tracked_inst);
1910
1911 const cau, const want_analysis = switch (kind) {
1912 .@"comptime" => cau: {
1913 const cau = existing_cau orelse try ip.createComptimeCau(gpa, pt.tid, tracked_inst, namespace_index);
1914
1915 // For a `comptime` declaration, whether to re-analyze is based solely on whether the
1916 // `Cau` is outdated. So, add this one to `outdated` and `outdated_ready` if not already.
1917 const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
1918 if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| {
1919 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1920 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1921 zcu.outdated.putAssumeCapacityNoClobber(unit, kv.value);
1922 if (kv.value == 0) { // no PO deps
1923 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1924 }
1925 } else if (!zcu.outdated.contains(unit)) {
1926 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1927 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1928 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
1929 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1930 }
19671931
1968 const comp = zcu.comp;
1969 const decl_mod = namespace.fileScope(zcu).mod;
1970 const want_analysis = declaration.flags.is_export or switch (kind) {
1971 .anon => unreachable,
1972 .@"comptime" => true,
1973 .@"usingnamespace" => a: {
1974 namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub);
1975 break :a true;
1932 break :cau .{ cau, true };
19761933 },
1977 .named => false,
1978 .@"test" => a: {
1979 if (!comp.config.is_test) break :a false;
1980 if (decl_mod != zcu.main_mod) break :a false;
1981 if (is_named_test and comp.test_filters.len > 0) {
1982 const decl_fqn = decl.fqn.toSlice(ip);
1983 for (comp.test_filters) |test_filter| {
1984 if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break;
1985 } else break :a false;
1986 }
1987 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
1988 break :a true;
1934 else => cau: {
1935 const name = maybe_name.unwrap().?;
1936 const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name);
1937 const cau, const nav = if (existing_cau) |cau_index| cau_nav: {
1938 const nav_index = ip.getCau(cau_index).owner.unwrap().nav;
1939 const nav = ip.getNav(nav_index);
1940 assert(nav.name == name);
1941 assert(nav.fqn == fqn);
1942 break :cau_nav .{ cau_index, nav_index };
1943 } else try ip.createPairedCauNav(gpa, pt.tid, name, fqn, tracked_inst, namespace_index, kind == .@"usingnamespace");
1944 const want_analysis = switch (kind) {
1945 .@"comptime" => unreachable,
1946 .@"usingnamespace" => a: {
1947 if (declaration.flags.is_pub) {
1948 try namespace.pub_usingnamespace.append(gpa, nav);
1949 } else {
1950 try namespace.priv_usingnamespace.append(gpa, nav);
1951 }
1952 break :a true;
1953 },
1954 .@"test" => a: {
1955 try namespace.other_decls.append(gpa, cau);
1956 // TODO: incremental compilation!
1957 // * remove from `test_functions` if no longer matching filter
1958 // * add to `test_functions` if newly passing filter
1959 // This logic is unaware of incremental: we'll end up with duplicates.
1960 // Perhaps we should add all test indiscriminately and filter at the end of the update.
1961 if (!comp.config.is_test) break :a false;
1962 if (file.mod != zcu.main_mod) break :a false;
1963 if (is_named_test and comp.test_filters.len > 0) {
1964 const fqn_slice = fqn.toSlice(ip);
1965 for (comp.test_filters) |test_filter| {
1966 if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break;
1967 } else break :a false;
1968 }
1969 try zcu.test_functions.put(gpa, nav, {});
1970 break :a true;
1971 },
1972 .named => a: {
1973 if (declaration.flags.is_pub) {
1974 try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
1975 } else {
1976 try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
1977 }
1978 break :a false;
1979 },
1980 };
1981 break :cau .{ cau, want_analysis };
19891982 },
19901983 };
19911984
1992 if (want_analysis) {
1993 // We will not queue analysis if the decl has been analyzed on a previous update and
1994 // `is_export` is unchanged. In this case, the incremental update mechanism will handle
1995 // re-analysis for us if necessary.
1996 if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {
1997 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{
1998 namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
1999 });
2000 try comp.queueJob(.{ .analyze_decl = decl_index });
2001 }
1985 if (want_analysis or declaration.flags.is_export) {
1986 log.debug(
1987 "scanDecl queue analyze_cau file='{s}' cau_index={d}",
1988 .{ namespace.fileScope(zcu).sub_file_path, cau },
1989 );
1990 try comp.queueJob(.{ .analyze_cau = cau });
20021991 }
20031992
2004 if (decl.getOwnedFunction(zcu) != null) {
2005 // TODO this logic is insufficient; namespaces we don't re-scan may still require
2006 // updated line numbers. Look into this!
2007 // TODO Look into detecting when this would be unnecessary by storing enough state
2008 // in `Decl` to notice that the line number did not change.
2009 try comp.queueJob(.{ .update_line_number = decl_index });
2010 }
1993 // TODO: we used to do line number updates here, but this is an inappropriate place for this logic to live.
20111994 }
20121995};
20131996
2014/// Cancel the creation of an anon decl and delete any references to it.
2015/// If other decls depend on this decl, they must be aborted first.
2016pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
2017 assert(!pt.zcu.declIsRoot(decl_index));
2018 pt.destroyDecl(decl_index);
2019}
2020
2021/// Finalize the creation of an anon decl.
2022pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
2023 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
2024 try pt.zcu.comp.queueJob(.{ .codegen_decl = decl_index });
2025 }
2026}
2027
2028pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
1997fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!Air {
20291998 const tracy = trace(@src());
20301999 defer tracy.end();
20312000
2032 const mod = pt.zcu;
2033 const gpa = mod.gpa;
2034 const ip = &mod.intern_pool;
2035 const func = mod.funcInfo(func_index);
2036 const decl_index = func.owner_decl;
2037 const decl = mod.declPtr(decl_index);
2001 const zcu = pt.zcu;
2002 const gpa = zcu.gpa;
2003 const ip = &zcu.intern_pool;
2004
2005 const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index });
2006 const func = zcu.funcInfo(func_index);
2007 const inst_info = func.zir_body_inst.resolveFull(ip);
2008 const file = zcu.fileByIndex(inst_info.file);
2009 const zir = file.zir;
2010
2011 try zcu.analysis_in_progress.put(gpa, anal_unit, {});
2012 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
2013
2014 func.setAnalysisState(ip, .analyzed);
2015
2016 // This is the `Cau` corresponding to the `declaration` instruction which the function or its generic owner originates from.
2017 const decl_cau = ip.getCau(cau: {
2018 const orig_nav = if (func.generic_owner == .none)
2019 func.owner_nav
2020 else
2021 zcu.funcInfo(func.generic_owner).owner_nav;
2022
2023 break :cau ip.getNav(orig_nav).analysis_owner.unwrap().?;
2024 });
20382025
2039 log.debug("func name '{}'", .{decl.fqn.fmt(ip)});
2040 defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
2026 const func_nav = ip.getNav(func.owner_nav);
20412027
2042 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
2028 const decl_prog_node = zcu.sema_prog_node.start(func_nav.fqn.toSlice(ip), 0);
20432029 defer decl_prog_node.end();
20442030
2045 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
2031 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
2032
2033 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
2034 defer analysis_arena.deinit();
20462035
20472036 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
20482037 defer comptime_err_ret_trace.deinit();
......@@ -2052,21 +2041,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20522041 // the runtime-known parameters only, not to be confused with the
20532042 // generic_owner function type, which potentially has more parameters,
20542043 // including comptime parameters.
2055 const fn_ty = decl.typeOf(mod);
2056 const fn_ty_info = mod.typeToFunc(fn_ty).?;
2044 const fn_ty = Type.fromInterned(func.ty);
2045 const fn_ty_info = zcu.typeToFunc(fn_ty).?;
20572046
20582047 var sema: Sema = .{
20592048 .pt = pt,
20602049 .gpa = gpa,
2061 .arena = arena,
2062 .code = decl.getFileScope(mod).zir,
2063 .owner_decl = decl,
2064 .owner_decl_index = decl_index,
2050 .arena = analysis_arena.allocator(),
2051 .code = zir,
2052 .owner = anal_unit,
20652053 .func_index = func_index,
20662054 .func_is_naked = fn_ty_info.cc == .Naked,
20672055 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
20682056 .fn_ret_ty_ies = null,
2069 .owner_func_index = func_index,
20702057 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),
20712058 .comptime_err_ret_trace = &comptime_err_ret_trace,
20722059 };
......@@ -2074,11 +2061,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20742061
20752062 // Every runtime function has a dependency on the source of the Decl it originates from.
20762063 // It also depends on the value of its owner Decl.
2077 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });
2078 try sema.declareDependency(.{ .decl_val = decl_index });
2064 try sema.declareDependency(.{ .src_hash = decl_cau.zir_index });
2065 try sema.declareDependency(.{ .nav_val = func.owner_nav });
20792066
20802067 if (func.analysisUnordered(ip).inferred_error_set) {
2081 const ies = try arena.create(Sema.InferredErrorSet);
2068 const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet);
20822069 ies.* = .{ .func = func_index };
20832070 sema.fn_ret_ty_ies = ies;
20842071 }
......@@ -2094,19 +2081,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20942081 var inner_block: Sema.Block = .{
20952082 .parent = null,
20962083 .sema = &sema,
2097 .namespace = decl.src_namespace,
2084 .namespace = decl_cau.namespace,
20982085 .instructions = .{},
20992086 .inlining = null,
21002087 .is_comptime = false,
2101 .src_base_inst = inst: {
2102 const owner_info = if (func.generic_owner == .none)
2103 func
2104 else
2105 mod.funcInfo(func.generic_owner);
2106 const orig_decl = mod.declPtr(owner_info.owner_decl);
2107 break :inst orig_decl.zir_decl_index.unwrap().?;
2108 },
2109 .type_name_ctx = decl.name,
2088 .src_base_inst = decl_cau.zir_index,
2089 .type_name_ctx = func_nav.fqn,
21102090 };
21112091 defer inner_block.instructions.deinit(gpa);
21122092
......@@ -2144,10 +2124,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
21442124 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
21452125 if (gop.found_existing) continue; // provided above by comptime arg
21462126
2147 const inst_info = sema.code.instructions.get(@intFromEnum(inst));
2148 const param_name: Zir.NullTerminatedString = switch (inst_info.tag) {
2149 .param_anytype => inst_info.data.str_tok.start,
2150 .param => sema.code.extraData(Zir.Inst.Param, inst_info.data.pl_tok.payload_index).data.name,
2127 const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
2128 const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
2129 .param_anytype => param_inst_info.data.str_tok.start,
2130 .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
21512131 else => unreachable,
21522132 };
21532133
......@@ -2179,8 +2159,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
21792159 });
21802160 }
21812161
2182 func.setAnalysisState(ip, .in_progress);
2183
21842162 const last_arg_index = inner_block.instructions.items.len;
21852163
21862164 // Save the error trace as our first action in the function.
......@@ -2190,9 +2168,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
21902168 inner_block.error_return_trace_index = error_return_trace_index;
21912169
21922170 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
2193 // TODO make these unreachable instead of @panic
2194 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
2195 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
2171 error.GenericPoison => unreachable,
2172 error.ComptimeReturn => unreachable,
21962173 else => |e| return e,
21972174 };
21982175
......@@ -2207,14 +2184,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
22072184
22082185 // If we don't get an error return trace from a caller, create our own.
22092186 if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and
2210 mod.comp.config.any_error_tracing and
2211 !sema.fn_ret_ty.isError(mod))
2187 zcu.comp.config.any_error_tracing and
2188 !sema.fn_ret_ty.isError(zcu))
22122189 {
22132190 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
2214 // TODO make these unreachable instead of @panic
2215 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
2216 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
2217 error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
2191 error.GenericPoison => unreachable,
2192 error.ComptimeReturn => unreachable,
2193 error.ComptimeBreak => unreachable,
22182194 else => |e| return e,
22192195 };
22202196 }
......@@ -2239,35 +2215,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
22392215 error.GenericPoison => unreachable,
22402216 error.ComptimeReturn => unreachable,
22412217 error.ComptimeBreak => unreachable,
2242 error.AnalysisFail => {
2243 // In this case our function depends on a type that had a compile error.
2244 // We should not try to lower this function.
2245 decl.analysis = .dependency_failure;
2246 return error.AnalysisFail;
2247 },
22482218 else => |e| return e,
22492219 };
22502220 assert(ies.resolved != .none);
22512221 ip.funcSetIesResolved(func_index, ies.resolved);
22522222 }
22532223
2254 func.setAnalysisState(ip, .success);
2224 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
22552225
22562226 // Finally we must resolve the return type and parameter types so that backends
22572227 // have full access to type information.
22582228 // Crucially, this happens *after* we set the function state to success above,
22592229 // so that dependencies on the function body will now be satisfied rather than
22602230 // result in circular dependency errors.
2231 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
2232 // The codegen timing guarantees that the parameter types will be populated.
22612233 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
22622234 error.GenericPoison => unreachable,
22632235 error.ComptimeReturn => unreachable,
22642236 error.ComptimeBreak => unreachable,
2265 error.AnalysisFail => {
2266 // In this case our function depends on a type that had a compile error.
2267 // We should not try to lower this function.
2268 decl.analysis = .dependency_failure;
2269 return error.AnalysisFail;
2270 },
22712237 else => |e| return e,
22722238 };
22732239
......@@ -2287,36 +2253,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index)
22872253 return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index);
22882254}
22892255
2290pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.Decl.Index {
2291 const zcu = pt.zcu;
2292 const gpa = zcu.gpa;
2293 const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{
2294 .name = undefined,
2295 .fqn = undefined,
2296 .src_namespace = namespace,
2297 .has_tv = false,
2298 .owns_tv = false,
2299 .val = undefined,
2300 .alignment = undefined,
2301 .@"linksection" = .none,
2302 .@"addrspace" = .generic,
2303 .analysis = .unreferenced,
2304 .zir_decl_index = .none,
2305 .is_pub = false,
2306 .is_exported = false,
2307 .kind = .anon,
2308 });
2309
2310 if (zcu.emit_h) |zcu_emit_h| {
2311 if (@intFromEnum(decl_index) >= zcu_emit_h.allocated_emit_h.len) {
2312 try zcu_emit_h.allocated_emit_h.append(gpa, .{});
2313 assert(@intFromEnum(decl_index) == zcu_emit_h.allocated_emit_h.len);
2314 }
2315 }
2316
2317 return decl_index;
2318}
2319
23202256pub fn getErrorValue(
23212257 pt: Zcu.PerThread,
23222258 name: InternPool.NullTerminatedString,
......@@ -2328,25 +2264,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err
23282264 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
23292265}
23302266
2331pub fn initNewAnonDecl(
2332 pt: Zcu.PerThread,
2333 new_decl_index: Zcu.Decl.Index,
2334 val: Value,
2335 name: InternPool.NullTerminatedString,
2336 fqn: InternPool.OptionalNullTerminatedString,
2337) Allocator.Error!void {
2338 const new_decl = pt.zcu.declPtr(new_decl_index);
2339
2340 new_decl.name = name;
2341 new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
2342 .internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
2343 new_decl.val = val;
2344 new_decl.alignment = .none;
2345 new_decl.@"linksection" = .none;
2346 new_decl.has_tv = true;
2347 new_decl.analysis = .complete;
2348}
2349
23502267fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
23512268 switch (file.status) {
23522269 .success_zir, .retryable_failure => {},
......@@ -2367,35 +2284,35 @@ pub fn processExports(pt: Zcu.PerThread) !void {
23672284 const zcu = pt.zcu;
23682285 const gpa = zcu.gpa;
23692286
2370 // First, construct a mapping of every exported value and Decl to the indices of all its different exports.
2371 var decl_exports: std.AutoArrayHashMapUnmanaged(Zcu.Decl.Index, std.ArrayListUnmanaged(u32)) = .{};
2372 var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
2287 // First, construct a mapping of every exported value and Nav to the indices of all its different exports.
2288 var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .{};
2289 var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
23732290 defer {
2374 for (decl_exports.values()) |*exports| {
2291 for (nav_exports.values()) |*exports| {
23752292 exports.deinit(gpa);
23762293 }
2377 decl_exports.deinit(gpa);
2378 for (value_exports.values()) |*exports| {
2294 nav_exports.deinit(gpa);
2295 for (uav_exports.values()) |*exports| {
23792296 exports.deinit(gpa);
23802297 }
2381 value_exports.deinit(gpa);
2298 uav_exports.deinit(gpa);
23822299 }
23832300
23842301 // We note as a heuristic:
23852302 // * It is rare to export a value.
2386 // * It is rare for one Decl to be exported multiple times.
2303 // * It is rare for one Nav to be exported multiple times.
23872304 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.
2388 try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
2305 try nav_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
23892306
23902307 for (zcu.single_exports.values()) |export_idx| {
23912308 const exp = zcu.all_exports.items[export_idx];
23922309 const value_ptr, const found_existing = switch (exp.exported) {
2393 .decl_index => |i| gop: {
2394 const gop = try decl_exports.getOrPut(gpa, i);
2310 .nav => |nav| gop: {
2311 const gop = try nav_exports.getOrPut(gpa, nav);
23952312 break :gop .{ gop.value_ptr, gop.found_existing };
23962313 },
2397 .value => |i| gop: {
2398 const gop = try value_exports.getOrPut(gpa, i);
2314 .uav => |uav| gop: {
2315 const gop = try uav_exports.getOrPut(gpa, uav);
23992316 break :gop .{ gop.value_ptr, gop.found_existing };
24002317 },
24012318 };
......@@ -2406,12 +2323,12 @@ pub fn processExports(pt: Zcu.PerThread) !void {
24062323 for (zcu.multi_exports.values()) |info| {
24072324 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {
24082325 const value_ptr, const found_existing = switch (exp.exported) {
2409 .decl_index => |i| gop: {
2410 const gop = try decl_exports.getOrPut(gpa, i);
2326 .nav => |nav| gop: {
2327 const gop = try nav_exports.getOrPut(gpa, nav);
24112328 break :gop .{ gop.value_ptr, gop.found_existing };
24122329 },
2413 .value => |i| gop: {
2414 const gop = try value_exports.getOrPut(gpa, i);
2330 .uav => |uav| gop: {
2331 const gop = try uav_exports.getOrPut(gpa, uav);
24152332 break :gop .{ gop.value_ptr, gop.found_existing };
24162333 },
24172334 };
......@@ -2424,13 +2341,13 @@ pub fn processExports(pt: Zcu.PerThread) !void {
24242341 var symbol_exports: SymbolExports = .{};
24252342 defer symbol_exports.deinit(gpa);
24262343
2427 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {
2428 const exported: Zcu.Exported = .{ .decl_index = exported_decl };
2344 for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| {
2345 const exported: Zcu.Exported = .{ .nav = exported_nav };
24292346 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
24302347 }
24312348
2432 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {
2433 const exported: Zcu.Exported = .{ .value = exported_value };
2349 for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| {
2350 const exported: Zcu.Exported = .{ .uav = exported_uav };
24342351 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
24352352 }
24362353}
......@@ -2467,20 +2384,31 @@ fn processExportsInner(
24672384 }
24682385
24692386 switch (exported) {
2470 .decl_index => |idx| if (failed: {
2471 const decl = zcu.declPtr(idx);
2472 if (decl.analysis != .complete) break :failed true;
2473 // Check if has owned function
2474 if (!decl.owns_tv) break :failed false;
2475 if (decl.typeOf(zcu).zigTypeTag(zcu) != .Fn) break :failed false;
2476 // Check if owned function failed
2477 break :failed zcu.funcInfo(decl.val.toIntern()).analysisUnordered(ip).state != .success;
2387 .nav => |nav_index| if (failed: {
2388 const nav = ip.getNav(nav_index);
2389 if (zcu.failed_codegen.contains(nav_index)) break :failed true;
2390 if (nav.analysis_owner.unwrap()) |cau| {
2391 const cau_unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
2392 if (zcu.failed_analysis.contains(cau_unit)) break :failed true;
2393 if (zcu.transitive_failed_analysis.contains(cau_unit)) break :failed true;
2394 }
2395 const val = switch (nav.status) {
2396 .unresolved => break :failed true,
2397 .resolved => |r| Value.fromInterned(r.val),
2398 };
2399 // If the value is a function, we also need to check if that function succeeded analysis.
2400 if (val.typeOf(zcu).zigTypeTag(zcu) == .Fn) {
2401 const func_unit = InternPool.AnalUnit.wrap(.{ .func = val.toIntern() });
2402 if (zcu.failed_analysis.contains(func_unit)) break :failed true;
2403 if (zcu.transitive_failed_analysis.contains(func_unit)) break :failed true;
2404 }
2405 break :failed false;
24782406 }) {
24792407 // This `Decl` is failed, so was never sent to codegen.
24802408 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?
24812409 return;
24822410 },
2483 .value => {},
2411 .uav => {},
24842412 }
24852413
24862414 if (zcu.comp.bin_file) |lf| {
......@@ -2499,46 +2427,49 @@ pub fn populateTestFunctions(
24992427 const ip = &zcu.intern_pool;
25002428 const builtin_mod = zcu.root_mod.getBuiltinDependency();
25012429 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
2502 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
2503 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
2504 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
2505 const test_functions_str = try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls);
2506 const decl_index = builtin_namespace.decls.getKeyAdapted(
2507 test_functions_str,
2508 Zcu.DeclAdapter{ .zcu = zcu },
2430 pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) {
2431 error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt
2432 error.OutOfMemory => |e| return e,
2433 };
2434 const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index));
2435 const builtin_namespace = builtin_root_type.getNamespace(zcu).?.unwrap().?;
2436 const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted(
2437 try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls),
2438 Zcu.Namespace.NameAdapter{ .zcu = zcu },
25092439 ).?;
25102440 {
2511 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
2441 // We have to call `ensureCauAnalyzed` here in case `builtin.test_functions`
25122442 // was not referenced by start code.
25132443 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
25142444 defer {
25152445 zcu.sema_prog_node.end();
25162446 zcu.sema_prog_node = std.Progress.Node.none;
25172447 }
2518 try pt.ensureDeclAnalyzed(decl_index);
2448 const cau_index = ip.getNav(nav_index).analysis_owner.unwrap().?;
2449 try pt.ensureCauAnalyzed(cau_index);
25192450 }
25202451
2521 const decl = zcu.declPtr(decl_index);
2522 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
2452 const test_fns_val = zcu.navValue(nav_index);
2453 const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
25232454
2524 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: {
2455 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = array: {
25252456 // Add zcu.test_functions to an array decl then make the test_functions
25262457 // decl reference it as a slice.
25272458 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
25282459 defer gpa.free(test_fn_vals);
25292460
2530 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
2531 const test_decl = zcu.declPtr(test_decl_index);
2532 const test_decl_name = test_decl.fqn;
2533 const test_decl_name_len = test_decl_name.length(ip);
2534 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
2461 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_nav_index| {
2462 const test_nav = ip.getNav(test_nav_index);
2463 const test_nav_name = test_nav.fqn;
2464 const test_nav_name_len = test_nav_name.length(ip);
2465 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = n: {
25352466 const test_name_ty = try pt.arrayType(.{
2536 .len = test_decl_name_len,
2467 .len = test_nav_name_len,
25372468 .child = .u8_type,
25382469 });
25392470 const test_name_val = try pt.intern(.{ .aggregate = .{
25402471 .ty = test_name_ty.toIntern(),
2541 .storage = .{ .bytes = test_decl_name.toString() },
2472 .storage = .{ .bytes = test_nav_name.toString() },
25422473 } });
25432474 break :n .{
25442475 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),
......@@ -2552,23 +2483,18 @@ pub fn populateTestFunctions(
25522483 .ty = .slice_const_u8_type,
25532484 .ptr = try pt.intern(.{ .ptr = .{
25542485 .ty = .manyptr_const_u8_type,
2555 .base_addr = .{ .anon_decl = test_name_anon_decl },
2486 .base_addr = .{ .uav = test_name_anon_decl },
25562487 .byte_offset = 0,
25572488 } }),
25582489 .len = try pt.intern(.{ .int = .{
25592490 .ty = .usize_type,
2560 .storage = .{ .u64 = test_decl_name_len },
2491 .storage = .{ .u64 = test_nav_name_len },
25612492 } }),
25622493 } }),
25632494 // func
25642495 try pt.intern(.{ .ptr = .{
2565 .ty = try pt.intern(.{ .ptr_type = .{
2566 .child = test_decl.typeOf(zcu).toIntern(),
2567 .flags = .{
2568 .is_const = true,
2569 },
2570 } }),
2571 .base_addr = .{ .decl = test_decl_index },
2496 .ty = (try pt.navPtrType(test_nav_index)).toIntern(),
2497 .base_addr = .{ .nav = test_nav_index },
25722498 .byte_offset = 0,
25732499 } }),
25742500 };
......@@ -2601,22 +2527,16 @@ pub fn populateTestFunctions(
26012527 .size = .Slice,
26022528 },
26032529 });
2604 const new_val = decl.val;
26052530 const new_init = try pt.intern(.{ .slice = .{
26062531 .ty = new_ty.toIntern(),
26072532 .ptr = try pt.intern(.{ .ptr = .{
26082533 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
2609 .base_addr = .{ .anon_decl = array_anon_decl },
2534 .base_addr = .{ .uav = array_anon_decl },
26102535 .byte_offset = 0,
26112536 } }),
26122537 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
26132538 } });
2614 ip.mutateVarInit(decl.val.toIntern(), new_init);
2615
2616 // Since we are replacing the Decl's value we must perform cleanup on the
2617 // previous value.
2618 decl.val = new_val;
2619 decl.has_tv = true;
2539 ip.mutateVarInit(test_fns_val.toIntern(), new_init);
26202540 }
26212541 {
26222542 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
......@@ -2625,40 +2545,45 @@ pub fn populateTestFunctions(
26252545 zcu.codegen_prog_node = std.Progress.Node.none;
26262546 }
26272547
2628 try pt.linkerUpdateDecl(decl_index);
2548 try pt.linkerUpdateNav(nav_index);
26292549 }
26302550}
26312551
2632pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
2552pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
26332553 const zcu = pt.zcu;
26342554 const comp = zcu.comp;
26352555
2636 const decl = zcu.declPtr(decl_index);
2637
2638 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(&zcu.intern_pool), 0);
2556 const nav = zcu.intern_pool.getNav(nav_index);
2557 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0);
26392558 defer codegen_prog_node.end();
26402559
26412560 if (comp.bin_file) |lf| {
2642 lf.updateDecl(pt, decl_index) catch |err| switch (err) {
2561 lf.updateNav(pt, nav_index) catch |err| switch (err) {
26432562 error.OutOfMemory => return error.OutOfMemory,
26442563 error.AnalysisFail => {
2645 decl.analysis = .codegen_failure;
2564 assert(zcu.failed_codegen.contains(nav_index));
26462565 },
26472566 else => {
26482567 const gpa = zcu.gpa;
2649 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
2650 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(
2568 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
2569 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, try Zcu.ErrorMsg.create(
26512570 gpa,
2652 decl.navSrcLoc(zcu),
2571 zcu.navSrcLoc(nav_index),
26532572 "unable to codegen: {s}",
26542573 .{@errorName(err)},
26552574 ));
2656 decl.analysis = .codegen_failure;
2657 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
2575 if (nav.analysis_owner.unwrap()) |cau| {
2576 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .cau = cau }));
2577 } else {
2578 // TODO: we don't have a way to indicate that this failure is retryable!
2579 // Since these are really rare, we could as a cop-out retry the whole build next update.
2580 // But perhaps we can do better...
2581 @panic("TODO: retryable failure codegenning non-declaration Nav");
2582 }
26582583 },
26592584 };
26602585 } else if (zcu.llvm_object) |llvm_object| {
2661 llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) {
2586 llvm_object.updateNav(pt, nav_index) catch |err| switch (err) {
26622587 error.OutOfMemory => return error.OutOfMemory,
26632588 };
26642589 }
......@@ -2750,9 +2675,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool
27502675 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
27512676}
27522677
2753/// Shortcut for calling `intern_pool.getCoerced`.
2678/// Essentially a shortcut for calling `intern_pool.getCoerced`.
2679/// However, this function also allows coercing `extern`s. The `InternPool` function can't do
2680/// this because it requires potentially pushing to the job queue.
27542681pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {
2755 return Value.fromInterned(try pt.zcu.intern_pool.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));
2682 const ip = &pt.zcu.intern_pool;
2683 switch (ip.indexToKey(val.toIntern())) {
2684 .@"extern" => |e| {
2685 const coerced = try pt.getExtern(.{
2686 .name = e.name,
2687 .ty = new_ty.toIntern(),
2688 .lib_name = e.lib_name,
2689 .is_const = e.is_const,
2690 .is_threadlocal = e.is_threadlocal,
2691 .is_weak_linkage = e.is_weak_linkage,
2692 .alignment = e.alignment,
2693 .@"addrspace" = e.@"addrspace",
2694 .zir_index = e.zir_index,
2695 .owner_nav = undefined, // ignored by `getExtern`.
2696 });
2697 return Value.fromInterned(coerced);
2698 },
2699 else => {},
2700 }
2701 return Value.fromInterned(try ip.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));
27562702}
27572703
27582704pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
......@@ -3237,24 +3183,29 @@ pub fn structPackedFieldBitOffset(
32373183}
32383184
32393185pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {
3240 const decl_index = try pt.getBuiltinDecl(name);
3241 pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");
3242 return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern());
3186 const zcu = pt.zcu;
3187 const ip = &zcu.intern_pool;
3188 const nav = try pt.getBuiltinNav(name);
3189 pt.ensureCauAnalyzed(ip.getNav(nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3190 return Air.internedToRef(ip.getNav(nav).status.resolved.val);
32433191}
32443192
3245pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex {
3193pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
32463194 const zcu = pt.zcu;
32473195 const gpa = zcu.gpa;
32483196 const ip = &zcu.intern_pool;
32493197 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
3250 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
3251 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
3198 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3199 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).?.unwrap().?);
32523200 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
3253 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
3254 pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");
3255 const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");
3201 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3202 @panic("lib/std.zig is corrupt and missing 'builtin'");
3203 pt.ensureCauAnalyzed(ip.getNav(builtin_nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3204 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.resolved.val);
3205 const builtin_namespace_index = (if (builtin_type.getNamespace(zcu)) |n| n.unwrap() else null) orelse @panic("std.builtin is corrupt");
3206 const builtin_namespace = zcu.namespacePtr(builtin_namespace_index);
32563207 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3257 return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3208 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
32583209}
32593210
32603211pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {
......@@ -3264,6 +3215,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type
32643215 return ty;
32653216}
32663217
3218pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator.Error!Type {
3219 const zcu = pt.zcu;
3220 const ip = &zcu.intern_pool;
3221 const r = ip.getNav(nav_index).status.resolved;
3222 const ty = Value.fromInterned(r.val).typeOf(zcu);
3223 return pt.ptrType(.{
3224 .child = ty.toIntern(),
3225 .flags = .{
3226 .alignment = if (r.alignment == ty.abiAlignment(pt))
3227 .none
3228 else
3229 r.alignment,
3230 .address_space = r.@"addrspace",
3231 .is_const = switch (ip.indexToKey(r.val)) {
3232 .variable => false,
3233 .@"extern" => |e| e.is_const,
3234 else => true,
3235 },
3236 },
3237 });
3238}
3239
3240/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
3241/// If necessary, the new `Nav` is queued for codegen.
3242/// `key.owner_nav` is ignored and may be `undefined`.
3243pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!InternPool.Index {
3244 const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key);
3245 if (result.new_nav.unwrap()) |nav| {
3246 try pt.zcu.comp.queueJob(.{ .codegen_nav = nav });
3247 }
3248 return result.index;
3249}
3250
3251// TODO: this shouldn't need a `PerThread`! Fix the signature of `Type.abiAlignment`.
3252pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPool.Alignment {
3253 const zcu = pt.zcu;
3254 const r = zcu.intern_pool.getNav(nav_index).status.resolved;
3255 if (r.alignment != .none) return r.alignment;
3256 return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(pt);
3257}
3258
32673259const Air = @import("../Air.zig");
32683260const Allocator = std.mem.Allocator;
32693261const assert = std.debug.assert;
src/arch/aarch64/CodeGen.zig+40-41
......@@ -52,7 +52,7 @@ bin_file: *link.File,
5252debug_output: DebugInfoOutput,
5353target: *const std.Target,
5454func_index: InternPool.Index,
55owner_decl: InternPool.DeclIndex,
55owner_nav: InternPool.Nav.Index,
5656err_msg: ?*ErrorMsg,
5757args: []MCValue,
5858ret_mcv: MCValue,
......@@ -184,7 +184,7 @@ const DbgInfoReloc = struct {
184184 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
185185 switch (function.debug_output) {
186186 .dwarf => |dw| {
187 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
187 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
188188 .register => |reg| .{ .register = reg.dwarfLocOp() },
189189 .stack_offset,
190190 .stack_argument_offset,
......@@ -202,7 +202,7 @@ const DbgInfoReloc = struct {
202202 else => unreachable, // not a possible argument
203203
204204 };
205 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.owner_decl, loc);
205 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.owner_nav, loc);
206206 },
207207 .plan9 => {},
208208 .none => {},
......@@ -218,7 +218,7 @@ const DbgInfoReloc = struct {
218218
219219 switch (function.debug_output) {
220220 .dwarf => |dw| {
221 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
221 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
222222 .register => |reg| .{ .register = reg.dwarfLocOp() },
223223 .ptr_stack_offset,
224224 .stack_offset,
......@@ -248,7 +248,7 @@ const DbgInfoReloc = struct {
248248 break :blk .nop;
249249 },
250250 };
251 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.owner_decl, is_ptr, loc);
251 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.owner_nav, is_ptr, loc);
252252 },
253253 .plan9 => {},
254254 .none => {},
......@@ -341,11 +341,9 @@ pub fn generate(
341341 const zcu = pt.zcu;
342342 const gpa = zcu.gpa;
343343 const func = zcu.funcInfo(func_index);
344 const fn_owner_decl = zcu.declPtr(func.owner_decl);
345 assert(fn_owner_decl.has_tv);
346 const fn_type = fn_owner_decl.typeOf(zcu);
347 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
348 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
344 const fn_type = Type.fromInterned(func.ty);
345 const file_scope = zcu.navFileScope(func.owner_nav);
346 const target = &file_scope.mod.resolved_target.result;
349347
350348 var branch_stack = std.ArrayList(Branch).init(gpa);
351349 defer {
......@@ -364,7 +362,7 @@ pub fn generate(
364362 .target = target,
365363 .bin_file = lf,
366364 .func_index = func_index,
367 .owner_decl = func.owner_decl,
365 .owner_nav = func.owner_nav,
368366 .err_msg = null,
369367 .args = undefined, // populated after `resolveCallingConventionValues`
370368 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
......@@ -4053,8 +4051,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
40534051 @panic("TODO store");
40544052 },
40554053 .coff => blk: {
4056 const coff_file = self.bin_file.cast(link.File.Coff).?;
4057 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
4054 const coff_file = self.bin_file.cast(.coff).?;
4055 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
40584056 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
40594057 },
40604058 else => unreachable, // unsupported target format
......@@ -4289,6 +4287,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42894287 const ty = self.typeOf(callee);
42904288 const pt = self.pt;
42914289 const mod = pt.zcu;
4290 const ip = &mod.intern_pool;
42924291
42934292 const fn_ty = switch (ty.zigTypeTag(mod)) {
42944293 .Fn => ty,
......@@ -4351,19 +4350,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43514350
43524351 // Due to incremental compilation, how function calls are generated depends
43534352 // on linking.
4354 if (try self.air.value(callee, pt)) |func_value| {
4355 if (func_value.getFunction(mod)) |func| {
4356 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4353 if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
4354 .func => |func| {
4355 if (self.bin_file.cast(.elf)) |elf_file| {
43574356 const zo = elf_file.zigObjectPtr().?;
4358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4357 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
43594358 const sym = zo.symbol(sym_index);
43604359 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
43614360 const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
43624361 try self.genSetReg(Type.usize, .x30, .{ .memory = got_addr });
4363 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4362 } else if (self.bin_file.cast(.macho)) |macho_file| {
43644363 _ = macho_file;
43654364 @panic("TODO airCall");
4366 // const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
4365 // const atom = try macho_file.getOrCreateAtomForNav(func.owner_nav);
43674366 // const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
43684367 // try self.genSetReg(Type.u64, .x30, .{
43694368 // .linker_load = .{
......@@ -4371,8 +4370,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43714370 // .sym_index = sym_index,
43724371 // },
43734372 // });
4374 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
4375 const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
4373 } else if (self.bin_file.cast(.coff)) |coff_file| {
4374 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
43764375 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
43774376 try self.genSetReg(Type.u64, .x30, .{
43784377 .linker_load = .{
......@@ -4380,8 +4379,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43804379 .sym_index = sym_index,
43814380 },
43824381 });
4383 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
4384 const atom_index = try p9.seeDecl(func.owner_decl);
4382 } else if (self.bin_file.cast(.plan9)) |p9| {
4383 const atom_index = try p9.seeNav(pt, func.owner_nav);
43854384 const atom = p9.getAtom(atom_index);
43864385 try self.genSetReg(Type.usize, .x30, .{ .memory = atom.getOffsetTableAddress(p9) });
43874386 } else unreachable;
......@@ -4390,14 +4389,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43904389 .tag = .blr,
43914390 .data = .{ .reg = .x30 },
43924391 });
4393 } else if (func_value.getExternFunc(mod)) |extern_func| {
4394 const decl_name = mod.declPtr(extern_func.decl).name.toSlice(&mod.intern_pool);
4395 const lib_name = extern_func.lib_name.toSlice(&mod.intern_pool);
4396 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4392 },
4393 .@"extern" => |@"extern"| {
4394 const nav_name = ip.getNav(@"extern".owner_nav).name.toSlice(ip);
4395 const lib_name = @"extern".lib_name.toSlice(ip);
4396 if (self.bin_file.cast(.macho)) |macho_file| {
43974397 _ = macho_file;
43984398 @panic("TODO airCall");
4399 // const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
4400 // const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
4399 // const sym_index = try macho_file.getGlobalSymbol(nav_name, lib_name);
4400 // const atom = try macho_file.getOrCreateAtomForNav(self.owner_nav);
44014401 // const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
44024402 // _ = try self.addInst(.{
44034403 // .tag = .call_extern,
......@@ -4408,8 +4408,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
44084408 // },
44094409 // },
44104410 // });
4411 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
4412 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
4411 } else if (self.bin_file.cast(.coff)) |coff_file| {
4412 const sym_index = try coff_file.getGlobalSymbol(nav_name, lib_name);
44134413 try self.genSetReg(Type.u64, .x30, .{
44144414 .linker_load = .{
44154415 .type = .import,
......@@ -4423,9 +4423,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
44234423 } else {
44244424 return self.fail("TODO implement calling extern functions", .{});
44254425 }
4426 } else {
4427 return self.fail("TODO implement calling bitcasted functions", .{});
4428 }
4426 },
4427 else => return self.fail("TODO implement calling bitcasted functions", .{}),
44294428 } else {
44304429 assert(ty.zigTypeTag(mod) == .Pointer);
44314430 const mcv = try self.resolveInst(callee);
......@@ -5594,8 +5593,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
55945593 @panic("TODO genSetStack");
55955594 },
55965595 .coff => blk: {
5597 const coff_file = self.bin_file.cast(link.File.Coff).?;
5598 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
5596 const coff_file = self.bin_file.cast(.coff).?;
5597 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
55995598 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
56005599 },
56015600 else => unreachable, // unsupported target format
......@@ -5717,8 +5716,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
57175716 // break :blk macho_file.getAtom(atom).getSymbolIndex().?;
57185717 },
57195718 .coff => blk: {
5720 const coff_file = self.bin_file.cast(link.File.Coff).?;
5721 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
5719 const coff_file = self.bin_file.cast(.coff).?;
5720 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
57225721 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
57235722 },
57245723 else => unreachable, // unsupported target format
......@@ -5915,8 +5914,8 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
59155914 // break :blk macho_file.getAtom(atom).getSymbolIndex().?;
59165915 },
59175916 .coff => blk: {
5918 const coff_file = self.bin_file.cast(link.File.Coff).?;
5919 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);
5917 const coff_file = self.bin_file.cast(.coff).?;
5918 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
59205919 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
59215920 },
59225921 else => unreachable, // unsupported target format
......@@ -6226,7 +6225,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
62266225 self.pt,
62276226 self.src_loc,
62286227 val,
6229 self.owner_decl,
6228 self.target.*,
62306229 )) {
62316230 .mcv => |mcv| switch (mcv) {
62326231 .none => .none,
src/arch/aarch64/Emit.zig+4-4
......@@ -687,7 +687,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
687687 };
688688 _ = offset;
689689
690 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
690 if (emit.bin_file.cast(.macho)) |macho_file| {
691691 _ = macho_file;
692692 @panic("TODO mirCallExtern");
693693 // // Add relocation to the decl.
......@@ -701,7 +701,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
701701 // .pcrel = true,
702702 // .length = 2,
703703 // });
704 } else if (emit.bin_file.cast(link.File.Coff)) |_| {
704 } else if (emit.bin_file.cast(.coff)) |_| {
705705 unreachable; // Calling imports is handled via `.load_memory_import`
706706 } else {
707707 return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});
......@@ -903,7 +903,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
903903 else => unreachable,
904904 }
905905
906 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
906 if (emit.bin_file.cast(.macho)) |macho_file| {
907907 _ = macho_file;
908908 @panic("TODO mirLoadMemoryPie");
909909 // const Atom = link.File.MachO.Atom;
......@@ -932,7 +932,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
932932 // else => unreachable,
933933 // },
934934 // } });
935 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
935 } else if (emit.bin_file.cast(.coff)) |coff_file| {
936936 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
937937 const target = switch (tag) {
938938 .load_memory_got,
src/arch/arm/CodeGen.zig+21-20
......@@ -262,7 +262,7 @@ const DbgInfoReloc = struct {
262262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
263263 switch (function.debug_output) {
264264 .dwarf => |dw| {
265 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
265 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
266266 .register => |reg| .{ .register = reg.dwarfLocOp() },
267267 .stack_offset,
268268 .stack_argument_offset,
......@@ -280,7 +280,7 @@ const DbgInfoReloc = struct {
280280 else => unreachable, // not a possible argument
281281 };
282282
283 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), loc);
283 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcInfo(function.func_index).owner_nav, loc);
284284 },
285285 .plan9 => {},
286286 .none => {},
......@@ -296,7 +296,7 @@ const DbgInfoReloc = struct {
296296
297297 switch (function.debug_output) {
298298 .dwarf => |dw| {
299 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
299 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
300300 .register => |reg| .{ .register = reg.dwarfLocOp() },
301301 .ptr_stack_offset,
302302 .stack_offset,
......@@ -323,7 +323,7 @@ const DbgInfoReloc = struct {
323323 break :blk .nop;
324324 },
325325 };
326 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), is_ptr, loc);
326 try dw.genVarDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcInfo(function.func_index).owner_nav, is_ptr, loc);
327327 },
328328 .plan9 => {},
329329 .none => {},
......@@ -346,11 +346,9 @@ pub fn generate(
346346 const zcu = pt.zcu;
347347 const gpa = zcu.gpa;
348348 const func = zcu.funcInfo(func_index);
349 const fn_owner_decl = zcu.declPtr(func.owner_decl);
350 assert(fn_owner_decl.has_tv);
351 const fn_type = fn_owner_decl.typeOf(zcu);
352 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
353 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
349 const func_ty = Type.fromInterned(func.ty);
350 const file_scope = zcu.navFileScope(func.owner_nav);
351 const target = &file_scope.mod.resolved_target.result;
354352
355353 var branch_stack = std.ArrayList(Branch).init(gpa);
356354 defer {
......@@ -372,7 +370,7 @@ pub fn generate(
372370 .err_msg = null,
373371 .args = undefined, // populated after `resolveCallingConventionValues`
374372 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
375 .fn_type = fn_type,
373 .fn_type = func_ty,
376374 .arg_index = 0,
377375 .branch_stack = &branch_stack,
378376 .src_loc = src_loc,
......@@ -385,7 +383,7 @@ pub fn generate(
385383 defer function.exitlude_jump_relocs.deinit(gpa);
386384 defer function.dbg_info_relocs.deinit(gpa);
387385
388 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
386 var call_info = function.resolveCallingConventionValues(func_ty) catch |err| switch (err) {
389387 error.CodegenFail => return Result{ .fail = function.err_msg.? },
390388 error.OutOfRegisters => return Result{
391389 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
......@@ -4264,6 +4262,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42644262 const ty = self.typeOf(callee);
42654263 const pt = self.pt;
42664264 const mod = pt.zcu;
4265 const ip = &mod.intern_pool;
42674266
42684267 const fn_ty = switch (ty.zigTypeTag(mod)) {
42694268 .Fn => ty,
......@@ -4333,16 +4332,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43334332
43344333 // Due to incremental compilation, how function calls are generated depends
43354334 // on linking.
4336 if (try self.air.value(callee, pt)) |func_value| {
4337 if (func_value.getFunction(mod)) |func| {
4338 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4335 if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
4336 .func => |func| {
4337 if (self.bin_file.cast(.elf)) |elf_file| {
43394338 const zo = elf_file.zigObjectPtr().?;
4340 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4339 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
43414340 const sym = zo.symbol(sym_index);
43424341 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
43434342 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
43444343 try self.genSetReg(Type.usize, .lr, .{ .memory = got_addr });
4345 } else if (self.bin_file.cast(link.File.MachO)) |_| {
4344 } else if (self.bin_file.cast(.macho)) |_| {
43464345 unreachable; // unsupported architecture for MachO
43474346 } else {
43484347 return self.fail("TODO implement call on {s} for {s}", .{
......@@ -4350,11 +4349,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43504349 @tagName(self.target.cpu.arch),
43514350 });
43524351 }
4353 } else if (func_value.getExternFunc(mod)) |_| {
4352 },
4353 .@"extern" => {
43544354 return self.fail("TODO implement calling extern functions", .{});
4355 } else {
4355 },
4356 else => {
43564357 return self.fail("TODO implement calling bitcasted functions", .{});
4357 }
4358 },
43584359 } else {
43594360 assert(ty.zigTypeTag(mod) == .Pointer);
43604361 const mcv = try self.resolveInst(callee);
......@@ -6178,7 +6179,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
61786179 pt,
61796180 self.src_loc,
61806181 val,
6181 pt.zcu.funcOwnerDeclIndex(self.func_index),
6182 self.target.*,
61826183 )) {
61836184 .mcv => |mcv| switch (mcv) {
61846185 .none => .none,
src/arch/riscv64/CodeGen.zig+40-77
......@@ -118,26 +118,18 @@ const RegisterOffset = struct { reg: Register, off: i32 = 0 };
118118pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
119119
120120const Owner = union(enum) {
121 func_index: InternPool.Index,
121 nav_index: InternPool.Nav.Index,
122122 lazy_sym: link.File.LazySymbol,
123123
124 fn getDecl(owner: Owner, zcu: *Zcu) InternPool.DeclIndex {
125 return switch (owner) {
126 .func_index => |func_index| zcu.funcOwnerDeclIndex(func_index),
127 .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(zcu),
128 };
129 }
130
131124 fn getSymbolIndex(owner: Owner, func: *Func) !u32 {
132125 const pt = func.pt;
133126 switch (owner) {
134 .func_index => |func_index| {
135 const decl_index = func.pt.zcu.funcOwnerDeclIndex(func_index);
136 const elf_file = func.bin_file.cast(link.File.Elf).?;
137 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
127 .nav_index => |nav_index| {
128 const elf_file = func.bin_file.cast(.elf).?;
129 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);
138130 },
139131 .lazy_sym => |lazy_sym| {
140 const elf_file = func.bin_file.cast(link.File.Elf).?;
132 const elf_file = func.bin_file.cast(.elf).?;
141133 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
142134 func.fail("{s} creating lazy symbol", .{@errorName(err)});
143135 },
......@@ -767,12 +759,8 @@ pub fn generate(
767759 const gpa = zcu.gpa;
768760 const ip = &zcu.intern_pool;
769761 const func = zcu.funcInfo(func_index);
770 const fn_owner_decl = zcu.declPtr(func.owner_decl);
771 assert(fn_owner_decl.has_tv);
772 const fn_type = fn_owner_decl.typeOf(zcu);
773 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
774 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
775 const mod = namespace.fileScope(zcu).mod;
762 const fn_type = Type.fromInterned(func.ty);
763 const mod = zcu.navFileScope(func.owner_nav).mod;
776764
777765 var branch_stack = std.ArrayList(Branch).init(gpa);
778766 defer {
......@@ -789,9 +777,9 @@ pub fn generate(
789777 .mod = mod,
790778 .bin_file = bin_file,
791779 .liveness = liveness,
792 .target = target,
780 .target = &mod.resolved_target.result,
793781 .debug_output = debug_output,
794 .owner = .{ .func_index = func_index },
782 .owner = .{ .nav_index = func.owner_nav },
795783 .err_msg = null,
796784 .args = undefined, // populated after `resolveCallingConventionValues`
797785 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
......@@ -818,7 +806,7 @@ pub fn generate(
818806 function.mir_instructions.deinit(gpa);
819807 }
820808
821 wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)});
809 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
822810
823811 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
824812 function.frame_allocs.set(
......@@ -1074,22 +1062,22 @@ fn fmtWipMir(func: *Func, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir)
10741062 return .{ .data = .{ .func = func, .inst = inst } };
10751063}
10761064
1077const FormatDeclData = struct {
1078 zcu: *Zcu,
1079 decl_index: InternPool.DeclIndex,
1065const FormatNavData = struct {
1066 ip: *const InternPool,
1067 nav_index: InternPool.Nav.Index,
10801068};
1081fn formatDecl(
1082 data: FormatDeclData,
1069fn formatNav(
1070 data: FormatNavData,
10831071 comptime _: []const u8,
10841072 _: std.fmt.FormatOptions,
10851073 writer: anytype,
10861074) @TypeOf(writer).Error!void {
1087 try writer.print("{}", .{data.zcu.declPtr(data.decl_index).fqn.fmt(&data.zcu.intern_pool)});
1075 try writer.print("{}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
10881076}
1089fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
1077fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
10901078 return .{ .data = .{
1091 .zcu = func.pt.zcu,
1092 .decl_index = decl_index,
1079 .ip = ip,
1080 .nav_index = nav_index,
10931081 } };
10941082}
10951083
......@@ -1393,9 +1381,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
13931381 const pt = func.pt;
13941382 const mod = pt.zcu;
13951383 const ip = &mod.intern_pool;
1396 switch (lazy_sym.ty.zigTypeTag(mod)) {
1384 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(mod)) {
13971385 .Enum => {
1398 const enum_ty = lazy_sym.ty;
1386 const enum_ty = Type.fromInterned(lazy_sym.ty);
13991387 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
14001388
14011389 const param_regs = abi.Registers.Integer.function_arg_regs;
......@@ -1408,11 +1396,11 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
14081396 const data_reg, const data_lock = try func.allocReg(.int);
14091397 defer func.register_manager.unlockReg(data_lock);
14101398
1411 const elf_file = func.bin_file.cast(link.File.Elf).?;
1399 const elf_file = func.bin_file.cast(.elf).?;
14121400 const zo = elf_file.zigObjectPtr().?;
14131401 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{
14141402 .kind = .const_data,
1415 .ty = enum_ty,
1403 .ty = enum_ty.toIntern(),
14161404 }) catch |err|
14171405 return func.fail("{s} creating lazy symbol", .{@errorName(err)});
14181406
......@@ -1479,7 +1467,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
14791467 },
14801468 else => return func.fail(
14811469 "TODO implement {s} for {}",
1482 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) },
1470 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
14831471 ),
14841472 }
14851473}
......@@ -4682,17 +4670,14 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
46824670}
46834671
46844672fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4685 const pt = func.pt;
4686 const zcu = pt.zcu;
46874673 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
46884674 const ty = arg.ty.toType();
4689 const owner_decl = func.owner.getDecl(zcu);
46904675 if (arg.name == .none) return;
46914676 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
46924677
46934678 switch (func.debug_output) {
46944679 .dwarf => |dw| switch (mcv) {
4695 .register => |reg| try dw.genArgDbgInfo(name, ty, owner_decl, .{
4680 .register => |reg| try dw.genArgDbgInfo(name, ty, func.owner.nav_index, .{
46964681 .register = reg.dwarfLocOp(),
46974682 }),
46984683 .load_frame => {},
......@@ -4940,14 +4925,14 @@ fn genCall(
49404925 switch (switch (func_key) {
49414926 else => func_key,
49424927 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
4943 .decl => |decl| zcu.intern_pool.indexToKey(zcu.declPtr(decl).val.toIntern()),
4928 .nav => |nav| zcu.intern_pool.indexToKey(zcu.navValue(nav).toIntern()),
49444929 else => func_key,
49454930 } else func_key,
49464931 }) {
49474932 .func => |func_val| {
4948 if (func.bin_file.cast(link.File.Elf)) |elf_file| {
4933 if (func.bin_file.cast(.elf)) |elf_file| {
49494934 const zo = elf_file.zigObjectPtr().?;
4950 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func_val.owner_decl);
4935 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func_val.owner_nav);
49514936
49524937 if (func.mod.pic) {
49534938 return func.fail("TODO: genCall pic", .{});
......@@ -4964,19 +4949,18 @@ fn genCall(
49644949 }
49654950 } else unreachable; // not a valid riscv64 format
49664951 },
4967 .extern_func => |extern_func| {
4968 const owner_decl = zcu.declPtr(extern_func.decl);
4969 const lib_name = extern_func.lib_name.toSlice(&zcu.intern_pool);
4970 const decl_name = owner_decl.name.toSlice(&zcu.intern_pool);
4952 .@"extern" => |@"extern"| {
4953 const lib_name = @"extern".lib_name.toSlice(&zcu.intern_pool);
4954 const name = @"extern".name.toSlice(&zcu.intern_pool);
49714955 const atom_index = try func.owner.getSymbolIndex(func);
49724956
4973 const elf_file = func.bin_file.cast(link.File.Elf).?;
4957 const elf_file = func.bin_file.cast(.elf).?;
49744958 _ = try func.addInst(.{
49754959 .tag = .pseudo_extern_fn_reloc,
49764960 .data = .{ .reloc = .{
49774961 .register = .ra,
49784962 .atom_index = atom_index,
4979 .sym_index = try elf_file.getGlobalSymbol(decl_name, lib_name),
4963 .sym_index = try elf_file.getGlobalSymbol(name, lib_name),
49804964 } },
49814965 });
49824966 },
......@@ -5213,8 +5197,6 @@ fn genVarDbgInfo(
52135197 mcv: MCValue,
52145198 name: [:0]const u8,
52155199) !void {
5216 const pt = func.pt;
5217 const zcu = pt.zcu;
52185200 const is_ptr = switch (tag) {
52195201 .dbg_var_ptr => true,
52205202 .dbg_var_val => false,
......@@ -5223,7 +5205,7 @@ fn genVarDbgInfo(
52235205
52245206 switch (func.debug_output) {
52255207 .dwarf => |dw| {
5226 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
5208 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (mcv) {
52275209 .register => |reg| .{ .register = reg.dwarfLocOp() },
52285210 .memory => |address| .{ .memory = address },
52295211 .load_symbol => |sym_off| loc: {
......@@ -5238,7 +5220,7 @@ fn genVarDbgInfo(
52385220 break :blk .nop;
52395221 },
52405222 };
5241 try dw.genVarDbgInfo(name, ty, func.owner.getDecl(zcu), is_ptr, loc);
5223 try dw.genVarDbgInfo(name, ty, func.owner.nav_index, is_ptr, loc);
52425224 },
52435225 .plan9 => {},
52445226 .none => {},
......@@ -7804,7 +7786,6 @@ fn airMemcpy(func: *Func, inst: Air.Inst.Index) !void {
78047786
78057787fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
78067788 const pt = func.pt;
7807 const zcu = pt.zcu;
78087789
78097790 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
78107791 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
......@@ -7820,7 +7801,7 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
78207801 const operand = try func.resolveInst(un_op);
78217802 try func.genSetReg(enum_ty, param_regs[1], operand);
78227803
7823 const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(zcu), zcu);
7804 const lazy_sym: link.File.LazySymbol = .{ .kind = .code, .ty = enum_ty.toIntern() };
78247805 const elf_file = func.bin_file.cast(link.File.Elf).?;
78257806 const zo = elf_file.zigObjectPtr().?;
78267807 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
......@@ -8033,32 +8014,14 @@ fn getResolvedInstValue(func: *Func, inst: Air.Inst.Index) *InstTracking {
80338014
80348015fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
80358016 const pt = func.pt;
8036 const zcu = pt.zcu;
8037 const gpa = func.gpa;
80388017
8039 const owner_decl_index = func.owner.getDecl(zcu);
80408018 const lf = func.bin_file;
80418019 const src_loc = func.src_loc;
80428020
8043 if (val.isUndef(pt.zcu)) {
8044 const local_sym_index = lf.lowerUnnamedConst(pt, val, owner_decl_index) catch |err| {
8045 const msg = try ErrorMsg.create(gpa, src_loc, "lowering unnamed undefined constant failed: {s}", .{@errorName(err)});
8046 func.err_msg = msg;
8047 return error.CodegenFail;
8048 };
8049 switch (lf.tag) {
8050 .elf => return MCValue{ .undef = local_sym_index },
8051 else => unreachable,
8052 }
8053 }
8054
8055 const result = try codegen.genTypedValue(
8056 lf,
8057 pt,
8058 src_loc,
8059 val,
8060 owner_decl_index,
8061 );
8021 const result = if (val.isUndef(pt.zcu))
8022 try lf.lowerUav(pt, val.toIntern(), .none, src_loc)
8023 else
8024 try codegen.genTypedValue(lf, pt, src_loc, val, func.target.*);
80628025 const mcv: MCValue = switch (result) {
80638026 .mcv => |mcv| switch (mcv) {
80648027 .none => .none,
src/arch/riscv64/Emit.zig+3-3
......@@ -49,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void {
4949 .Lib => emit.lower.link_mode == .static,
5050 };
5151
52 const elf_file = emit.bin_file.cast(link.File.Elf).?;
52 const elf_file = emit.bin_file.cast(.elf).?;
5353 const zo = elf_file.zigObjectPtr().?;
5454
5555 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
......@@ -81,7 +81,7 @@ pub fn emitMir(emit: *Emit) Error!void {
8181 });
8282 },
8383 .load_tlv_reloc => |symbol| {
84 const elf_file = emit.bin_file.cast(link.File.Elf).?;
84 const elf_file = emit.bin_file.cast(.elf).?;
8585 const zo = elf_file.zigObjectPtr().?;
8686
8787 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
......@@ -107,7 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void {
107107 });
108108 },
109109 .call_extern_fn_reloc => |symbol| {
110 const elf_file = emit.bin_file.cast(link.File.Elf).?;
110 const elf_file = emit.bin_file.cast(.elf).?;
111111 const zo = elf_file.zigObjectPtr().?;
112112 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
113113
src/arch/sparc64/CodeGen.zig+43-48
......@@ -273,11 +273,9 @@ pub fn generate(
273273 const zcu = pt.zcu;
274274 const gpa = zcu.gpa;
275275 const func = zcu.funcInfo(func_index);
276 const fn_owner_decl = zcu.declPtr(func.owner_decl);
277 assert(fn_owner_decl.has_tv);
278 const fn_type = fn_owner_decl.typeOf(zcu);
279 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
280 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
276 const func_ty = Type.fromInterned(func.ty);
277 const file_scope = zcu.navFileScope(func.owner_nav);
278 const target = &file_scope.mod.resolved_target.result;
281279
282280 var branch_stack = std.ArrayList(Branch).init(gpa);
283281 defer {
......@@ -300,7 +298,7 @@ pub fn generate(
300298 .err_msg = null,
301299 .args = undefined, // populated after `resolveCallingConventionValues`
302300 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
303 .fn_type = fn_type,
301 .fn_type = func_ty,
304302 .arg_index = 0,
305303 .branch_stack = &branch_stack,
306304 .src_loc = src_loc,
......@@ -312,7 +310,7 @@ pub fn generate(
312310 defer function.blocks.deinit(gpa);
313311 defer function.exitlude_jump_relocs.deinit(gpa);
314312
315 var call_info = function.resolveCallingConventionValues(fn_type, .callee) catch |err| switch (err) {
313 var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) {
316314 error.CodegenFail => return Result{ .fail = function.err_msg.? },
317315 error.OutOfRegisters => return Result{
318316 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
......@@ -1306,6 +1304,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13061304 const ty = self.typeOf(callee);
13071305 const pt = self.pt;
13081306 const mod = pt.zcu;
1307 const ip = &mod.intern_pool;
13091308 const fn_ty = switch (ty.zigTypeTag(mod)) {
13101309 .Fn => ty,
13111310 .Pointer => ty.childType(mod),
......@@ -1349,46 +1348,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13491348
13501349 // Due to incremental compilation, how function calls are generated depends
13511350 // on linking.
1352 if (try self.air.value(callee, pt)) |func_value| {
1353 if (self.bin_file.tag == link.File.Elf.base_tag) {
1354 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
1355 .func => |func| {
1356 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
1357 const zo = elf_file.zigObjectPtr().?;
1358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1359 const sym = zo.symbol(sym_index);
1360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
1361 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));
1362 } else unreachable;
1363
1364 try self.genSetReg(Type.usize, .o7, .{ .memory = got_addr });
1365
1366 _ = try self.addInst(.{
1367 .tag = .jmpl,
1368 .data = .{
1369 .arithmetic_3op = .{
1370 .is_imm = false,
1371 .rd = .o7,
1372 .rs1 = .o7,
1373 .rs2_or_imm = .{ .rs2 = .g0 },
1374 },
1375 },
1376 });
1351 if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
1352 .func => |func| {
1353 const got_addr = if (self.bin_file.cast(.elf)) |elf_file| blk: {
1354 const zo = elf_file.zigObjectPtr().?;
1355 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
1356 const sym = zo.symbol(sym_index);
1357 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
1358 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));
1359 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");
1360
1361 try self.genSetReg(Type.usize, .o7, .{ .memory = got_addr });
13771362
1378 // TODO Find a way to fill this delay slot
1379 _ = try self.addInst(.{
1380 .tag = .nop,
1381 .data = .{ .nop = {} },
1382 });
1383 },
1384 .extern_func => {
1385 return self.fail("TODO implement calling extern functions", .{});
1386 },
1387 else => {
1388 return self.fail("TODO implement calling bitcasted functions", .{});
1363 _ = try self.addInst(.{
1364 .tag = .jmpl,
1365 .data = .{
1366 .arithmetic_3op = .{
1367 .is_imm = false,
1368 .rd = .o7,
1369 .rs1 = .o7,
1370 .rs2_or_imm = .{ .rs2 = .g0 },
1371 },
13891372 },
1390 }
1391 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");
1373 });
1374
1375 // TODO Find a way to fill this delay slot
1376 _ = try self.addInst(.{
1377 .tag = .nop,
1378 .data = .{ .nop = {} },
1379 });
1380 },
1381 .@"extern" => {
1382 return self.fail("TODO implement calling extern functions", .{});
1383 },
1384 else => {
1385 return self.fail("TODO implement calling bitcasted functions", .{});
1386 },
13921387 } else {
13931388 assert(ty.zigTypeTag(mod) == .Pointer);
13941389 const mcv = try self.resolveInst(callee);
......@@ -3614,13 +3609,13 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
36143609 const mod = pt.zcu;
36153610 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
36163611 const ty = arg.ty.toType();
3617 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
3612 const owner_nav = mod.funcInfo(self.func_index).owner_nav;
36183613 if (arg.name == .none) return;
36193614 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
36203615
36213616 switch (self.debug_output) {
36223617 .dwarf => |dw| switch (mcv) {
3623 .register => |reg| try dw.genArgDbgInfo(name, ty, owner_decl, .{
3618 .register => |reg| try dw.genArgDbgInfo(name, ty, owner_nav, .{
36243619 .register = reg.dwarfLocOp(),
36253620 }),
36263621 else => {},
......@@ -4153,7 +4148,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
41534148 pt,
41544149 self.src_loc,
41554150 val,
4156 pt.zcu.funcOwnerDeclIndex(self.func_index),
4151 self.target.*,
41574152 )) {
41584153 .mcv => |mcv| switch (mcv) {
41594154 .none => .none,
src/arch/wasm/CodeGen.zig+194-197
......@@ -640,8 +640,8 @@ const CodeGen = @This();
640640
641641/// Reference to the function declaration the code
642642/// section belongs to
643decl: *Decl,
644decl_index: InternPool.DeclIndex,
643owner_nav: InternPool.Nav.Index,
644src_loc: Zcu.LazySrcLoc,
645645/// Current block depth. Used to calculate the relative difference between a break
646646/// and block
647647block_depth: u32 = 0,
......@@ -681,7 +681,7 @@ locals: std.ArrayListUnmanaged(u8),
681681/// are enabled also.
682682simd_immediates: std.ArrayListUnmanaged([16]u8) = .{},
683683/// The Target we're emitting (used to call intInfo)
684target: std.Target,
684target: *const std.Target,
685685/// Represents the wasm binary file that is being linked.
686686bin_file: *link.File.Wasm,
687687pt: Zcu.PerThread,
......@@ -765,8 +765,7 @@ pub fn deinit(func: *CodeGen) void {
765765
766766/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
767767fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
768 const src_loc = func.decl.navSrcLoc(func.pt.zcu);
769 func.err_msg = try Zcu.ErrorMsg.create(func.gpa, src_loc, fmt, args);
768 func.err_msg = try Zcu.ErrorMsg.create(func.gpa, func.src_loc, fmt, args);
770769 return error.CodegenFail;
771770}
772771
......@@ -803,8 +802,14 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
803802 //
804803 // In the other cases, we will simply lower the constant to a value that fits
805804 // into a single local (such as a pointer, integer, bool, etc).
806 const result: WValue = if (isByRef(ty, pt))
807 .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index) }
805 const result: WValue = if (isByRef(ty, pt, func.target.*))
806 switch (try func.bin_file.lowerUav(pt, val.toIntern(), .none, func.src_loc)) {
807 .mcv => |mcv| .{ .memory = mcv.load_symbol },
808 .fail => |err_msg| {
809 func.err_msg = err_msg;
810 return error.CodegenFail;
811 },
812 }
808813 else
809814 try func.lowerConstant(val, ty);
810815
......@@ -995,9 +1000,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32
9951000}
9961001
9971002/// Using a given `Type`, returns the corresponding valtype for .auto callconv
998fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
1003fn typeToValtype(ty: Type, pt: Zcu.PerThread, target: std.Target) wasm.Valtype {
9991004 const mod = pt.zcu;
1000 const target = mod.getTarget();
10011005 const ip = &mod.intern_pool;
10021006 return switch (ty.zigTypeTag(mod)) {
10031007 .Float => switch (ty.floatBits(target)) {
......@@ -1015,19 +1019,19 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
10151019 .Struct => blk: {
10161020 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {
10171021 const backing_int_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
1018 break :blk typeToValtype(backing_int_ty, pt);
1022 break :blk typeToValtype(backing_int_ty, pt, target);
10191023 } else {
10201024 break :blk .i32;
10211025 }
10221026 },
1023 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {
1027 .Vector => switch (determineSimdStoreStrategy(ty, pt, target)) {
10241028 .direct => .v128,
10251029 .unrolled => .i32,
10261030 },
10271031 .Union => switch (ty.containerLayout(pt.zcu)) {
10281032 .@"packed" => blk: {
10291033 const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(pt)))) catch @panic("out of memory");
1030 break :blk typeToValtype(int_ty, pt);
1034 break :blk typeToValtype(int_ty, pt, target);
10311035 },
10321036 else => .i32,
10331037 },
......@@ -1036,17 +1040,17 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
10361040}
10371041
10381042/// Using a given `Type`, returns the byte representation of its wasm value type
1039fn genValtype(ty: Type, pt: Zcu.PerThread) u8 {
1040 return wasm.valtype(typeToValtype(ty, pt));
1043fn genValtype(ty: Type, pt: Zcu.PerThread, target: std.Target) u8 {
1044 return wasm.valtype(typeToValtype(ty, pt, target));
10411045}
10421046
10431047/// Using a given `Type`, returns the corresponding wasm value type
10441048/// Differently from `genValtype` this also allows `void` to create a block
10451049/// with no return type
1046fn genBlockType(ty: Type, pt: Zcu.PerThread) u8 {
1050fn genBlockType(ty: Type, pt: Zcu.PerThread, target: std.Target) u8 {
10471051 return switch (ty.ip_index) {
10481052 .void_type, .noreturn_type => wasm.block_empty,
1049 else => genValtype(ty, pt),
1053 else => genValtype(ty, pt, target),
10501054 };
10511055}
10521056
......@@ -1108,7 +1112,7 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
11081112/// Returns a corresponding `Wvalue` with `local` as active tag
11091113fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11101114 const pt = func.pt;
1111 const valtype = typeToValtype(ty, pt);
1115 const valtype = typeToValtype(ty, pt, func.target.*);
11121116 const index_or_null = switch (valtype) {
11131117 .i32 => func.free_locals_i32.popOrNull(),
11141118 .i64 => func.free_locals_i64.popOrNull(),
......@@ -1128,7 +1132,7 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11281132/// to use a zero-initialized local.
11291133fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11301134 const pt = func.pt;
1131 try func.locals.append(func.gpa, genValtype(ty, pt));
1135 try func.locals.append(func.gpa, genValtype(ty, pt, func.target.*));
11321136 const initial_index = func.local_index;
11331137 func.local_index += 1;
11341138 return .{ .local = .{ .value = initial_index, .references = 1 } };
......@@ -1142,6 +1146,7 @@ fn genFunctype(
11421146 params: []const InternPool.Index,
11431147 return_type: Type,
11441148 pt: Zcu.PerThread,
1149 target: std.Target,
11451150) !wasm.Type {
11461151 const mod = pt.zcu;
11471152 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);
......@@ -1149,16 +1154,16 @@ fn genFunctype(
11491154 var returns = std.ArrayList(wasm.Valtype).init(gpa);
11501155 defer returns.deinit();
11511156
1152 if (firstParamSRet(cc, return_type, pt)) {
1157 if (firstParamSRet(cc, return_type, pt, target)) {
11531158 try temp_params.append(.i32); // memory address is always a 32-bit handle
11541159 } else if (return_type.hasRuntimeBitsIgnoreComptime(pt)) {
11551160 if (cc == .C) {
11561161 const res_classes = abi.classifyType(return_type, pt);
11571162 assert(res_classes[0] == .direct and res_classes[1] == .none);
11581163 const scalar_type = abi.scalarType(return_type, pt);
1159 try returns.append(typeToValtype(scalar_type, pt));
1164 try returns.append(typeToValtype(scalar_type, pt, target));
11601165 } else {
1161 try returns.append(typeToValtype(return_type, pt));
1166 try returns.append(typeToValtype(return_type, pt, target));
11621167 }
11631168 } else if (return_type.isError(mod)) {
11641169 try returns.append(.i32);
......@@ -1175,9 +1180,9 @@ fn genFunctype(
11751180 if (param_classes[1] == .none) {
11761181 if (param_classes[0] == .direct) {
11771182 const scalar_type = abi.scalarType(param_type, pt);
1178 try temp_params.append(typeToValtype(scalar_type, pt));
1183 try temp_params.append(typeToValtype(scalar_type, pt, target));
11791184 } else {
1180 try temp_params.append(typeToValtype(param_type, pt));
1185 try temp_params.append(typeToValtype(param_type, pt, target));
11811186 }
11821187 } else {
11831188 // i128/f128
......@@ -1185,7 +1190,7 @@ fn genFunctype(
11851190 try temp_params.append(.i64);
11861191 }
11871192 },
1188 else => try temp_params.append(typeToValtype(param_type, pt)),
1193 else => try temp_params.append(typeToValtype(param_type, pt, target)),
11891194 }
11901195 }
11911196
......@@ -1205,25 +1210,23 @@ pub fn generate(
12051210 code: *std.ArrayList(u8),
12061211 debug_output: codegen.DebugInfoOutput,
12071212) codegen.CodeGenError!codegen.Result {
1208 _ = src_loc;
12091213 const zcu = pt.zcu;
12101214 const gpa = zcu.gpa;
12111215 const func = zcu.funcInfo(func_index);
1212 const decl = zcu.declPtr(func.owner_decl);
1213 const namespace = zcu.namespacePtr(decl.src_namespace);
1214 const target = namespace.fileScope(zcu).mod.resolved_target.result;
1216 const file_scope = zcu.navFileScope(func.owner_nav);
1217 const target = &file_scope.mod.resolved_target.result;
12151218 var code_gen: CodeGen = .{
12161219 .gpa = gpa,
12171220 .pt = pt,
12181221 .air = air,
12191222 .liveness = liveness,
12201223 .code = code,
1221 .decl_index = func.owner_decl,
1222 .decl = decl,
1224 .owner_nav = func.owner_nav,
1225 .src_loc = src_loc,
12231226 .err_msg = undefined,
12241227 .locals = .{},
12251228 .target = target,
1226 .bin_file = bin_file.cast(link.File.Wasm).?,
1229 .bin_file = bin_file.cast(.wasm).?,
12271230 .debug_output = debug_output,
12281231 .func_index = func_index,
12291232 };
......@@ -1241,12 +1244,13 @@ fn genFunc(func: *CodeGen) InnerError!void {
12411244 const pt = func.pt;
12421245 const mod = pt.zcu;
12431246 const ip = &mod.intern_pool;
1244 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
1245 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt);
1247 const fn_ty = mod.navValue(func.owner_nav).typeOf(mod);
1248 const fn_info = mod.typeToFunc(fn_ty).?;
1249 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt, func.target.*);
12461250 defer func_type.deinit(func.gpa);
1247 _ = try func.bin_file.storeDeclType(func.decl_index, func_type);
1251 _ = try func.bin_file.storeNavType(func.owner_nav, func_type);
12481252
1249 var cc_result = try func.resolveCallingConventionValues(func.decl.typeOf(mod));
1253 var cc_result = try func.resolveCallingConventionValues(fn_ty);
12501254 defer cc_result.deinit(func.gpa);
12511255
12521256 func.args = cc_result.args;
......@@ -1324,7 +1328,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
13241328 .bin_file = func.bin_file,
13251329 .code = func.code,
13261330 .locals = func.locals.items,
1327 .decl_index = func.decl_index,
1331 .owner_nav = func.owner_nav,
13281332 .dbg_output = func.debug_output,
13291333 .prev_di_line = 0,
13301334 .prev_di_column = 0,
......@@ -1367,7 +1371,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13671371
13681372 // Check if we store the result as a pointer to the stack rather than
13691373 // by value
1370 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {
1374 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*)) {
13711375 // the sret arg will be passed as first argument, therefore we
13721376 // set the `return_value` before allocating locals for regular args.
13731377 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };
......@@ -1401,9 +1405,9 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
14011405 return result;
14021406}
14031407
1404fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread) bool {
1408fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread, target: std.Target) bool {
14051409 switch (cc) {
1406 .Unspecified, .Inline => return isByRef(return_type, pt),
1410 .Unspecified, .Inline => return isByRef(return_type, pt, target),
14071411 .C => {
14081412 const ty_classes = abi.classifyType(return_type, pt);
14091413 if (ty_classes[0] == .indirect) return true;
......@@ -1711,10 +1715,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
17111715
17121716/// For a given `Type`, will return true when the type will be passed
17131717/// by reference, rather than by value
1714fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
1718fn isByRef(ty: Type, pt: Zcu.PerThread, target: std.Target) bool {
17151719 const mod = pt.zcu;
17161720 const ip = &mod.intern_pool;
1717 const target = mod.getTarget();
17181721 switch (ty.zigTypeTag(mod)) {
17191722 .Type,
17201723 .ComptimeInt,
......@@ -1746,11 +1749,11 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
17461749 },
17471750 .Struct => {
17481751 if (mod.typeToPackedStruct(ty)) |packed_struct| {
1749 return isByRef(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt);
1752 return isByRef(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), pt, target);
17501753 }
17511754 return ty.hasRuntimeBitsIgnoreComptime(pt);
17521755 },
1753 .Vector => return determineSimdStoreStrategy(ty, pt) == .unrolled,
1756 .Vector => return determineSimdStoreStrategy(ty, pt, target) == .unrolled,
17541757 .Int => return ty.intInfo(mod).bits > 64,
17551758 .Enum => return ty.intInfo(mod).bits > 64,
17561759 .Float => return ty.floatBits(target) > 64,
......@@ -1784,11 +1787,10 @@ const SimdStoreStrategy = enum {
17841787/// This means when a given type is 128 bits and either the simd128 or relaxed-simd
17851788/// features are enabled, the function will return `.direct`. This would allow to store
17861789/// it using a instruction, rather than an unrolled version.
1787fn determineSimdStoreStrategy(ty: Type, pt: Zcu.PerThread) SimdStoreStrategy {
1790fn determineSimdStoreStrategy(ty: Type, pt: Zcu.PerThread, target: std.Target) SimdStoreStrategy {
17881791 std.debug.assert(ty.zigTypeTag(pt.zcu) == .Vector);
17891792 if (ty.bitSize(pt) != 128) return .unrolled;
17901793 const hasFeature = std.Target.wasm.featureSetHas;
1791 const target = pt.zcu.getTarget();
17921794 const features = target.cpu.features;
17931795 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {
17941796 return .direct;
......@@ -2091,7 +2093,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20912093 const mod = pt.zcu;
20922094 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
20932095 const operand = try func.resolveInst(un_op);
2094 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
2096 const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?;
20952097 const ret_ty = Type.fromInterned(fn_info.return_type);
20962098
20972099 // result must be stored in the stack and we return a pointer
......@@ -2108,7 +2110,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21082110 .op = .load,
21092111 .width = @as(u8, @intCast(scalar_type.abiSize(pt) * 8)),
21102112 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
2111 .valtype1 = typeToValtype(scalar_type, pt),
2113 .valtype1 = typeToValtype(scalar_type, pt, func.target.*),
21122114 });
21132115 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
21142116 .offset = operand.offset(),
......@@ -2140,8 +2142,8 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21402142 break :result try func.allocStack(Type.usize); // create pointer to void
21412143 }
21422144
2143 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
2144 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {
2145 const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?;
2146 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*)) {
21452147 break :result func.return_value;
21462148 }
21472149
......@@ -2158,12 +2160,12 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21582160 const operand = try func.resolveInst(un_op);
21592161 const ret_ty = func.typeOf(un_op).childType(mod);
21602162
2161 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;
2163 const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?;
21622164 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
21632165 if (ret_ty.isError(mod)) {
21642166 try func.addImm32(0);
21652167 }
2166 } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {
2168 } else if (!firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*)) {
21672169 // leave on the stack
21682170 _ = try func.load(operand, ret_ty, 0);
21692171 }
......@@ -2190,34 +2192,43 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
21902192 };
21912193 const ret_ty = fn_ty.fnReturnType(mod);
21922194 const fn_info = mod.typeToFunc(fn_ty).?;
2193 const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt);
2195 const first_param_sret = firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*);
21942196
2195 const callee: ?InternPool.DeclIndex = blk: {
2197 const callee: ?InternPool.Nav.Index = blk: {
21962198 const func_val = (try func.air.value(pl_op.operand, pt)) orelse break :blk null;
21972199
2198 if (func_val.getFunction(mod)) |function| {
2199 _ = try func.bin_file.getOrCreateAtomForDecl(pt, function.owner_decl);
2200 break :blk function.owner_decl;
2201 } else if (func_val.getExternFunc(mod)) |extern_func| {
2202 const ext_decl = mod.declPtr(extern_func.decl);
2203 const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?;
2204 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), pt);
2205 defer func_type.deinit(func.gpa);
2206 const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, extern_func.decl);
2207 const atom = func.bin_file.getAtomPtr(atom_index);
2208 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
2209 try func.bin_file.addOrUpdateImport(
2210 ext_decl.name.toSlice(&mod.intern_pool),
2211 atom.sym_index,
2212 ext_decl.getOwnedExternFunc(mod).?.lib_name.toSlice(&mod.intern_pool),
2213 type_index,
2214 );
2215 break :blk extern_func.decl;
2216 } else switch (mod.intern_pool.indexToKey(func_val.ip_index)) {
2200 switch (ip.indexToKey(func_val.toIntern())) {
2201 .func => |function| {
2202 _ = try func.bin_file.getOrCreateAtomForNav(pt, function.owner_nav);
2203 break :blk function.owner_nav;
2204 },
2205 .@"extern" => |@"extern"| {
2206 const ext_nav = ip.getNav(@"extern".owner_nav);
2207 const ext_info = mod.typeToFunc(Type.fromInterned(@"extern".ty)).?;
2208 var func_type = try genFunctype(
2209 func.gpa,
2210 ext_info.cc,
2211 ext_info.param_types.get(ip),
2212 Type.fromInterned(ext_info.return_type),
2213 pt,
2214 func.target.*,
2215 );
2216 defer func_type.deinit(func.gpa);
2217 const atom_index = try func.bin_file.getOrCreateAtomForNav(pt, @"extern".owner_nav);
2218 const atom = func.bin_file.getAtomPtr(atom_index);
2219 const type_index = try func.bin_file.storeNavType(@"extern".owner_nav, func_type);
2220 try func.bin_file.addOrUpdateImport(
2221 ext_nav.name.toSlice(ip),
2222 atom.sym_index,
2223 @"extern".lib_name.toSlice(ip),
2224 type_index,
2225 );
2226 break :blk @"extern".owner_nav;
2227 },
22172228 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
2218 .decl => |decl| {
2219 _ = try func.bin_file.getOrCreateAtomForDecl(pt, decl);
2220 break :blk decl;
2229 .nav => |nav| {
2230 _ = try func.bin_file.getOrCreateAtomForNav(pt, nav);
2231 break :blk nav;
22212232 },
22222233 else => {},
22232234 },
......@@ -2242,7 +2253,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22422253 }
22432254
22442255 if (callee) |direct| {
2245 const atom_index = func.bin_file.zigObjectPtr().?.decls_map.get(direct).?.atom;
2256 const atom_index = func.bin_file.zigObjectPtr().?.navs.get(direct).?.atom;
22462257 try func.addLabel(.call, @intFromEnum(func.bin_file.getAtom(atom_index).sym_index));
22472258 } else {
22482259 // in this case we call a function pointer
......@@ -2251,7 +2262,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22512262 const operand = try func.resolveInst(pl_op.operand);
22522263 try func.emitWValue(operand);
22532264
2254 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt);
2265 var fn_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), pt, func.target.*);
22552266 defer fn_type.deinit(func.gpa);
22562267
22572268 const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type);
......@@ -2315,7 +2326,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23152326 // load the value, and then shift+or the rhs into the result location.
23162327 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
23172328
2318 if (isByRef(int_elem_ty, pt)) {
2329 if (isByRef(int_elem_ty, pt, func.target.*)) {
23192330 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
23202331 }
23212332
......@@ -2381,11 +2392,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
23812392 const len = @as(u32, @intCast(abi_size));
23822393 return func.memcpy(lhs, rhs, .{ .imm32 = len });
23832394 },
2384 .Struct, .Array, .Union => if (isByRef(ty, pt)) {
2395 .Struct, .Array, .Union => if (isByRef(ty, pt, func.target.*)) {
23852396 const len = @as(u32, @intCast(abi_size));
23862397 return func.memcpy(lhs, rhs, .{ .imm32 = len });
23872398 },
2388 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {
2399 .Vector => switch (determineSimdStoreStrategy(ty, pt, func.target.*)) {
23892400 .unrolled => {
23902401 const len: u32 = @intCast(abi_size);
23912402 return func.memcpy(lhs, rhs, .{ .imm32 = len });
......@@ -2443,7 +2454,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24432454 // into lhs, so we calculate that and emit that instead
24442455 try func.lowerToStack(rhs);
24452456
2446 const valtype = typeToValtype(ty, pt);
2457 const valtype = typeToValtype(ty, pt, func.target.*);
24472458 const opcode = buildOpcode(.{
24482459 .valtype1 = valtype,
24492460 .width = @as(u8, @intCast(abi_size * 8)),
......@@ -2472,7 +2483,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24722483 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{ty_op.operand});
24732484
24742485 const result = result: {
2475 if (isByRef(ty, pt)) {
2486 if (isByRef(ty, pt, func.target.*)) {
24762487 const new_local = try func.allocStack(ty);
24772488 try func.store(new_local, operand, ty, 0);
24782489 break :result new_local;
......@@ -2522,7 +2533,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25222533
25232534 const abi_size: u8 = @intCast(ty.abiSize(pt));
25242535 const opcode = buildOpcode(.{
2525 .valtype1 = typeToValtype(ty, pt),
2536 .valtype1 = typeToValtype(ty, pt, func.target.*),
25262537 .width = abi_size * 8,
25272538 .op = .load,
25282539 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
......@@ -2544,7 +2555,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25442555 const mod = pt.zcu;
25452556 const arg_index = func.arg_index;
25462557 const arg = func.args[arg_index];
2547 const cc = mod.typeToFunc(func.decl.typeOf(mod)).?.cc;
2558 const cc = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?.cc;
25482559 const arg_ty = func.typeOfIndex(inst);
25492560 if (cc == .C) {
25502561 const arg_classes = abi.classifyType(arg_ty, pt);
......@@ -2577,7 +2588,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25772588 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
25782589 if (name_nts != .none) {
25792590 const name = func.air.nullTerminatedString(@intFromEnum(name_nts));
2580 try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
2591 try dwarf.genArgDbgInfo(name, arg_ty, func.owner_nav, .{
25812592 .wasm_local = arg.local.value,
25822593 });
25832594 }
......@@ -2631,7 +2642,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26312642 return func.floatOp(float_op, ty, &.{ lhs, rhs });
26322643 }
26332644
2634 if (isByRef(ty, pt)) {
2645 if (isByRef(ty, pt, func.target.*)) {
26352646 if (ty.zigTypeTag(mod) == .Int) {
26362647 return func.binOpBigInt(lhs, rhs, ty, op);
26372648 } else {
......@@ -2644,7 +2655,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26442655
26452656 const opcode: wasm.Opcode = buildOpcode(.{
26462657 .op = op,
2647 .valtype1 = typeToValtype(ty, pt),
2658 .valtype1 = typeToValtype(ty, pt, func.target.*),
26482659 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
26492660 });
26502661 try func.emitWValue(lhs);
......@@ -2896,7 +2907,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
28962907 return func.fail("TODO: Implement floatOps for vectors", .{});
28972908 }
28982909
2899 const float_bits = ty.floatBits(func.target);
2910 const float_bits = ty.floatBits(func.target.*);
29002911
29012912 if (float_op == .neg) {
29022913 return func.floatNeg(ty, args[0]);
......@@ -2907,7 +2918,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
29072918 for (args) |operand| {
29082919 try func.emitWValue(operand);
29092920 }
2910 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, pt) });
2921 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, pt, func.target.*) });
29112922 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
29122923 return .stack;
29132924 }
......@@ -2955,7 +2966,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
29552966
29562967/// NOTE: The result value remains on top of the stack.
29572968fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue {
2958 const float_bits = ty.floatBits(func.target);
2969 const float_bits = ty.floatBits(func.target.*);
29592970 switch (float_bits) {
29602971 16 => {
29612972 try func.emitWValue(arg);
......@@ -3115,8 +3126,8 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
31153126 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
31163127 const offset: u64 = prev_offset + ptr.byte_offset;
31173128 return switch (ptr.base_addr) {
3118 .decl => |decl| return func.lowerDeclRefValue(decl, @intCast(offset)),
3119 .anon_decl => |ad| return func.lowerAnonDeclRef(ad, @intCast(offset)),
3129 .nav => |nav| return func.lowerNavRef(nav, @intCast(offset)),
3130 .uav => |uav| return func.lowerUavRef(uav, @intCast(offset)),
31203131 .int => return func.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
31213132 .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}),
31223133 .opt_payload => |opt_ptr| return func.lowerPtr(opt_ptr, offset),
......@@ -3128,7 +3139,7 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
31283139 assert(base_ty.isSlice(zcu));
31293140 break :off switch (field.index) {
31303141 Value.slice_ptr_index => 0,
3131 Value.slice_len_index => @divExact(zcu.getTarget().ptrBitWidth(), 8),
3142 Value.slice_len_index => @divExact(func.target.ptrBitWidth(), 8),
31323143 else => unreachable,
31333144 };
31343145 },
......@@ -3160,32 +3171,29 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
31603171 };
31613172}
31623173
3163fn lowerAnonDeclRef(
3174fn lowerUavRef(
31643175 func: *CodeGen,
3165 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
3176 uav: InternPool.Key.Ptr.BaseAddr.Uav,
31663177 offset: u32,
31673178) InnerError!WValue {
31683179 const pt = func.pt;
31693180 const mod = pt.zcu;
3170 const decl_val = anon_decl.val;
3171 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
3181 const ty = Type.fromInterned(mod.intern_pool.typeOf(uav.val));
31723182
31733183 const is_fn_body = ty.zigTypeTag(mod) == .Fn;
31743184 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) {
31753185 return .{ .imm32 = 0xaaaaaaaa };
31763186 }
31773187
3178 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
3179 const res = try func.bin_file.lowerAnonDecl(pt, decl_val, decl_align, func.decl.navSrcLoc(mod));
3180 switch (res) {
3181 .ok => {},
3182 .fail => |em| {
3183 func.err_msg = em;
3188 const decl_align = mod.intern_pool.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
3189 const res = try func.bin_file.lowerUav(pt, uav.val, decl_align, func.src_loc);
3190 const target_sym_index = switch (res) {
3191 .mcv => |mcv| mcv.load_symbol,
3192 .fail => |err_msg| {
3193 func.err_msg = err_msg;
31843194 return error.CodegenFail;
31853195 },
3186 }
3187 const target_atom_index = func.bin_file.zigObjectPtr().?.anon_decls.get(decl_val).?;
3188 const target_sym_index = @intFromEnum(func.bin_file.getAtom(target_atom_index).sym_index);
3196 };
31893197 if (is_fn_body) {
31903198 return .{ .function_index = target_sym_index };
31913199 } else if (offset == 0) {
......@@ -3193,32 +3201,29 @@ fn lowerAnonDeclRef(
31933201 } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
31943202}
31953203
3196fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3204fn lowerNavRef(func: *CodeGen, nav_index: InternPool.Nav.Index, offset: u32) InnerError!WValue {
31973205 const pt = func.pt;
31983206 const mod = pt.zcu;
3207 const ip = &mod.intern_pool;
31993208
3200 const decl = mod.declPtr(decl_index);
32013209 // check if decl is an alias to a function, in which case we
32023210 // want to lower the actual decl, rather than the alias itself.
3203 if (decl.val.getFunction(mod)) |func_val| {
3204 if (func_val.owner_decl != decl_index) {
3205 return func.lowerDeclRefValue(func_val.owner_decl, offset);
3206 }
3207 } else if (decl.val.getExternFunc(mod)) |func_val| {
3208 if (func_val.decl != decl_index) {
3209 return func.lowerDeclRefValue(func_val.decl, offset);
3210 }
3211 }
3212 const decl_ty = decl.typeOf(mod);
3213 if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3211 const owner_nav = switch (ip.indexToKey(mod.navValue(nav_index).toIntern())) {
3212 .func => |function| function.owner_nav,
3213 .variable => |variable| variable.owner_nav,
3214 .@"extern" => |@"extern"| @"extern".owner_nav,
3215 else => nav_index,
3216 };
3217 const nav_ty = ip.getNav(owner_nav).typeOf(ip);
3218 if (!ip.isFunctionType(nav_ty) and !Type.fromInterned(nav_ty).hasRuntimeBitsIgnoreComptime(pt)) {
32143219 return .{ .imm32 = 0xaaaaaaaa };
32153220 }
32163221
3217 const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, decl_index);
3222 const atom_index = try func.bin_file.getOrCreateAtomForNav(pt, nav_index);
32183223 const atom = func.bin_file.getAtom(atom_index);
32193224
32203225 const target_sym_index = @intFromEnum(atom.sym_index);
3221 if (decl_ty.zigTypeTag(mod) == .Fn) {
3226 if (ip.isFunctionType(nav_ty)) {
32223227 return .{ .function_index = target_sym_index };
32233228 } else if (offset == 0) {
32243229 return .{ .memory = target_sym_index };
......@@ -3229,7 +3234,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
32293234fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32303235 const pt = func.pt;
32313236 const mod = pt.zcu;
3232 assert(!isByRef(ty, pt));
3237 assert(!isByRef(ty, pt, func.target.*));
32333238 const ip = &mod.intern_pool;
32343239 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);
32353240
......@@ -3268,7 +3273,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32683273 } },
32693274 },
32703275 .variable,
3271 .extern_func,
3276 .@"extern",
32723277 .func,
32733278 .enum_literal,
32743279 .empty_enum_value,
......@@ -3325,16 +3330,12 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33253330 .f64 => |f64_val| return .{ .float64 = f64_val },
33263331 else => unreachable,
33273332 },
3328 .slice => |slice| {
3329 var ptr = ip.indexToKey(slice.ptr).ptr;
3330 const owner_decl = while (true) switch (ptr.base_addr) {
3331 .decl => |decl| break decl,
3332 .int, .anon_decl => return func.fail("Wasm TODO: lower slice where ptr is not owned by decl", .{}),
3333 .opt_payload, .eu_payload => |base| ptr = ip.indexToKey(base).ptr,
3334 .field => |base_index| ptr = ip.indexToKey(base_index.base).ptr,
3335 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
3336 };
3337 return .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, owner_decl) };
3333 .slice => switch (try func.bin_file.lowerUav(pt, val.toIntern(), .none, func.src_loc)) {
3334 .mcv => |mcv| return .{ .memory = mcv.load_symbol },
3335 .fail => |err_msg| {
3336 func.err_msg = err_msg;
3337 return error.CodegenFail;
3338 },
33383339 },
33393340 .ptr => return func.lowerPtr(val.toIntern(), 0),
33403341 .opt => if (ty.optionalReprIsPayload(mod)) {
......@@ -3350,7 +3351,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33503351 .aggregate => switch (ip.indexToKey(ty.ip_index)) {
33513352 .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),
33523353 .vector_type => {
3353 assert(determineSimdStoreStrategy(ty, pt) == .direct);
3354 assert(determineSimdStoreStrategy(ty, pt, func.target.*) == .direct);
33543355 var buf: [16]u8 = undefined;
33553356 val.writeToMemory(ty, pt, &buf) catch unreachable;
33563357 return func.storeSimdImmd(buf);
......@@ -3405,7 +3406,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
34053406 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
34063407 else => unreachable,
34073408 },
3408 .Float => switch (ty.floatBits(func.target)) {
3409 .Float => switch (ty.floatBits(func.target.*)) {
34093410 16 => return .{ .imm32 = 0xaaaaaaaa },
34103411 32 => return .{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },
34113412 64 => return .{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
......@@ -3480,11 +3481,11 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
34803481
34813482fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
34823483 const pt = func.pt;
3483 const wasm_block_ty = genBlockType(block_ty, pt);
3484 const wasm_block_ty = genBlockType(block_ty, pt, func.target.*);
34843485
34853486 // if wasm_block_ty is non-empty, we create a register to store the temporary value
34863487 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
3487 const ty: Type = if (isByRef(block_ty, pt)) Type.u32 else block_ty;
3488 const ty: Type = if (isByRef(block_ty, pt, func.target.*)) Type.u32 else block_ty;
34883489 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
34893490 } else .none;
34903491
......@@ -3608,7 +3609,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
36083609 }
36093610 } else if (ty.isAnyFloat()) {
36103611 return func.cmpFloat(ty, lhs, rhs, op);
3611 } else if (isByRef(ty, pt)) {
3612 } else if (isByRef(ty, pt, func.target.*)) {
36123613 return func.cmpBigInt(lhs, rhs, ty, op);
36133614 }
36143615
......@@ -3626,7 +3627,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
36263627 try func.lowerToStack(rhs);
36273628
36283629 const opcode: wasm.Opcode = buildOpcode(.{
3629 .valtype1 = typeToValtype(ty, pt),
3630 .valtype1 = typeToValtype(ty, pt, func.target.*),
36303631 .op = switch (op) {
36313632 .lt => .lt,
36323633 .lte => .le,
......@@ -3645,7 +3646,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
36453646/// Compares two floats.
36463647/// NOTE: Leaves the result of the comparison on top of the stack.
36473648fn cmpFloat(func: *CodeGen, ty: Type, lhs: WValue, rhs: WValue, cmp_op: std.math.CompareOperator) InnerError!WValue {
3648 const float_bits = ty.floatBits(func.target);
3649 const float_bits = ty.floatBits(func.target.*);
36493650
36503651 const op: Op = switch (cmp_op) {
36513652 .lt => .lt,
......@@ -3829,7 +3830,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38293830 break :result try func.bitcast(wanted_ty, given_ty, operand);
38303831 }
38313832
3832 if (isByRef(given_ty, pt) and !isByRef(wanted_ty, pt)) {
3833 if (isByRef(given_ty, pt, func.target.*) and !isByRef(wanted_ty, pt, func.target.*)) {
38333834 const loaded_memory = try func.load(operand, wanted_ty, 0);
38343835 if (needs_wrapping) {
38353836 break :result try func.wrapOperand(loaded_memory, wanted_ty);
......@@ -3837,7 +3838,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38373838 break :result loaded_memory;
38383839 }
38393840 }
3840 if (!isByRef(given_ty, pt) and isByRef(wanted_ty, pt)) {
3841 if (!isByRef(given_ty, pt, func.target.*) and isByRef(wanted_ty, pt, func.target.*)) {
38413842 const stack_memory = try func.allocStack(wanted_ty);
38423843 try func.store(stack_memory, operand, given_ty, 0);
38433844 if (needs_wrapping) {
......@@ -3867,8 +3868,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
38673868
38683869 const opcode = buildOpcode(.{
38693870 .op = .reinterpret,
3870 .valtype1 = typeToValtype(wanted_ty, pt),
3871 .valtype2 = typeToValtype(given_ty, pt),
3871 .valtype1 = typeToValtype(wanted_ty, pt, func.target.*),
3872 .valtype2 = typeToValtype(given_ty, pt, func.target.*),
38723873 });
38733874 try func.emitWValue(operand);
38743875 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
......@@ -3990,8 +3991,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
39903991 break :result try func.trunc(shifted_value, field_ty, backing_ty);
39913992 },
39923993 .Union => result: {
3993 if (isByRef(struct_ty, pt)) {
3994 if (!isByRef(field_ty, pt)) {
3994 if (isByRef(struct_ty, pt, func.target.*)) {
3995 if (!isByRef(field_ty, pt, func.target.*)) {
39953996 break :result try func.load(operand, field_ty, 0);
39963997 } else {
39973998 const new_stack_val = try func.allocStack(field_ty);
......@@ -4017,7 +4018,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40174018 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, pt)) orelse {
40184019 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)});
40194020 };
4020 if (isByRef(field_ty, pt)) {
4021 if (isByRef(field_ty, pt, func.target.*)) {
40214022 switch (operand) {
40224023 .stack_offset => |stack_offset| {
40234024 break :result .{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
......@@ -4163,7 +4164,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
41634164 const val = try func.lowerConstant(case.values[0].value, target_ty);
41644165 try func.emitWValue(val);
41654166 const opcode = buildOpcode(.{
4166 .valtype1 = typeToValtype(target_ty, pt),
4167 .valtype1 = typeToValtype(target_ty, pt, func.target.*),
41674168 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.
41684169 .signedness = signedness,
41694170 });
......@@ -4177,7 +4178,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
41774178 const val = try func.lowerConstant(value.value, target_ty);
41784179 try func.emitWValue(val);
41794180 const opcode = buildOpcode(.{
4180 .valtype1 = typeToValtype(target_ty, pt),
4181 .valtype1 = typeToValtype(target_ty, pt, func.target.*),
41814182 .op = .eq,
41824183 .signedness = signedness,
41834184 });
......@@ -4265,7 +4266,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
42654266 }
42664267
42674268 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));
4268 if (op_is_ptr or isByRef(payload_ty, pt)) {
4269 if (op_is_ptr or isByRef(payload_ty, pt, func.target.*)) {
42694270 break :result try func.buildPointerOffset(operand, pl_offset, .new);
42704271 }
42714272
......@@ -4492,7 +4493,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44924493 const operand = try func.resolveInst(ty_op.operand);
44934494 if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand);
44944495
4495 if (isByRef(payload_ty, pt)) {
4496 if (isByRef(payload_ty, pt, func.target.*)) {
44964497 break :result try func.buildPointerOffset(operand, 0, .new);
44974498 }
44984499
......@@ -4626,7 +4627,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46264627 try func.addTag(.i32_mul);
46274628 try func.addTag(.i32_add);
46284629
4629 const elem_result = if (isByRef(elem_ty, pt))
4630 const elem_result = if (isByRef(elem_ty, pt, func.target.*))
46304631 .stack
46314632 else
46324633 try func.load(.stack, elem_ty, 0);
......@@ -4784,7 +4785,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47844785 try func.addTag(.i32_mul);
47854786 try func.addTag(.i32_add);
47864787
4787 const elem_result = if (isByRef(elem_ty, pt))
4788 const elem_result = if (isByRef(elem_ty, pt, func.target.*))
47884789 .stack
47894790 else
47904791 try func.load(.stack, elem_ty, 0);
......@@ -4835,7 +4836,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
48354836 else => ptr_ty.childType(mod),
48364837 };
48374838
4838 const valtype = typeToValtype(Type.usize, pt);
4839 const valtype = typeToValtype(Type.usize, pt, func.target.*);
48394840 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });
48404841 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });
48414842
......@@ -4982,7 +4983,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
49824983 const elem_ty = array_ty.childType(mod);
49834984 const elem_size = elem_ty.abiSize(pt);
49844985
4985 if (isByRef(array_ty, pt)) {
4986 if (isByRef(array_ty, pt, func.target.*)) {
49864987 try func.lowerToStack(array);
49874988 try func.emitWValue(index);
49884989 try func.addImm32(@intCast(elem_size));
......@@ -5025,7 +5026,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50255026 }
50265027 }
50275028
5028 const elem_result = if (isByRef(elem_ty, pt))
5029 const elem_result = if (isByRef(elem_ty, pt, func.target.*))
50295030 .stack
50305031 else
50315032 try func.load(.stack, elem_ty, 0);
......@@ -5040,7 +5041,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50405041
50415042 const operand = try func.resolveInst(ty_op.operand);
50425043 const op_ty = func.typeOf(ty_op.operand);
5043 const op_bits = op_ty.floatBits(func.target);
5044 const op_bits = op_ty.floatBits(func.target.*);
50445045
50455046 const dest_ty = func.typeOfIndex(inst);
50465047 const dest_info = dest_ty.intInfo(mod);
......@@ -5069,8 +5070,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50695070 try func.emitWValue(operand);
50705071 const op = buildOpcode(.{
50715072 .op = .trunc,
5072 .valtype1 = typeToValtype(dest_ty, pt),
5073 .valtype2 = typeToValtype(op_ty, pt),
5073 .valtype1 = typeToValtype(dest_ty, pt, func.target.*),
5074 .valtype2 = typeToValtype(op_ty, pt, func.target.*),
50745075 .signedness = dest_info.signedness,
50755076 });
50765077 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
......@@ -5088,7 +5089,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50885089 const op_info = op_ty.intInfo(mod);
50895090
50905091 const dest_ty = func.typeOfIndex(inst);
5091 const dest_bits = dest_ty.floatBits(func.target);
5092 const dest_bits = dest_ty.floatBits(func.target.*);
50925093
50935094 if (op_info.bits > 128) {
50945095 return func.fail("TODO: floatFromInt for integers/floats with bitsize {d} bits", .{op_info.bits});
......@@ -5114,8 +5115,8 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51145115 try func.emitWValue(operand);
51155116 const op = buildOpcode(.{
51165117 .op = .convert,
5117 .valtype1 = typeToValtype(dest_ty, pt),
5118 .valtype2 = typeToValtype(op_ty, pt),
5118 .valtype1 = typeToValtype(dest_ty, pt, func.target.*),
5119 .valtype2 = typeToValtype(op_ty, pt, func.target.*),
51195120 .signedness = op_info.signedness,
51205121 });
51215122 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
......@@ -5131,7 +5132,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51315132 const ty = func.typeOfIndex(inst);
51325133 const elem_ty = ty.childType(mod);
51335134
5134 if (determineSimdStoreStrategy(ty, pt) == .direct) blk: {
5135 if (determineSimdStoreStrategy(ty, pt, func.target.*) == .direct) blk: {
51355136 switch (operand) {
51365137 // when the operand lives in the linear memory section, we can directly
51375138 // load and splat the value at once. Meaning we do not first have to load
......@@ -5215,7 +5216,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52155216 const elem_size = child_ty.abiSize(pt);
52165217
52175218 // TODO: One of them could be by ref; handle in loop
5218 if (isByRef(func.typeOf(extra.a), pt) or isByRef(inst_ty, pt)) {
5219 if (isByRef(func.typeOf(extra.a), pt, func.target.*) or isByRef(inst_ty, pt, func.target.*)) {
52195220 const result = try func.allocStack(inst_ty);
52205221
52215222 for (0..mask_len) |index| {
......@@ -5291,7 +5292,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52915292 // When the element type is by reference, we must copy the entire
52925293 // value. It is therefore safer to move the offset pointer and store
52935294 // each value individually, instead of using store offsets.
5294 if (isByRef(elem_ty, pt)) {
5295 if (isByRef(elem_ty, pt, func.target.*)) {
52955296 // copy stack pointer into a temporary local, which is
52965297 // moved for each element to store each value in the right position.
52975298 const offset = try func.buildPointerOffset(result, 0, .new);
......@@ -5321,7 +5322,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53215322 },
53225323 .Struct => switch (result_ty.containerLayout(mod)) {
53235324 .@"packed" => {
5324 if (isByRef(result_ty, pt)) {
5325 if (isByRef(result_ty, pt, func.target.*)) {
53255326 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});
53265327 }
53275328 const packed_struct = mod.typeToPackedStruct(result_ty).?;
......@@ -5424,15 +5425,15 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
54245425 if (layout.tag_size == 0) {
54255426 break :result .none;
54265427 }
5427 assert(!isByRef(union_ty, pt));
5428 assert(!isByRef(union_ty, pt, func.target.*));
54285429 break :result tag_int;
54295430 }
54305431
5431 if (isByRef(union_ty, pt)) {
5432 if (isByRef(union_ty, pt, func.target.*)) {
54325433 const result_ptr = try func.allocStack(union_ty);
54335434 const payload = try func.resolveInst(extra.init);
54345435 if (layout.tag_align.compare(.gte, layout.payload_align)) {
5435 if (isByRef(field_ty, pt)) {
5436 if (isByRef(field_ty, pt, func.target.*)) {
54365437 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
54375438 try func.store(payload_ptr, payload, field_ty, 0);
54385439 } else {
......@@ -5513,7 +5514,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
55135514
55145515 _ = try func.load(lhs, payload_ty, 0);
55155516 _ = try func.load(rhs, payload_ty, 0);
5516 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, pt) });
5517 const opcode = buildOpcode(.{ .op = .ne, .valtype1 = typeToValtype(payload_ty, pt, func.target.*) });
55175518 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
55185519 try func.addLabel(.br_if, 0);
55195520
......@@ -5630,8 +5631,8 @@ fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
56305631/// Extends a float from a given `Type` to a larger wanted `Type`
56315632/// NOTE: Leaves the result on the stack
56325633fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
5633 const given_bits = given.floatBits(func.target);
5634 const wanted_bits = wanted.floatBits(func.target);
5634 const given_bits = given.floatBits(func.target.*);
5635 const wanted_bits = wanted.floatBits(func.target.*);
56355636
56365637 if (wanted_bits == 64 and given_bits == 32) {
56375638 try func.emitWValue(operand);
......@@ -5674,8 +5675,8 @@ fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
56745675/// Truncates a float from a given `Type` to its wanted `Type`
56755676/// NOTE: The result value remains on the stack
56765677fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
5677 const given_bits = given.floatBits(func.target);
5678 const wanted_bits = wanted.floatBits(func.target);
5678 const given_bits = given.floatBits(func.target.*);
5679 const wanted_bits = wanted.floatBits(func.target.*);
56795680
56805681 if (wanted_bits == 32 and given_bits == 64) {
56815682 try func.emitWValue(operand);
......@@ -6247,7 +6248,6 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
62476248 assert(op == .max or op == .min);
62486249 const pt = func.pt;
62496250 const mod = pt.zcu;
6250 const target = mod.getTarget();
62516251 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
62526252
62536253 const ty = func.typeOfIndex(inst);
......@@ -6264,7 +6264,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
62646264
62656265 if (ty.zigTypeTag(mod) == .Float) {
62666266 var fn_name_buf: [64]u8 = undefined;
6267 const float_bits = ty.floatBits(target);
6267 const float_bits = ty.floatBits(func.target.*);
62686268 const fn_name = std.fmt.bufPrint(&fn_name_buf, "{s}f{s}{s}", .{
62696269 target_util.libcFloatPrefix(float_bits),
62706270 @tagName(op),
......@@ -6300,7 +6300,7 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63006300 const lhs = try func.resolveInst(bin_op.lhs);
63016301 const rhs = try func.resolveInst(bin_op.rhs);
63026302
6303 const result = if (ty.floatBits(func.target) == 16) fl_result: {
6303 const result = if (ty.floatBits(func.target.*) == 16) fl_result: {
63046304 const rhs_ext = try func.fpext(rhs, ty, Type.f32);
63056305 const lhs_ext = try func.fpext(lhs, ty, Type.f32);
63066306 const addend_ext = try func.fpext(addend, ty, Type.f32);
......@@ -6457,8 +6457,6 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64576457fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {
64586458 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
64596459
6460 const pt = func.pt;
6461 const mod = pt.zcu;
64626460 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
64636461 const ty = func.typeOf(pl_op.operand);
64646462 const operand = try func.resolveInst(pl_op.operand);
......@@ -6468,14 +6466,14 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
64686466 const name = func.air.nullTerminatedString(pl_op.payload);
64696467 log.debug(" var name = ({s})", .{name});
64706468
6471 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (operand) {
6469 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (operand) {
64726470 .local => |local| .{ .wasm_local = local.value },
64736471 else => blk: {
64746472 log.debug("TODO generate debug info for {}", .{operand});
64756473 break :blk .nop;
64766474 },
64776475 };
6478 try func.debug_output.dwarf.genVarDbgInfo(name, ty, mod.funcOwnerDeclIndex(func.func_index), is_ptr, loc);
6476 try func.debug_output.dwarf.genVarDbgInfo(name, ty, func.owner_nav, is_ptr, loc);
64796477
64806478 return func.finishAir(inst, .none, &.{});
64816479}
......@@ -6552,7 +6550,7 @@ fn lowerTry(
65526550 }
65536551
65546552 const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
6555 if (isByRef(pl_ty, pt)) {
6553 if (isByRef(pl_ty, pt, func.target.*)) {
65566554 return buildPointerOffset(func, err_union, pl_offset, .new);
65576555 }
65586556 const payload = try func.load(err_union, pl_ty, pl_offset);
......@@ -6712,7 +6710,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
67126710 _ = try func.wrapOperand(.stack, ty);
67136711 }
67146712 } else {
6715 const float_bits = ty.floatBits(func.target);
6713 const float_bits = ty.floatBits(func.target.*);
67166714 if (float_bits > 64) {
67176715 return func.fail("TODO: `@divFloor` for floats with bitsize: {d}", .{float_bits});
67186716 }
......@@ -7126,12 +7124,12 @@ fn callIntrinsic(
71267124 // Always pass over C-ABI
71277125 const pt = func.pt;
71287126 const mod = pt.zcu;
7129 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, pt);
7127 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, pt, func.target.*);
71307128 defer func_type.deinit(func.gpa);
71317129 const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type);
71327130 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);
71337131
7134 const want_sret_param = firstParamSRet(.C, return_type, pt);
7132 const want_sret_param = firstParamSRet(.C, return_type, pt, func.target.*);
71357133 // if we want return as first param, we allocate a pointer to stack,
71367134 // and emit it as our first argument
71377135 const sret = if (want_sret_param) blk: {
......@@ -7181,14 +7179,12 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
71817179 const pt = func.pt;
71827180 const mod = pt.zcu;
71837181 const ip = &mod.intern_pool;
7184 const enum_decl_index = enum_ty.getOwnerDecl(mod);
71857182
71867183 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
71877184 defer arena_allocator.deinit();
71887185 const arena = arena_allocator.allocator();
71897186
7190 const decl = mod.declPtr(enum_decl_index);
7191 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{decl.fqn.fmt(ip)});
7187 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{ip.loadEnumType(enum_ty.toIntern()).name.fmt(ip)});
71927188
71937189 // check if we already generated code for this.
71947190 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {
......@@ -7232,11 +7228,13 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
72327228 .ty = name_ty.toIntern(),
72337229 .storage = .{ .bytes = tag_name.toString() },
72347230 } });
7235 const tag_sym_index = try func.bin_file.lowerUnnamedConst(
7236 pt,
7237 Value.fromInterned(name_val),
7238 enum_decl_index,
7239 );
7231 const tag_sym_index = switch (try func.bin_file.lowerUav(pt, name_val, .none, func.src_loc)) {
7232 .mcv => |mcv| mcv.load_symbol,
7233 .fail => |err_msg| {
7234 func.err_msg = err_msg;
7235 return error.CodegenFail;
7236 },
7237 };
72407238
72417239 // block for this if case
72427240 try writer.writeByte(std.wasm.opcode(.block));
......@@ -7333,7 +7331,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
73337331 try writer.writeByte(std.wasm.opcode(.end));
73347332
73357333 const slice_ty = Type.slice_const_u8_sentinel_0;
7336 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, pt);
7334 const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty.ip_index}, slice_ty, pt, func.target.*);
73377335 const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
73387336 return @intFromEnum(sym_index);
73397337}
......@@ -7477,7 +7475,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
74777475 break :val ptr_val;
74787476 };
74797477
7480 const result = if (isByRef(result_ty, pt)) val: {
7478 const result = if (isByRef(result_ty, pt, func.target.*)) val: {
74817479 try func.emitWValue(cmp_result);
74827480 try func.addImm32(~@as(u32, 0));
74837481 try func.addTag(.i32_xor);
......@@ -7706,8 +7704,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
77067704 // Only when the atomic feature is enabled, and we're not building
77077705 // for a single-threaded build, can we emit the `fence` instruction.
77087706 // In all other cases, we emit no instructions for a fence.
7709 const func_namespace = zcu.namespacePtr(func.decl.src_namespace);
7710 const single_threaded = func_namespace.fileScope(zcu).mod.single_threaded;
7707 const single_threaded = zcu.navFileScope(func.owner_nav).mod.single_threaded;
77117708 if (func.useAtomicFeature() and !single_threaded) {
77127709 try func.addAtomicTag(.atomic_fence);
77137710 }
src/arch/wasm/Emit.zig+7-7
......@@ -22,7 +22,7 @@ code: *std.ArrayList(u8),
2222/// List of allocated locals.
2323locals: []const u8,
2424/// The declaration that code is being generated for.
25decl_index: InternPool.DeclIndex,
25owner_nav: InternPool.Nav.Index,
2626
2727// Debug information
2828/// Holds the debug information for this emission
......@@ -257,7 +257,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
257257 const comp = emit.bin_file.base.comp;
258258 const zcu = comp.module.?;
259259 const gpa = comp.gpa;
260 emit.error_msg = try Zcu.ErrorMsg.create(gpa, zcu.declPtr(emit.decl_index).navSrcLoc(zcu), format, args);
260 emit.error_msg = try Zcu.ErrorMsg.create(gpa, zcu.navSrcLoc(emit.owner_nav), format, args);
261261 return error.EmitFail;
262262}
263263
......@@ -310,7 +310,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
310310 const global_offset = emit.offset();
311311 try emit.code.appendSlice(&buf);
312312
313 const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom;
313 const atom_index = emit.bin_file.zigObjectPtr().?.navs.get(emit.owner_nav).?.atom;
314314 const atom = emit.bin_file.getAtomPtr(atom_index);
315315 try atom.relocs.append(gpa, .{
316316 .index = label,
......@@ -370,7 +370,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
370370 try emit.code.appendSlice(&buf);
371371
372372 if (label != 0) {
373 const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom;
373 const atom_index = emit.bin_file.zigObjectPtr().?.navs.get(emit.owner_nav).?.atom;
374374 const atom = emit.bin_file.getAtomPtr(atom_index);
375375 try atom.relocs.append(gpa, .{
376376 .offset = call_offset,
......@@ -390,7 +390,7 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
390390 leb128.writeUnsignedFixed(5, &buf, type_index);
391391 try emit.code.appendSlice(&buf);
392392 if (type_index != 0) {
393 const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom;
393 const atom_index = emit.bin_file.zigObjectPtr().?.navs.get(emit.owner_nav).?.atom;
394394 const atom = emit.bin_file.getAtomPtr(atom_index);
395395 try atom.relocs.append(emit.bin_file.base.comp.gpa, .{
396396 .offset = call_offset,
......@@ -412,7 +412,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
412412 try emit.code.appendSlice(&buf);
413413
414414 if (symbol_index != 0) {
415 const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom;
415 const atom_index = emit.bin_file.zigObjectPtr().?.navs.get(emit.owner_nav).?.atom;
416416 const atom = emit.bin_file.getAtomPtr(atom_index);
417417 try atom.relocs.append(gpa, .{
418418 .offset = index_offset,
......@@ -443,7 +443,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
443443 }
444444
445445 if (mem.pointer != 0) {
446 const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom;
446 const atom_index = emit.bin_file.zigObjectPtr().?.navs.get(emit.owner_nav).?.atom;
447447 const atom = emit.bin_file.getAtomPtr(atom_index);
448448 try atom.relocs.append(gpa, .{
449449 .offset = mem_offset,
src/arch/x86_64/CodeGen.zig+84-109
......@@ -116,48 +116,36 @@ const RegisterOffset = struct { reg: Register, off: i32 = 0 };
116116const SymbolOffset = struct { sym: u32, off: i32 = 0 };
117117
118118const Owner = union(enum) {
119 func_index: InternPool.Index,
119 nav_index: InternPool.Nav.Index,
120120 lazy_sym: link.File.LazySymbol,
121121
122 fn getDecl(owner: Owner, zcu: *Zcu) InternPool.DeclIndex {
123 return switch (owner) {
124 .func_index => |func_index| zcu.funcOwnerDeclIndex(func_index),
125 .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(zcu),
126 };
127 }
128
129122 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {
130123 const pt = ctx.pt;
131124 switch (owner) {
132 .func_index => |func_index| {
133 const decl_index = ctx.pt.zcu.funcOwnerDeclIndex(func_index);
134 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
135 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
136 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
137 return macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index);
138 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
139 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
140 return coff_file.getAtom(atom).getSymbolIndex().?;
141 } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {
142 return p9_file.seeDecl(decl_index);
143 } else unreachable;
144 },
145 .lazy_sym => |lazy_sym| {
146 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
147 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
148 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
149 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
150 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
151 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
152 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
153 const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
154 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
155 return coff_file.getAtom(atom).getSymbolIndex().?;
156 } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {
157 return p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
158 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
159 } else unreachable;
160 },
125 .nav_index => |nav_index| if (ctx.bin_file.cast(.elf)) |elf_file| {
126 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);
127 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
128 return macho_file.getZigObject().?.getOrCreateMetadataForNav(macho_file, nav_index);
129 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
130 const atom = try coff_file.getOrCreateAtomForNav(nav_index);
131 return coff_file.getAtom(atom).getSymbolIndex().?;
132 } else if (ctx.bin_file.cast(.plan9)) |p9_file| {
133 return p9_file.seeNav(pt, nav_index);
134 } else unreachable,
135 .lazy_sym => |lazy_sym| if (ctx.bin_file.cast(.elf)) |elf_file| {
136 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
137 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
138 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
139 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
140 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
141 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
142 const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
143 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
144 return coff_file.getAtom(atom).getSymbolIndex().?;
145 } else if (ctx.bin_file.cast(.plan9)) |p9_file| {
146 return p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
147 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
148 } else unreachable,
161149 }
162150 }
163151};
......@@ -803,14 +791,12 @@ pub fn generate(
803791 debug_output: DebugInfoOutput,
804792) CodeGenError!Result {
805793 const zcu = pt.zcu;
806 const gpa = zcu.gpa;
807794 const comp = zcu.comp;
795 const gpa = zcu.gpa;
796 const ip = &zcu.intern_pool;
808797 const func = zcu.funcInfo(func_index);
809 const fn_owner_decl = zcu.declPtr(func.owner_decl);
810 assert(fn_owner_decl.has_tv);
811 const fn_type = fn_owner_decl.typeOf(zcu);
812 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
813 const mod = namespace.fileScope(zcu).mod;
798 const fn_type = Type.fromInterned(func.ty);
799 const mod = zcu.navFileScope(func.owner_nav).mod;
814800
815801 var function: Self = .{
816802 .gpa = gpa,
......@@ -821,7 +807,7 @@ pub fn generate(
821807 .mod = mod,
822808 .bin_file = bin_file,
823809 .debug_output = debug_output,
824 .owner = .{ .func_index = func_index },
810 .owner = .{ .nav_index = func.owner_nav },
825811 .inline_func = func_index,
826812 .err_msg = null,
827813 .args = undefined, // populated after `resolveCallingConventionValues`
......@@ -847,9 +833,7 @@ pub fn generate(
847833 function.mir_extra.deinit(gpa);
848834 }
849835
850 wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)});
851
852 const ip = &zcu.intern_pool;
836 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
853837
854838 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
855839 function.frame_allocs.set(
......@@ -1067,22 +1051,22 @@ pub fn generateLazy(
10671051 }
10681052}
10691053
1070const FormatDeclData = struct {
1071 zcu: *Zcu,
1072 decl_index: InternPool.DeclIndex,
1054const FormatNavData = struct {
1055 ip: *const InternPool,
1056 nav_index: InternPool.Nav.Index,
10731057};
1074fn formatDecl(
1075 data: FormatDeclData,
1058fn formatNav(
1059 data: FormatNavData,
10761060 comptime _: []const u8,
10771061 _: std.fmt.FormatOptions,
10781062 writer: anytype,
10791063) @TypeOf(writer).Error!void {
1080 try writer.print("{}", .{data.zcu.declPtr(data.decl_index).fqn.fmt(&data.zcu.intern_pool)});
1064 try writer.print("{}", .{data.ip.getNav(data.nav_index).fqn.fmt(data.ip)});
10811065}
1082fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
1066fn fmtNav(nav_index: InternPool.Nav.Index, ip: *const InternPool) std.fmt.Formatter(formatNav) {
10831067 return .{ .data = .{
1084 .zcu = self.pt.zcu,
1085 .decl_index = decl_index,
1068 .ip = ip,
1069 .nav_index = nav_index,
10861070 } };
10871071}
10881072
......@@ -2230,9 +2214,9 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
22302214 const pt = self.pt;
22312215 const mod = pt.zcu;
22322216 const ip = &mod.intern_pool;
2233 switch (lazy_sym.ty.zigTypeTag(mod)) {
2217 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(mod)) {
22342218 .Enum => {
2235 const enum_ty = lazy_sym.ty;
2219 const enum_ty = Type.fromInterned(lazy_sym.ty);
22362220 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
22372221
22382222 const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*);
......@@ -2249,7 +2233,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
22492233 const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
22502234 const data_lock = self.register_manager.lockRegAssumeUnused(data_reg);
22512235 defer self.register_manager.unlockReg(data_lock);
2252 try self.genLazySymbolRef(.lea, data_reg, .{ .kind = .const_data, .ty = enum_ty });
2236 try self.genLazySymbolRef(.lea, data_reg, .{ .kind = .const_data, .ty = enum_ty.toIntern() });
22532237
22542238 var data_off: i32 = 0;
22552239 const tag_names = enum_ty.enumFields(mod);
......@@ -2288,7 +2272,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
22882272 },
22892273 else => return self.fail(
22902274 "TODO implement {s} for {}",
2291 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) },
2275 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
22922276 ),
22932277 }
22942278}
......@@ -11932,11 +11916,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1193211916}
1193311917
1193411918fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
11935 const pt = self.pt;
11936 const mod = pt.zcu;
1193711919 switch (self.debug_output) {
1193811920 .dwarf => |dw| {
11939 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
11921 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (mcv) {
1194011922 .register => |reg| .{ .register = reg.dwarfNum() },
1194111923 .register_pair => |regs| .{ .register_pair = .{
1194211924 regs[0].dwarfNum(), regs[1].dwarfNum(),
......@@ -11955,7 +11937,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
1195511937 // TODO: this might need adjusting like the linkers do.
1195611938 // Instead of flattening the owner and passing Decl.Index here we may
1195711939 // want to special case LazySymbol in DWARF linker too.
11958 try dw.genArgDbgInfo(name, ty, self.owner.getDecl(mod), loc);
11940 try dw.genArgDbgInfo(name, ty, self.owner.nav_index, loc);
1195911941 },
1196011942 .plan9 => {},
1196111943 .none => {},
......@@ -11969,8 +11951,6 @@ fn genVarDbgInfo(
1196911951 mcv: MCValue,
1197011952 name: [:0]const u8,
1197111953) !void {
11972 const pt = self.pt;
11973 const mod = pt.zcu;
1197411954 const is_ptr = switch (tag) {
1197511955 .dbg_var_ptr => true,
1197611956 .dbg_var_val => false,
......@@ -11979,7 +11959,7 @@ fn genVarDbgInfo(
1197911959
1198011960 switch (self.debug_output) {
1198111961 .dwarf => |dw| {
11982 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
11962 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (mcv) {
1198311963 .register => |reg| .{ .register = reg.dwarfNum() },
1198411964 // TODO use a frame index
1198511965 .load_frame, .lea_frame => return,
......@@ -12007,7 +11987,7 @@ fn genVarDbgInfo(
1200711987 // TODO: this might need adjusting like the linkers do.
1200811988 // Instead of flattening the owner and passing Decl.Index here we may
1200911989 // want to special case LazySymbol in DWARF linker too.
12010 try dw.genVarDbgInfo(name, ty, self.owner.getDecl(mod), is_ptr, loc);
11990 try dw.genVarDbgInfo(name, ty, self.owner.nav_index, is_ptr, loc);
1201111991 },
1201211992 .plan9 => {},
1201311993 .none => {},
......@@ -12090,14 +12070,15 @@ fn genCall(self: *Self, info: union(enum) {
1209012070 },
1209112071}, arg_types: []const Type, args: []const MCValue) !MCValue {
1209212072 const pt = self.pt;
12093 const mod = pt.zcu;
12073 const zcu = pt.zcu;
12074 const ip = &zcu.intern_pool;
1209412075
1209512076 const fn_ty = switch (info) {
1209612077 .air => |callee| fn_info: {
1209712078 const callee_ty = self.typeOf(callee);
12098 break :fn_info switch (callee_ty.zigTypeTag(mod)) {
12079 break :fn_info switch (callee_ty.zigTypeTag(zcu)) {
1209912080 .Fn => callee_ty,
12100 .Pointer => callee_ty.childType(mod),
12081 .Pointer => callee_ty.childType(zcu),
1210112082 else => unreachable,
1210212083 };
1210312084 },
......@@ -12107,7 +12088,7 @@ fn genCall(self: *Self, info: union(enum) {
1210712088 .cc = .C,
1210812089 }),
1210912090 };
12110 const fn_info = mod.typeToFunc(fn_ty).?;
12091 const fn_info = zcu.typeToFunc(fn_ty).?;
1211112092 const resolved_cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);
1211212093
1211312094 const ExpectedContents = extern struct {
......@@ -12225,7 +12206,7 @@ fn genCall(self: *Self, info: union(enum) {
1222512206 try self.asmRegisterImmediate(
1222612207 .{ ._, .cmp },
1222712208 index_reg.to32(),
12228 Immediate.u(arg_ty.vectorLen(mod)),
12209 Immediate.u(arg_ty.vectorLen(zcu)),
1222912210 );
1223012211 _ = try self.asmJccReloc(.b, loop);
1223112212
......@@ -12317,18 +12298,18 @@ fn genCall(self: *Self, info: union(enum) {
1231712298 // on linking.
1231812299 switch (info) {
1231912300 .air => |callee| if (try self.air.value(callee, pt)) |func_value| {
12320 const func_key = mod.intern_pool.indexToKey(func_value.ip_index);
12301 const func_key = ip.indexToKey(func_value.ip_index);
1232112302 switch (switch (func_key) {
1232212303 else => func_key,
1232312304 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
12324 .decl => |decl| mod.intern_pool.indexToKey(mod.declPtr(decl).val.toIntern()),
12305 .nav => |nav| ip.indexToKey(zcu.navValue(nav).toIntern()),
1232512306 else => func_key,
1232612307 } else func_key,
1232712308 }) {
1232812309 .func => |func| {
12329 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
12310 if (self.bin_file.cast(.elf)) |elf_file| {
1233012311 const zo = elf_file.zigObjectPtr().?;
12331 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
12312 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
1233212313 if (self.mod.pic) {
1233312314 const callee_reg: Register = switch (resolved_cc) {
1233412315 .SysV => callee: {
......@@ -12356,14 +12337,14 @@ fn genCall(self: *Self, info: union(enum) {
1235612337 } },
1235712338 .mod = .{ .rm = .{ .size = .qword } },
1235812339 });
12359 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
12360 const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
12340 } else if (self.bin_file.cast(.coff)) |coff_file| {
12341 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
1236112342 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
1236212343 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{});
1236312344 try self.asmRegister(.{ ._, .call }, .rax);
12364 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
12345 } else if (self.bin_file.cast(.macho)) |macho_file| {
1236512346 const zo = macho_file.getZigObject().?;
12366 const sym_index = try zo.getOrCreateMetadataForDecl(macho_file, func.owner_decl);
12347 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, func.owner_nav);
1236712348 const sym = zo.symbols.items[sym_index];
1236812349 try self.genSetReg(
1236912350 .rax,
......@@ -12372,8 +12353,8 @@ fn genCall(self: *Self, info: union(enum) {
1237212353 .{},
1237312354 );
1237412355 try self.asmRegister(.{ ._, .call }, .rax);
12375 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
12376 const atom_index = try p9.seeDecl(func.owner_decl);
12356 } else if (self.bin_file.cast(.plan9)) |p9| {
12357 const atom_index = try p9.seeNav(pt, func.owner_nav);
1237712358 const atom = p9.getAtom(atom_index);
1237812359 try self.asmMemory(.{ ._, .call }, .{
1237912360 .base = .{ .reg = .ds },
......@@ -12384,16 +12365,15 @@ fn genCall(self: *Self, info: union(enum) {
1238412365 });
1238512366 } else unreachable;
1238612367 },
12387 .extern_func => |extern_func| {
12388 const owner_decl = mod.declPtr(extern_func.decl);
12389 const lib_name = extern_func.lib_name.toSlice(&mod.intern_pool);
12390 const decl_name = owner_decl.name.toSlice(&mod.intern_pool);
12391 try self.genExternSymbolRef(.call, lib_name, decl_name);
12392 },
12368 .@"extern" => |@"extern"| try self.genExternSymbolRef(
12369 .call,
12370 @"extern".lib_name.toSlice(ip),
12371 @"extern".name.toSlice(ip),
12372 ),
1239312373 else => return self.fail("TODO implement calling bitcasted functions", .{}),
1239412374 }
1239512375 } else {
12396 assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer);
12376 assert(self.typeOf(callee).zigTypeTag(zcu) == .Pointer);
1239712377 try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }, .{});
1239812378 try self.asmRegister(.{ ._, .call }, .rax);
1239912379 },
......@@ -12919,13 +12899,13 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
1291912899
1292012900fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
1292112901 const pt = self.pt;
12922 const mod = pt.zcu;
1292312902 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1292412903
1292512904 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
1292612905 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
1292712906 defer self.register_manager.unlockReg(addr_lock);
12928 try self.genLazySymbolRef(.lea, addr_reg, link.File.LazySymbol.initDecl(.const_data, null, mod));
12907 const anyerror_lazy_sym: link.File.LazySymbol = .{ .kind = .const_data, .ty = .anyerror_type };
12908 try self.genLazySymbolRef(.lea, addr_reg, anyerror_lazy_sym);
1292912909
1293012910 try self.spillEflagsIfOccupied();
1293112911
......@@ -15273,7 +15253,7 @@ fn genExternSymbolRef(
1527315253 callee: []const u8,
1527415254) InnerError!void {
1527515255 const atom_index = try self.owner.getSymbolIndex(self);
15276 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
15256 if (self.bin_file.cast(.elf)) |elf_file| {
1527715257 _ = try self.addInst(.{
1527815258 .tag = tag,
1527915259 .ops = .extern_fn_reloc,
......@@ -15282,7 +15262,7 @@ fn genExternSymbolRef(
1528215262 .sym_index = try elf_file.getGlobalSymbol(callee, lib),
1528315263 } },
1528415264 });
15285 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
15265 } else if (self.bin_file.cast(.coff)) |coff_file| {
1528615266 const global_index = try coff_file.getGlobalSymbol(callee, lib);
1528715267 _ = try self.addInst(.{
1528815268 .tag = .mov,
......@@ -15300,7 +15280,7 @@ fn genExternSymbolRef(
1530015280 .call => try self.asmRegister(.{ ._, .call }, .rax),
1530115281 else => unreachable,
1530215282 }
15303 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
15283 } else if (self.bin_file.cast(.macho)) |macho_file| {
1530415284 _ = try self.addInst(.{
1530515285 .tag = .call,
1530615286 .ops = .extern_fn_reloc,
......@@ -15319,7 +15299,7 @@ fn genLazySymbolRef(
1531915299 lazy_sym: link.File.LazySymbol,
1532015300) InnerError!void {
1532115301 const pt = self.pt;
15322 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
15302 if (self.bin_file.cast(.elf)) |elf_file| {
1532315303 const zo = elf_file.zigObjectPtr().?;
1532415304 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
1532515305 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
......@@ -15355,7 +15335,7 @@ fn genLazySymbolRef(
1535515335 else => unreachable,
1535615336 }
1535715337 }
15358 } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| {
15338 } else if (self.bin_file.cast(.plan9)) |p9_file| {
1535915339 const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
1536015340 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1536115341 var atom = p9_file.getAtom(atom_index);
......@@ -15382,7 +15362,7 @@ fn genLazySymbolRef(
1538215362 ),
1538315363 else => unreachable,
1538415364 }
15385 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
15365 } else if (self.bin_file.cast(.coff)) |coff_file| {
1538615366 const atom_index = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
1538715367 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1538815368 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
......@@ -15396,7 +15376,7 @@ fn genLazySymbolRef(
1539615376 .call => try self.asmRegister(.{ ._, .call }, reg),
1539715377 else => unreachable,
1539815378 }
15399 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
15379 } else if (self.bin_file.cast(.macho)) |macho_file| {
1540015380 const zo = macho_file.getZigObject().?;
1540115381 const sym_index = zo.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
1540215382 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
......@@ -16361,7 +16341,6 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
1636116341
1636216342fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
1636316343 const pt = self.pt;
16364 const mod = pt.zcu;
1636516344 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1636616345 const inst_ty = self.typeOfIndex(inst);
1636716346 const enum_ty = self.typeOf(un_op);
......@@ -16393,18 +16372,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
1639316372 const operand = try self.resolveInst(un_op);
1639416373 try self.genSetReg(param_regs[1], enum_ty, operand, .{});
1639516374
16396 try self.genLazySymbolRef(
16397 .call,
16398 .rax,
16399 link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(mod), mod),
16400 );
16375 const enum_lazy_sym: link.File.LazySymbol = .{ .kind = .code, .ty = enum_ty.toIntern() };
16376 try self.genLazySymbolRef(.call, .rax, enum_lazy_sym);
1640116377
1640216378 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
1640316379}
1640416380
1640516381fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16406 const pt = self.pt;
16407 const mod = pt.zcu;
1640816382 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1640916383
1641016384 const err_ty = self.typeOf(un_op);
......@@ -16416,7 +16390,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
1641616390 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
1641716391 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
1641816392 defer self.register_manager.unlockReg(addr_lock);
16419 try self.genLazySymbolRef(.lea, addr_reg, link.File.LazySymbol.initDecl(.const_data, null, mod));
16393 const anyerror_lazy_sym: link.File.LazySymbol = .{ .kind = .const_data, .ty = .anyerror_type };
16394 try self.genLazySymbolRef(.lea, addr_reg, anyerror_lazy_sym);
1642016395
1642116396 const start_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
1642216397 const start_lock = self.register_manager.lockRegAssumeUnused(start_reg);
......@@ -18808,7 +18783,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
1880818783
1880918784fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
1881018785 const pt = self.pt;
18811 return switch (try codegen.genTypedValue(self.bin_file, pt, self.src_loc, val, self.owner.getDecl(pt.zcu))) {
18786 return switch (try codegen.genTypedValue(self.bin_file, pt, self.src_loc, val, self.target.*)) {
1881218787 .mcv => |mcv| switch (mcv) {
1881318788 .none => .none,
1881418789 .undef => .undef,
src/arch/x86_64/Emit.zig+11-11
......@@ -40,7 +40,7 @@ pub fn emitMir(emit: *Emit) Error!void {
4040 .offset = end_offset - 4,
4141 .length = @intCast(end_offset - start_offset),
4242 }),
43 .linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
43 .linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(.elf)) |elf_file| {
4444 // Add relocation to the decl.
4545 const zo = elf_file.zigObjectPtr().?;
4646 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
......@@ -50,7 +50,7 @@ pub fn emitMir(emit: *Emit) Error!void {
5050 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
5151 .r_addend = -4,
5252 });
53 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
53 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
5454 // Add relocation to the decl.
5555 const zo = macho_file.getZigObject().?;
5656 const atom = zo.symbols.items[symbol.atom_index].getAtom(macho_file).?;
......@@ -67,7 +67,7 @@ pub fn emitMir(emit: *Emit) Error!void {
6767 .symbolnum = @intCast(symbol.sym_index),
6868 },
6969 });
70 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
70 } else if (emit.lower.bin_file.cast(.coff)) |coff_file| {
7171 // Add relocation to the decl.
7272 const atom_index = coff_file.getAtomIndexForSymbol(
7373 .{ .sym_index = symbol.atom_index, .file = null },
......@@ -88,7 +88,7 @@ pub fn emitMir(emit: *Emit) Error!void {
8888 @tagName(emit.lower.bin_file.tag),
8989 }),
9090 .linker_tlsld => |data| {
91 const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;
91 const elf_file = emit.lower.bin_file.cast(.elf).?;
9292 const zo = elf_file.zigObjectPtr().?;
9393 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
9494 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
......@@ -99,7 +99,7 @@ pub fn emitMir(emit: *Emit) Error!void {
9999 });
100100 },
101101 .linker_dtpoff => |data| {
102 const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;
102 const elf_file = emit.lower.bin_file.cast(.elf).?;
103103 const zo = elf_file.zigObjectPtr().?;
104104 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
105105 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
......@@ -109,7 +109,7 @@ pub fn emitMir(emit: *Emit) Error!void {
109109 .r_addend = 0,
110110 });
111111 },
112 .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
112 .linker_reloc => |data| if (emit.lower.bin_file.cast(.elf)) |elf_file| {
113113 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
114114 .Exe => false,
115115 .Obj => true,
......@@ -157,7 +157,7 @@ pub fn emitMir(emit: *Emit) Error!void {
157157 });
158158 }
159159 }
160 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
160 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
161161 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
162162 .Exe => false,
163163 .Obj => true,
......@@ -196,11 +196,11 @@ pub fn emitMir(emit: *Emit) Error!void {
196196 .linker_got,
197197 .linker_direct,
198198 .linker_import,
199 => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {
199 => |symbol| if (emit.lower.bin_file.cast(.elf)) |_| {
200200 unreachable;
201 } else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {
201 } else if (emit.lower.bin_file.cast(.macho)) |_| {
202202 unreachable;
203 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
203 } else if (emit.lower.bin_file.cast(.coff)) |coff_file| {
204204 const atom_index = coff_file.getAtomIndexForSymbol(.{
205205 .sym_index = symbol.atom_index,
206206 .file = null,
......@@ -222,7 +222,7 @@ pub fn emitMir(emit: *Emit) Error!void {
222222 .pcrel = true,
223223 .length = 2,
224224 });
225 } else if (emit.lower.bin_file.cast(link.File.Plan9)) |p9_file| {
225 } else if (emit.lower.bin_file.cast(.plan9)) |p9_file| {
226226 const atom_index = symbol.atom_index;
227227 try p9_file.addReloc(atom_index, .{ // TODO we may need to add a .type field to the relocs if they are .linker_got instead of just .linker_direct
228228 .target = symbol.sym_index, // we set sym_index to just be the atom index
src/arch/x86_64/Lower.zig+2-2
......@@ -348,7 +348,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
348348 assert(mem_op.sib.disp == 0);
349349 assert(mem_op.sib.scale_index.scale == 0);
350350
351 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
351 if (lower.bin_file.cast(.elf)) |elf_file| {
352352 const zo = elf_file.zigObjectPtr().?;
353353 const elf_sym = zo.symbol(sym.sym_index);
354354
......@@ -424,7 +424,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
424424 },
425425 else => unreachable,
426426 };
427 } else if (lower.bin_file.cast(link.File.MachO)) |macho_file| {
427 } else if (lower.bin_file.cast(.macho)) |macho_file| {
428428 const zo = macho_file.getZigObject().?;
429429 const macho_sym = zo.symbols.items[sym.sym_index];
430430
src/codegen.zig+71-132
......@@ -17,7 +17,7 @@ const ErrorMsg = Zcu.ErrorMsg;
1717const InternPool = @import("InternPool.zig");
1818const Liveness = @import("Liveness.zig");
1919const Zcu = @import("Zcu.zig");
20const Target = std.Target;
20
2121const Type = @import("Type.zig");
2222const Value = @import("Value.zig");
2323const Zir = std.zig.Zir;
......@@ -26,7 +26,7 @@ const dev = @import("dev.zig");
2626
2727pub const Result = union(enum) {
2828 /// The `code` parameter passed to `generateSymbol` has the value ok.
29 ok: void,
29 ok,
3030
3131 /// There was a codegen error.
3232 fail: *ErrorMsg,
......@@ -39,7 +39,7 @@ pub const CodeGenError = error{
3939};
4040
4141pub const DebugInfoOutput = union(enum) {
42 dwarf: *link.File.Dwarf.DeclState,
42 dwarf: *link.File.Dwarf.NavState,
4343 plan9: *link.File.Plan9.DebugInfoOutput,
4444 none,
4545};
......@@ -73,9 +73,7 @@ pub fn generateFunction(
7373) CodeGenError!Result {
7474 const zcu = pt.zcu;
7575 const func = zcu.funcInfo(func_index);
76 const decl = zcu.declPtr(func.owner_decl);
77 const namespace = zcu.namespacePtr(decl.src_namespace);
78 const target = namespace.fileScope(zcu).mod.resolved_target.result;
76 const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;
7977 switch (target_util.zigBackend(target, false)) {
8078 else => unreachable,
8179 inline .stage2_aarch64,
......@@ -100,10 +98,8 @@ pub fn generateLazyFunction(
10098 debug_output: DebugInfoOutput,
10199) CodeGenError!Result {
102100 const zcu = pt.zcu;
103 const decl_index = lazy_sym.ty.getOwnerDecl(zcu);
104 const decl = zcu.declPtr(decl_index);
105 const namespace = zcu.namespacePtr(decl.src_namespace);
106 const target = namespace.fileScope(zcu).mod.resolved_target.result;
101 const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(&zcu.intern_pool).file;
102 const target = zcu.fileByIndex(file).mod.resolved_target.result;
107103 switch (target_util.zigBackend(target, false)) {
108104 else => unreachable,
109105 inline .stage2_x86_64,
......@@ -115,7 +111,7 @@ pub fn generateLazyFunction(
115111 }
116112}
117113
118fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian, code: []u8) void {
114fn writeFloat(comptime F: type, f: F, target: std.Target, endian: std.builtin.Endian, code: []u8) void {
119115 _ = target;
120116 const bits = @typeInfo(F).Float.bits;
121117 const Int = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = bits } });
......@@ -147,7 +143,7 @@ pub fn generateLazySymbol(
147143
148144 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
149145 @tagName(lazy_sym.kind),
150 lazy_sym.ty.fmt(pt),
146 Type.fromInterned(lazy_sym.ty).fmt(pt),
151147 });
152148
153149 if (lazy_sym.kind == .code) {
......@@ -155,7 +151,7 @@ pub fn generateLazySymbol(
155151 return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, code, debug_output);
156152 }
157153
158 if (lazy_sym.ty.isAnyError(pt.zcu)) {
154 if (lazy_sym.ty == .anyerror_type) {
159155 alignment.* = .@"4";
160156 const err_names = ip.global_error_set.getNamesFromMainThread();
161157 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);
......@@ -171,9 +167,10 @@ pub fn generateLazySymbol(
171167 }
172168 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);
173169 return Result.ok;
174 } else if (lazy_sym.ty.zigTypeTag(pt.zcu) == .Enum) {
170 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .Enum) {
175171 alignment.* = .@"1";
176 const tag_names = lazy_sym.ty.enumFields(pt.zcu);
172 const enum_ty = Type.fromInterned(lazy_sym.ty);
173 const tag_names = enum_ty.enumFields(pt.zcu);
177174 for (0..tag_names.len) |tag_index| {
178175 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
179176 try code.ensureUnusedCapacity(tag_name.len + 1);
......@@ -185,7 +182,7 @@ pub fn generateLazySymbol(
185182 gpa,
186183 src_loc,
187184 "TODO implement generateLazySymbol for {s} {}",
188 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(pt) },
185 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
189186 ) };
190187}
191188
......@@ -251,7 +248,7 @@ pub fn generateSymbol(
251248 }),
252249 },
253250 .variable,
254 .extern_func,
251 .@"extern",
255252 .func,
256253 .enum_literal,
257254 .empty_enum_value,
......@@ -651,8 +648,8 @@ fn lowerPtr(
651648 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
652649 const offset: u64 = prev_offset + ptr.byte_offset;
653650 return switch (ptr.base_addr) {
654 .decl => |decl| try lowerDeclRef(bin_file, pt, src_loc, decl, code, debug_output, reloc_info, offset),
655 .anon_decl => |ad| try lowerAnonDeclRef(bin_file, pt, src_loc, ad, code, debug_output, reloc_info, offset),
651 .nav => |nav| try lowerNavRef(bin_file, pt, src_loc, nav, code, debug_output, reloc_info, offset),
652 .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, code, debug_output, reloc_info, offset),
656653 .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, debug_output, reloc_info),
657654 .eu_payload => |eu_ptr| try lowerPtr(
658655 bin_file,
......@@ -705,11 +702,11 @@ const RelocInfo = struct {
705702 parent_atom_index: u32,
706703};
707704
708fn lowerAnonDeclRef(
705fn lowerUavRef(
709706 lf: *link.File,
710707 pt: Zcu.PerThread,
711708 src_loc: Zcu.LazySrcLoc,
712 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
709 uav: InternPool.Key.Ptr.BaseAddr.Uav,
713710 code: *std.ArrayList(u8),
714711 debug_output: DebugInfoOutput,
715712 reloc_info: RelocInfo,
......@@ -720,23 +717,23 @@ fn lowerAnonDeclRef(
720717 const target = lf.comp.root_mod.resolved_target.result;
721718
722719 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
723 const decl_val = anon_decl.val;
724 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
725 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(pt)});
726 const is_fn_body = decl_ty.zigTypeTag(pt.zcu) == .Fn;
727 if (!is_fn_body and !decl_ty.hasRuntimeBits(pt)) {
720 const uav_val = uav.val;
721 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));
722 log.debug("lowerUavRef: ty = {}", .{uav_ty.fmt(pt)});
723 const is_fn_body = uav_ty.zigTypeTag(pt.zcu) == .Fn;
724 if (!is_fn_body and !uav_ty.hasRuntimeBits(pt)) {
728725 try code.appendNTimes(0xaa, ptr_width_bytes);
729726 return Result.ok;
730727 }
731728
732 const decl_align = ip.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
733 const res = try lf.lowerAnonDecl(pt, decl_val, decl_align, src_loc);
729 const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
730 const res = try lf.lowerUav(pt, uav_val, uav_align, src_loc);
734731 switch (res) {
735 .ok => {},
732 .mcv => {},
736733 .fail => |em| return .{ .fail = em },
737734 }
738735
739 const vaddr = try lf.getAnonDeclVAddr(decl_val, .{
736 const vaddr = try lf.getUavVAddr(uav_val, .{
740737 .parent_atom_index = reloc_info.parent_atom_index,
741738 .offset = code.items.len,
742739 .addend = @intCast(offset),
......@@ -752,11 +749,11 @@ fn lowerAnonDeclRef(
752749 return Result.ok;
753750}
754751
755fn lowerDeclRef(
752fn lowerNavRef(
756753 lf: *link.File,
757754 pt: Zcu.PerThread,
758755 src_loc: Zcu.LazySrcLoc,
759 decl_index: InternPool.DeclIndex,
756 nav_index: InternPool.Nav.Index,
760757 code: *std.ArrayList(u8),
761758 debug_output: DebugInfoOutput,
762759 reloc_info: RelocInfo,
......@@ -765,18 +762,18 @@ fn lowerDeclRef(
765762 _ = src_loc;
766763 _ = debug_output;
767764 const zcu = pt.zcu;
768 const decl = zcu.declPtr(decl_index);
769 const namespace = zcu.namespacePtr(decl.src_namespace);
770 const target = namespace.fileScope(zcu).mod.resolved_target.result;
765 const ip = &zcu.intern_pool;
766 const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
771767
772768 const ptr_width = target.ptrBitWidth();
773 const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn;
774 if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(pt)) {
769 const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
770 const is_fn_body = nav_ty.zigTypeTag(zcu) == .Fn;
771 if (!is_fn_body and !nav_ty.hasRuntimeBits(pt)) {
775772 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));
776773 return Result.ok;
777774 }
778775
779 const vaddr = try lf.getDeclVAddr(pt, decl_index, .{
776 const vaddr = try lf.getNavVAddr(pt, nav_index, .{
780777 .parent_atom_index = reloc_info.parent_atom_index,
781778 .offset = code.items.len,
782779 .addend = @intCast(offset),
......@@ -848,34 +845,21 @@ pub const GenResult = union(enum) {
848845 }
849846};
850847
851fn genDeclRef(
848fn genNavRef(
852849 lf: *link.File,
853850 pt: Zcu.PerThread,
854851 src_loc: Zcu.LazySrcLoc,
855852 val: Value,
856 ptr_decl_index: InternPool.DeclIndex,
853 ref_nav_index: InternPool.Nav.Index,
854 target: std.Target,
857855) CodeGenError!GenResult {
858856 const zcu = pt.zcu;
859857 const ip = &zcu.intern_pool;
860858 const ty = val.typeOf(zcu);
861 log.debug("genDeclRef: val = {}", .{val.fmtValue(pt)});
862
863 const ptr_decl = zcu.declPtr(ptr_decl_index);
864 const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
865 const target = namespace.fileScope(zcu).mod.resolved_target.result;
866
867 const ptr_bits = target.ptrBitWidth();
868 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
869
870 const decl_index = switch (ip.indexToKey(ptr_decl.val.toIntern())) {
871 .func => |func| func.owner_decl,
872 .extern_func => |extern_func| extern_func.decl,
873 else => ptr_decl_index,
874 };
875 const decl = zcu.declPtr(decl_index);
859 log.debug("genNavRef: val = {}", .{val.fmtValue(pt)});
876860
877 if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
878 const imm: u64 = switch (ptr_bytes) {
861 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
862 const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
879863 1 => 0xaa,
880864 2 => 0xaaaa,
881865 4 => 0xaaaaaaaa,
......@@ -900,96 +884,56 @@ fn genDeclRef(
900884 }
901885 }
902886
903 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
904 const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded;
905 const is_threadlocal = val.isPtrToThreadLocal(zcu) and !single_threaded;
906 const is_extern = decl.isExtern(zcu);
907
908 if (lf.cast(link.File.Elf)) |elf_file| {
887 const nav_index, const is_extern, const lib_name, const is_threadlocal = switch (ip.indexToKey(zcu.navValue(ref_nav_index).toIntern())) {
888 .func => |func| .{ func.owner_nav, false, .none, false },
889 .variable => |variable| .{ variable.owner_nav, false, variable.lib_name, variable.is_threadlocal },
890 .@"extern" => |@"extern"| .{ @"extern".owner_nav, true, @"extern".lib_name, @"extern".is_threadlocal },
891 else => .{ ref_nav_index, false, .none, false },
892 };
893 const single_threaded = zcu.navFileScope(nav_index).mod.single_threaded;
894 const name = ip.getNav(nav_index).name;
895 if (lf.cast(.elf)) |elf_file| {
909896 const zo = elf_file.zigObjectPtr().?;
910897 if (is_extern) {
911 const name = decl.name.toSlice(ip);
912898 // TODO audit this
913 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;
914 const sym_index = try elf_file.getGlobalSymbol(name, lib_name);
899 const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
915900 zo.symbol(sym_index).flags.needs_got = true;
916901 return GenResult.mcv(.{ .load_symbol = sym_index });
917902 }
918 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, decl_index);
919 if (is_threadlocal) {
903 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);
904 if (!single_threaded and is_threadlocal) {
920905 return GenResult.mcv(.{ .load_tlv = sym_index });
921906 }
922907 return GenResult.mcv(.{ .load_symbol = sym_index });
923 } else if (lf.cast(link.File.MachO)) |macho_file| {
908 } else if (lf.cast(.macho)) |macho_file| {
924909 const zo = macho_file.getZigObject().?;
925910 if (is_extern) {
926 const name = decl.name.toSlice(ip);
927 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;
928 const sym_index = try macho_file.getGlobalSymbol(name, lib_name);
911 const sym_index = try macho_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
929912 zo.symbols.items[sym_index].setSectionFlags(.{ .needs_got = true });
930913 return GenResult.mcv(.{ .load_symbol = sym_index });
931914 }
932 const sym_index = try zo.getOrCreateMetadataForDecl(macho_file, decl_index);
915 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
933916 const sym = zo.symbols.items[sym_index];
934 if (is_threadlocal) {
917 if (!single_threaded and is_threadlocal) {
935918 return GenResult.mcv(.{ .load_tlv = sym.nlist_idx });
936919 }
937920 return GenResult.mcv(.{ .load_symbol = sym.nlist_idx });
938 } else if (lf.cast(link.File.Coff)) |coff_file| {
921 } else if (lf.cast(.coff)) |coff_file| {
939922 if (is_extern) {
940 const name = decl.name.toSlice(ip);
941923 // TODO audit this
942 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;
943 const global_index = try coff_file.getGlobalSymbol(name, lib_name);
924 const global_index = try coff_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
944925 try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT
945926 return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index });
946927 }
947 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
928 const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
948929 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
949930 return GenResult.mcv(.{ .load_got = sym_index });
950 } else if (lf.cast(link.File.Plan9)) |p9| {
951 const atom_index = try p9.seeDecl(decl_index);
931 } else if (lf.cast(.plan9)) |p9| {
932 const atom_index = try p9.seeNav(pt, nav_index);
952933 const atom = p9.getAtom(atom_index);
953934 return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) });
954935 } else {
955 return GenResult.fail(gpa, src_loc, "TODO genDeclRef for target {}", .{target});
956 }
957}
958
959fn genUnnamedConst(
960 lf: *link.File,
961 pt: Zcu.PerThread,
962 src_loc: Zcu.LazySrcLoc,
963 val: Value,
964 owner_decl_index: InternPool.DeclIndex,
965) CodeGenError!GenResult {
966 const gpa = lf.comp.gpa;
967 log.debug("genUnnamedConst: val = {}", .{val.fmtValue(pt)});
968
969 const local_sym_index = lf.lowerUnnamedConst(pt, val, owner_decl_index) catch |err| {
970 return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
971 };
972 switch (lf.tag) {
973 .elf => {
974 return GenResult.mcv(.{ .load_symbol = local_sym_index });
975 },
976 .macho => {
977 const macho_file = lf.cast(link.File.MachO).?;
978 const local = macho_file.getZigObject().?.symbols.items[local_sym_index];
979 return GenResult.mcv(.{ .load_symbol = local.nlist_idx });
980 },
981 .coff => {
982 return GenResult.mcv(.{ .load_direct = local_sym_index });
983 },
984 .plan9 => {
985 const atom_index = local_sym_index; // plan9 returns the atom_index
986 return GenResult.mcv(.{ .load_direct = atom_index });
987 },
988
989 .c => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for -ofmt=c", .{}),
990 .wasm => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for wasm", .{}),
991 .spirv => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for spirv", .{}),
992 .nvptx => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for nvptx", .{}),
936 return GenResult.fail(gpa, src_loc, "TODO genNavRef for target {}", .{target});
993937 }
994938}
995939
......@@ -998,7 +942,7 @@ pub fn genTypedValue(
998942 pt: Zcu.PerThread,
999943 src_loc: Zcu.LazySrcLoc,
1000944 val: Value,
1001 owner_decl_index: InternPool.DeclIndex,
945 target: std.Target,
1002946) CodeGenError!GenResult {
1003947 const zcu = pt.zcu;
1004948 const ip = &zcu.intern_pool;
......@@ -1010,14 +954,9 @@ pub fn genTypedValue(
1010954 return GenResult.mcv(.undef);
1011955 }
1012956
1013 const owner_decl = zcu.declPtr(owner_decl_index);
1014 const namespace = zcu.namespacePtr(owner_decl.src_namespace);
1015 const target = namespace.fileScope(zcu).mod.resolved_target.result;
1016 const ptr_bits = target.ptrBitWidth();
1017
1018957 if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) {
1019958 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1020 .decl => |decl| return genDeclRef(lf, pt, src_loc, val, decl),
959 .nav => |nav| return genNavRef(lf, pt, src_loc, val, nav, target),
1021960 else => {},
1022961 },
1023962 else => {},
......@@ -1042,7 +981,7 @@ pub fn genTypedValue(
1042981 },
1043982 .Int => {
1044983 const info = ty.intInfo(zcu);
1045 if (info.bits <= ptr_bits) {
984 if (info.bits <= target.ptrBitWidth()) {
1046985 const unsigned: u64 = switch (info.signedness) {
1047986 .signed => @bitCast(val.toSignedInt(pt)),
1048987 .unsigned => val.toUnsignedInt(pt),
......@@ -1060,7 +999,7 @@ pub fn genTypedValue(
1060999 pt,
10611000 src_loc,
10621001 val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),
1063 owner_decl_index,
1002 target,
10641003 );
10651004 } else if (ty.abiSize(pt) == 1) {
10661005 return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) });
......@@ -1073,7 +1012,7 @@ pub fn genTypedValue(
10731012 pt,
10741013 src_loc,
10751014 Value.fromInterned(enum_tag.int),
1076 owner_decl_index,
1015 target,
10771016 );
10781017 },
10791018 .ErrorSet => {
......@@ -1096,14 +1035,14 @@ pub fn genTypedValue(
10961035 .ty = err_type.toIntern(),
10971036 .name = err_name,
10981037 } })),
1099 owner_decl_index,
1038 target,
11001039 ),
11011040 .payload => return genTypedValue(
11021041 lf,
11031042 pt,
11041043 src_loc,
11051044 try pt.intValue(err_int_ty, 0),
1106 owner_decl_index,
1045 target,
11071046 ),
11081047 }
11091048 }
......@@ -1121,7 +1060,7 @@ pub fn genTypedValue(
11211060 else => {},
11221061 }
11231062
1124 return genUnnamedConst(lf, pt, src_loc, val, owner_decl_index);
1063 return lf.lowerUav(pt, val.toIntern(), .none, src_loc);
11251064}
11261065
11271066pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {
src/codegen/c.zig+251-229
......@@ -38,8 +38,8 @@ pub const CValue = union(enum) {
3838 /// Index into a tuple's fields
3939 field: usize,
4040 /// By-value
41 decl: InternPool.DeclIndex,
42 decl_ref: InternPool.DeclIndex,
41 nav: InternPool.Nav.Index,
42 nav_ref: InternPool.Nav.Index,
4343 /// An undefined value (cannot be dereferenced)
4444 undef: Type,
4545 /// Rendered as an identifier (using fmtIdent)
......@@ -58,19 +58,12 @@ const BlockData = struct {
5858pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);
5959
6060pub const LazyFnKey = union(enum) {
61 tag_name: InternPool.DeclIndex,
62 never_tail: InternPool.DeclIndex,
63 never_inline: InternPool.DeclIndex,
61 tag_name: InternPool.Index,
62 never_tail: InternPool.Nav.Index,
63 never_inline: InternPool.Nav.Index,
6464};
6565pub const LazyFnValue = struct {
6666 fn_name: CType.Pool.String,
67 data: Data,
68
69 const Data = union {
70 tag_name: Type,
71 never_tail: void,
72 never_inline: void,
73 };
7467};
7568pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue);
7669
......@@ -498,10 +491,11 @@ pub const Function = struct {
498491 return f.object.dg.fmtIntLiteral(val, .Other);
499492 }
500493
501 fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 {
494 fn getLazyFnName(f: *Function, key: LazyFnKey) ![]const u8 {
502495 const gpa = f.object.dg.gpa;
503496 const pt = f.object.dg.pt;
504497 const zcu = pt.zcu;
498 const ip = &zcu.intern_pool;
505499 const ctype_pool = &f.object.dg.ctype_pool;
506500
507501 const gop = try f.lazy_fns.getOrPut(gpa, key);
......@@ -511,19 +505,19 @@ pub const Function = struct {
511505 gop.value_ptr.* = .{
512506 .fn_name = switch (key) {
513507 .tag_name,
508 => |enum_ty| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{
509 @tagName(key),
510 fmtIdent(ip.loadEnumType(enum_ty).name.toSlice(ip)),
511 @intFromEnum(enum_ty),
512 }),
514513 .never_tail,
515514 .never_inline,
516 => |owner_decl| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{
515 => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{
517516 @tagName(key),
518 fmtIdent(zcu.declPtr(owner_decl).name.toSlice(&zcu.intern_pool)),
519 @intFromEnum(owner_decl),
517 fmtIdent(ip.getNav(owner_nav).name.toSlice(ip)),
518 @intFromEnum(owner_nav),
520519 }),
521520 },
522 .data = switch (key) {
523 .tag_name => .{ .tag_name = data.tag_name },
524 .never_tail => .{ .never_tail = data.never_tail },
525 .never_inline => .{ .never_inline = data.never_inline },
526 },
527521 };
528522 }
529523 return gop.value_ptr.fn_name.toSlice(ctype_pool).?;
......@@ -618,12 +612,12 @@ pub const DeclGen = struct {
618612 scratch: std.ArrayListUnmanaged(u32),
619613 /// Keeps track of anonymous decls that need to be rendered before this
620614 /// (named) Decl in the output C code.
621 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),
622 aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
615 uav_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.AvBlock),
616 aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
623617
624618 pub const Pass = union(enum) {
625 decl: InternPool.DeclIndex,
626 anon: InternPool.Index,
619 nav: InternPool.Nav.Index,
620 uav: InternPool.Index,
627621 flush,
628622 };
629623
......@@ -634,39 +628,37 @@ pub const DeclGen = struct {
634628 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
635629 @setCold(true);
636630 const zcu = dg.pt.zcu;
637 const decl_index = dg.pass.decl;
638 const decl = zcu.declPtr(decl_index);
639 const src_loc = decl.navSrcLoc(zcu);
631 const src_loc = zcu.navSrcLoc(dg.pass.nav);
640632 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
641633 return error.AnalysisFail;
642634 }
643635
644 fn renderAnonDeclValue(
636 fn renderUav(
645637 dg: *DeclGen,
646638 writer: anytype,
647 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
639 uav: InternPool.Key.Ptr.BaseAddr.Uav,
648640 location: ValueRenderLocation,
649641 ) error{ OutOfMemory, AnalysisFail }!void {
650642 const pt = dg.pt;
651643 const zcu = pt.zcu;
652644 const ip = &zcu.intern_pool;
653645 const ctype_pool = &dg.ctype_pool;
654 const decl_val = Value.fromInterned(anon_decl.val);
655 const decl_ty = decl_val.typeOf(zcu);
646 const uav_val = Value.fromInterned(uav.val);
647 const uav_ty = uav_val.typeOf(zcu);
656648
657649 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
658 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);
659 if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(pt)) {
650 const ptr_ty = Type.fromInterned(uav.orig_ty);
651 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(pt)) {
660652 return dg.writeCValue(writer, .{ .undef = ptr_ty });
661653 }
662654
663655 // Chase function values in order to be able to reference the original function.
664 if (decl_val.getFunction(zcu)) |func|
665 return dg.renderDeclValue(writer, func.owner_decl, location);
666 if (decl_val.getExternFunc(zcu)) |extern_func|
667 return dg.renderDeclValue(writer, extern_func.decl, location);
668
669 assert(decl_val.getVariable(zcu) == null);
656 switch (ip.indexToKey(uav.val)) {
657 .variable => unreachable,
658 .func => |func| return dg.renderNav(writer, func.owner_nav, location),
659 .@"extern" => |@"extern"| return dg.renderNav(writer, @"extern".owner_nav, location),
660 else => {},
661 }
670662
671663 // We shouldn't cast C function pointers as this is UB (when you call
672664 // them). The analysis until now should ensure that the C function
......@@ -674,22 +666,22 @@ pub const DeclGen = struct {
674666 // somewhere and we should let the C compiler tell us about it.
675667 const ptr_ctype = try dg.ctypeFromType(ptr_ty, .complete);
676668 const elem_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
677 const decl_ctype = try dg.ctypeFromType(decl_ty, .complete);
678 const need_cast = !elem_ctype.eql(decl_ctype) and
679 (elem_ctype.info(ctype_pool) != .function or decl_ctype.info(ctype_pool) != .function);
669 const uav_ctype = try dg.ctypeFromType(uav_ty, .complete);
670 const need_cast = !elem_ctype.eql(uav_ctype) and
671 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
680672 if (need_cast) {
681673 try writer.writeAll("((");
682674 try dg.renderCType(writer, ptr_ctype);
683675 try writer.writeByte(')');
684676 }
685677 try writer.writeByte('&');
686 try renderAnonDeclName(writer, decl_val);
678 try renderUavName(writer, uav_val);
687679 if (need_cast) try writer.writeByte(')');
688680
689681 // Indicate that the anon decl should be rendered to the output so that
690682 // our reference above is not undefined.
691 const ptr_type = ip.indexToKey(anon_decl.orig_ty).ptr_type;
692 const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, anon_decl.val);
683 const ptr_type = ip.indexToKey(uav.orig_ty).ptr_type;
684 const gop = try dg.uav_deps.getOrPut(dg.gpa, uav.val);
693685 if (!gop.found_existing) gop.value_ptr.* = .{};
694686
695687 // Only insert an alignment entry if the alignment is greater than ABI
......@@ -698,7 +690,7 @@ pub const DeclGen = struct {
698690 if (explicit_alignment != .none) {
699691 const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(pt);
700692 if (explicit_alignment.order(abi_alignment).compare(.gt)) {
701 const aligned_gop = try dg.aligned_anon_decls.getOrPut(dg.gpa, anon_decl.val);
693 const aligned_gop = try dg.aligned_uavs.getOrPut(dg.gpa, uav.val);
702694 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)
703695 aligned_gop.value_ptr.maxStrict(explicit_alignment)
704696 else
......@@ -707,47 +699,49 @@ pub const DeclGen = struct {
707699 }
708700 }
709701
710 fn renderDeclValue(
702 fn renderNav(
711703 dg: *DeclGen,
712704 writer: anytype,
713 decl_index: InternPool.DeclIndex,
705 nav_index: InternPool.Nav.Index,
714706 location: ValueRenderLocation,
715707 ) error{ OutOfMemory, AnalysisFail }!void {
708 _ = location;
716709 const pt = dg.pt;
717710 const zcu = pt.zcu;
711 const ip = &zcu.intern_pool;
718712 const ctype_pool = &dg.ctype_pool;
719 const decl = zcu.declPtr(decl_index);
720 assert(decl.has_tv);
713
714 // Chase function values in order to be able to reference the original function.
715 const owner_nav = switch (ip.indexToKey(zcu.navValue(nav_index).toIntern())) {
716 .variable => |variable| variable.owner_nav,
717 .func => |func| func.owner_nav,
718 .@"extern" => |@"extern"| @"extern".owner_nav,
719 else => nav_index,
720 };
721721
722722 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
723 const decl_ty = decl.typeOf(zcu);
724 const ptr_ty = try decl.declPtrType(pt);
725 if (!decl_ty.isFnOrHasRuntimeBits(pt)) {
723 const nav_ty = Type.fromInterned(ip.getNav(owner_nav).typeOf(ip));
724 const ptr_ty = try pt.navPtrType(owner_nav);
725 if (!nav_ty.isFnOrHasRuntimeBits(pt)) {
726726 return dg.writeCValue(writer, .{ .undef = ptr_ty });
727727 }
728728
729 // Chase function values in order to be able to reference the original function.
730 if (decl.val.getFunction(zcu)) |func| if (func.owner_decl != decl_index)
731 return dg.renderDeclValue(writer, func.owner_decl, location);
732 if (decl.val.getExternFunc(zcu)) |extern_func| if (extern_func.decl != decl_index)
733 return dg.renderDeclValue(writer, extern_func.decl, location);
734
735729 // We shouldn't cast C function pointers as this is UB (when you call
736730 // them). The analysis until now should ensure that the C function
737731 // pointers are compatible. If they are not, then there is a bug
738732 // somewhere and we should let the C compiler tell us about it.
739733 const ctype = try dg.ctypeFromType(ptr_ty, .complete);
740734 const elem_ctype = ctype.info(ctype_pool).pointer.elem_ctype;
741 const decl_ctype = try dg.ctypeFromType(decl_ty, .complete);
742 const need_cast = !elem_ctype.eql(decl_ctype) and
743 (elem_ctype.info(ctype_pool) != .function or decl_ctype.info(ctype_pool) != .function);
735 const nav_ctype = try dg.ctypeFromType(nav_ty, .complete);
736 const need_cast = !elem_ctype.eql(nav_ctype) and
737 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
744738 if (need_cast) {
745739 try writer.writeAll("((");
746740 try dg.renderCType(writer, ctype);
747741 try writer.writeByte(')');
748742 }
749743 try writer.writeByte('&');
750 try dg.renderDeclName(writer, decl_index);
744 try dg.renderNavName(writer, owner_nav);
751745 if (need_cast) try writer.writeByte(')');
752746 }
753747
......@@ -769,8 +763,8 @@ pub const DeclGen = struct {
769763 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});
770764 },
771765
772 .decl_ptr => |decl| try dg.renderDeclValue(writer, decl, location),
773 .anon_decl_ptr => |ad| try dg.renderAnonDeclValue(writer, ad, location),
766 .nav_ptr => |nav| try dg.renderNav(writer, nav, location),
767 .uav_ptr => |uav| try dg.renderUav(writer, uav, location),
774768
775769 inline .eu_payload_ptr, .opt_payload_ptr => |info| {
776770 try writer.writeAll("&(");
......@@ -918,7 +912,7 @@ pub const DeclGen = struct {
918912 .true => try writer.writeAll("true"),
919913 },
920914 .variable,
921 .extern_func,
915 .@"extern",
922916 .func,
923917 .enum_literal,
924918 .empty_enum_value,
......@@ -1743,7 +1737,7 @@ pub const DeclGen = struct {
17431737 .undef,
17441738 .simple_value,
17451739 .variable,
1746 .extern_func,
1740 .@"extern",
17471741 .func,
17481742 .int,
17491743 .err,
......@@ -1758,7 +1752,7 @@ pub const DeclGen = struct {
17581752 .aggregate,
17591753 .un,
17601754 .memoized_call,
1761 => unreachable,
1755 => unreachable, // values, not types
17621756 },
17631757 }
17641758 }
......@@ -1770,7 +1764,7 @@ pub const DeclGen = struct {
17701764 fn_align: InternPool.Alignment,
17711765 kind: CType.Kind,
17721766 name: union(enum) {
1773 decl: InternPool.DeclIndex,
1767 nav: InternPool.Nav.Index,
17741768 fmt_ctype_pool_string: std.fmt.Formatter(formatCTypePoolString),
17751769 @"export": struct {
17761770 main_name: InternPool.NullTerminatedString,
......@@ -1805,7 +1799,7 @@ pub const DeclGen = struct {
18051799
18061800 try w.print("{}", .{trailing});
18071801 switch (name) {
1808 .decl => |decl_index| try dg.renderDeclName(w, decl_index),
1802 .nav => |nav| try dg.renderNavName(w, nav),
18091803 .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}),
18101804 .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),
18111805 }
......@@ -1828,7 +1822,7 @@ pub const DeclGen = struct {
18281822 .forward => {
18291823 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});
18301824 switch (name) {
1831 .decl, .fmt_ctype_pool_string => {},
1825 .nav, .fmt_ctype_pool_string => {},
18321826 .@"export" => |@"export"| {
18331827 const extern_name = @"export".extern_name.toSlice(ip);
18341828 const is_mangled = isMangledIdent(extern_name, true);
......@@ -2069,8 +2063,8 @@ pub const DeclGen = struct {
20692063 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {
20702064 switch (c_value) {
20712065 .new_local, .local => |i| try w.print("t{d}", .{i}),
2072 .constant => |val| try renderAnonDeclName(w, val),
2073 .decl => |decl| try dg.renderDeclName(w, decl),
2066 .constant => |uav| try renderUavName(w, uav),
2067 .nav => |nav| try dg.renderNavName(w, nav),
20742068 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
20752069 else => unreachable,
20762070 }
......@@ -2079,13 +2073,13 @@ pub const DeclGen = struct {
20792073 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {
20802074 switch (c_value) {
20812075 .none, .new_local, .local, .local_ref => unreachable,
2082 .constant => |val| try renderAnonDeclName(w, val),
2076 .constant => |uav| try renderUavName(w, uav),
20832077 .arg, .arg_array => unreachable,
20842078 .field => |i| try w.print("f{d}", .{i}),
2085 .decl => |decl| try dg.renderDeclName(w, decl),
2086 .decl_ref => |decl| {
2079 .nav => |nav| try dg.renderNavName(w, nav),
2080 .nav_ref => |nav| {
20872081 try w.writeByte('&');
2088 try dg.renderDeclName(w, decl);
2082 try dg.renderNavName(w, nav);
20892083 },
20902084 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),
20912085 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
......@@ -2111,12 +2105,12 @@ pub const DeclGen = struct {
21112105 .ctype_pool_string,
21122106 => unreachable,
21132107 .field => |i| try w.print("f{d}", .{i}),
2114 .decl => |decl| {
2108 .nav => |nav| {
21152109 try w.writeAll("(*");
2116 try dg.renderDeclName(w, decl);
2110 try dg.renderNavName(w, nav);
21172111 try w.writeByte(')');
21182112 },
2119 .decl_ref => |decl| try dg.renderDeclName(w, decl),
2113 .nav_ref => |nav| try dg.renderNavName(w, nav),
21202114 .undef => unreachable,
21212115 .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}),
21222116 .payload_identifier => |ident| try w.print("(*{ }.{ })", .{
......@@ -2150,11 +2144,11 @@ pub const DeclGen = struct {
21502144 .arg_array,
21512145 .ctype_pool_string,
21522146 => unreachable,
2153 .decl, .identifier, .payload_identifier => {
2147 .nav, .identifier, .payload_identifier => {
21542148 try dg.writeCValue(writer, c_value);
21552149 try writer.writeAll("->");
21562150 },
2157 .decl_ref => {
2151 .nav_ref => {
21582152 try dg.writeCValueDeref(writer, c_value);
21592153 try writer.writeByte('.');
21602154 },
......@@ -2164,46 +2158,53 @@ pub const DeclGen = struct {
21642158
21652159 fn renderFwdDecl(
21662160 dg: *DeclGen,
2167 decl_index: InternPool.DeclIndex,
2168 variable: InternPool.Key.Variable,
2161 nav_index: InternPool.Nav.Index,
2162 flags: struct {
2163 is_extern: bool,
2164 is_const: bool,
2165 is_threadlocal: bool,
2166 is_weak_linkage: bool,
2167 },
21692168 ) !void {
21702169 const zcu = dg.pt.zcu;
2171 const decl = zcu.declPtr(decl_index);
2170 const ip = &zcu.intern_pool;
2171 const nav = ip.getNav(nav_index);
21722172 const fwd = dg.fwdDeclWriter();
2173 try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static ");
2174 if (variable.is_weak_linkage) try fwd.writeAll("zig_weak_linkage ");
2175 if (variable.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal ");
2173 try fwd.writeAll(if (flags.is_extern) "zig_extern " else "static ");
2174 if (flags.is_weak_linkage) try fwd.writeAll("zig_weak_linkage ");
2175 if (flags.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal ");
21762176 try dg.renderTypeAndName(
21772177 fwd,
2178 decl.typeOf(zcu),
2179 .{ .decl = decl_index },
2180 CQualifiers.init(.{ .@"const" = variable.is_const }),
2181 decl.alignment,
2178 Type.fromInterned(nav.typeOf(ip)),
2179 .{ .nav = nav_index },
2180 CQualifiers.init(.{ .@"const" = flags.is_const }),
2181 nav.status.resolved.alignment,
21822182 .complete,
21832183 );
21842184 try fwd.writeAll(";\n");
21852185 }
21862186
2187 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: InternPool.DeclIndex) !void {
2187 fn renderNavName(dg: *DeclGen, writer: anytype, nav_index: InternPool.Nav.Index) !void {
21882188 const zcu = dg.pt.zcu;
21892189 const ip = &zcu.intern_pool;
2190 const decl = zcu.declPtr(decl_index);
2191
2192 if (decl.getExternDecl(zcu).unwrap()) |extern_decl_index| try writer.print("{ }", .{
2193 fmtIdent(zcu.declPtr(extern_decl_index).name.toSlice(ip)),
2194 }) else {
2195 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
2196 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2197 const fqn_slice = decl.fqn.toSlice(ip);
2198 try writer.print("{}__{d}", .{
2199 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
2200 @intFromEnum(decl_index),
2201 });
2190 switch (ip.indexToKey(zcu.navValue(nav_index).toIntern())) {
2191 .@"extern" => |@"extern"| try writer.print("{ }", .{
2192 fmtIdent(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
2193 }),
2194 else => {
2195 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
2196 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2197 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
2198 try writer.print("{}__{d}", .{
2199 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
2200 @intFromEnum(nav_index),
2201 });
2202 },
22022203 }
22032204 }
22042205
2205 fn renderAnonDeclName(writer: anytype, anon_decl_val: Value) !void {
2206 try writer.print("__anon_{d}", .{@intFromEnum(anon_decl_val.toIntern())});
2206 fn renderUavName(writer: anytype, uav: Value) !void {
2207 try writer.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
22072208 }
22082209
22092210 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
......@@ -2301,12 +2302,13 @@ fn renderFwdDeclTypeName(
23012302 fwd_decl: CType.Info.FwdDecl,
23022303 attributes: []const u8,
23032304) !void {
2305 const ip = &zcu.intern_pool;
23042306 try w.print("{s} {s}", .{ @tagName(fwd_decl.tag), attributes });
23052307 switch (fwd_decl.name) {
23062308 .anon => try w.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),
2307 .owner_decl => |owner_decl| try w.print("{}__{d}", .{
2308 fmtIdent(zcu.declPtr(owner_decl).name.toSlice(&zcu.intern_pool)),
2309 @intFromEnum(owner_decl),
2309 .index => |index| try w.print("{}__{d}", .{
2310 fmtIdent(Type.fromInterned(index).containerTypeName(ip).toSlice(&zcu.intern_pool)),
2311 @intFromEnum(index),
23102312 }),
23112313 }
23122314}
......@@ -2340,11 +2342,11 @@ fn renderTypePrefix(
23402342 },
23412343
23422344 .aligned => switch (pass) {
2343 .decl => |decl_index| try w.print("decl__{d}_{d}", .{
2344 @intFromEnum(decl_index), @intFromEnum(ctype.index),
2345 .nav => |nav| try w.print("nav__{d}_{d}", .{
2346 @intFromEnum(nav), @intFromEnum(ctype.index),
23452347 }),
2346 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{
2347 @intFromEnum(anon_decl), @intFromEnum(ctype.index),
2348 .uav => |uav| try w.print("uav__{d}_{d}", .{
2349 @intFromEnum(uav), @intFromEnum(ctype.index),
23482350 }),
23492351 .flush => try renderAlignedTypeName(w, ctype),
23502352 },
......@@ -2370,15 +2372,15 @@ fn renderTypePrefix(
23702372
23712373 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
23722374 .anon => switch (pass) {
2373 .decl => |decl_index| try w.print("decl__{d}_{d}", .{
2374 @intFromEnum(decl_index), @intFromEnum(ctype.index),
2375 .nav => |nav| try w.print("nav__{d}_{d}", .{
2376 @intFromEnum(nav), @intFromEnum(ctype.index),
23752377 }),
2376 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{
2377 @intFromEnum(anon_decl), @intFromEnum(ctype.index),
2378 .uav => |uav| try w.print("uav__{d}_{d}", .{
2379 @intFromEnum(uav), @intFromEnum(ctype.index),
23782380 }),
23792381 .flush => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
23802382 },
2381 .owner_decl => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2383 .index => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
23822384 },
23832385
23842386 .aggregate => |aggregate_info| switch (aggregate_info.name) {
......@@ -2557,7 +2559,7 @@ pub fn genTypeDecl(
25572559 try writer.writeAll(";\n");
25582560 }
25592561 switch (pass) {
2560 .decl, .anon => {
2562 .nav, .uav => {
25612563 try writer.writeAll("typedef ");
25622564 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
25632565 try writer.writeByte(' ');
......@@ -2569,7 +2571,7 @@ pub fn genTypeDecl(
25692571 },
25702572 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
25712573 .anon => switch (pass) {
2572 .decl, .anon => {
2574 .nav, .uav => {
25732575 try writer.writeAll("typedef ");
25742576 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
25752577 try writer.writeByte(' ');
......@@ -2578,13 +2580,14 @@ pub fn genTypeDecl(
25782580 },
25792581 .flush => {},
25802582 },
2581 .owner_decl => |owner_decl_index| if (!found_existing) {
2583 .index => |index| if (!found_existing) {
2584 const ip = &zcu.intern_pool;
2585 const ty = Type.fromInterned(index);
25822586 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
25832587 try writer.writeByte(';');
2584 const owner_decl = zcu.declPtr(owner_decl_index);
2585 const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod;
2586 if (!owner_mod.strip) try writer.print(" /* {} */", .{
2587 owner_decl.fqn.fmt(&zcu.intern_pool),
2588 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file;
2589 if (!zcu.fileByIndex(file_scope).mod.strip) try writer.print(" /* {} */", .{
2590 ty.containerTypeName(ip).fmt(ip),
25882591 });
25892592 try writer.writeByte('\n');
25902593 },
......@@ -2709,9 +2712,8 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
27092712 const key = lazy_fn.key_ptr.*;
27102713 const val = lazy_fn.value_ptr;
27112714 switch (key) {
2712 .tag_name => {
2713 const enum_ty = val.data.tag_name;
2714
2715 .tag_name => |enum_ty_ip| {
2716 const enum_ty = Type.fromInterned(enum_ty_ip);
27152717 const name_slice_ty = Type.slice_const_u8_sentinel_0;
27162718
27172719 try w.writeAll("static ");
......@@ -2756,25 +2758,25 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
27562758 _ = try airBreakpoint(w);
27572759 try w.writeAll("}\n");
27582760 },
2759 .never_tail, .never_inline => |fn_decl_index| {
2760 const fn_decl = zcu.declPtr(fn_decl_index);
2761 const fn_ctype = try o.dg.ctypeFromType(fn_decl.typeOf(zcu), .complete);
2761 .never_tail, .never_inline => |fn_nav_index| {
2762 const fn_val = zcu.navValue(fn_nav_index);
2763 const fn_ctype = try o.dg.ctypeFromType(fn_val.typeOf(zcu), .complete);
27622764 const fn_info = fn_ctype.info(ctype_pool).function;
27632765 const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool);
27642766
27652767 const fwd = o.dg.fwdDeclWriter();
27662768 try fwd.print("static zig_{s} ", .{@tagName(key)});
2767 try o.dg.renderFunctionSignature(fwd, fn_decl.val, fn_decl.alignment, .forward, .{
2769 try o.dg.renderFunctionSignature(fwd, fn_val, ip.getNav(fn_nav_index).status.resolved.alignment, .forward, .{
27682770 .fmt_ctype_pool_string = fn_name,
27692771 });
27702772 try fwd.writeAll(";\n");
27712773
27722774 try w.print("zig_{s} ", .{@tagName(key)});
2773 try o.dg.renderFunctionSignature(w, fn_decl.val, .none, .complete, .{
2775 try o.dg.renderFunctionSignature(w, fn_val, .none, .complete, .{
27742776 .fmt_ctype_pool_string = fn_name,
27752777 });
27762778 try w.writeAll(" {\n return ");
2777 try o.dg.renderDeclName(w, fn_decl_index);
2779 try o.dg.renderNavName(w, fn_nav_index);
27782780 try w.writeByte('(');
27792781 for (0..fn_info.param_ctypes.len) |arg| {
27802782 if (arg > 0) try w.writeAll(", ");
......@@ -2791,9 +2793,11 @@ pub fn genFunc(f: *Function) !void {
27912793
27922794 const o = &f.object;
27932795 const zcu = o.dg.pt.zcu;
2796 const ip = &zcu.intern_pool;
27942797 const gpa = o.dg.gpa;
2795 const decl_index = o.dg.pass.decl;
2796 const decl = zcu.declPtr(decl_index);
2798 const nav_index = o.dg.pass.nav;
2799 const nav_val = zcu.navValue(nav_index);
2800 const nav = ip.getNav(nav_index);
27972801
27982802 o.code_header = std.ArrayList(u8).init(gpa);
27992803 defer o.code_header.deinit();
......@@ -2802,21 +2806,21 @@ pub fn genFunc(f: *Function) !void {
28022806 try fwd.writeAll("static ");
28032807 try o.dg.renderFunctionSignature(
28042808 fwd,
2805 decl.val,
2806 decl.alignment,
2809 nav_val,
2810 nav.status.resolved.alignment,
28072811 .forward,
2808 .{ .decl = decl_index },
2812 .{ .nav = nav_index },
28092813 );
28102814 try fwd.writeAll(";\n");
28112815
2812 if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s|
2816 if (nav.status.resolved.@"linksection".toSlice(ip)) |s|
28132817 try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)});
28142818 try o.dg.renderFunctionSignature(
28152819 o.writer(),
2816 decl.val,
2820 nav_val,
28172821 .none,
28182822 .complete,
2819 .{ .decl = decl_index },
2823 .{ .nav = nav_index },
28202824 );
28212825 try o.writer().writeByte(' ');
28222826
......@@ -2883,44 +2887,66 @@ pub fn genDecl(o: *Object) !void {
28832887
28842888 const pt = o.dg.pt;
28852889 const zcu = pt.zcu;
2886 const decl_index = o.dg.pass.decl;
2887 const decl = zcu.declPtr(decl_index);
2888 const decl_ty = decl.typeOf(zcu);
2890 const ip = &zcu.intern_pool;
2891 const nav = ip.getNav(o.dg.pass.nav);
2892 const nav_ty = Type.fromInterned(nav.typeOf(ip));
2893
2894 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return;
2895 switch (ip.indexToKey(nav.status.resolved.val)) {
2896 .@"extern" => |@"extern"| {
2897 if (!ip.isFunctionType(nav_ty.toIntern())) return o.dg.renderFwdDecl(o.dg.pass.nav, .{
2898 .is_extern = true,
2899 .is_const = @"extern".is_const,
2900 .is_threadlocal = @"extern".is_threadlocal,
2901 .is_weak_linkage = @"extern".is_weak_linkage,
2902 });
28892903
2890 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) return;
2891 if (decl.val.getExternFunc(zcu)) |_| {
2892 const fwd = o.dg.fwdDeclWriter();
2893 try fwd.writeAll("zig_extern ");
2894 try o.dg.renderFunctionSignature(
2895 fwd,
2896 decl.val,
2897 decl.alignment,
2898 .forward,
2899 .{ .@"export" = .{
2900 .main_name = decl.name,
2901 .extern_name = decl.name,
2902 } },
2903 );
2904 try fwd.writeAll(";\n");
2905 } else if (decl.val.getVariable(zcu)) |variable| {
2906 try o.dg.renderFwdDecl(decl_index, variable);
2907
2908 if (variable.is_extern) return;
2909
2910 const w = o.writer();
2911 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2912 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");
2913 if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s|
2914 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
2915 const decl_c_value = .{ .decl = decl_index };
2916 try o.dg.renderTypeAndName(w, decl_ty, decl_c_value, .{}, decl.alignment, .complete);
2917 try w.writeAll(" = ");
2918 try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);
2919 try w.writeByte(';');
2920 try o.indent_writer.insertNewline();
2921 } else {
2922 const decl_c_value = .{ .decl = decl_index };
2923 try genDeclValue(o, decl.val, decl_c_value, decl.alignment, decl.@"linksection");
2904 const fwd = o.dg.fwdDeclWriter();
2905 try fwd.writeAll("zig_extern ");
2906 try o.dg.renderFunctionSignature(
2907 fwd,
2908 Value.fromInterned(nav.status.resolved.val),
2909 nav.status.resolved.alignment,
2910 .forward,
2911 .{ .@"export" = .{
2912 .main_name = nav.name,
2913 .extern_name = nav.name,
2914 } },
2915 );
2916 try fwd.writeAll(";\n");
2917 },
2918 .variable => |variable| {
2919 try o.dg.renderFwdDecl(o.dg.pass.nav, .{
2920 .is_extern = false,
2921 .is_const = false,
2922 .is_threadlocal = variable.is_threadlocal,
2923 .is_weak_linkage = variable.is_weak_linkage,
2924 });
2925 const w = o.writer();
2926 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2927 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");
2928 if (nav.status.resolved.@"linksection".toSlice(&zcu.intern_pool)) |s|
2929 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
2930 try o.dg.renderTypeAndName(
2931 w,
2932 nav_ty,
2933 .{ .nav = o.dg.pass.nav },
2934 .{},
2935 nav.status.resolved.alignment,
2936 .complete,
2937 );
2938 try w.writeAll(" = ");
2939 try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);
2940 try w.writeByte(';');
2941 try o.indent_writer.insertNewline();
2942 },
2943 else => try genDeclValue(
2944 o,
2945 Value.fromInterned(nav.status.resolved.val),
2946 .{ .nav = o.dg.pass.nav },
2947 nav.status.resolved.alignment,
2948 nav.status.resolved.@"linksection",
2949 ),
29242950 }
29252951}
29262952
......@@ -2956,31 +2982,34 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
29562982 const main_name = zcu.all_exports.items[export_indices[0]].opts.name;
29572983 try fwd.writeAll("#define ");
29582984 switch (exported) {
2959 .decl_index => |decl_index| try dg.renderDeclName(fwd, decl_index),
2960 .value => |value| try DeclGen.renderAnonDeclName(fwd, Value.fromInterned(value)),
2985 .nav => |nav| try dg.renderNavName(fwd, nav),
2986 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),
29612987 }
29622988 try fwd.writeByte(' ');
29632989 try fwd.print("{ }", .{fmtIdent(main_name.toSlice(ip))});
29642990 try fwd.writeByte('\n');
29652991
2966 const is_const = switch (ip.indexToKey(exported.getValue(zcu).toIntern())) {
2967 .func, .extern_func => return for (export_indices) |export_index| {
2968 const @"export" = &zcu.all_exports.items[export_index];
2969 try fwd.writeAll("zig_extern ");
2970 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");
2971 try dg.renderFunctionSignature(
2972 fwd,
2973 exported.getValue(zcu),
2974 exported.getAlign(zcu),
2975 .forward,
2976 .{ .@"export" = .{
2977 .main_name = main_name,
2978 .extern_name = @"export".opts.name,
2979 } },
2980 );
2981 try fwd.writeAll(";\n");
2982 },
2983 .variable => |variable| variable.is_const,
2992 const exported_val = exported.getValue(zcu);
2993 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {
2994 const @"export" = &zcu.all_exports.items[export_index];
2995 try fwd.writeAll("zig_extern ");
2996 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");
2997 try dg.renderFunctionSignature(
2998 fwd,
2999 exported.getValue(zcu),
3000 exported.getAlign(zcu),
3001 .forward,
3002 .{ .@"export" = .{
3003 .main_name = main_name,
3004 .extern_name = @"export".opts.name,
3005 } },
3006 );
3007 try fwd.writeAll(";\n");
3008 };
3009 const is_const = switch (ip.indexToKey(exported_val.toIntern())) {
3010 .func => unreachable,
3011 .@"extern" => |@"extern"| @"extern".is_const,
3012 .variable => false,
29843013 else => true,
29853014 };
29863015 for (export_indices) |export_index| {
......@@ -4474,24 +4503,19 @@ fn airCall(
44744503
44754504 callee: {
44764505 known: {
4477 const fn_decl = fn_decl: {
4478 const callee_val = (try f.air.value(pl_op.operand, pt)) orelse break :known;
4479 break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) {
4480 .extern_func => |extern_func| extern_func.decl,
4481 .func => |func| func.owner_decl,
4482 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
4483 .decl => |decl| decl,
4484 else => break :known,
4485 } else break :known,
4506 const callee_val = (try f.air.value(pl_op.operand, pt)) orelse break :known;
4507 const fn_nav = switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) {
4508 .@"extern" => |@"extern"| @"extern".owner_nav,
4509 .func => |func| func.owner_nav,
4510 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
4511 .nav => |nav| nav,
44864512 else => break :known,
4487 };
4513 } else break :known,
4514 else => break :known,
44884515 };
44894516 switch (modifier) {
4490 .auto, .always_tail => try f.object.dg.renderDeclName(writer, fn_decl),
4491 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(
4492 @unionInit(LazyFnKey, @tagName(m), fn_decl),
4493 @unionInit(LazyFnValue.Data, @tagName(m), {}),
4494 )),
4517 .auto, .always_tail => try f.object.dg.renderNavName(writer, fn_nav),
4518 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
44954519 else => unreachable,
44964520 }
44974521 break :callee;
......@@ -4554,11 +4578,12 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
45544578fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
45554579 const pt = f.object.dg.pt;
45564580 const zcu = pt.zcu;
4581 const ip = &zcu.intern_pool;
45574582 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
45584583 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4559 const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);
4584 const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav);
45604585 const writer = f.object.writer();
4561 try writer.print("/* inline:{} */\n", .{owner_decl.fqn.fmt(&zcu.intern_pool)});
4586 try writer.print("/* inline:{} */\n", .{owner_nav.fqn.fmt(&zcu.intern_pool)});
45624587 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
45634588}
45644589
......@@ -5059,7 +5084,7 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
50595084 else => switch (value) {
50605085 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
50615086 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
5062 .decl => false,
5087 .nav => false,
50635088 else => true,
50645089 } else true,
50655090 else => true,
......@@ -6841,8 +6866,6 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
68416866}
68426867
68436868fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6844 const pt = f.object.dg.pt;
6845 const zcu = pt.zcu;
68466869 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
68476870
68486871 const inst_ty = f.typeOfIndex(inst);
......@@ -6854,7 +6877,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
68546877 const local = try f.allocLocal(inst, inst_ty);
68556878 try f.writeCValue(writer, local, .Other);
68566879 try writer.print(" = {s}(", .{
6857 try f.getLazyFnName(.{ .tag_name = enum_ty.getOwnerDecl(zcu) }, .{ .tag_name = enum_ty }),
6880 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),
68586881 });
68596882 try f.writeCValue(writer, operand, .Other);
68606883 try writer.writeAll(");\n");
......@@ -7390,18 +7413,17 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
73907413 const pt = f.object.dg.pt;
73917414 const zcu = pt.zcu;
73927415 const inst_ty = f.typeOfIndex(inst);
7393 const decl_index = f.object.dg.pass.decl;
7394 const decl = zcu.declPtr(decl_index);
7395 const function_ctype = try f.ctypeFromType(decl.typeOf(zcu), .complete);
7396 const params_len = function_ctype.info(&f.object.dg.ctype_pool).function.param_ctypes.len;
7416 const function_ty = zcu.navValue(f.object.dg.pass.nav).typeOf(zcu);
7417 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;
7418 assert(function_info.varargs);
73977419
73987420 const writer = f.object.writer();
73997421 const local = try f.allocLocal(inst, inst_ty);
74007422 try writer.writeAll("va_start(*(va_list *)&");
74017423 try f.writeCValue(writer, local, .Other);
7402 if (params_len > 0) {
7424 if (function_info.param_ctypes.len > 0) {
74037425 try writer.writeAll(", ");
7404 try f.writeCValue(writer, .{ .arg = params_len - 1 }, .FunctionArgument);
7426 try f.writeCValue(writer, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);
74057427 }
74067428 try writer.writeAll(");\n");
74077429 return local;
......@@ -7941,7 +7963,7 @@ const Materialize = struct {
79417963
79427964 pub fn start(f: *Function, inst: Air.Inst.Index, ty: Type, value: CValue) !Materialize {
79437965 return .{ .local = switch (value) {
7944 .local_ref, .constant, .decl_ref, .undef => try f.moveCValue(inst, ty, value),
7966 .local_ref, .constant, .nav_ref, .undef => try f.moveCValue(inst, ty, value),
79457967 .new_local => |local| .{ .local = local },
79467968 else => value,
79477969 } };
src/codegen/c/Type.zig+36-37
......@@ -449,18 +449,18 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
449449 },
450450 .fwd_decl_struct => return .{ .fwd_decl = .{
451451 .tag = .@"struct",
452 .name = .{ .owner_decl = @enumFromInt(item.data) },
452 .name = .{ .index = @enumFromInt(item.data) },
453453 } },
454454 .fwd_decl_union => return .{ .fwd_decl = .{
455455 .tag = .@"union",
456 .name = .{ .owner_decl = @enumFromInt(item.data) },
456 .name = .{ .index = @enumFromInt(item.data) },
457457 } },
458458 .aggregate_struct_anon => {
459459 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);
460460 return .{ .aggregate = .{
461461 .tag = .@"struct",
462462 .name = .{ .anon = .{
463 .owner_decl = extra_trail.extra.owner_decl,
463 .index = extra_trail.extra.index,
464464 .id = extra_trail.extra.id,
465465 } },
466466 .fields = .{
......@@ -474,7 +474,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
474474 return .{ .aggregate = .{
475475 .tag = .@"union",
476476 .name = .{ .anon = .{
477 .owner_decl = extra_trail.extra.owner_decl,
477 .index = extra_trail.extra.index,
478478 .id = extra_trail.extra.id,
479479 } },
480480 .fields = .{
......@@ -489,7 +489,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
489489 .tag = .@"struct",
490490 .@"packed" = true,
491491 .name = .{ .anon = .{
492 .owner_decl = extra_trail.extra.owner_decl,
492 .index = extra_trail.extra.index,
493493 .id = extra_trail.extra.id,
494494 } },
495495 .fields = .{
......@@ -504,7 +504,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
504504 .tag = .@"union",
505505 .@"packed" = true,
506506 .name = .{ .anon = .{
507 .owner_decl = extra_trail.extra.owner_decl,
507 .index = extra_trail.extra.index,
508508 .id = extra_trail.extra.id,
509509 } },
510510 .fields = .{
......@@ -834,7 +834,7 @@ pub const Info = union(enum) {
834834 tag: AggregateTag,
835835 name: union(enum) {
836836 anon: Field.Slice,
837 owner_decl: DeclIndex,
837 index: InternPool.Index,
838838 },
839839 };
840840
......@@ -843,7 +843,7 @@ pub const Info = union(enum) {
843843 @"packed": bool = false,
844844 name: union(enum) {
845845 anon: struct {
846 owner_decl: DeclIndex,
846 index: InternPool.Index,
847847 id: u32,
848848 },
849849 fwd_decl: CType,
......@@ -885,14 +885,14 @@ pub const Info = union(enum) {
885885 rhs_pool,
886886 pool_adapter,
887887 ),
888 .owner_decl => |lhs_owner_decl| rhs_info.fwd_decl.name == .owner_decl and
889 lhs_owner_decl == rhs_info.fwd_decl.name.owner_decl,
888 .index => |lhs_index| rhs_info.fwd_decl.name == .index and
889 lhs_index == rhs_info.fwd_decl.name.index,
890890 },
891891 .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and
892892 lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and
893893 switch (lhs_aggregate_info.name) {
894894 .anon => |lhs_anon| rhs_info.aggregate.name == .anon and
895 lhs_anon.owner_decl == rhs_info.aggregate.name.anon.owner_decl and
895 lhs_anon.index == rhs_info.aggregate.name.anon.index and
896896 lhs_anon.id == rhs_info.aggregate.name.anon.id,
897897 .fwd_decl => |lhs_fwd_decl| rhs_info.aggregate.name == .fwd_decl and
898898 pool_adapter.eql(lhs_fwd_decl, rhs_info.aggregate.name.fwd_decl),
......@@ -1105,7 +1105,7 @@ pub const Pool = struct {
11051105 tag: Info.AggregateTag,
11061106 name: union(enum) {
11071107 anon: []const Info.Field,
1108 owner_decl: DeclIndex,
1108 index: InternPool.Index,
11091109 },
11101110 },
11111111 ) !CType {
......@@ -1145,13 +1145,13 @@ pub const Pool = struct {
11451145 .@"enum" => unreachable,
11461146 }, extra_index);
11471147 },
1148 .owner_decl => |owner_decl| {
1149 hasher.update(owner_decl);
1148 .index => |index| {
1149 hasher.update(index);
11501150 return pool.tagData(allocator, hasher, switch (fwd_decl_info.tag) {
11511151 .@"struct" => .fwd_decl_struct,
11521152 .@"union" => .fwd_decl_union,
11531153 .@"enum" => unreachable,
1154 }, @intFromEnum(owner_decl));
1154 }, @intFromEnum(index));
11551155 },
11561156 }
11571157 }
......@@ -1164,7 +1164,7 @@ pub const Pool = struct {
11641164 @"packed": bool = false,
11651165 name: union(enum) {
11661166 anon: struct {
1167 owner_decl: DeclIndex,
1167 index: InternPool.Index,
11681168 id: u32,
11691169 },
11701170 fwd_decl: CType,
......@@ -1176,7 +1176,7 @@ pub const Pool = struct {
11761176 switch (aggregate_info.name) {
11771177 .anon => |anon| {
11781178 const extra: AggregateAnon = .{
1179 .owner_decl = anon.owner_decl,
1179 .index = anon.index,
11801180 .id = anon.id,
11811181 .fields_len = @intCast(aggregate_info.fields.len),
11821182 };
......@@ -1683,7 +1683,7 @@ pub const Pool = struct {
16831683 .auto, .@"extern" => {
16841684 const fwd_decl = try pool.getFwdDecl(allocator, .{
16851685 .tag = .@"struct",
1686 .name = .{ .owner_decl = loaded_struct.decl.unwrap().? },
1686 .name = .{ .index = ip_index },
16871687 });
16881688 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))
16891689 fwd_decl
......@@ -1822,7 +1822,7 @@ pub const Pool = struct {
18221822 const has_tag = loaded_union.hasTag(ip);
18231823 const fwd_decl = try pool.getFwdDecl(allocator, .{
18241824 .tag = if (has_tag) .@"struct" else .@"union",
1825 .name = .{ .owner_decl = loaded_union.decl },
1825 .name = .{ .index = ip_index },
18261826 });
18271827 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))
18281828 fwd_decl
......@@ -1837,7 +1837,7 @@ pub const Pool = struct {
18371837 );
18381838 var hasher = Hasher.init;
18391839 var tag: Pool.Tag = .aggregate_union;
1840 var payload_align: Alignment = .@"1";
1840 var payload_align: InternPool.Alignment = .@"1";
18411841 for (0..loaded_union.field_types.len) |field_index| {
18421842 const field_type = Type.fromInterned(
18431843 loaded_union.field_types.get(ip)[field_index],
......@@ -1915,7 +1915,7 @@ pub const Pool = struct {
19151915 &hasher,
19161916 AggregateAnon,
19171917 .{
1918 .owner_decl = loaded_union.decl,
1918 .index = ip_index,
19191919 .id = 0,
19201920 .fields_len = fields_len,
19211921 },
......@@ -2017,7 +2017,7 @@ pub const Pool = struct {
20172017 .undef,
20182018 .simple_value,
20192019 .variable,
2020 .extern_func,
2020 .@"extern",
20212021 .func,
20222022 .int,
20232023 .err,
......@@ -2032,7 +2032,7 @@ pub const Pool = struct {
20322032 .aggregate,
20332033 .un,
20342034 .memoized_call,
2035 => unreachable,
2035 => unreachable, // values, not types
20362036 },
20372037 }
20382038 }
......@@ -2123,9 +2123,9 @@ pub const Pool = struct {
21232123 });
21242124 }
21252125 },
2126 .owner_decl => |owner_decl| pool.items.appendAssumeCapacity(.{
2126 .index => |index| pool.items.appendAssumeCapacity(.{
21272127 .tag = tag,
2128 .data = @intFromEnum(owner_decl),
2128 .data = @intFromEnum(index),
21292129 }),
21302130 },
21312131 .aggregate => |aggregate_info| {
......@@ -2133,7 +2133,7 @@ pub const Pool = struct {
21332133 .tag = tag,
21342134 .data = switch (aggregate_info.name) {
21352135 .anon => |anon| try pool.addExtra(allocator, AggregateAnon, .{
2136 .owner_decl = anon.owner_decl,
2136 .index = anon.index,
21372137 .id = anon.id,
21382138 .fields_len = aggregate_info.fields.len,
21392139 }, aggregate_info.fields.len * @typeInfo(Field).Struct.fields.len),
......@@ -2221,7 +2221,7 @@ pub const Pool = struct {
22212221 Pool.Tag => @compileError("pass tag to final"),
22222222 CType, CType.Index => @compileError("hash ctype.hash(pool) instead"),
22232223 String, String.Index => @compileError("hash string.slice(pool) instead"),
2224 u32, DeclIndex, Aligned.Flags => hasher.impl.update(std.mem.asBytes(&data)),
2224 u32, InternPool.Index, Aligned.Flags => hasher.impl.update(std.mem.asBytes(&data)),
22252225 []const u8 => hasher.impl.update(data),
22262226 else => @compileError("unhandled type: " ++ @typeName(@TypeOf(data))),
22272227 }
......@@ -2426,7 +2426,7 @@ pub const Pool = struct {
24262426 };
24272427
24282428 const AggregateAnon = struct {
2429 owner_decl: DeclIndex,
2429 index: InternPool.Index,
24302430 id: u32,
24312431 fields_len: u32,
24322432 };
......@@ -2467,7 +2467,7 @@ pub const Pool = struct {
24672467 const value = @field(extra, field.name);
24682468 array.appendAssumeCapacity(switch (field.type) {
24692469 u32 => value,
2470 CType.Index, String.Index, DeclIndex => @intFromEnum(value),
2470 CType.Index, String.Index, InternPool.Index => @intFromEnum(value),
24712471 Aligned.Flags => @bitCast(value),
24722472 else => @compileError("bad field type: " ++ field.name ++ ": " ++
24732473 @typeName(field.type)),
......@@ -2530,7 +2530,7 @@ pub const Pool = struct {
25302530 inline for (fields, pool.extra.items[extra_index..][0..fields.len]) |field, value|
25312531 @field(extra, field.name) = switch (field.type) {
25322532 u32 => value,
2533 CType.Index, String.Index, DeclIndex => @enumFromInt(value),
2533 CType.Index, String.Index, InternPool.Index => @enumFromInt(value),
25342534 Aligned.Flags => @bitCast(value),
25352535 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
25362536 };
......@@ -2546,8 +2546,8 @@ pub const Pool = struct {
25462546};
25472547
25482548pub const AlignAs = packed struct {
2549 @"align": Alignment,
2550 abi: Alignment,
2549 @"align": InternPool.Alignment,
2550 abi: InternPool.Alignment,
25512551
25522552 pub fn fromAlignment(alignas: AlignAs) AlignAs {
25532553 assert(alignas.abi != .none);
......@@ -2556,14 +2556,14 @@ pub const AlignAs = packed struct {
25562556 .abi = alignas.abi,
25572557 };
25582558 }
2559 pub fn fromAbiAlignment(abi: Alignment) AlignAs {
2559 pub fn fromAbiAlignment(abi: InternPool.Alignment) AlignAs {
25602560 assert(abi != .none);
25612561 return .{ .@"align" = abi, .abi = abi };
25622562 }
25632563 pub fn fromByteUnits(@"align": u64, abi: u64) AlignAs {
25642564 return fromAlignment(.{
2565 .@"align" = Alignment.fromByteUnits(@"align"),
2566 .abi = Alignment.fromNonzeroByteUnits(abi),
2565 .@"align" = InternPool.Alignment.fromByteUnits(@"align"),
2566 .abi = InternPool.Alignment.fromNonzeroByteUnits(abi),
25672567 });
25682568 }
25692569
......@@ -2578,11 +2578,10 @@ pub const AlignAs = packed struct {
25782578 }
25792579};
25802580
2581const Alignment = @import("../../InternPool.zig").Alignment;
25822581const assert = std.debug.assert;
25832582const CType = @This();
2583const InternPool = @import("../../InternPool.zig");
25842584const Module = @import("../../Package/Module.zig");
25852585const std = @import("std");
25862586const Type = @import("../../Type.zig");
25872587const Zcu = @import("../../Zcu.zig");
2588const DeclIndex = @import("../../InternPool.zig").DeclIndex;
src/codegen/llvm.zig+409-439
......@@ -776,7 +776,7 @@ pub const Object = struct {
776776 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),
777777 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),
778778
779 debug_file_map: std.AutoHashMapUnmanaged(*const Zcu.File, Builder.Metadata),
779 debug_file_map: std.AutoHashMapUnmanaged(Zcu.File.Index, Builder.Metadata),
780780 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),
781781
782782 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
......@@ -790,11 +790,13 @@ pub const Object = struct {
790790 /// version of the name and incorrectly get function not found in the llvm module.
791791 /// * it works for functions not all globals.
792792 /// Therefore, this table keeps track of the mapping.
793 decl_map: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Builder.Global.Index),
793 nav_map: std.AutoHashMapUnmanaged(InternPool.Nav.Index, Builder.Global.Index),
794794 /// Same deal as `decl_map` but for anonymous declarations, which are always global constants.
795 anon_decl_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Global.Index),
796 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.
797 named_enum_map: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Builder.Function.Index),
795 uav_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Global.Index),
796 /// Maps enum types to their corresponding LLVM functions for implementing the `tag_name` instruction.
797 enum_tag_name_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Global.Index),
798 /// Serves the same purpose as `enum_tag_name_map` but for the `is_named_enum_value` instruction.
799 named_enum_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Function.Index),
798800 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
799801 /// the compiler.
800802 /// TODO when InternPool garbage collection is implemented, this map needs
......@@ -963,8 +965,9 @@ pub const Object = struct {
963965 .debug_type_map = .{},
964966 .debug_unresolved_namespace_scopes = .{},
965967 .target = target,
966 .decl_map = .{},
967 .anon_decl_map = .{},
968 .nav_map = .{},
969 .uav_map = .{},
970 .enum_tag_name_map = .{},
968971 .named_enum_map = .{},
969972 .type_map = .{},
970973 .error_name_table = .none,
......@@ -981,8 +984,9 @@ pub const Object = struct {
981984 self.debug_file_map.deinit(gpa);
982985 self.debug_type_map.deinit(gpa);
983986 self.debug_unresolved_namespace_scopes.deinit(gpa);
984 self.decl_map.deinit(gpa);
985 self.anon_decl_map.deinit(gpa);
987 self.nav_map.deinit(gpa);
988 self.uav_map.deinit(gpa);
989 self.enum_tag_name_map.deinit(gpa);
986990 self.named_enum_map.deinit(gpa);
987991 self.type_map.deinit(gpa);
988992 self.builder.deinit();
......@@ -1108,7 +1112,7 @@ pub const Object = struct {
11081112 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
11091113
11101114 const namespace = zcu.namespacePtr(namespace_index);
1111 const debug_type = try self.lowerDebugType(namespace.getType(zcu));
1115 const debug_type = try self.lowerDebugType(Type.fromInterned(namespace.owner_type));
11121116
11131117 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
11141118 }
......@@ -1328,24 +1332,22 @@ pub const Object = struct {
13281332 assert(std.meta.eql(pt, o.pt));
13291333 const zcu = pt.zcu;
13301334 const comp = zcu.comp;
1335 const ip = &zcu.intern_pool;
13311336 const func = zcu.funcInfo(func_index);
1332 const decl_index = func.owner_decl;
1333 const decl = zcu.declPtr(decl_index);
1334 const namespace = zcu.namespacePtr(decl.src_namespace);
1335 const file_scope = namespace.fileScope(zcu);
1336 const owner_mod = file_scope.mod;
1337 const fn_info = zcu.typeToFunc(decl.typeOf(zcu)).?;
1337 const nav = ip.getNav(func.owner_nav);
1338 const file_scope = zcu.navFileScopeIndex(func.owner_nav);
1339 const owner_mod = zcu.fileByIndex(file_scope).mod;
1340 const fn_ty = Type.fromInterned(func.ty);
1341 const fn_info = zcu.typeToFunc(fn_ty).?;
13381342 const target = owner_mod.resolved_target.result;
1339 const ip = &zcu.intern_pool;
13401343
1341 var dg: DeclGen = .{
1344 var ng: NavGen = .{
13421345 .object = o,
1343 .decl_index = decl_index,
1344 .decl = decl,
1346 .nav_index = func.owner_nav,
13451347 .err_msg = null,
13461348 };
13471349
1348 const function_index = try o.resolveLlvmFunction(decl_index);
1350 const function_index = try o.resolveLlvmFunction(func.owner_nav);
13491351
13501352 var attributes = try function_index.ptrConst(&o.builder).attributes.toWip(&o.builder);
13511353 defer attributes.deinit(&o.builder);
......@@ -1409,7 +1411,7 @@ pub const Object = struct {
14091411 } }, &o.builder);
14101412 }
14111413
1412 if (decl.@"linksection".toSlice(ip)) |section|
1414 if (nav.status.resolved.@"linksection".toSlice(ip)) |section|
14131415 function_index.setSection(try o.builder.string(section), &o.builder);
14141416
14151417 var deinit_wip = true;
......@@ -1422,7 +1424,7 @@ pub const Object = struct {
14221424
14231425 var llvm_arg_i: u32 = 0;
14241426
1425 // This gets the LLVM values from the function and stores them in `dg.args`.
1427 // This gets the LLVM values from the function and stores them in `ng.args`.
14261428 const sret = firstParamSRet(fn_info, pt, target);
14271429 const ret_ptr: Builder.Value = if (sret) param: {
14281430 const param = wip.arg(llvm_arg_i);
......@@ -1622,13 +1624,13 @@ pub const Object = struct {
16221624 const file, const subprogram = if (!wip.strip) debug_info: {
16231625 const file = try o.getDebugFile(file_scope);
16241626
1625 const line_number = decl.navSrcLine(zcu) + 1;
1626 const is_internal_linkage = decl.val.getExternFunc(zcu) == null;
1627 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu));
1627 const line_number = zcu.navSrcLine(func.owner_nav) + 1;
1628 const is_internal_linkage = ip.indexToKey(nav.status.resolved.val) != .@"extern";
1629 const debug_decl_type = try o.lowerDebugType(fn_ty);
16281630
16291631 const subprogram = try o.builder.debugSubprogram(
16301632 file,
1631 try o.builder.metadataString(decl.name.toSlice(ip)),
1633 try o.builder.metadataString(nav.name.toSlice(ip)),
16321634 try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)),
16331635 line_number,
16341636 line_number + func.lbrace_line,
......@@ -1654,7 +1656,7 @@ pub const Object = struct {
16541656 .gpa = gpa,
16551657 .air = air,
16561658 .liveness = liveness,
1657 .dg = &dg,
1659 .ng = &ng,
16581660 .wip = wip,
16591661 .is_naked = fn_info.cc == .Naked,
16601662 .ret_ptr = ret_ptr,
......@@ -1665,7 +1667,7 @@ pub const Object = struct {
16651667 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
16661668 .file = file,
16671669 .scope = subprogram,
1668 .base_line = dg.decl.navSrcLine(zcu),
1670 .base_line = zcu.navSrcLine(func.owner_nav),
16691671 .prev_dbg_line = 0,
16701672 .prev_dbg_column = 0,
16711673 .err_ret_trace = err_ret_trace,
......@@ -1675,9 +1677,8 @@ pub const Object = struct {
16751677
16761678 fg.genBody(air.getMainBody()) catch |err| switch (err) {
16771679 error.CodegenFail => {
1678 decl.analysis = .codegen_failure;
1679 try zcu.failed_analysis.put(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?);
1680 dg.err_msg = null;
1680 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);
1681 ng.err_msg = null;
16811682 return;
16821683 },
16831684 else => |e| return e,
......@@ -1686,20 +1687,17 @@ pub const Object = struct {
16861687 try fg.wip.finish();
16871688 }
16881689
1689 pub fn updateDecl(self: *Object, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1690 pub fn updateNav(self: *Object, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
16901691 assert(std.meta.eql(pt, self.pt));
1691 const decl = pt.zcu.declPtr(decl_index);
1692 var dg: DeclGen = .{
1692 var ng: NavGen = .{
16931693 .object = self,
1694 .decl = decl,
1695 .decl_index = decl_index,
1694 .nav_index = nav_index,
16961695 .err_msg = null,
16971696 };
1698 dg.genDecl() catch |err| switch (err) {
1697 ng.genDecl() catch |err| switch (err) {
16991698 error.CodegenFail => {
1700 decl.analysis = .codegen_failure;
1701 try pt.zcu.failed_analysis.put(pt.zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?);
1702 dg.err_msg = null;
1699 try pt.zcu.failed_codegen.put(pt.zcu.gpa, nav_index, ng.err_msg.?);
1700 ng.err_msg = null;
17031701 return;
17041702 },
17051703 else => |e| return e,
......@@ -1714,19 +1712,18 @@ pub const Object = struct {
17141712 ) link.File.UpdateExportsError!void {
17151713 assert(std.meta.eql(pt, self.pt));
17161714 const zcu = pt.zcu;
1717 const decl_index = switch (exported) {
1718 .decl_index => |i| i,
1719 .value => |val| return updateExportedValue(self, zcu, val, export_indices),
1715 const nav_index = switch (exported) {
1716 .nav => |nav| nav,
1717 .uav => |uav| return updateExportedValue(self, zcu, uav, export_indices),
17201718 };
17211719 const ip = &zcu.intern_pool;
1722 const global_index = self.decl_map.get(decl_index).?;
1723 const decl = zcu.declPtr(decl_index);
1720 const global_index = self.nav_map.get(nav_index).?;
17241721 const comp = zcu.comp;
17251722
17261723 if (export_indices.len != 0) {
17271724 return updateExportedGlobal(self, zcu, global_index, export_indices);
17281725 } else {
1729 const fqn = try self.builder.strtabString(decl.fqn.toSlice(ip));
1726 const fqn = try self.builder.strtabString(ip.getNav(nav_index).fqn.toSlice(ip));
17301727 try global_index.rename(fqn, &self.builder);
17311728 global_index.setLinkage(.internal, &self.builder);
17321729 if (comp.config.dll_export_fns)
......@@ -1745,7 +1742,7 @@ pub const Object = struct {
17451742 const ip = &mod.intern_pool;
17461743 const main_exp_name = try o.builder.strtabString(mod.all_exports.items[export_indices[0]].opts.name.toSlice(ip));
17471744 const global_index = i: {
1748 const gop = try o.anon_decl_map.getOrPut(gpa, exported_value);
1745 const gop = try o.uav_map.getOrPut(gpa, exported_value);
17491746 if (gop.found_existing) {
17501747 const global_index = gop.value_ptr.*;
17511748 try global_index.rename(main_exp_name, &o.builder);
......@@ -1868,11 +1865,12 @@ pub const Object = struct {
18681865 global.delete(&self.builder);
18691866 }
18701867
1871 fn getDebugFile(o: *Object, file: *const Zcu.File) Allocator.Error!Builder.Metadata {
1868 fn getDebugFile(o: *Object, file_index: Zcu.File.Index) Allocator.Error!Builder.Metadata {
18721869 const gpa = o.gpa;
1873 const gop = try o.debug_file_map.getOrPut(gpa, file);
1874 errdefer assert(o.debug_file_map.remove(file));
1870 const gop = try o.debug_file_map.getOrPut(gpa, file_index);
1871 errdefer assert(o.debug_file_map.remove(file_index));
18751872 if (gop.found_existing) return gop.value_ptr.*;
1873 const file = o.pt.zcu.fileByIndex(file_index);
18761874 gop.value_ptr.* = try o.builder.debugFile(
18771875 try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)),
18781876 dir_path: {
......@@ -1930,17 +1928,13 @@ pub const Object = struct {
19301928 return debug_int_type;
19311929 },
19321930 .Enum => {
1933 const owner_decl_index = ty.getOwnerDecl(zcu);
1934 const owner_decl = zcu.declPtr(owner_decl_index);
1935
19361931 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
1937 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
1932 const debug_enum_type = try o.makeEmptyNamespaceDebugType(ty);
19381933 try o.debug_type_map.put(gpa, ty, debug_enum_type);
19391934 return debug_enum_type;
19401935 }
19411936
19421937 const enum_type = ip.loadEnumType(ty.toIntern());
1943
19441938 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
19451939 defer gpa.free(enumerators);
19461940
......@@ -1963,9 +1957,11 @@ pub const Object = struct {
19631957 );
19641958 }
19651959
1966 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);
1967 const file = try o.getDebugFile(file_scope);
1968 const scope = try o.namespaceToDebugScope(owner_decl.src_namespace);
1960 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file);
1961 const scope = if (ty.getParentNamespace(zcu).?.unwrap()) |parent_namespace|
1962 try o.namespaceToDebugScope(parent_namespace)
1963 else
1964 file;
19691965
19701966 const name = try o.allocTypeName(ty);
19711967 defer gpa.free(name);
......@@ -1974,7 +1970,7 @@ pub const Object = struct {
19741970 try o.builder.metadataString(name),
19751971 file,
19761972 scope,
1977 owner_decl.typeSrcLine(zcu) + 1, // Line
1973 ty.typeDeclSrcLine(zcu).? + 1, // Line
19781974 try o.lowerDebugType(int_ty),
19791975 ty.abiSize(pt) * 8,
19801976 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
......@@ -2138,14 +2134,18 @@ pub const Object = struct {
21382134
21392135 const name = try o.allocTypeName(ty);
21402136 defer gpa.free(name);
2141 const owner_decl_index = ty.getOwnerDecl(zcu);
2142 const owner_decl = zcu.declPtr(owner_decl_index);
2143 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);
2137
2138 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file);
2139 const scope = if (ty.getParentNamespace(zcu).?.unwrap()) |parent_namespace|
2140 try o.namespaceToDebugScope(parent_namespace)
2141 else
2142 file;
2143
21442144 const debug_opaque_type = try o.builder.debugStructType(
21452145 try o.builder.metadataString(name),
2146 try o.getDebugFile(file_scope),
2147 try o.namespaceToDebugScope(owner_decl.src_namespace),
2148 owner_decl.typeSrcLine(zcu) + 1, // Line
2146 file,
2147 scope,
2148 ty.typeDeclSrcLine(zcu).? + 1, // Line
21492149 .none, // Underlying type
21502150 0, // Size
21512151 0, // Align
......@@ -2460,8 +2460,7 @@ pub const Object = struct {
24602460 // into. Therefore we can satisfy this by making an empty namespace,
24612461 // rather than changing the frontend to unnecessarily resolve the
24622462 // struct field types.
2463 const owner_decl_index = ty.getOwnerDecl(zcu);
2464 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2463 const debug_struct_type = try o.makeEmptyNamespaceDebugType(ty);
24652464 try o.debug_type_map.put(gpa, ty, debug_struct_type);
24662465 return debug_struct_type;
24672466 }
......@@ -2470,8 +2469,7 @@ pub const Object = struct {
24702469 }
24712470
24722471 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2473 const owner_decl_index = ty.getOwnerDecl(zcu);
2474 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2472 const debug_struct_type = try o.makeEmptyNamespaceDebugType(ty);
24752473 try o.debug_type_map.put(gpa, ty, debug_struct_type);
24762474 return debug_struct_type;
24772475 }
......@@ -2536,8 +2534,6 @@ pub const Object = struct {
25362534 return debug_struct_type;
25372535 },
25382536 .Union => {
2539 const owner_decl_index = ty.getOwnerDecl(zcu);
2540
25412537 const name = try o.allocTypeName(ty);
25422538 defer gpa.free(name);
25432539
......@@ -2546,7 +2542,7 @@ pub const Object = struct {
25462542 !ty.hasRuntimeBitsIgnoreComptime(pt) or
25472543 !union_type.haveLayout(ip))
25482544 {
2549 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2545 const debug_union_type = try o.makeEmptyNamespaceDebugType(ty);
25502546 try o.debug_type_map.put(gpa, ty, debug_union_type);
25512547 return debug_union_type;
25522548 }
......@@ -2762,8 +2758,7 @@ pub const Object = struct {
27622758 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
27632759 const zcu = o.pt.zcu;
27642760 const namespace = zcu.namespacePtr(namespace_index);
2765 const file_scope = namespace.fileScope(zcu);
2766 if (namespace.parent == .none) return try o.getDebugFile(file_scope);
2761 if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope);
27672762
27682763 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);
27692764
......@@ -2772,15 +2767,19 @@ pub const Object = struct {
27722767 return gop.value_ptr.*;
27732768 }
27742769
2775 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {
2770 fn makeEmptyNamespaceDebugType(o: *Object, ty: Type) !Builder.Metadata {
27762771 const zcu = o.pt.zcu;
2777 const decl = zcu.declPtr(decl_index);
2778 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
2772 const ip = &zcu.intern_pool;
2773 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file);
2774 const scope = if (ty.getParentNamespace(zcu).?.unwrap()) |parent_namespace|
2775 try o.namespaceToDebugScope(parent_namespace)
2776 else
2777 file;
27792778 return o.builder.debugStructType(
2780 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)), // TODO use fully qualified name
2781 try o.getDebugFile(file_scope),
2782 try o.namespaceToDebugScope(decl.src_namespace),
2783 decl.typeSrcLine(zcu) + 1,
2779 try o.builder.metadataString(ty.containerTypeName(ip).toSlice(ip)), // TODO use fully qualified name
2780 file,
2781 scope,
2782 ty.typeDeclSrcLine(zcu).? + 1,
27842783 .none,
27852784 0,
27862785 0,
......@@ -2791,25 +2790,24 @@ pub const Object = struct {
27912790 fn getStackTraceType(o: *Object) Allocator.Error!Type {
27922791 const pt = o.pt;
27932792 const zcu = pt.zcu;
2793 const ip = &zcu.intern_pool;
27942794
27952795 const std_mod = zcu.std_mod;
27962796 const std_file_imported = pt.importPkg(std_mod) catch unreachable;
27972797
2798 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
2799 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);
2800 const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace);
2801 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }).?;
2798 const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
2799 const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
2800 const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu).unwrap().?);
2801 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?;
28022802
2803 const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "StackTrace", .no_embedded_nulls);
2803 const stack_trace_str = try ip.getOrPutString(zcu.gpa, pt.tid, "StackTrace", .no_embedded_nulls);
28042804 // buffer is only used for int_type, `builtin` is a struct.
2805 const builtin_ty = zcu.declPtr(builtin_decl).val.toType();
2805 const builtin_ty = zcu.navValue(builtin_nav).toType();
28062806 const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?;
2807 const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Zcu.DeclAdapter{ .zcu = zcu }).?;
2808 const stack_trace_decl = zcu.declPtr(stack_trace_decl_index);
2807 const stack_trace_nav = builtin_namespace.pub_decls.getKeyAdapted(stack_trace_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?;
28092808
28102809 // Sema should have ensured that StackTrace was analyzed.
2811 assert(stack_trace_decl.has_tv);
2812 return stack_trace_decl.val.toType();
2810 return zcu.navValue(stack_trace_nav).toType();
28132811 }
28142812
28152813 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
......@@ -2824,29 +2822,33 @@ pub const Object = struct {
28242822 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
28252823 fn resolveLlvmFunction(
28262824 o: *Object,
2827 decl_index: InternPool.DeclIndex,
2825 nav_index: InternPool.Nav.Index,
28282826 ) Allocator.Error!Builder.Function.Index {
28292827 const pt = o.pt;
28302828 const zcu = pt.zcu;
28312829 const ip = &zcu.intern_pool;
28322830 const gpa = o.gpa;
2833 const decl = zcu.declPtr(decl_index);
2834 const namespace = zcu.namespacePtr(decl.src_namespace);
2835 const owner_mod = namespace.fileScope(zcu).mod;
2836 const zig_fn_type = decl.typeOf(zcu);
2837 const gop = try o.decl_map.getOrPut(gpa, decl_index);
2831 const nav = ip.getNav(nav_index);
2832 const owner_mod = zcu.navFileScope(nav_index).mod;
2833 const resolved = nav.status.resolved;
2834 const val = Value.fromInterned(resolved.val);
2835 const ty = val.typeOf(zcu);
2836 const gop = try o.nav_map.getOrPut(gpa, nav_index);
28382837 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
28392838
2840 assert(decl.has_tv);
2841 const fn_info = zcu.typeToFunc(zig_fn_type).?;
2839 const fn_info = zcu.typeToFunc(ty).?;
28422840 const target = owner_mod.resolved_target.result;
28432841 const sret = firstParamSRet(fn_info, pt, target);
28442842
2845 const is_extern = decl.isExtern(zcu);
2843 const is_extern, const lib_name = switch (ip.indexToKey(val.toIntern())) {
2844 .variable => |variable| .{ false, variable.lib_name },
2845 .@"extern" => |@"extern"| .{ true, @"extern".lib_name },
2846 else => .{ false, .none },
2847 };
28462848 const function_index = try o.builder.addFunction(
2847 try o.lowerType(zig_fn_type),
2848 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
2849 toLlvmAddressSpace(decl.@"addrspace", target),
2849 try o.lowerType(ty),
2850 try o.builder.strtabString((if (is_extern) nav.name else nav.fqn).toSlice(ip)),
2851 toLlvmAddressSpace(resolved.@"addrspace", target),
28502852 );
28512853 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
28522854
......@@ -2860,12 +2862,12 @@ pub const Object = struct {
28602862 if (target.isWasm()) {
28612863 try attributes.addFnAttr(.{ .string = .{
28622864 .kind = try o.builder.string("wasm-import-name"),
2863 .value = try o.builder.string(decl.name.toSlice(ip)),
2865 .value = try o.builder.string(nav.name.toSlice(ip)),
28642866 } }, &o.builder);
2865 if (decl.getOwnedExternFunc(zcu).?.lib_name.toSlice(ip)) |lib_name| {
2866 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{
2867 if (lib_name.toSlice(ip)) |lib_name_slice| {
2868 if (!std.mem.eql(u8, lib_name_slice, "c")) try attributes.addFnAttr(.{ .string = .{
28672869 .kind = try o.builder.string("wasm-import-module"),
2868 .value = try o.builder.string(lib_name),
2870 .value = try o.builder.string(lib_name_slice),
28692871 } }, &o.builder);
28702872 }
28712873 }
......@@ -2901,8 +2903,8 @@ pub const Object = struct {
29012903 else => function_index.setCallConv(toLlvmCallConv(fn_info.cc, target), &o.builder),
29022904 }
29032905
2904 if (decl.alignment != .none)
2905 function_index.setAlignment(decl.alignment.toLlvm(), &o.builder);
2906 if (resolved.alignment != .none)
2907 function_index.setAlignment(resolved.alignment.toLlvm(), &o.builder);
29062908
29072909 // Function attributes that are independent of analysis results of the function body.
29082910 try o.addCommonFnAttributes(&attributes, owner_mod);
......@@ -3006,15 +3008,15 @@ pub const Object = struct {
30063008 }
30073009 }
30083010
3009 fn resolveGlobalAnonDecl(
3011 fn resolveGlobalUav(
30103012 o: *Object,
3011 decl_val: InternPool.Index,
3013 uav: InternPool.Index,
30123014 llvm_addr_space: Builder.AddrSpace,
30133015 alignment: InternPool.Alignment,
30143016 ) Error!Builder.Variable.Index {
30153017 assert(alignment != .none);
30163018 // TODO: Add address space to the anon_decl_map
3017 const gop = try o.anon_decl_map.getOrPut(o.gpa, decl_val);
3019 const gop = try o.uav_map.getOrPut(o.gpa, uav);
30183020 if (gop.found_existing) {
30193021 // Keep the greater of the two alignments.
30203022 const variable_index = gop.value_ptr.ptr(&o.builder).kind.variable;
......@@ -3023,19 +3025,19 @@ pub const Object = struct {
30233025 variable_index.setAlignment(max_alignment.toLlvm(), &o.builder);
30243026 return variable_index;
30253027 }
3026 errdefer assert(o.anon_decl_map.remove(decl_val));
3028 errdefer assert(o.uav_map.remove(uav));
30273029
30283030 const mod = o.pt.zcu;
3029 const decl_ty = mod.intern_pool.typeOf(decl_val);
3031 const decl_ty = mod.intern_pool.typeOf(uav);
30303032
30313033 const variable_index = try o.builder.addVariable(
3032 try o.builder.strtabStringFmt("__anon_{d}", .{@intFromEnum(decl_val)}),
3034 try o.builder.strtabStringFmt("__anon_{d}", .{@intFromEnum(uav)}),
30333035 try o.lowerType(Type.fromInterned(decl_ty)),
30343036 llvm_addr_space,
30353037 );
30363038 gop.value_ptr.* = variable_index.ptrConst(&o.builder).global;
30373039
3038 try variable_index.setInitializer(try o.lowerValue(decl_val), &o.builder);
3040 try variable_index.setInitializer(try o.lowerValue(uav), &o.builder);
30393041 variable_index.setLinkage(.internal, &o.builder);
30403042 variable_index.setMutability(.constant, &o.builder);
30413043 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
......@@ -3043,24 +3045,29 @@ pub const Object = struct {
30433045 return variable_index;
30443046 }
30453047
3046 fn resolveGlobalDecl(
3048 fn resolveGlobalNav(
30473049 o: *Object,
3048 decl_index: InternPool.DeclIndex,
3050 nav_index: InternPool.Nav.Index,
30493051 ) Allocator.Error!Builder.Variable.Index {
3050 const gop = try o.decl_map.getOrPut(o.gpa, decl_index);
3052 const gop = try o.nav_map.getOrPut(o.gpa, nav_index);
30513053 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;
3052 errdefer assert(o.decl_map.remove(decl_index));
3054 errdefer assert(o.nav_map.remove(nav_index));
30533055
30543056 const pt = o.pt;
30553057 const zcu = pt.zcu;
30563058 const ip = &zcu.intern_pool;
3057 const decl = zcu.declPtr(decl_index);
3058 const is_extern = decl.isExtern(zcu);
3059 const nav = ip.getNav(nav_index);
3060 const resolved = nav.status.resolved;
3061 const is_extern, const is_threadlocal, const is_weak_linkage = switch (ip.indexToKey(resolved.val)) {
3062 .variable => |variable| .{ false, variable.is_threadlocal, variable.is_weak_linkage },
3063 .@"extern" => |@"extern"| .{ true, @"extern".is_threadlocal, @"extern".is_weak_linkage },
3064 else => .{ false, false, false },
3065 };
30593066
30603067 const variable_index = try o.builder.addVariable(
3061 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
3062 try o.lowerType(decl.typeOf(zcu)),
3063 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),
3068 try o.builder.strtabString((if (is_extern) nav.name else nav.fqn).toSlice(ip)),
3069 try o.lowerType(Type.fromInterned(nav.typeOf(ip))),
3070 toLlvmGlobalAddressSpace(resolved.@"addrspace", zcu.getTarget()),
30643071 );
30653072 gop.value_ptr.* = variable_index.ptrConst(&o.builder).global;
30663073
......@@ -3068,15 +3075,9 @@ pub const Object = struct {
30683075 if (is_extern) {
30693076 variable_index.setLinkage(.external, &o.builder);
30703077 variable_index.setUnnamedAddr(.default, &o.builder);
3071 if (decl.val.getVariable(zcu)) |decl_var| {
3072 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
3073 const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded;
3074 variable_index.setThreadLocal(
3075 if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default,
3076 &o.builder,
3077 );
3078 if (decl_var.is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder);
3079 }
3078 if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded)
3079 variable_index.setThreadLocal(.generaldynamic, &o.builder);
3080 if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder);
30803081 } else {
30813082 variable_index.setLinkage(.internal, &o.builder);
30823083 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
......@@ -3286,8 +3287,6 @@ pub const Object = struct {
32863287 return int_ty;
32873288 }
32883289
3289 const decl = mod.declPtr(struct_type.decl.unwrap().?);
3290
32913290 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
32923291 defer llvm_field_types.deinit(o.gpa);
32933292 // Although we can estimate how much capacity to add, these cannot be
......@@ -3351,7 +3350,7 @@ pub const Object = struct {
33513350 );
33523351 }
33533352
3354 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3353 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
33553354 try o.type_map.put(o.gpa, t.toIntern(), ty);
33563355
33573356 o.builder.namedTypeSetBody(
......@@ -3440,8 +3439,6 @@ pub const Object = struct {
34403439 return enum_tag_ty;
34413440 }
34423441
3443 const decl = mod.declPtr(union_obj.decl);
3444
34453442 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
34463443 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
34473444
......@@ -3460,7 +3457,7 @@ pub const Object = struct {
34603457 };
34613458
34623459 if (layout.tag_size == 0) {
3463 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3460 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
34643461 try o.type_map.put(o.gpa, t.toIntern(), ty);
34653462
34663463 o.builder.namedTypeSetBody(
......@@ -3488,7 +3485,7 @@ pub const Object = struct {
34883485 llvm_fields_len += 1;
34893486 }
34903487
3491 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3488 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
34923489 try o.type_map.put(o.gpa, t.toIntern(), ty);
34933490
34943491 o.builder.namedTypeSetBody(
......@@ -3500,8 +3497,7 @@ pub const Object = struct {
35003497 .opaque_type => {
35013498 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
35023499 if (!gop.found_existing) {
3503 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
3504 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3500 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
35053501 }
35063502 return gop.value_ptr.*;
35073503 },
......@@ -3512,7 +3508,7 @@ pub const Object = struct {
35123508 .undef,
35133509 .simple_value,
35143510 .variable,
3515 .extern_func,
3511 .@"extern",
35163512 .func,
35173513 .int,
35183514 .err,
......@@ -3632,15 +3628,13 @@ pub const Object = struct {
36323628
36333629 const ty = Type.fromInterned(val_key.typeOf());
36343630 switch (val_key) {
3635 .extern_func => |extern_func| {
3636 const fn_decl_index = extern_func.decl;
3637 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3631 .@"extern" => |@"extern"| {
3632 const function_index = try o.resolveLlvmFunction(@"extern".owner_nav);
36383633 const ptr = function_index.ptrConst(&o.builder).global.toConst();
36393634 return o.builder.convConst(ptr, llvm_int_ty);
36403635 },
36413636 .func => |func| {
3642 const fn_decl_index = func.owner_decl;
3643 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3637 const function_index = try o.resolveLlvmFunction(func.owner_nav);
36443638 const ptr = function_index.ptrConst(&o.builder).global.toConst();
36453639 return o.builder.convConst(ptr, llvm_int_ty);
36463640 },
......@@ -3783,14 +3777,12 @@ pub const Object = struct {
37833777 .enum_literal,
37843778 .empty_enum_value,
37853779 => unreachable, // non-runtime values
3786 .extern_func => |extern_func| {
3787 const fn_decl_index = extern_func.decl;
3788 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3780 .@"extern" => |@"extern"| {
3781 const function_index = try o.resolveLlvmFunction(@"extern".owner_nav);
37893782 return function_index.ptrConst(&o.builder).global.toConst();
37903783 },
37913784 .func => |func| {
3792 const fn_decl_index = func.owner_decl;
3793 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3785 const function_index = try o.resolveLlvmFunction(func.owner_nav);
37943786 return function_index.ptrConst(&o.builder).global.toConst();
37953787 },
37963788 .int => {
......@@ -4284,14 +4276,14 @@ pub const Object = struct {
42844276 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
42854277 const offset: u64 = prev_offset + ptr.byte_offset;
42864278 return switch (ptr.base_addr) {
4287 .decl => |decl| {
4288 const base_ptr = try o.lowerDeclRefValue(decl);
4279 .nav => |nav| {
4280 const base_ptr = try o.lowerNavRefValue(nav);
42894281 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{
42904282 try o.builder.intConst(.i64, offset),
42914283 });
42924284 },
4293 .anon_decl => |ad| {
4294 const base_ptr = try o.lowerAnonDeclRef(ad);
4285 .uav => |uav| {
4286 const base_ptr = try o.lowerUavRef(uav);
42954287 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{
42964288 try o.builder.intConst(.i64, offset),
42974289 });
......@@ -4332,39 +4324,37 @@ pub const Object = struct {
43324324 };
43334325 }
43344326
4335 /// This logic is very similar to `lowerDeclRefValue` but for anonymous declarations.
4327 /// This logic is very similar to `lowerNavRefValue` but for anonymous declarations.
43364328 /// Maybe the logic could be unified.
4337 fn lowerAnonDeclRef(
4329 fn lowerUavRef(
43384330 o: *Object,
4339 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
4331 uav: InternPool.Key.Ptr.BaseAddr.Uav,
43404332 ) Error!Builder.Constant {
43414333 const pt = o.pt;
43424334 const mod = pt.zcu;
43434335 const ip = &mod.intern_pool;
4344 const decl_val = anon_decl.val;
4345 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
4336 const uav_val = uav.val;
4337 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));
43464338 const target = mod.getTarget();
43474339
4348 if (Value.fromInterned(decl_val).getFunction(mod)) |func| {
4349 _ = func;
4350 @panic("TODO");
4351 } else if (Value.fromInterned(decl_val).getExternFunc(mod)) |func| {
4352 _ = func;
4353 @panic("TODO");
4340 switch (ip.indexToKey(uav_val)) {
4341 .func => @panic("TODO"),
4342 .@"extern" => @panic("TODO"),
4343 else => {},
43544344 }
43554345
4356 const ptr_ty = Type.fromInterned(anon_decl.orig_ty);
4346 const ptr_ty = Type.fromInterned(uav.orig_ty);
43574347
4358 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4359 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or
4360 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);
4348 const is_fn_body = uav_ty.zigTypeTag(mod) == .Fn;
4349 if ((!is_fn_body and !uav_ty.hasRuntimeBits(pt)) or
4350 (is_fn_body and mod.typeToFunc(uav_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);
43614351
43624352 if (is_fn_body)
43634353 @panic("TODO");
43644354
43654355 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);
43664356 const alignment = ptr_ty.ptrAlignment(pt);
4367 const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
4357 const llvm_global = (try o.resolveGlobalUav(uav.val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
43684358
43694359 const llvm_val = try o.builder.convConst(
43704360 llvm_global.toConst(),
......@@ -4374,44 +4364,41 @@ pub const Object = struct {
43744364 return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));
43754365 }
43764366
4377 fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {
4367 fn lowerNavRefValue(o: *Object, nav_index: InternPool.Nav.Index) Allocator.Error!Builder.Constant {
43784368 const pt = o.pt;
4379 const mod = pt.zcu;
4369 const zcu = pt.zcu;
4370 const ip = &zcu.intern_pool;
43804371
43814372 // In the case of something like:
43824373 // fn foo() void {}
43834374 // const bar = foo;
43844375 // ... &bar;
43854376 // `bar` is just an alias and we actually want to lower a reference to `foo`.
4386 const decl = mod.declPtr(decl_index);
4387 if (decl.val.getFunction(mod)) |func| {
4388 if (func.owner_decl != decl_index) {
4389 return o.lowerDeclRefValue(func.owner_decl);
4390 }
4391 } else if (decl.val.getExternFunc(mod)) |func| {
4392 if (func.decl != decl_index) {
4393 return o.lowerDeclRefValue(func.decl);
4394 }
4395 }
4377 const owner_nav_index = switch (ip.indexToKey(zcu.navValue(nav_index).toIntern())) {
4378 .func => |func| func.owner_nav,
4379 .@"extern" => |@"extern"| @"extern".owner_nav,
4380 else => nav_index,
4381 };
4382 const owner_nav = ip.getNav(owner_nav_index);
43964383
4397 const decl_ty = decl.typeOf(mod);
4398 const ptr_ty = try decl.declPtrType(pt);
4384 const nav_ty = Type.fromInterned(owner_nav.typeOf(ip));
4385 const ptr_ty = try pt.navPtrType(owner_nav_index);
43994386
4400 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
4401 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or
4402 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic))
4387 const is_fn_body = nav_ty.zigTypeTag(zcu) == .Fn;
4388 if ((!is_fn_body and !nav_ty.hasRuntimeBits(pt)) or
4389 (is_fn_body and zcu.typeToFunc(nav_ty).?.is_generic))
44034390 {
44044391 return o.lowerPtrToVoid(ptr_ty);
44054392 }
44064393
44074394 const llvm_global = if (is_fn_body)
4408 (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global
4395 (try o.resolveLlvmFunction(owner_nav_index)).ptrConst(&o.builder).global
44094396 else
4410 (try o.resolveGlobalDecl(decl_index)).ptrConst(&o.builder).global;
4397 (try o.resolveGlobalNav(owner_nav_index)).ptrConst(&o.builder).global;
44114398
44124399 const llvm_val = try o.builder.convConst(
44134400 llvm_global.toConst(),
4414 try o.builder.ptrType(toLlvmAddressSpace(decl.@"addrspace", mod.getTarget())),
4401 try o.builder.ptrType(toLlvmAddressSpace(owner_nav.status.resolved.@"addrspace", zcu.getTarget())),
44154402 );
44164403
44174404 return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));
......@@ -4553,18 +4540,16 @@ pub const Object = struct {
45534540 const ip = &zcu.intern_pool;
45544541 const enum_type = ip.loadEnumType(enum_ty.toIntern());
45554542
4556 // TODO: detect when the type changes and re-emit this function.
4557 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
4543 const gop = try o.enum_tag_name_map.getOrPut(o.gpa, enum_ty.toIntern());
45584544 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;
4559 errdefer assert(o.decl_map.remove(enum_type.decl));
4545 errdefer assert(o.enum_tag_name_map.remove(enum_ty.toIntern()));
45604546
45614547 const usize_ty = try o.lowerType(Type.usize);
45624548 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4563 const decl = zcu.declPtr(enum_type.decl);
45644549 const target = zcu.root_mod.resolved_target.result;
45654550 const function_index = try o.builder.addFunction(
45664551 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
4567 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{decl.fqn.fmt(ip)}),
4552 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{enum_type.name.fmt(ip)}),
45684553 toLlvmAddressSpace(.generic, target),
45694554 );
45704555
......@@ -4624,86 +4609,73 @@ pub const Object = struct {
46244609 }
46254610};
46264611
4627pub const DeclGen = struct {
4612pub const NavGen = struct {
46284613 object: *Object,
4629 decl: *Zcu.Decl,
4630 decl_index: InternPool.DeclIndex,
4614 nav_index: InternPool.Nav.Index,
46314615 err_msg: ?*Zcu.ErrorMsg,
46324616
4633 fn ownerModule(dg: DeclGen) *Package.Module {
4634 const o = dg.object;
4635 const zcu = o.pt.zcu;
4636 const namespace = zcu.namespacePtr(dg.decl.src_namespace);
4637 const file_scope = namespace.fileScope(zcu);
4638 return file_scope.mod;
4617 fn ownerModule(ng: NavGen) *Package.Module {
4618 return ng.object.pt.zcu.navFileScope(ng.nav_index).mod;
46394619 }
46404620
4641 fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
4621 fn todo(ng: *NavGen, comptime format: []const u8, args: anytype) Error {
46424622 @setCold(true);
4643 assert(dg.err_msg == null);
4644 const o = dg.object;
4623 assert(ng.err_msg == null);
4624 const o = ng.object;
46454625 const gpa = o.gpa;
4646 const src_loc = dg.decl.navSrcLoc(o.pt.zcu);
4647 dg.err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
4626 const src_loc = o.pt.zcu.navSrcLoc(ng.nav_index);
4627 ng.err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
46484628 return error.CodegenFail;
46494629 }
46504630
4651 fn genDecl(dg: *DeclGen) !void {
4652 const o = dg.object;
4631 fn genDecl(ng: *NavGen) !void {
4632 const o = ng.object;
46534633 const pt = o.pt;
46544634 const zcu = pt.zcu;
46554635 const ip = &zcu.intern_pool;
4656 const decl = dg.decl;
4657 const decl_index = dg.decl_index;
4658 assert(decl.has_tv);
4636 const nav_index = ng.nav_index;
4637 const nav = ip.getNav(nav_index);
4638 const resolved = nav.status.resolved;
4639
4640 const is_extern, const lib_name, const is_threadlocal, const is_weak_linkage, const is_const, const init_val, const owner_nav = switch (ip.indexToKey(resolved.val)) {
4641 .variable => |variable| .{ false, variable.lib_name, variable.is_threadlocal, variable.is_weak_linkage, false, variable.init, variable.owner_nav },
4642 .@"extern" => |@"extern"| .{ true, @"extern".lib_name, @"extern".is_threadlocal, @"extern".is_weak_linkage, @"extern".is_const, .none, @"extern".owner_nav },
4643 else => .{ false, .none, false, false, true, resolved.val, nav_index },
4644 };
4645 const ty = Type.fromInterned(nav.typeOf(ip));
46594646
4660 if (decl.val.getExternFunc(zcu)) |extern_func| {
4661 _ = try o.resolveLlvmFunction(extern_func.decl);
4647 if (is_extern and ip.isFunctionType(ty.toIntern())) {
4648 _ = try o.resolveLlvmFunction(owner_nav);
46624649 } else {
4663 const variable_index = try o.resolveGlobalDecl(decl_index);
4664 variable_index.setAlignment(
4665 decl.getAlignment(pt).toLlvm(),
4666 &o.builder,
4667 );
4668 if (decl.@"linksection".toSlice(ip)) |section|
4650 const variable_index = try o.resolveGlobalNav(nav_index);
4651 variable_index.setAlignment(pt.navAlignment(nav_index).toLlvm(), &o.builder);
4652 if (resolved.@"linksection".toSlice(ip)) |section|
46694653 variable_index.setSection(try o.builder.string(section), &o.builder);
4670 assert(decl.has_tv);
4671 const init_val = if (decl.val.getVariable(zcu)) |decl_var| decl_var.init else init_val: {
4672 variable_index.setMutability(.constant, &o.builder);
4673 break :init_val decl.val.toIntern();
4674 };
4654 if (is_const) variable_index.setMutability(.constant, &o.builder);
46754655 try variable_index.setInitializer(switch (init_val) {
46764656 .none => .no_init,
46774657 else => try o.lowerValue(init_val),
46784658 }, &o.builder);
46794659
4680 if (decl.val.getVariable(zcu)) |decl_var| {
4681 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
4682 const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded;
4683 variable_index.setThreadLocal(
4684 if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default,
4685 &o.builder,
4686 );
4687 }
4688
4689 const line_number = decl.navSrcLine(zcu) + 1;
4660 const file_scope = zcu.navFileScopeIndex(nav_index);
4661 const mod = zcu.fileByIndex(file_scope).mod;
4662 if (is_threadlocal and !mod.single_threaded)
4663 variable_index.setThreadLocal(.generaldynamic, &o.builder);
46904664
4691 const namespace = zcu.namespacePtr(decl.src_namespace);
4692 const file_scope = namespace.fileScope(zcu);
4693 const owner_mod = file_scope.mod;
4665 const line_number = zcu.navSrcLine(nav_index) + 1;
46944666
4695 if (!owner_mod.strip) {
4667 if (!mod.strip) {
46964668 const debug_file = try o.getDebugFile(file_scope);
46974669
46984670 const debug_global_var = try o.builder.debugGlobalVar(
4699 try o.builder.metadataString(decl.name.toSlice(ip)), // Name
4671 try o.builder.metadataString(nav.name.toSlice(ip)), // Name
47004672 try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name
47014673 debug_file, // File
47024674 debug_file, // Scope
47034675 line_number,
4704 try o.lowerDebugType(decl.typeOf(zcu)),
4676 try o.lowerDebugType(ty),
47054677 variable_index,
4706 .{ .local = !decl.isExtern(zcu) },
4678 .{ .local = !is_extern },
47074679 );
47084680
47094681 const debug_expression = try o.builder.debugExpression(&.{});
......@@ -4718,18 +4690,18 @@ pub const DeclGen = struct {
47184690 }
47194691 }
47204692
4721 if (decl.isExtern(zcu)) {
4722 const global_index = o.decl_map.get(decl_index).?;
4693 if (is_extern) {
4694 const global_index = o.nav_map.get(nav_index).?;
47234695
47244696 const decl_name = decl_name: {
4725 if (zcu.getTarget().isWasm() and decl.typeOf(zcu).zigTypeTag(zcu) == .Fn) {
4726 if (decl.getOwnedExternFunc(zcu).?.lib_name.toSlice(ip)) |lib_name| {
4727 if (!std.mem.eql(u8, lib_name, "c")) {
4728 break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ decl.name.fmt(ip), lib_name });
4697 if (zcu.getTarget().isWasm() and ty.zigTypeTag(zcu) == .Fn) {
4698 if (lib_name.toSlice(ip)) |lib_name_slice| {
4699 if (!std.mem.eql(u8, lib_name_slice, "c")) {
4700 break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ nav.name.fmt(ip), lib_name_slice });
47294701 }
47304702 }
47314703 }
4732 break :decl_name try o.builder.strtabString(decl.name.toSlice(ip));
4704 break :decl_name try o.builder.strtabString(nav.name.toSlice(ip));
47334705 };
47344706
47354707 if (o.builder.getGlobal(decl_name)) |other_global| {
......@@ -4746,16 +4718,14 @@ pub const DeclGen = struct {
47464718 if (zcu.comp.config.dll_export_fns)
47474719 global_index.setDllStorageClass(.default, &o.builder);
47484720
4749 if (decl.val.getVariable(zcu)) |decl_var| {
4750 if (decl_var.is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder);
4751 }
4721 if (is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder);
47524722 }
47534723 }
47544724};
47554725
47564726pub const FuncGen = struct {
47574727 gpa: Allocator,
4758 dg: *DeclGen,
4728 ng: *NavGen,
47594729 air: Air,
47604730 liveness: Liveness,
47614731 wip: Builder.WipFunction,
......@@ -4815,7 +4785,7 @@ pub const FuncGen = struct {
48154785
48164786 fn todo(self: *FuncGen, comptime format: []const u8, args: anytype) Error {
48174787 @setCold(true);
4818 return self.dg.todo(format, args);
4788 return self.ng.todo(format, args);
48194789 }
48204790
48214791 fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !Builder.Value {
......@@ -4823,13 +4793,13 @@ pub const FuncGen = struct {
48234793 const gop = try self.func_inst_table.getOrPut(gpa, inst);
48244794 if (gop.found_existing) return gop.value_ptr.*;
48254795
4826 const llvm_val = try self.resolveValue((try self.air.value(inst, self.dg.object.pt)).?);
4796 const llvm_val = try self.resolveValue((try self.air.value(inst, self.ng.object.pt)).?);
48274797 gop.value_ptr.* = llvm_val.toValue();
48284798 return llvm_val.toValue();
48294799 }
48304800
48314801 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {
4832 const o = self.dg.object;
4802 const o = self.ng.object;
48334803 const pt = o.pt;
48344804 const ty = val.typeOf(pt.zcu);
48354805 const llvm_val = try o.lowerValue(val.toIntern());
......@@ -4855,7 +4825,7 @@ pub const FuncGen = struct {
48554825 }
48564826
48574827 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {
4858 const o = self.dg.object;
4828 const o = self.ng.object;
48594829 const pt = o.pt;
48604830 if (o.null_opt_usize == .no_init) {
48614831 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try pt.intern(.{ .opt = .{
......@@ -4867,7 +4837,7 @@ pub const FuncGen = struct {
48674837 }
48684838
48694839 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
4870 const o = self.dg.object;
4840 const o = self.ng.object;
48714841 const mod = o.pt.zcu;
48724842 const ip = &mod.intern_pool;
48734843 const air_tags = self.air.instructions.items(.tag);
......@@ -5132,20 +5102,19 @@ pub const FuncGen = struct {
51325102 defer self.scope = old_scope;
51335103
51345104 if (maybe_inline_func) |inline_func| {
5135 const o = self.dg.object;
5105 const o = self.ng.object;
51365106 const pt = o.pt;
51375107 const zcu = pt.zcu;
5108 const ip = &zcu.intern_pool;
51385109
51395110 const func = zcu.funcInfo(inline_func);
5140 const decl_index = func.owner_decl;
5141 const decl = zcu.declPtr(decl_index);
5142 const namespace = zcu.namespacePtr(decl.src_namespace);
5143 const file_scope = namespace.fileScope(zcu);
5144 const owner_mod = file_scope.mod;
5111 const nav = ip.getNav(func.owner_nav);
5112 const file_scope = zcu.navFileScopeIndex(func.owner_nav);
5113 const mod = zcu.fileByIndex(file_scope).mod;
51455114
51465115 self.file = try o.getDebugFile(file_scope);
51475116
5148 const line_number = decl.navSrcLine(zcu) + 1;
5117 const line_number = zcu.navSrcLine(func.owner_nav) + 1;
51495118 self.inlined = self.wip.debug_location;
51505119
51515120 const fn_ty = try pt.funcType(.{
......@@ -5155,15 +5124,15 @@ pub const FuncGen = struct {
51555124
51565125 self.scope = try o.builder.debugSubprogram(
51575126 self.file,
5158 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),
5159 try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
5127 try o.builder.metadataString(nav.name.toSlice(&zcu.intern_pool)),
5128 try o.builder.metadataString(nav.fqn.toSlice(&zcu.intern_pool)),
51605129 line_number,
51615130 line_number + func.lbrace_line,
51625131 try o.lowerDebugType(fn_ty),
51635132 .{
51645133 .di_flags = .{ .StaticMember = true },
51655134 .sp_flags = .{
5166 .Optimized = owner_mod.optimize_mode != .Debug,
5135 .Optimized = mod.optimize_mode != .Debug,
51675136 .Definition = true,
51685137 .LocalToUnit = true, // TODO: we can't know this at this point, since the function could be exported later!
51695138 },
......@@ -5171,7 +5140,7 @@ pub const FuncGen = struct {
51715140 o.debug_compile_unit,
51725141 );
51735142
5174 self.base_line = decl.navSrcLine(zcu);
5143 self.base_line = zcu.navSrcLine(func.owner_nav);
51755144 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
51765145 self.wip.debug_location = .{
51775146 .location = .{
......@@ -5183,7 +5152,7 @@ pub const FuncGen = struct {
51835152 };
51845153 }
51855154
5186 self.scope = try self.dg.object.builder.debugLexicalBlock(
5155 self.scope = try self.ng.object.builder.debugLexicalBlock(
51875156 self.scope,
51885157 self.file,
51895158 self.prev_dbg_line,
......@@ -5214,7 +5183,7 @@ pub const FuncGen = struct {
52145183 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
52155184 const extra = self.air.extraData(Air.Call, pl_op.payload);
52165185 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
5217 const o = self.dg.object;
5186 const o = self.ng.object;
52185187 const pt = o.pt;
52195188 const mod = pt.zcu;
52205189 const ip = &mod.intern_pool;
......@@ -5515,14 +5484,15 @@ pub const FuncGen = struct {
55155484 }
55165485
55175486 fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {
5518 const o = fg.dg.object;
5519 const mod = o.pt.zcu;
5520 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;
5521 const msg_decl = mod.declPtr(msg_decl_index);
5522 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);
5523 const msg_ptr = try o.lowerValue(msg_decl.val.toIntern());
5487 const o = fg.ng.object;
5488 const zcu = o.pt.zcu;
5489 const ip = &zcu.intern_pool;
5490 const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
5491 const msg_nav = ip.getNav(msg_nav_index);
5492 const msg_len = Type.fromInterned(msg_nav.typeOf(ip)).childType(zcu).arrayLen(zcu);
5493 const msg_ptr = try o.lowerValue(msg_nav.status.resolved.val);
55245494 const null_opt_addr_global = try fg.resolveNullOptUsize();
5525 const target = mod.getTarget();
5495 const target = zcu.getTarget();
55265496 const llvm_usize = try o.lowerType(Type.usize);
55275497 // example:
55285498 // call fastcc void @test2.panic(
......@@ -5531,10 +5501,10 @@ pub const FuncGen = struct {
55315501 // ptr null, ; stack trace
55325502 // ptr @2, ; addr (null ?usize)
55335503 // )
5534 const panic_func = mod.funcInfo(mod.panic_func_index);
5535 const panic_decl = mod.declPtr(panic_func.owner_decl);
5536 const fn_info = mod.typeToFunc(panic_decl.typeOf(mod)).?;
5537 const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl);
5504 const panic_func = zcu.funcInfo(zcu.panic_func_index);
5505 const panic_nav = ip.getNav(panic_func.owner_nav);
5506 const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
5507 const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);
55385508 _ = try fg.wip.call(
55395509 .normal,
55405510 toLlvmCallConv(fn_info.cc, target),
......@@ -5553,9 +5523,10 @@ pub const FuncGen = struct {
55535523 }
55545524
55555525 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
5556 const o = self.dg.object;
5526 const o = self.ng.object;
55575527 const pt = o.pt;
55585528 const mod = pt.zcu;
5529 const ip = &mod.intern_pool;
55595530 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
55605531 const ret_ty = self.typeOf(un_op);
55615532
......@@ -5581,7 +5552,7 @@ pub const FuncGen = struct {
55815552 len,
55825553 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
55835554 );
5584 const owner_mod = self.dg.ownerModule();
5555 const owner_mod = self.ng.ownerModule();
55855556 if (owner_mod.valgrind) {
55865557 try self.valgrindMarkUndef(self.ret_ptr, len);
55875558 }
......@@ -5602,7 +5573,7 @@ pub const FuncGen = struct {
56025573 _ = try self.wip.retVoid();
56035574 return .none;
56045575 }
5605 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
5576 const fn_info = mod.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?;
56065577 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
56075578 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
56085579 // Functions with an empty error set are emitted with an error code
......@@ -5631,7 +5602,7 @@ pub const FuncGen = struct {
56315602 len,
56325603 .normal,
56335604 );
5634 const owner_mod = self.dg.ownerModule();
5605 const owner_mod = self.ng.ownerModule();
56355606 if (owner_mod.valgrind) {
56365607 try self.valgrindMarkUndef(rp, len);
56375608 }
......@@ -5659,13 +5630,14 @@ pub const FuncGen = struct {
56595630 }
56605631
56615632 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5662 const o = self.dg.object;
5633 const o = self.ng.object;
56635634 const pt = o.pt;
56645635 const mod = pt.zcu;
5636 const ip = &mod.intern_pool;
56655637 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
56665638 const ptr_ty = self.typeOf(un_op);
56675639 const ret_ty = ptr_ty.childType(mod);
5668 const fn_info = mod.typeToFunc(self.dg.decl.typeOf(mod)).?;
5640 const fn_info = mod.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?;
56695641 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
56705642 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
56715643 // Functions with an empty error set are emitted with an error code
......@@ -5689,7 +5661,7 @@ pub const FuncGen = struct {
56895661 }
56905662
56915663 fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5692 const o = self.dg.object;
5664 const o = self.ng.object;
56935665 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
56945666 const list = try self.resolveInst(ty_op.operand);
56955667 const arg_ty = ty_op.ty.toType();
......@@ -5699,7 +5671,7 @@ pub const FuncGen = struct {
56995671 }
57005672
57015673 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5702 const o = self.dg.object;
5674 const o = self.ng.object;
57035675 const pt = o.pt;
57045676 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57055677 const src_list = try self.resolveInst(ty_op.operand);
......@@ -5725,7 +5697,7 @@ pub const FuncGen = struct {
57255697 }
57265698
57275699 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5728 const o = self.dg.object;
5700 const o = self.ng.object;
57295701 const pt = o.pt;
57305702 const va_list_ty = self.typeOfIndex(inst);
57315703 const llvm_va_list_ty = try o.lowerType(va_list_ty);
......@@ -5767,7 +5739,7 @@ pub const FuncGen = struct {
57675739 }
57685740
57695741 fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5770 const o = self.dg.object;
5742 const o = self.ng.object;
57715743 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
57725744 const operand = try self.resolveInst(un_op);
57735745 const llvm_fn = try o.getCmpLtErrorsLenFunction();
......@@ -5790,7 +5762,7 @@ pub const FuncGen = struct {
57905762 lhs: Builder.Value,
57915763 rhs: Builder.Value,
57925764 ) Allocator.Error!Builder.Value {
5793 const o = self.dg.object;
5765 const o = self.ng.object;
57945766 const pt = o.pt;
57955767 const mod = pt.zcu;
57965768 const scalar_ty = operand_ty.scalarType(mod);
......@@ -5897,7 +5869,7 @@ pub const FuncGen = struct {
58975869 maybe_inline_func: ?InternPool.Index,
58985870 body: []const Air.Inst.Index,
58995871 ) !Builder.Value {
5900 const o = self.dg.object;
5872 const o = self.ng.object;
59015873 const pt = o.pt;
59025874 const mod = pt.zcu;
59035875 const inst_ty = self.typeOfIndex(inst);
......@@ -5948,7 +5920,7 @@ pub const FuncGen = struct {
59485920 }
59495921
59505922 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5951 const o = self.dg.object;
5923 const o = self.ng.object;
59525924 const pt = o.pt;
59535925 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
59545926 const block = self.blocks.get(branch.block_inst).?;
......@@ -5988,7 +5960,7 @@ pub const FuncGen = struct {
59885960 }
59895961
59905962 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
5991 const o = self.dg.object;
5963 const o = self.ng.object;
59925964 const pt = o.pt;
59935965 const inst = body_tail[0];
59945966 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
......@@ -6003,7 +5975,7 @@ pub const FuncGen = struct {
60035975 }
60045976
60055977 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6006 const o = self.dg.object;
5978 const o = self.ng.object;
60075979 const mod = o.pt.zcu;
60085980 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
60095981 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
......@@ -6023,7 +5995,7 @@ pub const FuncGen = struct {
60235995 can_elide_load: bool,
60245996 is_unused: bool,
60255997 ) !Builder.Value {
6026 const o = fg.dg.object;
5998 const o = fg.ng.object;
60275999 const pt = o.pt;
60286000 const mod = pt.zcu;
60296001 const payload_ty = err_union_ty.errorUnionPayload(mod);
......@@ -6088,7 +6060,7 @@ pub const FuncGen = struct {
60886060 }
60896061
60906062 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6091 const o = self.dg.object;
6063 const o = self.ng.object;
60926064 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
60936065 const cond = try self.resolveInst(pl_op.operand);
60946066 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
......@@ -6152,7 +6124,7 @@ pub const FuncGen = struct {
61526124 }
61536125
61546126 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6155 const o = self.dg.object;
6127 const o = self.ng.object;
61566128 const mod = o.pt.zcu;
61576129 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
61586130 const loop = self.air.extraData(Air.Block, ty_pl.payload);
......@@ -6176,7 +6148,7 @@ pub const FuncGen = struct {
61766148 }
61776149
61786150 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6179 const o = self.dg.object;
6151 const o = self.ng.object;
61806152 const pt = o.pt;
61816153 const mod = pt.zcu;
61826154 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -6195,7 +6167,7 @@ pub const FuncGen = struct {
61956167 }
61966168
61976169 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6198 const o = self.dg.object;
6170 const o = self.ng.object;
61996171 const pt = o.pt;
62006172 const mod = pt.zcu;
62016173 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -6280,7 +6252,7 @@ pub const FuncGen = struct {
62806252 ) !Builder.Value {
62816253 _ = fast;
62826254
6283 const o = self.dg.object;
6255 const o = self.ng.object;
62846256 const pt = o.pt;
62856257 const mod = pt.zcu;
62866258 const target = mod.getTarget();
......@@ -6342,13 +6314,13 @@ pub const FuncGen = struct {
63426314 }
63436315
63446316 fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
6345 const o = fg.dg.object;
6317 const o = fg.ng.object;
63466318 const mod = o.pt.zcu;
63476319 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;
63486320 }
63496321
63506322 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {
6351 const o = fg.dg.object;
6323 const o = fg.ng.object;
63526324 const pt = o.pt;
63536325 const mod = pt.zcu;
63546326 const llvm_usize = try o.lowerType(Type.usize);
......@@ -6378,7 +6350,7 @@ pub const FuncGen = struct {
63786350 }
63796351
63806352 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value {
6381 const o = self.dg.object;
6353 const o = self.ng.object;
63826354 const mod = o.pt.zcu;
63836355 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63846356 const slice_ptr = try self.resolveInst(ty_op.operand);
......@@ -6389,7 +6361,7 @@ pub const FuncGen = struct {
63896361 }
63906362
63916363 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6392 const o = self.dg.object;
6364 const o = self.ng.object;
63936365 const pt = o.pt;
63946366 const mod = pt.zcu;
63956367 const inst = body_tail[0];
......@@ -6413,7 +6385,7 @@ pub const FuncGen = struct {
64136385 }
64146386
64156387 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6416 const o = self.dg.object;
6388 const o = self.ng.object;
64176389 const mod = o.pt.zcu;
64186390 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
64196391 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -6427,7 +6399,7 @@ pub const FuncGen = struct {
64276399 }
64286400
64296401 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6430 const o = self.dg.object;
6402 const o = self.ng.object;
64316403 const pt = o.pt;
64326404 const mod = pt.zcu;
64336405 const inst = body_tail[0];
......@@ -6460,7 +6432,7 @@ pub const FuncGen = struct {
64606432 }
64616433
64626434 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6463 const o = self.dg.object;
6435 const o = self.ng.object;
64646436 const pt = o.pt;
64656437 const mod = pt.zcu;
64666438 const inst = body_tail[0];
......@@ -6486,7 +6458,7 @@ pub const FuncGen = struct {
64866458 }
64876459
64886460 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6489 const o = self.dg.object;
6461 const o = self.ng.object;
64906462 const pt = o.pt;
64916463 const mod = pt.zcu;
64926464 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -6529,7 +6501,7 @@ pub const FuncGen = struct {
65296501 }
65306502
65316503 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6532 const o = self.dg.object;
6504 const o = self.ng.object;
65336505 const pt = o.pt;
65346506 const mod = pt.zcu;
65356507 const inst = body_tail[0];
......@@ -6635,7 +6607,7 @@ pub const FuncGen = struct {
66356607 }
66366608
66376609 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6638 const o = self.dg.object;
6610 const o = self.ng.object;
66396611 const pt = o.pt;
66406612 const mod = pt.zcu;
66416613 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -6697,7 +6669,7 @@ pub const FuncGen = struct {
66976669 }
66986670
66996671 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6700 const o = self.dg.object;
6672 const o = self.ng.object;
67016673 const mod = o.pt.zcu;
67026674 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
67036675 const operand = try self.resolveInst(pl_op.operand);
......@@ -6729,7 +6701,7 @@ pub const FuncGen = struct {
67296701 }
67306702
67316703 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6732 const o = self.dg.object;
6704 const o = self.ng.object;
67336705 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
67346706 const operand = try self.resolveInst(pl_op.operand);
67356707 const operand_ty = self.typeOf(pl_op.operand);
......@@ -6746,7 +6718,7 @@ pub const FuncGen = struct {
67466718 );
67476719
67486720 const pt = o.pt;
6749 const owner_mod = self.dg.ownerModule();
6721 const owner_mod = self.ng.ownerModule();
67506722 if (isByRef(operand_ty, pt)) {
67516723 _ = try self.wip.callIntrinsic(
67526724 .normal,
......@@ -6800,7 +6772,7 @@ pub const FuncGen = struct {
68006772 // We don't have such an assembler implemented yet though. For now,
68016773 // this implementation feeds the inline assembly code directly to LLVM.
68026774
6803 const o = self.dg.object;
6775 const o = self.ng.object;
68046776 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
68056777 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
68066778 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
......@@ -7181,7 +7153,7 @@ pub const FuncGen = struct {
71817153 operand_is_ptr: bool,
71827154 cond: Builder.IntegerCondition,
71837155 ) !Builder.Value {
7184 const o = self.dg.object;
7156 const o = self.ng.object;
71857157 const pt = o.pt;
71867158 const mod = pt.zcu;
71877159 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
......@@ -7226,7 +7198,7 @@ pub const FuncGen = struct {
72267198 cond: Builder.IntegerCondition,
72277199 operand_is_ptr: bool,
72287200 ) !Builder.Value {
7229 const o = self.dg.object;
7201 const o = self.ng.object;
72307202 const pt = o.pt;
72317203 const mod = pt.zcu;
72327204 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
......@@ -7266,7 +7238,7 @@ pub const FuncGen = struct {
72667238 }
72677239
72687240 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7269 const o = self.dg.object;
7241 const o = self.ng.object;
72707242 const pt = o.pt;
72717243 const mod = pt.zcu;
72727244 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -7288,7 +7260,7 @@ pub const FuncGen = struct {
72887260 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
72897261 comptime assert(optional_layout_version == 3);
72907262
7291 const o = self.dg.object;
7263 const o = self.ng.object;
72927264 const pt = o.pt;
72937265 const mod = pt.zcu;
72947266 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -7320,7 +7292,7 @@ pub const FuncGen = struct {
73207292 }
73217293
73227294 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7323 const o = self.dg.object;
7295 const o = self.ng.object;
73247296 const pt = o.pt;
73257297 const mod = pt.zcu;
73267298 const inst = body_tail[0];
......@@ -7345,7 +7317,7 @@ pub const FuncGen = struct {
73457317 body_tail: []const Air.Inst.Index,
73467318 operand_is_ptr: bool,
73477319 ) !Builder.Value {
7348 const o = self.dg.object;
7320 const o = self.ng.object;
73497321 const pt = o.pt;
73507322 const mod = pt.zcu;
73517323 const inst = body_tail[0];
......@@ -7381,7 +7353,7 @@ pub const FuncGen = struct {
73817353 inst: Air.Inst.Index,
73827354 operand_is_ptr: bool,
73837355 ) !Builder.Value {
7384 const o = self.dg.object;
7356 const o = self.ng.object;
73857357 const pt = o.pt;
73867358 const mod = pt.zcu;
73877359 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -7415,7 +7387,7 @@ pub const FuncGen = struct {
74157387 }
74167388
74177389 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7418 const o = self.dg.object;
7390 const o = self.ng.object;
74197391 const pt = o.pt;
74207392 const mod = pt.zcu;
74217393 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -7456,7 +7428,7 @@ pub const FuncGen = struct {
74567428 }
74577429
74587430 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7459 const o = self.dg.object;
7431 const o = self.ng.object;
74607432 const pt = o.pt;
74617433 const mod = pt.zcu;
74627434
......@@ -7502,7 +7474,7 @@ pub const FuncGen = struct {
75027474 }
75037475
75047476 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7505 const o = self.dg.object;
7477 const o = self.ng.object;
75067478 const pt = o.pt;
75077479 const mod = pt.zcu;
75087480 const inst = body_tail[0];
......@@ -7536,7 +7508,7 @@ pub const FuncGen = struct {
75367508 }
75377509
75387510 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7539 const o = self.dg.object;
7511 const o = self.ng.object;
75407512 const pt = o.pt;
75417513 const inst = body_tail[0];
75427514 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -7577,7 +7549,7 @@ pub const FuncGen = struct {
75777549 }
75787550
75797551 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7580 const o = self.dg.object;
7552 const o = self.ng.object;
75817553 const pt = o.pt;
75827554 const mod = pt.zcu;
75837555 const inst = body_tail[0];
......@@ -7618,7 +7590,7 @@ pub const FuncGen = struct {
76187590 }
76197591
76207592 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7621 const o = self.dg.object;
7593 const o = self.ng.object;
76227594 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
76237595 const index = pl_op.payload;
76247596 const llvm_usize = try o.lowerType(Type.usize);
......@@ -7628,7 +7600,7 @@ pub const FuncGen = struct {
76287600 }
76297601
76307602 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7631 const o = self.dg.object;
7603 const o = self.ng.object;
76327604 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
76337605 const index = pl_op.payload;
76347606 const llvm_isize = try o.lowerType(Type.isize);
......@@ -7638,7 +7610,7 @@ pub const FuncGen = struct {
76387610 }
76397611
76407612 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7641 const o = self.dg.object;
7613 const o = self.ng.object;
76427614 const pt = o.pt;
76437615 const mod = pt.zcu;
76447616 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
......@@ -7661,7 +7633,7 @@ pub const FuncGen = struct {
76617633 }
76627634
76637635 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7664 const o = self.dg.object;
7636 const o = self.ng.object;
76657637 const mod = o.pt.zcu;
76667638 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
76677639 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7681,7 +7653,7 @@ pub const FuncGen = struct {
76817653 }
76827654
76837655 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7684 const o = self.dg.object;
7656 const o = self.ng.object;
76857657 const mod = o.pt.zcu;
76867658 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
76877659 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7701,7 +7673,7 @@ pub const FuncGen = struct {
77017673 }
77027674
77037675 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7704 const o = self.dg.object;
7676 const o = self.ng.object;
77057677 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
77067678 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
77077679 const ptr = try self.resolveInst(bin_op.lhs);
......@@ -7711,7 +7683,7 @@ pub const FuncGen = struct {
77117683 }
77127684
77137685 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7714 const o = self.dg.object;
7686 const o = self.ng.object;
77157687 const mod = o.pt.zcu;
77167688 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
77177689 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7729,7 +7701,7 @@ pub const FuncGen = struct {
77297701 signed_intrinsic: Builder.Intrinsic,
77307702 unsigned_intrinsic: Builder.Intrinsic,
77317703 ) !Builder.Value {
7732 const o = fg.dg.object;
7704 const o = fg.ng.object;
77337705 const mod = o.pt.zcu;
77347706
77357707 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -7777,7 +7749,7 @@ pub const FuncGen = struct {
77777749 }
77787750
77797751 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7780 const o = self.dg.object;
7752 const o = self.ng.object;
77817753 const mod = o.pt.zcu;
77827754 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
77837755 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7797,7 +7769,7 @@ pub const FuncGen = struct {
77977769 }
77987770
77997771 fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7800 const o = self.dg.object;
7772 const o = self.ng.object;
78017773 const mod = o.pt.zcu;
78027774 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
78037775 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7818,7 +7790,7 @@ pub const FuncGen = struct {
78187790 }
78197791
78207792 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7821 const o = self.dg.object;
7793 const o = self.ng.object;
78227794 const mod = o.pt.zcu;
78237795 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
78247796 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7838,7 +7810,7 @@ pub const FuncGen = struct {
78387810 }
78397811
78407812 fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7841 const o = self.dg.object;
7813 const o = self.ng.object;
78427814 const mod = o.pt.zcu;
78437815 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
78447816 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7859,7 +7831,7 @@ pub const FuncGen = struct {
78597831 }
78607832
78617833 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7862 const o = self.dg.object;
7834 const o = self.ng.object;
78637835 const mod = o.pt.zcu;
78647836 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
78657837 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7888,7 +7860,7 @@ pub const FuncGen = struct {
78887860 }
78897861
78907862 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7891 const o = self.dg.object;
7863 const o = self.ng.object;
78927864 const mod = o.pt.zcu;
78937865 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
78947866 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7904,7 +7876,7 @@ pub const FuncGen = struct {
79047876 }
79057877
79067878 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7907 const o = self.dg.object;
7879 const o = self.ng.object;
79087880 const mod = o.pt.zcu;
79097881 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
79107882 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7936,7 +7908,7 @@ pub const FuncGen = struct {
79367908 }
79377909
79387910 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7939 const o = self.dg.object;
7911 const o = self.ng.object;
79407912 const mod = o.pt.zcu;
79417913 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
79427914 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7954,7 +7926,7 @@ pub const FuncGen = struct {
79547926 }
79557927
79567928 fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7957 const o = self.dg.object;
7929 const o = self.ng.object;
79587930 const mod = o.pt.zcu;
79597931 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
79607932 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -7971,7 +7943,7 @@ pub const FuncGen = struct {
79717943 }
79727944
79737945 fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
7974 const o = self.dg.object;
7946 const o = self.ng.object;
79757947 const mod = o.pt.zcu;
79767948 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
79777949 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -8007,7 +7979,7 @@ pub const FuncGen = struct {
80077979 }
80087980
80097981 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8010 const o = self.dg.object;
7982 const o = self.ng.object;
80117983 const mod = o.pt.zcu;
80127984 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
80137985 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -8029,7 +8001,7 @@ pub const FuncGen = struct {
80298001 }
80308002
80318003 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8032 const o = self.dg.object;
8004 const o = self.ng.object;
80338005 const mod = o.pt.zcu;
80348006 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
80358007 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -8057,7 +8029,7 @@ pub const FuncGen = struct {
80578029 signed_intrinsic: Builder.Intrinsic,
80588030 unsigned_intrinsic: Builder.Intrinsic,
80598031 ) !Builder.Value {
8060 const o = self.dg.object;
8032 const o = self.ng.object;
80618033 const pt = o.pt;
80628034 const mod = pt.zcu;
80638035 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -8111,7 +8083,7 @@ pub const FuncGen = struct {
81118083 result_vector: Builder.Value,
81128084 vector_len: usize,
81138085 ) !Builder.Value {
8114 const o = self.dg.object;
8086 const o = self.ng.object;
81158087 assert(args_vectors.len <= 3);
81168088
81178089 var i: usize = 0;
......@@ -8143,7 +8115,7 @@ pub const FuncGen = struct {
81438115 param_types: []const Builder.Type,
81448116 return_type: Builder.Type,
81458117 ) Allocator.Error!Builder.Function.Index {
8146 const o = self.dg.object;
8118 const o = self.ng.object;
81478119 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
81488120 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
81498121 .function => |function| function,
......@@ -8165,7 +8137,7 @@ pub const FuncGen = struct {
81658137 ty: Type,
81668138 params: [2]Builder.Value,
81678139 ) !Builder.Value {
8168 const o = self.dg.object;
8140 const o = self.ng.object;
81698141 const mod = o.pt.zcu;
81708142 const target = mod.getTarget();
81718143 const scalar_ty = ty.scalarType(mod);
......@@ -8271,7 +8243,7 @@ pub const FuncGen = struct {
82718243 comptime params_len: usize,
82728244 params: [params_len]Builder.Value,
82738245 ) !Builder.Value {
8274 const o = self.dg.object;
8246 const o = self.ng.object;
82758247 const mod = o.pt.zcu;
82768248 const target = mod.getTarget();
82778249 const scalar_ty = ty.scalarType(mod);
......@@ -8412,7 +8384,7 @@ pub const FuncGen = struct {
84128384 }
84138385
84148386 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8415 const o = self.dg.object;
8387 const o = self.ng.object;
84168388 const pt = o.pt;
84178389 const mod = pt.zcu;
84188390 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -8483,7 +8455,7 @@ pub const FuncGen = struct {
84838455 }
84848456
84858457 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8486 const o = self.dg.object;
8458 const o = self.ng.object;
84878459 const mod = o.pt.zcu;
84888460 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
84898461
......@@ -8501,7 +8473,7 @@ pub const FuncGen = struct {
85018473 }
85028474
85038475 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8504 const o = self.dg.object;
8476 const o = self.ng.object;
85058477 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85068478
85078479 const lhs = try self.resolveInst(bin_op.lhs);
......@@ -8514,7 +8486,7 @@ pub const FuncGen = struct {
85148486 }
85158487
85168488 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8517 const o = self.dg.object;
8489 const o = self.ng.object;
85188490 const pt = o.pt;
85198491 const mod = pt.zcu;
85208492 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -8557,7 +8529,7 @@ pub const FuncGen = struct {
85578529 }
85588530
85598531 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {
8560 const o = self.dg.object;
8532 const o = self.ng.object;
85618533 const mod = o.pt.zcu;
85628534 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85638535
......@@ -8576,7 +8548,7 @@ pub const FuncGen = struct {
85768548 }
85778549
85788550 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8579 const o = self.dg.object;
8551 const o = self.ng.object;
85808552 const mod = o.pt.zcu;
85818553 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
85828554 const operand = try self.resolveInst(ty_op.operand);
......@@ -8598,7 +8570,7 @@ pub const FuncGen = struct {
85988570 }
85998571
86008572 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8601 const o = self.dg.object;
8573 const o = self.ng.object;
86028574 const mod = o.pt.zcu;
86038575 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
86048576 const dest_ty = self.typeOfIndex(inst);
......@@ -8614,7 +8586,7 @@ pub const FuncGen = struct {
86148586 }
86158587
86168588 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8617 const o = self.dg.object;
8589 const o = self.ng.object;
86188590 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
86198591 const operand = try self.resolveInst(ty_op.operand);
86208592 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
......@@ -8622,7 +8594,7 @@ pub const FuncGen = struct {
86228594 }
86238595
86248596 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8625 const o = self.dg.object;
8597 const o = self.ng.object;
86268598 const mod = o.pt.zcu;
86278599 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
86288600 const operand = try self.resolveInst(ty_op.operand);
......@@ -8656,7 +8628,7 @@ pub const FuncGen = struct {
86568628 }
86578629
86588630 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8659 const o = self.dg.object;
8631 const o = self.ng.object;
86608632 const mod = o.pt.zcu;
86618633 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
86628634 const operand = try self.resolveInst(ty_op.operand);
......@@ -8696,7 +8668,7 @@ pub const FuncGen = struct {
86968668 }
86978669
86988670 fn airIntFromPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8699 const o = self.dg.object;
8671 const o = self.ng.object;
87008672 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
87018673 const operand = try self.resolveInst(un_op);
87028674 const ptr_ty = self.typeOf(un_op);
......@@ -8714,7 +8686,7 @@ pub const FuncGen = struct {
87148686 }
87158687
87168688 fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {
8717 const o = self.dg.object;
8689 const o = self.ng.object;
87188690 const pt = o.pt;
87198691 const mod = pt.zcu;
87208692 const operand_is_ref = isByRef(operand_ty, pt);
......@@ -8739,7 +8711,7 @@ pub const FuncGen = struct {
87398711 if (operand_ty.zigTypeTag(mod) == .Vector and inst_ty.zigTypeTag(mod) == .Array) {
87408712 const elem_ty = operand_ty.childType(mod);
87418713 if (!result_is_ref) {
8742 return self.dg.todo("implement bitcast vector to non-ref array", .{});
8714 return self.ng.todo("implement bitcast vector to non-ref array", .{});
87438715 }
87448716 const alignment = inst_ty.abiAlignment(pt).toLlvm();
87458717 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
......@@ -8766,7 +8738,7 @@ pub const FuncGen = struct {
87668738 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {
87678739 const elem_ty = operand_ty.childType(mod);
87688740 const llvm_vector_ty = try o.lowerType(inst_ty);
8769 if (!operand_is_ref) return self.dg.todo("implement bitcast non-ref array to vector", .{});
8741 if (!operand_is_ref) return self.ng.todo("implement bitcast non-ref array to vector", .{});
87708742
87718743 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;
87728744 if (bitcast_ok) {
......@@ -8831,9 +8803,9 @@ pub const FuncGen = struct {
88318803 }
88328804
88338805 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8834 const o = self.dg.object;
8806 const o = self.ng.object;
88358807 const pt = o.pt;
8836 const mod = pt.zcu;
8808 const zcu = pt.zcu;
88378809 const arg_val = self.args[self.arg_index];
88388810 self.arg_index += 1;
88398811
......@@ -8846,9 +8818,8 @@ pub const FuncGen = struct {
88468818 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
88478819 if (name == .none) return arg_val;
88488820
8849 const func_index = self.dg.decl.getOwnedFunctionIndex();
8850 const func = mod.funcInfo(func_index);
8851 const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;
8821 const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());
8822 const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;
88528823 const lbrace_col = func.lbrace_column + 1;
88538824
88548825 const debug_parameter = try o.builder.debugParameter(
......@@ -8870,7 +8841,7 @@ pub const FuncGen = struct {
88708841 },
88718842 };
88728843
8873 const owner_mod = self.dg.ownerModule();
8844 const mod = self.ng.ownerModule();
88748845 if (isByRef(inst_ty, pt)) {
88758846 _ = try self.wip.callIntrinsic(
88768847 .normal,
......@@ -8884,7 +8855,7 @@ pub const FuncGen = struct {
88848855 },
88858856 "",
88868857 );
8887 } else if (owner_mod.optimize_mode == .Debug) {
8858 } else if (mod.optimize_mode == .Debug) {
88888859 const alignment = inst_ty.abiAlignment(pt).toLlvm();
88898860 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
88908861 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
......@@ -8920,7 +8891,7 @@ pub const FuncGen = struct {
89208891 }
89218892
89228893 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8923 const o = self.dg.object;
8894 const o = self.ng.object;
89248895 const pt = o.pt;
89258896 const mod = pt.zcu;
89268897 const ptr_ty = self.typeOfIndex(inst);
......@@ -8934,7 +8905,7 @@ pub const FuncGen = struct {
89348905 }
89358906
89368907 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8937 const o = self.dg.object;
8908 const o = self.ng.object;
89388909 const pt = o.pt;
89398910 const mod = pt.zcu;
89408911 const ptr_ty = self.typeOfIndex(inst);
......@@ -8954,7 +8925,7 @@ pub const FuncGen = struct {
89548925 llvm_ty: Builder.Type,
89558926 alignment: Builder.Alignment,
89568927 ) Allocator.Error!Builder.Value {
8957 const target = self.dg.object.pt.zcu.getTarget();
8928 const target = self.ng.object.pt.zcu.getTarget();
89588929 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);
89598930 }
89608931
......@@ -8964,12 +8935,12 @@ pub const FuncGen = struct {
89648935 ty: Type,
89658936 alignment: Builder.Alignment,
89668937 ) Allocator.Error!Builder.Value {
8967 const o = self.dg.object;
8938 const o = self.ng.object;
89688939 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment);
89698940 }
89708941
89718942 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
8972 const o = self.dg.object;
8943 const o = self.ng.object;
89738944 const pt = o.pt;
89748945 const mod = pt.zcu;
89758946 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -8979,7 +8950,7 @@ pub const FuncGen = struct {
89798950
89808951 const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false;
89818952 if (val_is_undef) {
8982 const owner_mod = self.dg.ownerModule();
8953 const owner_mod = self.ng.ownerModule();
89838954
89848955 // Even if safety is disabled, we still emit a memset to undefined since it conveys
89858956 // extra information to LLVM, and LLVM will optimize it out. Safety makes the difference
......@@ -9029,7 +9000,7 @@ pub const FuncGen = struct {
90299000 ///
90309001 /// The first instruction of `body_tail` is the one whose copy we want to elide.
90319002 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {
9032 const o = fg.dg.object;
9003 const o = fg.ng.object;
90339004 const mod = o.pt.zcu;
90349005 const ip = &mod.intern_pool;
90359006 for (body_tail[1..]) |body_inst| {
......@@ -9045,7 +9016,7 @@ pub const FuncGen = struct {
90459016 }
90469017
90479018 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
9048 const o = fg.dg.object;
9019 const o = fg.ng.object;
90499020 const pt = o.pt;
90509021 const mod = pt.zcu;
90519022 const inst = body_tail[0];
......@@ -9077,7 +9048,7 @@ pub const FuncGen = struct {
90779048
90789049 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
90799050 _ = inst;
9080 const o = self.dg.object;
9051 const o = self.ng.object;
90819052 const llvm_usize = try o.lowerType(Type.usize);
90829053 if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) {
90839054 // https://github.com/ziglang/zig/issues/11946
......@@ -9089,7 +9060,7 @@ pub const FuncGen = struct {
90899060
90909061 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
90919062 _ = inst;
9092 const o = self.dg.object;
9063 const o = self.ng.object;
90939064 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");
90949065 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");
90959066 }
......@@ -9106,7 +9077,7 @@ pub const FuncGen = struct {
91069077 inst: Air.Inst.Index,
91079078 kind: Builder.Function.Instruction.CmpXchg.Kind,
91089079 ) !Builder.Value {
9109 const o = self.dg.object;
9080 const o = self.ng.object;
91109081 const pt = o.pt;
91119082 const mod = pt.zcu;
91129083 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -9157,7 +9128,7 @@ pub const FuncGen = struct {
91579128 }
91589129
91599130 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9160 const o = self.dg.object;
9131 const o = self.ng.object;
91619132 const pt = o.pt;
91629133 const mod = pt.zcu;
91639134 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
......@@ -9221,7 +9192,7 @@ pub const FuncGen = struct {
92219192 }
92229193
92239194 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9224 const o = self.dg.object;
9195 const o = self.ng.object;
92259196 const pt = o.pt;
92269197 const mod = pt.zcu;
92279198 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
......@@ -9269,7 +9240,7 @@ pub const FuncGen = struct {
92699240 inst: Air.Inst.Index,
92709241 ordering: Builder.AtomicOrdering,
92719242 ) !Builder.Value {
9272 const o = self.dg.object;
9243 const o = self.ng.object;
92739244 const pt = o.pt;
92749245 const mod = pt.zcu;
92759246 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -9294,7 +9265,7 @@ pub const FuncGen = struct {
92949265 }
92959266
92969267 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
9297 const o = self.dg.object;
9268 const o = self.ng.object;
92989269 const pt = o.pt;
92999270 const mod = pt.zcu;
93009271 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -9329,7 +9300,7 @@ pub const FuncGen = struct {
93299300 } else {
93309301 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
93319302 }
9332 const owner_mod = self.dg.ownerModule();
9303 const owner_mod = self.ng.ownerModule();
93339304 if (safety and owner_mod.valgrind) {
93349305 try self.valgrindMarkUndef(dest_ptr, len);
93359306 }
......@@ -9435,7 +9406,7 @@ pub const FuncGen = struct {
94359406 dest_ptr_align: Builder.Alignment,
94369407 access_kind: Builder.MemoryAccessKind,
94379408 ) !void {
9438 const o = self.dg.object;
9409 const o = self.ng.object;
94399410 const usize_zero = try o.builder.intValue(try o.lowerType(Type.usize), 0);
94409411 const cond = try self.cmp(.normal, .neq, Type.usize, len, usize_zero);
94419412 const memset_block = try self.wip.block(1, "MemsetTrapSkip");
......@@ -9448,7 +9419,7 @@ pub const FuncGen = struct {
94489419 }
94499420
94509421 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9451 const o = self.dg.object;
9422 const o = self.ng.object;
94529423 const pt = o.pt;
94539424 const mod = pt.zcu;
94549425 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -9502,7 +9473,7 @@ pub const FuncGen = struct {
95029473 }
95039474
95049475 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9505 const o = self.dg.object;
9476 const o = self.ng.object;
95069477 const pt = o.pt;
95079478 const mod = pt.zcu;
95089479 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -9524,7 +9495,7 @@ pub const FuncGen = struct {
95249495 }
95259496
95269497 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9527 const o = self.dg.object;
9498 const o = self.ng.object;
95289499 const pt = o.pt;
95299500 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
95309501 const un_ty = self.typeOf(ty_op.operand);
......@@ -9563,7 +9534,7 @@ pub const FuncGen = struct {
95639534 }
95649535
95659536 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {
9566 const o = self.dg.object;
9537 const o = self.ng.object;
95679538 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
95689539 const inst_ty = self.typeOfIndex(inst);
95699540 const operand_ty = self.typeOf(ty_op.operand);
......@@ -9581,7 +9552,7 @@ pub const FuncGen = struct {
95819552 }
95829553
95839554 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {
9584 const o = self.dg.object;
9555 const o = self.ng.object;
95859556 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
95869557 const inst_ty = self.typeOfIndex(inst);
95879558 const operand_ty = self.typeOf(ty_op.operand);
......@@ -9599,7 +9570,7 @@ pub const FuncGen = struct {
95999570 }
96009571
96019572 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9602 const o = self.dg.object;
9573 const o = self.ng.object;
96039574 const mod = o.pt.zcu;
96049575 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
96059576 const operand_ty = self.typeOf(ty_op.operand);
......@@ -9633,7 +9604,7 @@ pub const FuncGen = struct {
96339604 }
96349605
96359606 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9636 const o = self.dg.object;
9607 const o = self.ng.object;
96379608 const mod = o.pt.zcu;
96389609 const ip = &mod.intern_pool;
96399610 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -9665,7 +9636,7 @@ pub const FuncGen = struct {
96659636 }
96669637
96679638 fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9668 const o = self.dg.object;
9639 const o = self.ng.object;
96699640 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
96709641 const operand = try self.resolveInst(un_op);
96719642 const enum_ty = self.typeOf(un_op);
......@@ -9683,22 +9654,21 @@ pub const FuncGen = struct {
96839654 }
96849655
96859656 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9686 const o = self.dg.object;
9657 const o = self.ng.object;
96879658 const pt = o.pt;
96889659 const zcu = pt.zcu;
96899660 const ip = &zcu.intern_pool;
96909661 const enum_type = ip.loadEnumType(enum_ty.toIntern());
96919662
96929663 // TODO: detect when the type changes and re-emit this function.
9693 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
9664 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());
96949665 if (gop.found_existing) return gop.value_ptr.*;
9695 errdefer assert(o.named_enum_map.remove(enum_type.decl));
9666 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));
96969667
9697 const decl = zcu.declPtr(enum_type.decl);
96989668 const target = zcu.root_mod.resolved_target.result;
96999669 const function_index = try o.builder.addFunction(
97009670 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9701 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{decl.fqn.fmt(ip)}),
9671 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{enum_type.name.fmt(ip)}),
97029672 toLlvmAddressSpace(.generic, target),
97039673 );
97049674
......@@ -9741,7 +9711,7 @@ pub const FuncGen = struct {
97419711 }
97429712
97439713 fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9744 const o = self.dg.object;
9714 const o = self.ng.object;
97459715 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
97469716 const operand = try self.resolveInst(un_op);
97479717 const enum_ty = self.typeOf(un_op);
......@@ -9759,7 +9729,7 @@ pub const FuncGen = struct {
97599729 }
97609730
97619731 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9762 const o = self.dg.object;
9732 const o = self.ng.object;
97639733 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
97649734 const operand = try self.resolveInst(un_op);
97659735 const slice_ty = self.typeOfIndex(inst);
......@@ -9774,7 +9744,7 @@ pub const FuncGen = struct {
97749744 }
97759745
97769746 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9777 const o = self.dg.object;
9747 const o = self.ng.object;
97789748 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
97799749 const scalar = try self.resolveInst(ty_op.operand);
97809750 const vector_ty = self.typeOfIndex(inst);
......@@ -9792,7 +9762,7 @@ pub const FuncGen = struct {
97929762 }
97939763
97949764 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9795 const o = self.dg.object;
9765 const o = self.ng.object;
97969766 const pt = o.pt;
97979767 const mod = pt.zcu;
97989768 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -9848,7 +9818,7 @@ pub const FuncGen = struct {
98489818 vector_len: usize,
98499819 accum_init: Builder.Value,
98509820 ) !Builder.Value {
9851 const o = self.dg.object;
9821 const o = self.ng.object;
98529822 const usize_ty = try o.lowerType(Type.usize);
98539823 const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len);
98549824 const llvm_result_ty = accum_init.typeOfWip(&self.wip);
......@@ -9902,7 +9872,7 @@ pub const FuncGen = struct {
99029872 }
99039873
99049874 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {
9905 const o = self.dg.object;
9875 const o = self.ng.object;
99069876 const mod = o.pt.zcu;
99079877 const target = mod.getTarget();
99089878
......@@ -10012,7 +9982,7 @@ pub const FuncGen = struct {
100129982 }
100139983
100149984 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10015 const o = self.dg.object;
9985 const o = self.ng.object;
100169986 const pt = o.pt;
100179987 const mod = pt.zcu;
100189988 const ip = &mod.intern_pool;
......@@ -10133,7 +10103,7 @@ pub const FuncGen = struct {
1013310103 }
1013410104
1013510105 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10136 const o = self.dg.object;
10106 const o = self.ng.object;
1013710107 const pt = o.pt;
1013810108 const mod = pt.zcu;
1013910109 const ip = &mod.intern_pool;
......@@ -10256,7 +10226,7 @@ pub const FuncGen = struct {
1025610226 }
1025710227
1025810228 fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10259 const o = self.dg.object;
10229 const o = self.ng.object;
1026010230 const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
1026110231
1026210232 comptime assert(@intFromEnum(std.builtin.PrefetchOptions.Rw.read) == 0);
......@@ -10306,7 +10276,7 @@ pub const FuncGen = struct {
1030610276 }
1030710277
1030810278 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10309 const o = self.dg.object;
10279 const o = self.ng.object;
1031010280 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1031110281 const inst_ty = self.typeOfIndex(inst);
1031210282 const operand = try self.resolveInst(ty_op.operand);
......@@ -10324,12 +10294,12 @@ pub const FuncGen = struct {
1032410294 0 => @field(Builder.Intrinsic, basename ++ ".x"),
1032510295 1 => @field(Builder.Intrinsic, basename ++ ".y"),
1032610296 2 => @field(Builder.Intrinsic, basename ++ ".z"),
10327 else => return self.dg.object.builder.intValue(.i32, default),
10297 else => return self.ng.object.builder.intValue(.i32, default),
1032810298 }, &.{}, &.{}, "");
1032910299 }
1033010300
1033110301 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10332 const o = self.dg.object;
10302 const o = self.ng.object;
1033310303 const target = o.pt.zcu.getTarget();
1033410304 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1033510305
......@@ -10339,7 +10309,7 @@ pub const FuncGen = struct {
1033910309 }
1034010310
1034110311 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10342 const o = self.dg.object;
10312 const o = self.ng.object;
1034310313 const target = o.pt.zcu.getTarget();
1034410314 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1034510315
......@@ -10362,7 +10332,7 @@ pub const FuncGen = struct {
1036210332 }
1036310333
1036410334 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10365 const o = self.dg.object;
10335 const o = self.ng.object;
1036610336 const target = o.pt.zcu.getTarget();
1036710337 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1036810338
......@@ -10372,7 +10342,7 @@ pub const FuncGen = struct {
1037210342 }
1037310343
1037410344 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {
10375 const o = self.dg.object;
10345 const o = self.ng.object;
1037610346 const pt = o.pt;
1037710347
1037810348 const table = o.error_name_table;
......@@ -10401,7 +10371,7 @@ pub const FuncGen = struct {
1040110371 opt_handle: Builder.Value,
1040210372 is_by_ref: bool,
1040310373 ) Allocator.Error!Builder.Value {
10404 const o = self.dg.object;
10374 const o = self.ng.object;
1040510375 const field = b: {
1040610376 if (is_by_ref) {
1040710377 const field_ptr = try self.wip.gepStruct(opt_llvm_ty, opt_handle, 1, "");
......@@ -10422,7 +10392,7 @@ pub const FuncGen = struct {
1042210392 opt_ty: Type,
1042310393 can_elide_load: bool,
1042410394 ) !Builder.Value {
10425 const o = fg.dg.object;
10395 const o = fg.ng.object;
1042610396 const pt = o.pt;
1042710397 const mod = pt.zcu;
1042810398 const payload_ty = opt_ty.optionalChild(mod);
......@@ -10451,7 +10421,7 @@ pub const FuncGen = struct {
1045110421 payload: Builder.Value,
1045210422 non_null_bit: Builder.Value,
1045310423 ) !Builder.Value {
10454 const o = self.dg.object;
10424 const o = self.ng.object;
1045510425 const pt = o.pt;
1045610426 const optional_llvm_ty = try o.lowerType(optional_ty);
1045710427 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");
......@@ -10483,7 +10453,7 @@ pub const FuncGen = struct {
1048310453 struct_ptr_ty: Type,
1048410454 field_index: u32,
1048510455 ) !Builder.Value {
10486 const o = self.dg.object;
10456 const o = self.ng.object;
1048710457 const pt = o.pt;
1048810458 const mod = pt.zcu;
1048910459 const struct_ty = struct_ptr_ty.childType(mod);
......@@ -10552,7 +10522,7 @@ pub const FuncGen = struct {
1055210522 // "When loading a value of a type like i20 with a size that is not an integral number of bytes, the result is undefined if the value was not originally written using a store of the same type. "
1055310523 // => so load the byte aligned value and trunc the unwanted bits.
1055410524
10555 const o = fg.dg.object;
10525 const o = fg.ng.object;
1055610526 const pt = o.pt;
1055710527 const mod = pt.zcu;
1055810528 const payload_llvm_ty = try o.lowerType(payload_ty);
......@@ -10599,7 +10569,7 @@ pub const FuncGen = struct {
1059910569 ptr_alignment: Builder.Alignment,
1060010570 access_kind: Builder.MemoryAccessKind,
1060110571 ) !Builder.Value {
10602 const o = fg.dg.object;
10572 const o = fg.ng.object;
1060310573 const pt = o.pt;
1060410574 //const pointee_llvm_ty = try o.lowerType(pointee_type);
1060510575 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(pt)).toLlvm();
......@@ -10620,7 +10590,7 @@ pub const FuncGen = struct {
1062010590 /// alloca and copies the value into it, then returns the alloca instruction.
1062110591 /// For isByRef=false types, it creates a load instruction and returns it.
1062210592 fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {
10623 const o = self.dg.object;
10593 const o = self.ng.object;
1062410594 const pt = o.pt;
1062510595 const mod = pt.zcu;
1062610596 const info = ptr_ty.ptrInfo(mod);
......@@ -10693,7 +10663,7 @@ pub const FuncGen = struct {
1069310663 elem: Builder.Value,
1069410664 ordering: Builder.AtomicOrdering,
1069510665 ) !void {
10696 const o = self.dg.object;
10666 const o = self.ng.object;
1069710667 const pt = o.pt;
1069810668 const mod = pt.zcu;
1069910669 const info = ptr_ty.ptrInfo(mod);
......@@ -10784,7 +10754,7 @@ pub const FuncGen = struct {
1078410754
1078510755 fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {
1078610756 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
10787 const o = fg.dg.object;
10757 const o = fg.ng.object;
1078810758 const usize_ty = try o.lowerType(Type.usize);
1078910759 const zero = try o.builder.intValue(usize_ty, 0);
1079010760 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);
......@@ -10802,7 +10772,7 @@ pub const FuncGen = struct {
1080210772 a4: Builder.Value,
1080310773 a5: Builder.Value,
1080410774 ) Allocator.Error!Builder.Value {
10805 const o = fg.dg.object;
10775 const o = fg.ng.object;
1080610776 const pt = o.pt;
1080710777 const mod = pt.zcu;
1080810778 const target = mod.getTarget();
......@@ -10869,13 +10839,13 @@ pub const FuncGen = struct {
1086910839 }
1087010840
1087110841 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
10872 const o = fg.dg.object;
10842 const o = fg.ng.object;
1087310843 const mod = o.pt.zcu;
1087410844 return fg.air.typeOf(inst, &mod.intern_pool);
1087510845 }
1087610846
1087710847 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
10878 const o = fg.dg.object;
10848 const o = fg.ng.object;
1087910849 const mod = o.pt.zcu;
1088010850 return fg.air.typeOfIndex(inst, &mod.intern_pool);
1088110851 }
src/codegen/spirv.zig+287-299
......@@ -31,9 +31,9 @@ const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);
3131
3232pub const zig_call_abi_ver = 3;
3333
34const InternMap = std.AutoHashMapUnmanaged(struct { InternPool.Index, DeclGen.Repr }, IdResult);
34const InternMap = std.AutoHashMapUnmanaged(struct { InternPool.Index, NavGen.Repr }, IdResult);
3535const PtrTypeMap = std.AutoHashMapUnmanaged(
36 struct { InternPool.Index, StorageClass, DeclGen.Repr },
36 struct { InternPool.Index, StorageClass, NavGen.Repr },
3737 struct { ty_id: IdRef, fwd_emitted: bool },
3838);
3939
......@@ -142,7 +142,7 @@ const ControlFlow = union(enum) {
142142};
143143
144144/// This structure holds information that is relevant to the entire compilation,
145/// in contrast to `DeclGen`, which only holds relevant information about a
145/// in contrast to `NavGen`, which only holds relevant information about a
146146/// single decl.
147147pub const Object = struct {
148148 /// A general-purpose allocator that can be used for any allocation for this Object.
......@@ -153,10 +153,10 @@ pub const Object = struct {
153153
154154 /// The Zig module that this object file is generated for.
155155 /// A map of Zig decl indices to SPIR-V decl indices.
156 decl_link: std.AutoHashMapUnmanaged(InternPool.DeclIndex, SpvModule.Decl.Index) = .{},
156 nav_link: std.AutoHashMapUnmanaged(InternPool.Nav.Index, SpvModule.Decl.Index) = .{},
157157
158158 /// A map of Zig InternPool indices for anonymous decls to SPIR-V decl indices.
159 anon_decl_link: std.AutoHashMapUnmanaged(struct { InternPool.Index, StorageClass }, SpvModule.Decl.Index) = .{},
159 uav_link: std.AutoHashMapUnmanaged(struct { InternPool.Index, StorageClass }, SpvModule.Decl.Index) = .{},
160160
161161 /// A map that maps AIR intern pool indices to SPIR-V result-ids.
162162 intern_map: InternMap = .{},
......@@ -178,31 +178,29 @@ pub const Object = struct {
178178
179179 pub fn deinit(self: *Object) void {
180180 self.spv.deinit();
181 self.decl_link.deinit(self.gpa);
182 self.anon_decl_link.deinit(self.gpa);
181 self.nav_link.deinit(self.gpa);
182 self.uav_link.deinit(self.gpa);
183183 self.intern_map.deinit(self.gpa);
184184 self.ptr_types.deinit(self.gpa);
185185 }
186186
187 fn genDecl(
187 fn genNav(
188188 self: *Object,
189189 pt: Zcu.PerThread,
190 decl_index: InternPool.DeclIndex,
190 nav_index: InternPool.Nav.Index,
191191 air: Air,
192192 liveness: Liveness,
193193 ) !void {
194194 const zcu = pt.zcu;
195195 const gpa = zcu.gpa;
196 const decl = zcu.declPtr(decl_index);
197 const namespace = zcu.namespacePtr(decl.src_namespace);
198 const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg;
196 const structured_cfg = zcu.navFileScope(nav_index).mod.structured_cfg;
199197
200 var decl_gen = DeclGen{
198 var nav_gen = NavGen{
201199 .gpa = gpa,
202200 .object = self,
203201 .pt = pt,
204202 .spv = &self.spv,
205 .decl_index = decl_index,
203 .owner_nav = nav_index,
206204 .air = air,
207205 .liveness = liveness,
208206 .intern_map = &self.intern_map,
......@@ -212,18 +210,18 @@ pub const Object = struct {
212210 false => .{ .unstructured = .{} },
213211 },
214212 .current_block_label = undefined,
215 .base_line = decl.navSrcLine(zcu),
213 .base_line = zcu.navSrcLine(nav_index),
216214 };
217 defer decl_gen.deinit();
215 defer nav_gen.deinit();
218216
219 decl_gen.genDecl() catch |err| switch (err) {
217 nav_gen.genNav() catch |err| switch (err) {
220218 error.CodegenFail => {
221 try zcu.failed_analysis.put(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), decl_gen.error_msg.?);
219 try zcu.failed_codegen.put(gpa, nav_index, nav_gen.error_msg.?);
222220 },
223221 else => |other| {
224222 // There might be an error that happened *after* self.error_msg
225223 // was already allocated, so be sure to free it.
226 if (decl_gen.error_msg) |error_msg| {
224 if (nav_gen.error_msg) |error_msg| {
227225 error_msg.deinit(gpa);
228226 }
229227
......@@ -239,31 +237,30 @@ pub const Object = struct {
239237 air: Air,
240238 liveness: Liveness,
241239 ) !void {
242 const decl_index = pt.zcu.funcInfo(func_index).owner_decl;
240 const nav = pt.zcu.funcInfo(func_index).owner_nav;
243241 // TODO: Separate types for generating decls and functions?
244 try self.genDecl(pt, decl_index, air, liveness);
242 try self.genNav(pt, nav, air, liveness);
245243 }
246244
247 pub fn updateDecl(
245 pub fn updateNav(
248246 self: *Object,
249247 pt: Zcu.PerThread,
250 decl_index: InternPool.DeclIndex,
248 nav: InternPool.Nav.Index,
251249 ) !void {
252 try self.genDecl(pt, decl_index, undefined, undefined);
250 try self.genNav(pt, nav, undefined, undefined);
253251 }
254252
255 /// Fetch or allocate a result id for decl index. This function also marks the decl as alive.
256 /// Note: Function does not actually generate the decl, it just allocates an index.
257 pub fn resolveDecl(self: *Object, zcu: *Zcu, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {
258 const decl = zcu.declPtr(decl_index);
259 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?
260
261 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);
253 /// Fetch or allocate a result id for nav index. This function also marks the nav as alive.
254 /// Note: Function does not actually generate the nav, it just allocates an index.
255 pub fn resolveNav(self: *Object, zcu: *Zcu, nav_index: InternPool.Nav.Index) !SpvModule.Decl.Index {
256 const ip = &zcu.intern_pool;
257 const entry = try self.nav_link.getOrPut(self.gpa, nav_index);
262258 if (!entry.found_existing) {
259 const nav = ip.getNav(nav_index);
263260 // TODO: Extern fn?
264 const kind: SpvModule.Decl.Kind = if (decl.val.isFuncBody(zcu))
261 const kind: SpvModule.Decl.Kind = if (ip.isFunctionType(nav.typeOf(ip)))
265262 .func
266 else switch (decl.@"addrspace") {
263 else switch (nav.status.resolved.@"addrspace") {
267264 .generic => .invocation_global,
268265 else => .global,
269266 };
......@@ -276,8 +273,8 @@ pub const Object = struct {
276273};
277274
278275/// This structure is used to compile a declaration, and contains all relevant meta-information to deal with that.
279const DeclGen = struct {
280 /// A general-purpose allocator that can be used for any allocations for this DeclGen.
276const NavGen = struct {
277 /// A general-purpose allocator that can be used for any allocations for this NavGen.
281278 gpa: Allocator,
282279
283280 /// The object that this decl is generated into.
......@@ -291,7 +288,7 @@ const DeclGen = struct {
291288 spv: *SpvModule,
292289
293290 /// The decl we are currently generating code for.
294 decl_index: InternPool.DeclIndex,
291 owner_nav: InternPool.Nav.Index,
295292
296293 /// The intermediate code of the declaration we are currently generating. Note: If
297294 /// the declaration is not a function, this value will be undefined!
......@@ -399,8 +396,8 @@ const DeclGen = struct {
399396 indirect,
400397 };
401398
402 /// Free resources owned by the DeclGen.
403 pub fn deinit(self: *DeclGen) void {
399 /// Free resources owned by the NavGen.
400 pub fn deinit(self: *NavGen) void {
404401 self.args.deinit(self.gpa);
405402 self.inst_results.deinit(self.gpa);
406403 self.control_flow.deinit(self.gpa);
......@@ -408,26 +405,26 @@ const DeclGen = struct {
408405 }
409406
410407 /// Return the target which we are currently compiling for.
411 pub fn getTarget(self: *DeclGen) std.Target {
408 pub fn getTarget(self: *NavGen) std.Target {
412409 return self.pt.zcu.getTarget();
413410 }
414411
415 pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
412 pub fn fail(self: *NavGen, comptime format: []const u8, args: anytype) Error {
416413 @setCold(true);
417414 const zcu = self.pt.zcu;
418 const src_loc = zcu.declPtr(self.decl_index).navSrcLoc(zcu);
415 const src_loc = zcu.navSrcLoc(self.owner_nav);
419416 assert(self.error_msg == null);
420417 self.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, format, args);
421418 return error.CodegenFail;
422419 }
423420
424 pub fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
421 pub fn todo(self: *NavGen, comptime format: []const u8, args: anytype) Error {
425422 return self.fail("TODO (SPIR-V): " ++ format, args);
426423 }
427424
428425 /// This imports the "default" extended instruction set for the target
429426 /// For OpenCL, OpenCL.std.100. For Vulkan, GLSL.std.450.
430 fn importExtendedSet(self: *DeclGen) !IdResult {
427 fn importExtendedSet(self: *NavGen) !IdResult {
431428 const target = self.getTarget();
432429 return switch (target.os.tag) {
433430 .opencl => try self.spv.importInstructionSet(.@"OpenCL.std"),
......@@ -437,18 +434,18 @@ const DeclGen = struct {
437434 }
438435
439436 /// Fetch the result-id for a previously generated instruction or constant.
440 fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef {
437 fn resolve(self: *NavGen, inst: Air.Inst.Ref) !IdRef {
441438 const pt = self.pt;
442439 const mod = pt.zcu;
443440 if (try self.air.value(inst, pt)) |val| {
444441 const ty = self.typeOf(inst);
445442 if (ty.zigTypeTag(mod) == .Fn) {
446 const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) {
447 .extern_func => |extern_func| extern_func.decl,
448 .func => |func| func.owner_decl,
443 const fn_nav = switch (mod.intern_pool.indexToKey(val.ip_index)) {
444 .@"extern" => |@"extern"| @"extern".owner_nav,
445 .func => |func| func.owner_nav,
449446 else => unreachable,
450447 };
451 const spv_decl_index = try self.object.resolveDecl(mod, fn_decl_index);
448 const spv_decl_index = try self.object.resolveNav(mod, fn_nav);
452449 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});
453450 return self.spv.declPtr(spv_decl_index).result_id;
454451 }
......@@ -459,7 +456,7 @@ const DeclGen = struct {
459456 return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage.
460457 }
461458
462 fn resolveAnonDecl(self: *DeclGen, val: InternPool.Index) !IdRef {
459 fn resolveUav(self: *NavGen, val: InternPool.Index) !IdRef {
463460 // TODO: This cannot be a function at this point, but it should probably be handled anyway.
464461
465462 const mod = self.pt.zcu;
......@@ -467,7 +464,7 @@ const DeclGen = struct {
467464 const decl_ptr_ty_id = try self.ptrType(ty, .Generic);
468465
469466 const spv_decl_index = blk: {
470 const entry = try self.object.anon_decl_link.getOrPut(self.object.gpa, .{ val, .Function });
467 const entry = try self.object.uav_link.getOrPut(self.object.gpa, .{ val, .Function });
471468 if (entry.found_existing) {
472469 try self.addFunctionDep(entry.value_ptr.*, .Function);
473470
......@@ -540,7 +537,7 @@ const DeclGen = struct {
540537 return try self.castToGeneric(decl_ptr_ty_id, result_id);
541538 }
542539
543 fn addFunctionDep(self: *DeclGen, decl_index: SpvModule.Decl.Index, storage_class: StorageClass) !void {
540 fn addFunctionDep(self: *NavGen, decl_index: SpvModule.Decl.Index, storage_class: StorageClass) !void {
544541 const target = self.getTarget();
545542 if (target.os.tag == .vulkan) {
546543 // Shader entry point dependencies must be variables with Input or Output storage class
......@@ -555,7 +552,7 @@ const DeclGen = struct {
555552 }
556553 }
557554
558 fn castToGeneric(self: *DeclGen, type_id: IdRef, ptr_id: IdRef) !IdRef {
555 fn castToGeneric(self: *NavGen, type_id: IdRef, ptr_id: IdRef) !IdRef {
559556 const target = self.getTarget();
560557
561558 if (target.os.tag == .vulkan) {
......@@ -575,7 +572,7 @@ const DeclGen = struct {
575572 /// block we are currently generating.
576573 /// Note that there is no such thing as nested blocks like in ZIR or AIR, so we don't need to
577574 /// keep track of the previous block.
578 fn beginSpvBlock(self: *DeclGen, label: IdResult) !void {
575 fn beginSpvBlock(self: *NavGen, label: IdResult) !void {
579576 try self.func.body.emit(self.spv.gpa, .OpLabel, .{ .id_result = label });
580577 self.current_block_label = label;
581578 }
......@@ -590,7 +587,7 @@ const DeclGen = struct {
590587 /// TODO: The extension SPV_INTEL_arbitrary_precision_integers allows any integer size (at least up to 32 bits).
591588 /// TODO: This probably needs an ABI-version as well (especially in combination with SPV_INTEL_arbitrary_precision_integers).
592589 /// TODO: Should the result of this function be cached?
593 fn backingIntBits(self: *DeclGen, bits: u16) ?u16 {
590 fn backingIntBits(self: *NavGen, bits: u16) ?u16 {
594591 const target = self.getTarget();
595592
596593 // The backend will never be asked to compiler a 0-bit integer, so we won't have to handle those in this function.
......@@ -625,7 +622,7 @@ const DeclGen = struct {
625622 /// In theory that could also be used, but since the spec says that it only guarantees support up to 32-bit ints there
626623 /// is no way of knowing whether those are actually supported.
627624 /// TODO: Maybe this should be cached?
628 fn largestSupportedIntBits(self: *DeclGen) u16 {
625 fn largestSupportedIntBits(self: *NavGen) u16 {
629626 const target = self.getTarget();
630627 return if (Target.spirv.featureSetHas(target.cpu.features, .Int64))
631628 64
......@@ -636,12 +633,12 @@ const DeclGen = struct {
636633 /// Checks whether the type is "composite int", an integer consisting of multiple native integers. These are represented by
637634 /// arrays of largestSupportedIntBits().
638635 /// Asserts `ty` is an integer.
639 fn isCompositeInt(self: *DeclGen, ty: Type) bool {
636 fn isCompositeInt(self: *NavGen, ty: Type) bool {
640637 return self.backingIntBits(ty) == null;
641638 }
642639
643640 /// Checks whether the type can be directly translated to SPIR-V vectors
644 fn isSpvVector(self: *DeclGen, ty: Type) bool {
641 fn isSpvVector(self: *NavGen, ty: Type) bool {
645642 const mod = self.pt.zcu;
646643 const target = self.getTarget();
647644 if (ty.zigTypeTag(mod) != .Vector) return false;
......@@ -667,7 +664,7 @@ const DeclGen = struct {
667664 return is_scalar and (spirv_len or opencl_len);
668665 }
669666
670 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo {
667 fn arithmeticTypeInfo(self: *NavGen, ty: Type) ArithmeticTypeInfo {
671668 const mod = self.pt.zcu;
672669 const target = self.getTarget();
673670 var scalar_ty = ty.scalarType(mod);
......@@ -715,7 +712,7 @@ const DeclGen = struct {
715712 }
716713
717714 /// Emits a bool constant in a particular representation.
718 fn constBool(self: *DeclGen, value: bool, repr: Repr) !IdRef {
715 fn constBool(self: *NavGen, value: bool, repr: Repr) !IdRef {
719716 // TODO: Cache?
720717
721718 const section = &self.spv.sections.types_globals_constants;
......@@ -742,7 +739,7 @@ const DeclGen = struct {
742739 /// Emits an integer constant.
743740 /// This function, unlike SpvModule.constInt, takes care to bitcast
744741 /// the value to an unsigned int first for Kernels.
745 fn constInt(self: *DeclGen, ty: Type, value: anytype, repr: Repr) !IdRef {
742 fn constInt(self: *NavGen, ty: Type, value: anytype, repr: Repr) !IdRef {
746743 // TODO: Cache?
747744 const mod = self.pt.zcu;
748745 const scalar_ty = ty.scalarType(mod);
......@@ -809,7 +806,7 @@ const DeclGen = struct {
809806 /// ty must be a struct type.
810807 /// Constituents should be in `indirect` representation (as the elements of a struct should be).
811808 /// Result is in `direct` representation.
812 fn constructStruct(self: *DeclGen, ty: Type, types: []const Type, constituents: []const IdRef) !IdRef {
809 fn constructStruct(self: *NavGen, ty: Type, types: []const Type, constituents: []const IdRef) !IdRef {
813810 assert(types.len == constituents.len);
814811
815812 const result_id = self.spv.allocId();
......@@ -823,7 +820,7 @@ const DeclGen = struct {
823820
824821 /// Construct a vector at runtime.
825822 /// ty must be an vector type.
826 fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef {
823 fn constructVector(self: *NavGen, ty: Type, constituents: []const IdRef) !IdRef {
827824 const mod = self.pt.zcu;
828825 assert(ty.vectorLen(mod) == constituents.len);
829826
......@@ -847,7 +844,7 @@ const DeclGen = struct {
847844
848845 /// Construct a vector at runtime with all lanes set to the same value.
849846 /// ty must be an vector type.
850 fn constructVectorSplat(self: *DeclGen, ty: Type, constituent: IdRef) !IdRef {
847 fn constructVectorSplat(self: *NavGen, ty: Type, constituent: IdRef) !IdRef {
851848 const mod = self.pt.zcu;
852849 const n = ty.vectorLen(mod);
853850
......@@ -862,7 +859,7 @@ const DeclGen = struct {
862859 /// ty must be an array type.
863860 /// Constituents should be in `indirect` representation (as the elements of an array should be).
864861 /// Result is in `direct` representation.
865 fn constructArray(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef {
862 fn constructArray(self: *NavGen, ty: Type, constituents: []const IdRef) !IdRef {
866863 const result_id = self.spv.allocId();
867864 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
868865 .id_result_type = try self.resolveType(ty, .direct),
......@@ -878,7 +875,7 @@ const DeclGen = struct {
878875 /// is done by emitting a sequence of instructions that initialize the value.
879876 //
880877 /// This function should only be called during function code generation.
881 fn constant(self: *DeclGen, ty: Type, val: Value, repr: Repr) !IdRef {
878 fn constant(self: *NavGen, ty: Type, val: Value, repr: Repr) !IdRef {
882879 // Note: Using intern_map can only be used with constants that DO NOT generate any runtime code!!
883880 // Ideally that should be all constants in the future, or it should be cleaned up somehow. For
884881 // now, only use the intern_map on case-by-case basis by breaking to :cache.
......@@ -922,7 +919,7 @@ const DeclGen = struct {
922919 .undef => unreachable, // handled above
923920
924921 .variable,
925 .extern_func,
922 .@"extern",
926923 .func,
927924 .enum_literal,
928925 .empty_enum_value,
......@@ -1142,7 +1139,7 @@ const DeclGen = struct {
11421139 return cacheable_id;
11431140 }
11441141
1145 fn constantPtr(self: *DeclGen, ptr_val: Value) Error!IdRef {
1142 fn constantPtr(self: *NavGen, ptr_val: Value) Error!IdRef {
11461143 // TODO: Caching??
11471144
11481145 const pt = self.pt;
......@@ -1160,7 +1157,7 @@ const DeclGen = struct {
11601157 return self.derivePtr(derivation);
11611158 }
11621159
1163 fn derivePtr(self: *DeclGen, derivation: Value.PointerDeriveStep) Error!IdRef {
1160 fn derivePtr(self: *NavGen, derivation: Value.PointerDeriveStep) Error!IdRef {
11641161 const pt = self.pt;
11651162 const zcu = pt.zcu;
11661163 switch (derivation) {
......@@ -1178,13 +1175,13 @@ const DeclGen = struct {
11781175 });
11791176 return result_ptr_id;
11801177 },
1181 .decl_ptr => |decl| {
1182 const result_ptr_ty = try zcu.declPtr(decl).declPtrType(pt);
1183 return self.constantDeclRef(result_ptr_ty, decl);
1178 .nav_ptr => |nav| {
1179 const result_ptr_ty = try pt.navPtrType(nav);
1180 return self.constantNavRef(result_ptr_ty, nav);
11841181 },
1185 .anon_decl_ptr => |ad| {
1186 const result_ptr_ty = Type.fromInterned(ad.orig_ty);
1187 return self.constantAnonDeclRef(result_ptr_ty, ad);
1182 .uav_ptr => |uav| {
1183 const result_ptr_ty = Type.fromInterned(uav.orig_ty);
1184 return self.constantUavRef(result_ptr_ty, uav);
11881185 },
11891186 .eu_payload_ptr => @panic("TODO"),
11901187 .opt_payload_ptr => @panic("TODO"),
......@@ -1227,10 +1224,10 @@ const DeclGen = struct {
12271224 }
12281225 }
12291226
1230 fn constantAnonDeclRef(
1231 self: *DeclGen,
1227 fn constantUavRef(
1228 self: *NavGen,
12321229 ty: Type,
1233 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,
1230 uav: InternPool.Key.Ptr.BaseAddr.Uav,
12341231 ) !IdRef {
12351232 // TODO: Merge this function with constantDeclRef.
12361233
......@@ -1238,31 +1235,24 @@ const DeclGen = struct {
12381235 const mod = pt.zcu;
12391236 const ip = &mod.intern_pool;
12401237 const ty_id = try self.resolveType(ty, .direct);
1241 const decl_val = anon_decl.val;
1242 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
1238 const uav_ty = Type.fromInterned(ip.typeOf(uav.val));
12431239
1244 if (Value.fromInterned(decl_val).getFunction(mod)) |func| {
1245 _ = func;
1246 unreachable; // TODO
1247 } else if (Value.fromInterned(decl_val).getExternFunc(mod)) |func| {
1248 _ = func;
1249 unreachable;
1240 switch (ip.indexToKey(uav.val)) {
1241 .func => unreachable, // TODO
1242 .@"extern" => assert(!ip.isFunctionType(uav_ty.toIntern())),
1243 else => {},
12501244 }
12511245
12521246 // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
1253 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1254 // Pointer to nothing - return undefoined
1247 if (!uav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1248 // Pointer to nothing - return undefined
12551249 return self.spv.constUndef(ty_id);
12561250 }
12571251
1258 if (decl_ty.zigTypeTag(mod) == .Fn) {
1259 unreachable; // TODO
1260 }
1261
1262 // Anon decl refs are always generic.
1252 // Uav refs are always generic.
12631253 assert(ty.ptrAddressSpace(mod) == .generic);
1264 const decl_ptr_ty_id = try self.ptrType(decl_ty, .Generic);
1265 const ptr_id = try self.resolveAnonDecl(decl_val);
1254 const decl_ptr_ty_id = try self.ptrType(uav_ty, .Generic);
1255 const ptr_id = try self.resolveUav(uav.val);
12661256
12671257 if (decl_ptr_ty_id != ty_id) {
12681258 // Differing pointer types, insert a cast.
......@@ -1278,28 +1268,31 @@ const DeclGen = struct {
12781268 }
12791269 }
12801270
1281 fn constantDeclRef(self: *DeclGen, ty: Type, decl_index: InternPool.DeclIndex) !IdRef {
1271 fn constantNavRef(self: *NavGen, ty: Type, nav_index: InternPool.Nav.Index) !IdRef {
12821272 const pt = self.pt;
12831273 const mod = pt.zcu;
1274 const ip = &mod.intern_pool;
12841275 const ty_id = try self.resolveType(ty, .direct);
1285 const decl = mod.declPtr(decl_index);
1276 const nav = ip.getNav(nav_index);
1277 const nav_val = mod.navValue(nav_index);
1278 const nav_ty = nav_val.typeOf(mod);
12861279
1287 switch (mod.intern_pool.indexToKey(decl.val.ip_index)) {
1280 switch (ip.indexToKey(nav_val.toIntern())) {
12881281 .func => {
12891282 // TODO: Properly lower function pointers. For now we are going to hack around it and
12901283 // just generate an empty pointer. Function pointers are represented by a pointer to usize.
12911284 return try self.spv.constUndef(ty_id);
12921285 },
1293 .extern_func => unreachable, // TODO
1286 .@"extern" => assert(!ip.isFunctionType(nav_ty.toIntern())), // TODO
12941287 else => {},
12951288 }
12961289
1297 if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1290 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
12981291 // Pointer to nothing - return undefined.
12991292 return self.spv.constUndef(ty_id);
13001293 }
13011294
1302 const spv_decl_index = try self.object.resolveDecl(mod, decl_index);
1295 const spv_decl_index = try self.object.resolveNav(mod, nav_index);
13031296 const spv_decl = self.spv.declPtr(spv_decl_index);
13041297
13051298 const decl_id = switch (spv_decl.kind) {
......@@ -1307,10 +1300,10 @@ const DeclGen = struct {
13071300 .global, .invocation_global => spv_decl.result_id,
13081301 };
13091302
1310 const final_storage_class = self.spvStorageClass(decl.@"addrspace");
1303 const final_storage_class = self.spvStorageClass(nav.status.resolved.@"addrspace");
13111304 try self.addFunctionDep(spv_decl_index, final_storage_class);
13121305
1313 const decl_ptr_ty_id = try self.ptrType(decl.typeOf(mod), final_storage_class);
1306 const decl_ptr_ty_id = try self.ptrType(nav_ty, final_storage_class);
13141307
13151308 const ptr_id = switch (final_storage_class) {
13161309 .Generic => try self.castToGeneric(decl_ptr_ty_id, decl_id),
......@@ -1332,7 +1325,7 @@ const DeclGen = struct {
13321325 }
13331326
13341327 // Turn a Zig type's name into a cache reference.
1335 fn resolveTypeName(self: *DeclGen, ty: Type) ![]const u8 {
1328 fn resolveTypeName(self: *NavGen, ty: Type) ![]const u8 {
13361329 var name = std.ArrayList(u8).init(self.gpa);
13371330 defer name.deinit();
13381331 try ty.print(name.writer(), self.pt);
......@@ -1343,7 +1336,7 @@ const DeclGen = struct {
13431336 /// The integer type that is returned by this function is the type that is used to perform
13441337 /// actual operations (as well as store) a Zig type of a particular number of bits. To create
13451338 /// a type with an exact size, use SpvModule.intType.
1346 fn intType(self: *DeclGen, signedness: std.builtin.Signedness, bits: u16) !IdRef {
1339 fn intType(self: *NavGen, signedness: std.builtin.Signedness, bits: u16) !IdRef {
13471340 const backing_bits = self.backingIntBits(bits) orelse {
13481341 // TODO: Integers too big for any native type are represented as "composite integers":
13491342 // An array of largestSupportedIntBits.
......@@ -1358,7 +1351,7 @@ const DeclGen = struct {
13581351 return self.spv.intType(.unsigned, backing_bits);
13591352 }
13601353
1361 fn arrayType(self: *DeclGen, len: u32, child_ty: IdRef) !IdRef {
1354 fn arrayType(self: *NavGen, len: u32, child_ty: IdRef) !IdRef {
13621355 // TODO: Cache??
13631356 const len_id = try self.constInt(Type.u32, len, .direct);
13641357 const result_id = self.spv.allocId();
......@@ -1371,11 +1364,11 @@ const DeclGen = struct {
13711364 return result_id;
13721365 }
13731366
1374 fn ptrType(self: *DeclGen, child_ty: Type, storage_class: StorageClass) !IdRef {
1367 fn ptrType(self: *NavGen, child_ty: Type, storage_class: StorageClass) !IdRef {
13751368 return try self.ptrType2(child_ty, storage_class, .indirect);
13761369 }
13771370
1378 fn ptrType2(self: *DeclGen, child_ty: Type, storage_class: StorageClass, child_repr: Repr) !IdRef {
1371 fn ptrType2(self: *NavGen, child_ty: Type, storage_class: StorageClass, child_repr: Repr) !IdRef {
13791372 const key = .{ child_ty.toIntern(), storage_class, child_repr };
13801373 const entry = try self.ptr_types.getOrPut(self.gpa, key);
13811374 if (entry.found_existing) {
......@@ -1407,7 +1400,7 @@ const DeclGen = struct {
14071400 return result_id;
14081401 }
14091402
1410 fn functionType(self: *DeclGen, return_ty: Type, param_types: []const Type) !IdRef {
1403 fn functionType(self: *NavGen, return_ty: Type, param_types: []const Type) !IdRef {
14111404 // TODO: Cache??
14121405
14131406 const param_ids = try self.gpa.alloc(IdRef, param_types.len);
......@@ -1427,7 +1420,7 @@ const DeclGen = struct {
14271420 return ty_id;
14281421 }
14291422
1430 fn zigScalarOrVectorTypeLike(self: *DeclGen, new_ty: Type, base_ty: Type) !Type {
1423 fn zigScalarOrVectorTypeLike(self: *NavGen, new_ty: Type, base_ty: Type) !Type {
14311424 const pt = self.pt;
14321425 const new_scalar_ty = new_ty.scalarType(pt.zcu);
14331426 if (!base_ty.isVector(pt.zcu)) {
......@@ -1458,7 +1451,7 @@ const DeclGen = struct {
14581451 /// padding: [padding_size]u8,
14591452 /// }
14601453 /// If any of the fields' size is 0, it will be omitted.
1461 fn resolveUnionType(self: *DeclGen, ty: Type) !IdRef {
1454 fn resolveUnionType(self: *NavGen, ty: Type) !IdRef {
14621455 const mod = self.pt.zcu;
14631456 const ip = &mod.intern_pool;
14641457 const union_obj = mod.typeToUnion(ty).?;
......@@ -1509,7 +1502,7 @@ const DeclGen = struct {
15091502 return result_id;
15101503 }
15111504
1512 fn resolveFnReturnType(self: *DeclGen, ret_ty: Type) !IdRef {
1505 fn resolveFnReturnType(self: *NavGen, ret_ty: Type) !IdRef {
15131506 const pt = self.pt;
15141507 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
15151508 // If the return type is an error set or an error union, then we make this
......@@ -1526,7 +1519,7 @@ const DeclGen = struct {
15261519 }
15271520
15281521 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
1529 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef {
1522 fn resolveType(self: *NavGen, ty: Type, repr: Repr) Error!IdRef {
15301523 if (self.intern_map.get(.{ ty.toIntern(), repr })) |id| {
15311524 return id;
15321525 }
......@@ -1536,7 +1529,7 @@ const DeclGen = struct {
15361529 return id;
15371530 }
15381531
1539 fn resolveTypeInner(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef {
1532 fn resolveTypeInner(self: *NavGen, ty: Type, repr: Repr) Error!IdRef {
15401533 const pt = self.pt;
15411534 const mod = pt.zcu;
15421535 const ip = &mod.intern_pool;
......@@ -1839,7 +1832,7 @@ const DeclGen = struct {
18391832 }
18401833 }
18411834
1842 fn spvStorageClass(self: *DeclGen, as: std.builtin.AddressSpace) StorageClass {
1835 fn spvStorageClass(self: *NavGen, as: std.builtin.AddressSpace) StorageClass {
18431836 const target = self.getTarget();
18441837 return switch (as) {
18451838 .generic => switch (target.os.tag) {
......@@ -1882,7 +1875,7 @@ const DeclGen = struct {
18821875 }
18831876 };
18841877
1885 fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout {
1878 fn errorUnionLayout(self: *NavGen, payload_ty: Type) ErrorUnionLayout {
18861879 const pt = self.pt;
18871880
18881881 const error_align = Type.anyerror.abiAlignment(pt);
......@@ -1913,7 +1906,7 @@ const DeclGen = struct {
19131906 total_fields: u32,
19141907 };
19151908
1916 fn unionLayout(self: *DeclGen, ty: Type) UnionLayout {
1909 fn unionLayout(self: *NavGen, ty: Type) UnionLayout {
19171910 const pt = self.pt;
19181911 const mod = pt.zcu;
19191912 const ip = &mod.intern_pool;
......@@ -2004,25 +1997,25 @@ const DeclGen = struct {
20041997 return .{ .ty = ty, .value = .{ .singleton = singleton } };
20051998 }
20061999
2007 fn materialize(self: Temporary, dg: *DeclGen) !IdResult {
2008 const mod = dg.pt.zcu;
2000 fn materialize(self: Temporary, ng: *NavGen) !IdResult {
2001 const mod = ng.pt.zcu;
20092002 switch (self.value) {
20102003 .singleton => |id| return id,
20112004 .exploded_vector => |range| {
20122005 assert(self.ty.isVector(mod));
20132006 assert(self.ty.vectorLen(mod) == range.len);
2014 const consituents = try dg.gpa.alloc(IdRef, range.len);
2015 defer dg.gpa.free(consituents);
2007 const consituents = try ng.gpa.alloc(IdRef, range.len);
2008 defer ng.gpa.free(consituents);
20162009 for (consituents, 0..range.len) |*id, i| {
20172010 id.* = range.at(i);
20182011 }
2019 return dg.constructVector(self.ty, consituents);
2012 return ng.constructVector(self.ty, consituents);
20202013 },
20212014 }
20222015 }
20232016
2024 fn vectorization(self: Temporary, dg: *DeclGen) Vectorization {
2025 return Vectorization.fromType(self.ty, dg);
2017 fn vectorization(self: Temporary, ng: *NavGen) Vectorization {
2018 return Vectorization.fromType(self.ty, ng);
20262019 }
20272020
20282021 fn pun(self: Temporary, new_ty: Type) Temporary {
......@@ -2034,8 +2027,8 @@ const DeclGen = struct {
20342027
20352028 /// 'Explode' a temporary into separate elements. This turns a vector
20362029 /// into a bag of elements.
2037 fn explode(self: Temporary, dg: *DeclGen) !IdRange {
2038 const mod = dg.pt.zcu;
2030 fn explode(self: Temporary, ng: *NavGen) !IdRange {
2031 const mod = ng.pt.zcu;
20392032
20402033 // If the value is a scalar, then this is a no-op.
20412034 if (!self.ty.isVector(mod)) {
......@@ -2045,9 +2038,9 @@ const DeclGen = struct {
20452038 };
20462039 }
20472040
2048 const ty_id = try dg.resolveType(self.ty.scalarType(mod), .direct);
2041 const ty_id = try ng.resolveType(self.ty.scalarType(mod), .direct);
20492042 const n = self.ty.vectorLen(mod);
2050 const results = dg.spv.allocIds(n);
2043 const results = ng.spv.allocIds(n);
20512044
20522045 const id = switch (self.value) {
20532046 .singleton => |id| id,
......@@ -2056,7 +2049,7 @@ const DeclGen = struct {
20562049
20572050 for (0..n) |i| {
20582051 const indexes = [_]u32{@intCast(i)};
2059 try dg.func.body.emit(dg.spv.gpa, .OpCompositeExtract, .{
2052 try ng.func.body.emit(ng.spv.gpa, .OpCompositeExtract, .{
20602053 .id_result_type = ty_id,
20612054 .id_result = results.at(i),
20622055 .composite = id,
......@@ -2069,7 +2062,7 @@ const DeclGen = struct {
20692062 };
20702063
20712064 /// Initialize a `Temporary` from an AIR value.
2072 fn temporary(self: *DeclGen, inst: Air.Inst.Ref) !Temporary {
2065 fn temporary(self: *NavGen, inst: Air.Inst.Ref) !Temporary {
20732066 return .{
20742067 .ty = self.typeOf(inst),
20752068 .value = .{ .singleton = try self.resolve(inst) },
......@@ -2093,11 +2086,11 @@ const DeclGen = struct {
20932086 /// Derive a vectorization from a particular type. This usually
20942087 /// only checks the size, but the source-of-truth is implemented
20952088 /// by `isSpvVector()`.
2096 fn fromType(ty: Type, dg: *DeclGen) Vectorization {
2097 const mod = dg.pt.zcu;
2089 fn fromType(ty: Type, ng: *NavGen) Vectorization {
2090 const mod = ng.pt.zcu;
20982091 if (!ty.isVector(mod)) {
20992092 return .scalar;
2100 } else if (dg.isSpvVector(ty)) {
2093 } else if (ng.isSpvVector(ty)) {
21012094 return .{ .spv_vectorized = ty.vectorLen(mod) };
21022095 } else {
21032096 return .{ .unrolled = ty.vectorLen(mod) };
......@@ -2169,8 +2162,8 @@ const DeclGen = struct {
21692162
21702163 /// Turns `ty` into the result-type of an individual vector operation.
21712164 /// `ty` may be a scalar or vector, it doesn't matter.
2172 fn operationType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {
2173 const pt = dg.pt;
2165 fn operationType(self: Vectorization, ng: *NavGen, ty: Type) !Type {
2166 const pt = ng.pt;
21742167 const scalar_ty = ty.scalarType(pt.zcu);
21752168 return switch (self) {
21762169 .scalar, .unrolled => scalar_ty,
......@@ -2183,8 +2176,8 @@ const DeclGen = struct {
21832176
21842177 /// Turns `ty` into the result-type of the entire operation.
21852178 /// `ty` may be a scalar or vector, it doesn't matter.
2186 fn resultType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {
2187 const pt = dg.pt;
2179 fn resultType(self: Vectorization, ng: *NavGen, ty: Type) !Type {
2180 const pt = ng.pt;
21882181 const scalar_ty = ty.scalarType(pt.zcu);
21892182 return switch (self) {
21902183 .scalar => scalar_ty,
......@@ -2198,10 +2191,10 @@ const DeclGen = struct {
21982191 /// Before a temporary can be used, some setup may need to be one. This function implements
21992192 /// this setup, and returns a new type that holds the relevant information on how to access
22002193 /// elements of the input.
2201 fn prepare(self: Vectorization, dg: *DeclGen, tmp: Temporary) !PreparedOperand {
2202 const pt = dg.pt;
2194 fn prepare(self: Vectorization, ng: *NavGen, tmp: Temporary) !PreparedOperand {
2195 const pt = ng.pt;
22032196 const is_vector = tmp.ty.isVector(pt.zcu);
2204 const is_spv_vector = dg.isSpvVector(tmp.ty);
2197 const is_spv_vector = ng.isSpvVector(tmp.ty);
22052198 const value: PreparedOperand.Value = switch (tmp.value) {
22062199 .singleton => |id| switch (self) {
22072200 .scalar => blk: {
......@@ -2220,7 +2213,7 @@ const DeclGen = struct {
22202213 .child = tmp.ty.toIntern(),
22212214 });
22222215
2223 const vector = try dg.constructVectorSplat(vector_ty, id);
2216 const vector = try ng.constructVectorSplat(vector_ty, id);
22242217 return .{
22252218 .ty = vector_ty,
22262219 .value = .{ .spv_vectorwise = vector },
......@@ -2228,7 +2221,7 @@ const DeclGen = struct {
22282221 },
22292222 .unrolled => blk: {
22302223 if (is_vector) {
2231 break :blk .{ .vector_exploded = try tmp.explode(dg) };
2224 break :blk .{ .vector_exploded = try tmp.explode(ng) };
22322225 } else {
22332226 break :blk .{ .scalar_broadcast = id };
22342227 }
......@@ -2243,7 +2236,7 @@ const DeclGen = struct {
22432236 // a type that cannot do that.
22442237 assert(is_spv_vector);
22452238 assert(range.len == n);
2246 const vec = try tmp.materialize(dg);
2239 const vec = try tmp.materialize(ng);
22472240 break :blk .{ .spv_vectorwise = vec };
22482241 },
22492242 .unrolled => |n| blk: {
......@@ -2324,7 +2317,7 @@ const DeclGen = struct {
23242317 /// - A `Vectorization` instance
23252318 /// - A Type, in which case the vectorization is computed via `Vectorization.fromType`.
23262319 /// - A Temporary, in which case the vectorization is computed via `Temporary.vectorization`.
2327 fn vectorization(self: *DeclGen, args: anytype) Vectorization {
2320 fn vectorization(self: *NavGen, args: anytype) Vectorization {
23282321 var v: Vectorization = undefined;
23292322 assert(args.len >= 1);
23302323 inline for (args, 0..) |arg, i| {
......@@ -2345,7 +2338,7 @@ const DeclGen = struct {
23452338
23462339 /// This function builds an OpSConvert of OpUConvert depending on the
23472340 /// signedness of the types.
2348 fn buildIntConvert(self: *DeclGen, dst_ty: Type, src: Temporary) !Temporary {
2341 fn buildIntConvert(self: *NavGen, dst_ty: Type, src: Temporary) !Temporary {
23492342 const mod = self.pt.zcu;
23502343
23512344 const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct);
......@@ -2384,7 +2377,7 @@ const DeclGen = struct {
23842377 return v.finalize(result_ty, results);
23852378 }
23862379
2387 fn buildFma(self: *DeclGen, a: Temporary, b: Temporary, c: Temporary) !Temporary {
2380 fn buildFma(self: *NavGen, a: Temporary, b: Temporary, c: Temporary) !Temporary {
23882381 const target = self.getTarget();
23892382
23902383 const v = self.vectorization(.{ a, b, c });
......@@ -2424,7 +2417,7 @@ const DeclGen = struct {
24242417 return v.finalize(result_ty, results);
24252418 }
24262419
2427 fn buildSelect(self: *DeclGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary {
2420 fn buildSelect(self: *NavGen, condition: Temporary, lhs: Temporary, rhs: Temporary) !Temporary {
24282421 const mod = self.pt.zcu;
24292422
24302423 const v = self.vectorization(.{ condition, lhs, rhs });
......@@ -2475,7 +2468,7 @@ const DeclGen = struct {
24752468 f_oge,
24762469 };
24772470
2478 fn buildCmp(self: *DeclGen, pred: CmpPredicate, lhs: Temporary, rhs: Temporary) !Temporary {
2471 fn buildCmp(self: *NavGen, pred: CmpPredicate, lhs: Temporary, rhs: Temporary) !Temporary {
24792472 const v = self.vectorization(.{ lhs, rhs });
24802473 const ops = v.operations();
24812474 const results = self.spv.allocIds(ops);
......@@ -2543,7 +2536,7 @@ const DeclGen = struct {
25432536 log10,
25442537 };
25452538
2546 fn buildUnary(self: *DeclGen, op: UnaryOp, operand: Temporary) !Temporary {
2539 fn buildUnary(self: *NavGen, op: UnaryOp, operand: Temporary) !Temporary {
25472540 const target = self.getTarget();
25482541 const v = blk: {
25492542 const v = self.vectorization(.{operand});
......@@ -2673,7 +2666,7 @@ const DeclGen = struct {
26732666 l_or,
26742667 };
26752668
2676 fn buildBinary(self: *DeclGen, op: BinaryOp, lhs: Temporary, rhs: Temporary) !Temporary {
2669 fn buildBinary(self: *NavGen, op: BinaryOp, lhs: Temporary, rhs: Temporary) !Temporary {
26772670 const target = self.getTarget();
26782671
26792672 const v = self.vectorization(.{ lhs, rhs });
......@@ -2762,7 +2755,7 @@ const DeclGen = struct {
27622755 /// This function builds an extended multiplication, either OpSMulExtended or OpUMulExtended on Vulkan,
27632756 /// or OpIMul and s_mul_hi or u_mul_hi on OpenCL.
27642757 fn buildWideMul(
2765 self: *DeclGen,
2758 self: *NavGen,
27662759 op: enum {
27672760 s_mul_extended,
27682761 u_mul_extended,
......@@ -2893,7 +2886,7 @@ const DeclGen = struct {
28932886 /// OpFunctionEnd
28942887 /// TODO is to also write out the error as a function call parameter, and to somehow fetch
28952888 /// the name of an error in the text executor.
2896 fn generateTestEntryPoint(self: *DeclGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void {
2889 fn generateTestEntryPoint(self: *NavGen, name: []const u8, spv_test_decl_index: SpvModule.Decl.Index) !void {
28972890 const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct);
28982891 const ptr_anyerror_ty = try self.pt.ptrType(.{
28992892 .child = Type.anyerror.toIntern(),
......@@ -2946,21 +2939,22 @@ const DeclGen = struct {
29462939 try self.spv.declareEntryPoint(spv_decl_index, test_name, .Kernel);
29472940 }
29482941
2949 fn genDecl(self: *DeclGen) !void {
2942 fn genNav(self: *NavGen) !void {
29502943 const pt = self.pt;
29512944 const mod = pt.zcu;
29522945 const ip = &mod.intern_pool;
2953 const decl = mod.declPtr(self.decl_index);
2954 const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index);
2946 const spv_decl_index = try self.object.resolveNav(mod, self.owner_nav);
29552947 const result_id = self.spv.declPtr(spv_decl_index).result_id;
29562948
2949 const nav = ip.getNav(self.owner_nav);
2950 const val = mod.navValue(self.owner_nav);
2951 const ty = val.typeOf(mod);
29572952 switch (self.spv.declPtr(spv_decl_index).kind) {
29582953 .func => {
2959 assert(decl.typeOf(mod).zigTypeTag(mod) == .Fn);
2960 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
2954 const fn_info = mod.typeToFunc(ty).?;
29612955 const return_ty_id = try self.resolveFnReturnType(Type.fromInterned(fn_info.return_type));
29622956
2963 const prototype_ty_id = try self.resolveType(decl.typeOf(mod), .direct);
2957 const prototype_ty_id = try self.resolveType(ty, .direct);
29642958 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
29652959 .id_result_type = return_ty_id,
29662960 .id_result = result_id,
......@@ -3012,27 +3006,26 @@ const DeclGen = struct {
30123006 // Append the actual code into the functions section.
30133007 try self.spv.addFunction(spv_decl_index, self.func);
30143008
3015 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
3009 try self.spv.debugName(result_id, nav.fqn.toSlice(ip));
30163010
30173011 // Temporarily generate a test kernel declaration if this is a test function.
3018 if (self.pt.zcu.test_functions.contains(self.decl_index)) {
3019 try self.generateTestEntryPoint(decl.fqn.toSlice(ip), spv_decl_index);
3012 if (self.pt.zcu.test_functions.contains(self.owner_nav)) {
3013 try self.generateTestEntryPoint(nav.fqn.toSlice(ip), spv_decl_index);
30203014 }
30213015 },
30223016 .global => {
3023 const maybe_init_val: ?Value = blk: {
3024 if (decl.val.getVariable(mod)) |payload| {
3025 if (payload.is_extern) break :blk null;
3026 break :blk Value.fromInterned(payload.init);
3027 }
3028 break :blk decl.val;
3017 const maybe_init_val: ?Value = switch (ip.indexToKey(val.toIntern())) {
3018 .func => unreachable,
3019 .variable => |variable| Value.fromInterned(variable.init),
3020 .@"extern" => null,
3021 else => val,
30293022 };
30303023 assert(maybe_init_val == null); // TODO
30313024
3032 const final_storage_class = self.spvStorageClass(decl.@"addrspace");
3025 const final_storage_class = self.spvStorageClass(nav.status.resolved.@"addrspace");
30333026 assert(final_storage_class != .Generic); // These should be instance globals
30343027
3035 const ptr_ty_id = try self.ptrType(decl.typeOf(mod), final_storage_class);
3028 const ptr_ty_id = try self.ptrType(ty, final_storage_class);
30363029
30373030 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{
30383031 .id_result_type = ptr_ty_id,
......@@ -3040,21 +3033,20 @@ const DeclGen = struct {
30403033 .storage_class = final_storage_class,
30413034 });
30423035
3043 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
3036 try self.spv.debugName(result_id, nav.fqn.toSlice(ip));
30443037 try self.spv.declareDeclDeps(spv_decl_index, &.{});
30453038 },
30463039 .invocation_global => {
3047 const maybe_init_val: ?Value = blk: {
3048 if (decl.val.getVariable(mod)) |payload| {
3049 if (payload.is_extern) break :blk null;
3050 break :blk Value.fromInterned(payload.init);
3051 }
3052 break :blk decl.val;
3040 const maybe_init_val: ?Value = switch (ip.indexToKey(val.toIntern())) {
3041 .func => unreachable,
3042 .variable => |variable| Value.fromInterned(variable.init),
3043 .@"extern" => null,
3044 else => val,
30533045 };
30543046
30553047 try self.spv.declareDeclDeps(spv_decl_index, &.{});
30563048
3057 const ptr_ty_id = try self.ptrType(decl.typeOf(mod), .Function);
3049 const ptr_ty_id = try self.ptrType(ty, .Function);
30583050
30593051 if (maybe_init_val) |init_val| {
30603052 // TODO: Combine with resolveAnonDecl?
......@@ -3074,7 +3066,7 @@ const DeclGen = struct {
30743066 });
30753067 self.current_block_label = root_block_id;
30763068
3077 const val_id = try self.constant(decl.typeOf(mod), init_val, .indirect);
3069 const val_id = try self.constant(ty, init_val, .indirect);
30783070 try self.func.body.emit(self.spv.gpa, .OpStore, .{
30793071 .pointer = result_id,
30803072 .object = val_id,
......@@ -3084,7 +3076,7 @@ const DeclGen = struct {
30843076 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
30853077 try self.spv.addFunction(spv_decl_index, self.func);
30863078
3087 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{decl.fqn.fmt(ip)});
3079 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{nav.fqn.fmt(ip)});
30883080
30893081 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
30903082 .id_result_type = ptr_ty_id,
......@@ -3106,11 +3098,11 @@ const DeclGen = struct {
31063098 }
31073099 }
31083100
3109 fn intFromBool(self: *DeclGen, value: Temporary) !Temporary {
3101 fn intFromBool(self: *NavGen, value: Temporary) !Temporary {
31103102 return try self.intFromBool2(value, Type.u1);
31113103 }
31123104
3113 fn intFromBool2(self: *DeclGen, value: Temporary, result_ty: Type) !Temporary {
3105 fn intFromBool2(self: *NavGen, value: Temporary, result_ty: Type) !Temporary {
31143106 const zero_id = try self.constInt(result_ty, 0, .direct);
31153107 const one_id = try self.constInt(result_ty, 1, .direct);
31163108
......@@ -3123,7 +3115,7 @@ const DeclGen = struct {
31233115
31243116 /// Convert representation from indirect (in memory) to direct (in 'register')
31253117 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).
3126 fn convertToDirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
3118 fn convertToDirect(self: *NavGen, ty: Type, operand_id: IdRef) !IdRef {
31273119 const mod = self.pt.zcu;
31283120 switch (ty.scalarType(mod).zigTypeTag(mod)) {
31293121 .Bool => {
......@@ -3149,7 +3141,7 @@ const DeclGen = struct {
31493141
31503142 /// Convert representation from direct (in 'register) to direct (in memory)
31513143 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).
3152 fn convertToIndirect(self: *DeclGen, ty: Type, operand_id: IdRef) !IdRef {
3144 fn convertToIndirect(self: *NavGen, ty: Type, operand_id: IdRef) !IdRef {
31533145 const mod = self.pt.zcu;
31543146 switch (ty.scalarType(mod).zigTypeTag(mod)) {
31553147 .Bool => {
......@@ -3160,7 +3152,7 @@ const DeclGen = struct {
31603152 }
31613153 }
31623154
3163 fn extractField(self: *DeclGen, result_ty: Type, object: IdRef, field: u32) !IdRef {
3155 fn extractField(self: *NavGen, result_ty: Type, object: IdRef, field: u32) !IdRef {
31643156 const result_ty_id = try self.resolveType(result_ty, .indirect);
31653157 const result_id = self.spv.allocId();
31663158 const indexes = [_]u32{field};
......@@ -3174,7 +3166,7 @@ const DeclGen = struct {
31743166 return try self.convertToDirect(result_ty, result_id);
31753167 }
31763168
3177 fn extractVectorComponent(self: *DeclGen, result_ty: Type, vector_id: IdRef, field: u32) !IdRef {
3169 fn extractVectorComponent(self: *NavGen, result_ty: Type, vector_id: IdRef, field: u32) !IdRef {
31783170 // Whether this is an OpTypeVector or OpTypeArray, we need to emit the same instruction regardless.
31793171 const result_ty_id = try self.resolveType(result_ty, .direct);
31803172 const result_id = self.spv.allocId();
......@@ -3193,7 +3185,7 @@ const DeclGen = struct {
31933185 is_volatile: bool = false,
31943186 };
31953187
3196 fn load(self: *DeclGen, value_ty: Type, ptr_id: IdRef, options: MemoryOptions) !IdRef {
3188 fn load(self: *NavGen, value_ty: Type, ptr_id: IdRef, options: MemoryOptions) !IdRef {
31973189 const indirect_value_ty_id = try self.resolveType(value_ty, .indirect);
31983190 const result_id = self.spv.allocId();
31993191 const access = spec.MemoryAccess.Extended{
......@@ -3208,7 +3200,7 @@ const DeclGen = struct {
32083200 return try self.convertToDirect(value_ty, result_id);
32093201 }
32103202
3211 fn store(self: *DeclGen, value_ty: Type, ptr_id: IdRef, value_id: IdRef, options: MemoryOptions) !void {
3203 fn store(self: *NavGen, value_ty: Type, ptr_id: IdRef, value_id: IdRef, options: MemoryOptions) !void {
32123204 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);
32133205 const access = spec.MemoryAccess.Extended{
32143206 .Volatile = options.is_volatile,
......@@ -3220,13 +3212,13 @@ const DeclGen = struct {
32203212 });
32213213 }
32223214
3223 fn genBody(self: *DeclGen, body: []const Air.Inst.Index) Error!void {
3215 fn genBody(self: *NavGen, body: []const Air.Inst.Index) Error!void {
32243216 for (body) |inst| {
32253217 try self.genInst(inst);
32263218 }
32273219 }
32283220
3229 fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {
3221 fn genInst(self: *NavGen, inst: Air.Inst.Index) !void {
32303222 const mod = self.pt.zcu;
32313223 const ip = &mod.intern_pool;
32323224 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
......@@ -3397,7 +3389,7 @@ const DeclGen = struct {
33973389 try self.inst_results.putNoClobber(self.gpa, inst, result_id);
33983390 }
33993391
3400 fn airBinOpSimple(self: *DeclGen, inst: Air.Inst.Index, op: BinaryOp) !?IdRef {
3392 fn airBinOpSimple(self: *NavGen, inst: Air.Inst.Index, op: BinaryOp) !?IdRef {
34013393 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34023394 const lhs = try self.temporary(bin_op.lhs);
34033395 const rhs = try self.temporary(bin_op.rhs);
......@@ -3406,7 +3398,7 @@ const DeclGen = struct {
34063398 return try result.materialize(self);
34073399 }
34083400
3409 fn airShift(self: *DeclGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef {
3401 fn airShift(self: *NavGen, inst: Air.Inst.Index, unsigned: BinaryOp, signed: BinaryOp) !?IdRef {
34103402 const mod = self.pt.zcu;
34113403 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34123404
......@@ -3441,7 +3433,7 @@ const DeclGen = struct {
34413433
34423434 const MinMax = enum { min, max };
34433435
3444 fn airMinMax(self: *DeclGen, inst: Air.Inst.Index, op: MinMax) !?IdRef {
3436 fn airMinMax(self: *NavGen, inst: Air.Inst.Index, op: MinMax) !?IdRef {
34453437 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34463438
34473439 const lhs = try self.temporary(bin_op.lhs);
......@@ -3451,7 +3443,7 @@ const DeclGen = struct {
34513443 return try result.materialize(self);
34523444 }
34533445
3454 fn minMax(self: *DeclGen, lhs: Temporary, rhs: Temporary, op: MinMax) !Temporary {
3446 fn minMax(self: *NavGen, lhs: Temporary, rhs: Temporary, op: MinMax) !Temporary {
34553447 const info = self.arithmeticTypeInfo(lhs.ty);
34563448
34573449 const binop: BinaryOp = switch (info.class) {
......@@ -3484,7 +3476,7 @@ const DeclGen = struct {
34843476 /// - Signed integers are also sign extended if they are negative.
34853477 /// All other values are returned unmodified (this makes strange integer
34863478 /// wrapping easier to use in generic operations).
3487 fn normalize(self: *DeclGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary {
3479 fn normalize(self: *NavGen, value: Temporary, info: ArithmeticTypeInfo) !Temporary {
34883480 const mod = self.pt.zcu;
34893481 const ty = value.ty;
34903482 switch (info.class) {
......@@ -3507,7 +3499,7 @@ const DeclGen = struct {
35073499 }
35083500 }
35093501
3510 fn airDivFloor(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3502 fn airDivFloor(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
35113503 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
35123504
35133505 const lhs = try self.temporary(bin_op.lhs);
......@@ -3564,7 +3556,7 @@ const DeclGen = struct {
35643556 }
35653557 }
35663558
3567 fn airDivTrunc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3559 fn airDivTrunc(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
35683560 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
35693561
35703562 const lhs = try self.temporary(bin_op.lhs);
......@@ -3592,7 +3584,7 @@ const DeclGen = struct {
35923584 }
35933585 }
35943586
3595 fn airUnOpSimple(self: *DeclGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef {
3587 fn airUnOpSimple(self: *NavGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef {
35963588 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
35973589 const operand = try self.temporary(un_op);
35983590 const result = try self.buildUnary(op, operand);
......@@ -3600,7 +3592,7 @@ const DeclGen = struct {
36003592 }
36013593
36023594 fn airArithOp(
3603 self: *DeclGen,
3595 self: *NavGen,
36043596 inst: Air.Inst.Index,
36053597 comptime fop: BinaryOp,
36063598 comptime sop: BinaryOp,
......@@ -3626,7 +3618,7 @@ const DeclGen = struct {
36263618 return try result.materialize(self);
36273619 }
36283620
3629 fn airAbs(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3621 fn airAbs(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
36303622 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
36313623 const operand = try self.temporary(ty_op.operand);
36323624 // Note: operand_ty may be signed, while ty is always unsigned!
......@@ -3635,7 +3627,7 @@ const DeclGen = struct {
36353627 return try result.materialize(self);
36363628 }
36373629
3638 fn abs(self: *DeclGen, result_ty: Type, value: Temporary) !Temporary {
3630 fn abs(self: *NavGen, result_ty: Type, value: Temporary) !Temporary {
36393631 const target = self.getTarget();
36403632 const operand_info = self.arithmeticTypeInfo(value.ty);
36413633
......@@ -3658,7 +3650,7 @@ const DeclGen = struct {
36583650 }
36593651
36603652 fn airAddSubOverflow(
3661 self: *DeclGen,
3653 self: *NavGen,
36623654 inst: Air.Inst.Index,
36633655 comptime add: BinaryOp,
36643656 comptime ucmp: CmpPredicate,
......@@ -3724,7 +3716,7 @@ const DeclGen = struct {
37243716 );
37253717 }
37263718
3727 fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3719 fn airMulOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
37283720 const target = self.getTarget();
37293721 const pt = self.pt;
37303722
......@@ -3904,7 +3896,7 @@ const DeclGen = struct {
39043896 );
39053897 }
39063898
3907 fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3899 fn airShlOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
39083900 const mod = self.pt.zcu;
39093901
39103902 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -3944,7 +3936,7 @@ const DeclGen = struct {
39443936 );
39453937 }
39463938
3947 fn airMulAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3939 fn airMulAdd(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
39483940 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
39493941 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
39503942
......@@ -3960,7 +3952,7 @@ const DeclGen = struct {
39603952 return try result.materialize(self);
39613953 }
39623954
3963 fn airClzCtz(self: *DeclGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef {
3955 fn airClzCtz(self: *NavGen, inst: Air.Inst.Index, op: UnaryOp) !?IdRef {
39643956 if (self.liveness.isUnused(inst)) return null;
39653957
39663958 const mod = self.pt.zcu;
......@@ -3991,7 +3983,7 @@ const DeclGen = struct {
39913983 return try result.materialize(self);
39923984 }
39933985
3994 fn airSelect(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3986 fn airSelect(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
39953987 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
39963988 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
39973989 const pred = try self.temporary(pl_op.operand);
......@@ -4002,7 +3994,7 @@ const DeclGen = struct {
40023994 return try result.materialize(self);
40033995 }
40043996
4005 fn airSplat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3997 fn airSplat(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
40063998 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
40073999
40084000 const operand_id = try self.resolve(ty_op.operand);
......@@ -4011,7 +4003,7 @@ const DeclGen = struct {
40114003 return try self.constructVectorSplat(result_ty, operand_id);
40124004 }
40134005
4014 fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4006 fn airReduce(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
40154007 const mod = self.pt.zcu;
40164008 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
40174009 const operand = try self.resolve(reduce.operand);
......@@ -4086,7 +4078,7 @@ const DeclGen = struct {
40864078 return result_id;
40874079 }
40884080
4089 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4081 fn airShuffle(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
40904082 const pt = self.pt;
40914083 const mod = pt.zcu;
40924084 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -4163,7 +4155,7 @@ const DeclGen = struct {
41634155 return try self.constructVector(result_ty, components);
41644156 }
41654157
4166 fn indicesToIds(self: *DeclGen, indices: []const u32) ![]IdRef {
4158 fn indicesToIds(self: *NavGen, indices: []const u32) ![]IdRef {
41674159 const ids = try self.gpa.alloc(IdRef, indices.len);
41684160 errdefer self.gpa.free(ids);
41694161 for (indices, ids) |index, *id| {
......@@ -4174,7 +4166,7 @@ const DeclGen = struct {
41744166 }
41754167
41764168 fn accessChainId(
4177 self: *DeclGen,
4169 self: *NavGen,
41784170 result_ty_id: IdRef,
41794171 base: IdRef,
41804172 indices: []const IdRef,
......@@ -4194,7 +4186,7 @@ const DeclGen = struct {
41944186 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain
41954187 /// is the latter and PtrAccessChain is the former.
41964188 fn accessChain(
4197 self: *DeclGen,
4189 self: *NavGen,
41984190 result_ty_id: IdRef,
41994191 base: IdRef,
42004192 indices: []const u32,
......@@ -4205,7 +4197,7 @@ const DeclGen = struct {
42054197 }
42064198
42074199 fn ptrAccessChain(
4208 self: *DeclGen,
4200 self: *NavGen,
42094201 result_ty_id: IdRef,
42104202 base: IdRef,
42114203 element: IdRef,
......@@ -4225,7 +4217,7 @@ const DeclGen = struct {
42254217 return result_id;
42264218 }
42274219
4228 fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef {
4220 fn ptrAdd(self: *NavGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef {
42294221 const mod = self.pt.zcu;
42304222 const result_ty_id = try self.resolveType(result_ty, .direct);
42314223
......@@ -4246,7 +4238,7 @@ const DeclGen = struct {
42464238 }
42474239 }
42484240
4249 fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4241 fn airPtrAdd(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
42504242 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
42514243 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
42524244 const ptr_id = try self.resolve(bin_op.lhs);
......@@ -4257,7 +4249,7 @@ const DeclGen = struct {
42574249 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);
42584250 }
42594251
4260 fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4252 fn airPtrSub(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
42614253 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
42624254 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
42634255 const ptr_id = try self.resolve(bin_op.lhs);
......@@ -4277,7 +4269,7 @@ const DeclGen = struct {
42774269 }
42784270
42794271 fn cmp(
4280 self: *DeclGen,
4272 self: *NavGen,
42814273 op: std.math.CompareOperator,
42824274 lhs: Temporary,
42834275 rhs: Temporary,
......@@ -4443,7 +4435,7 @@ const DeclGen = struct {
44434435 }
44444436
44454437 fn airCmp(
4446 self: *DeclGen,
4438 self: *NavGen,
44474439 inst: Air.Inst.Index,
44484440 comptime op: std.math.CompareOperator,
44494441 ) !?IdRef {
......@@ -4455,7 +4447,7 @@ const DeclGen = struct {
44554447 return try result.materialize(self);
44564448 }
44574449
4458 fn airVectorCmp(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4450 fn airVectorCmp(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
44594451 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
44604452 const vec_cmp = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
44614453 const lhs = try self.temporary(vec_cmp.lhs);
......@@ -4468,7 +4460,7 @@ const DeclGen = struct {
44684460
44694461 /// Bitcast one type to another. Note: both types, input, output are expected in **direct** representation.
44704462 fn bitCast(
4471 self: *DeclGen,
4463 self: *NavGen,
44724464 dst_ty: Type,
44734465 src_ty: Type,
44744466 src_id: IdRef,
......@@ -4536,7 +4528,7 @@ const DeclGen = struct {
45364528 return result_id;
45374529 }
45384530
4539 fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4531 fn airBitCast(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
45404532 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45414533 const operand_id = try self.resolve(ty_op.operand);
45424534 const operand_ty = self.typeOf(ty_op.operand);
......@@ -4544,7 +4536,7 @@ const DeclGen = struct {
45444536 return try self.bitCast(result_ty, operand_ty, operand_id);
45454537 }
45464538
4547 fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4539 fn airIntCast(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
45484540 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45494541 const src = try self.temporary(ty_op.operand);
45504542 const dst_ty = self.typeOfIndex(inst);
......@@ -4570,7 +4562,7 @@ const DeclGen = struct {
45704562 return try result.materialize(self);
45714563 }
45724564
4573 fn intFromPtr(self: *DeclGen, operand_id: IdRef) !IdRef {
4565 fn intFromPtr(self: *NavGen, operand_id: IdRef) !IdRef {
45744566 const result_type_id = try self.resolveType(Type.usize, .direct);
45754567 const result_id = self.spv.allocId();
45764568 try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{
......@@ -4581,13 +4573,13 @@ const DeclGen = struct {
45814573 return result_id;
45824574 }
45834575
4584 fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4576 fn airIntFromPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
45854577 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
45864578 const operand_id = try self.resolve(un_op);
45874579 return try self.intFromPtr(operand_id);
45884580 }
45894581
4590 fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4582 fn airFloatFromInt(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
45914583 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45924584 const operand_ty = self.typeOf(ty_op.operand);
45934585 const operand_id = try self.resolve(ty_op.operand);
......@@ -4595,7 +4587,7 @@ const DeclGen = struct {
45954587 return try self.floatFromInt(result_ty, operand_ty, operand_id);
45964588 }
45974589
4598 fn floatFromInt(self: *DeclGen, result_ty: Type, operand_ty: Type, operand_id: IdRef) !IdRef {
4590 fn floatFromInt(self: *NavGen, result_ty: Type, operand_ty: Type, operand_id: IdRef) !IdRef {
45994591 const operand_info = self.arithmeticTypeInfo(operand_ty);
46004592 const result_id = self.spv.allocId();
46014593 const result_ty_id = try self.resolveType(result_ty, .direct);
......@@ -4614,14 +4606,14 @@ const DeclGen = struct {
46144606 return result_id;
46154607 }
46164608
4617 fn airIntFromFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4609 fn airIntFromFloat(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
46184610 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46194611 const operand_id = try self.resolve(ty_op.operand);
46204612 const result_ty = self.typeOfIndex(inst);
46214613 return try self.intFromFloat(result_ty, operand_id);
46224614 }
46234615
4624 fn intFromFloat(self: *DeclGen, result_ty: Type, operand_id: IdRef) !IdRef {
4616 fn intFromFloat(self: *NavGen, result_ty: Type, operand_id: IdRef) !IdRef {
46254617 const result_info = self.arithmeticTypeInfo(result_ty);
46264618 const result_ty_id = try self.resolveType(result_ty, .direct);
46274619 const result_id = self.spv.allocId();
......@@ -4640,14 +4632,14 @@ const DeclGen = struct {
46404632 return result_id;
46414633 }
46424634
4643 fn airIntFromBool(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4635 fn airIntFromBool(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
46444636 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
46454637 const operand = try self.temporary(un_op);
46464638 const result = try self.intFromBool(operand);
46474639 return try result.materialize(self);
46484640 }
46494641
4650 fn airFloatCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4642 fn airFloatCast(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
46514643 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46524644 const operand_id = try self.resolve(ty_op.operand);
46534645 const dest_ty = self.typeOfIndex(inst);
......@@ -4662,7 +4654,7 @@ const DeclGen = struct {
46624654 return result_id;
46634655 }
46644656
4665 fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4657 fn airNot(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
46664658 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46674659 const operand = try self.temporary(ty_op.operand);
46684660 const result_ty = self.typeOfIndex(inst);
......@@ -4681,7 +4673,7 @@ const DeclGen = struct {
46814673 return try result.materialize(self);
46824674 }
46834675
4684 fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4676 fn airArrayToSlice(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
46854677 const pt = self.pt;
46864678 const mod = pt.zcu;
46874679 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -4709,7 +4701,7 @@ const DeclGen = struct {
47094701 );
47104702 }
47114703
4712 fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4704 fn airSlice(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
47134705 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
47144706 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
47154707 const ptr_id = try self.resolve(bin_op.lhs);
......@@ -4726,7 +4718,7 @@ const DeclGen = struct {
47264718 );
47274719 }
47284720
4729 fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4721 fn airAggregateInit(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
47304722 const pt = self.pt;
47314723 const mod = pt.zcu;
47324724 const ip = &mod.intern_pool;
......@@ -4816,7 +4808,7 @@ const DeclGen = struct {
48164808 }
48174809 }
48184810
4819 fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {
4811 fn sliceOrArrayLen(self: *NavGen, operand_id: IdRef, ty: Type) !IdRef {
48204812 const pt = self.pt;
48214813 const mod = pt.zcu;
48224814 switch (ty.ptrSize(mod)) {
......@@ -4832,7 +4824,7 @@ const DeclGen = struct {
48324824 }
48334825 }
48344826
4835 fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {
4827 fn sliceOrArrayPtr(self: *NavGen, operand_id: IdRef, ty: Type) !IdRef {
48364828 const mod = self.pt.zcu;
48374829 if (ty.isSlice(mod)) {
48384830 const ptr_ty = ty.slicePtrFieldType(mod);
......@@ -4841,7 +4833,7 @@ const DeclGen = struct {
48414833 return operand_id;
48424834 }
48434835
4844 fn airMemcpy(self: *DeclGen, inst: Air.Inst.Index) !void {
4836 fn airMemcpy(self: *NavGen, inst: Air.Inst.Index) !void {
48454837 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
48464838 const dest_slice = try self.resolve(bin_op.lhs);
48474839 const src_slice = try self.resolve(bin_op.rhs);
......@@ -4857,14 +4849,14 @@ const DeclGen = struct {
48574849 });
48584850 }
48594851
4860 fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {
4852 fn airSliceField(self: *NavGen, inst: Air.Inst.Index, field: u32) !?IdRef {
48614853 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
48624854 const field_ty = self.typeOfIndex(inst);
48634855 const operand_id = try self.resolve(ty_op.operand);
48644856 return try self.extractField(field_ty, operand_id, field);
48654857 }
48664858
4867 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4859 fn airSliceElemPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
48684860 const mod = self.pt.zcu;
48694861 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
48704862 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -4881,7 +4873,7 @@ const DeclGen = struct {
48814873 return try self.ptrAccessChain(ptr_ty_id, slice_ptr, index_id, &.{});
48824874 }
48834875
4884 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4876 fn airSliceElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
48854877 const mod = self.pt.zcu;
48864878 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
48874879 const slice_ty = self.typeOf(bin_op.lhs);
......@@ -4898,7 +4890,7 @@ const DeclGen = struct {
48984890 return try self.load(slice_ty.childType(mod), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(mod) });
48994891 }
49004892
4901 fn ptrElemPtr(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
4893 fn ptrElemPtr(self: *NavGen, ptr_ty: Type, ptr_id: IdRef, index_id: IdRef) !IdRef {
49024894 const mod = self.pt.zcu;
49034895 // Construct new pointer type for the resulting pointer
49044896 const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.
......@@ -4913,7 +4905,7 @@ const DeclGen = struct {
49134905 }
49144906 }
49154907
4916 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4908 fn airPtrElemPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
49174909 const pt = self.pt;
49184910 const mod = pt.zcu;
49194911 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -4931,7 +4923,7 @@ const DeclGen = struct {
49314923 return try self.ptrElemPtr(src_ptr_ty, ptr_id, index_id);
49324924 }
49334925
4934 fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4926 fn airArrayElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
49354927 const mod = self.pt.zcu;
49364928 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
49374929 const array_ty = self.typeOf(bin_op.lhs);
......@@ -4992,7 +4984,7 @@ const DeclGen = struct {
49924984 return try self.convertToDirect(elem_ty, result_id);
49934985 }
49944986
4995 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
4987 fn airPtrElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
49964988 const mod = self.pt.zcu;
49974989 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
49984990 const ptr_ty = self.typeOf(bin_op.lhs);
......@@ -5003,7 +4995,7 @@ const DeclGen = struct {
50034995 return try self.load(elem_ty, elem_ptr_id, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
50044996 }
50054997
5006 fn airVectorStoreElem(self: *DeclGen, inst: Air.Inst.Index) !void {
4998 fn airVectorStoreElem(self: *NavGen, inst: Air.Inst.Index) !void {
50074999 const mod = self.pt.zcu;
50085000 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
50095001 const extra = self.air.extraData(Air.Bin, data.payload).data;
......@@ -5025,7 +5017,7 @@ const DeclGen = struct {
50255017 });
50265018 }
50275019
5028 fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {
5020 fn airSetUnionTag(self: *NavGen, inst: Air.Inst.Index) !void {
50295021 const mod = self.pt.zcu;
50305022 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
50315023 const un_ptr_ty = self.typeOf(bin_op.lhs);
......@@ -5048,7 +5040,7 @@ const DeclGen = struct {
50485040 }
50495041 }
50505042
5051 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5043 fn airGetUnionTag(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
50525044 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
50535045 const un_ty = self.typeOf(ty_op.operand);
50545046
......@@ -5064,7 +5056,7 @@ const DeclGen = struct {
50645056 }
50655057
50665058 fn unionInit(
5067 self: *DeclGen,
5059 self: *NavGen,
50685060 ty: Type,
50695061 active_field: u32,
50705062 payload: ?IdRef,
......@@ -5129,7 +5121,7 @@ const DeclGen = struct {
51295121 return try self.load(ty, tmp_id, .{});
51305122 }
51315123
5132 fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5124 fn airUnionInit(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
51335125 const pt = self.pt;
51345126 const mod = pt.zcu;
51355127 const ip = &mod.intern_pool;
......@@ -5146,7 +5138,7 @@ const DeclGen = struct {
51465138 return try self.unionInit(ty, extra.field_index, payload);
51475139 }
51485140
5149 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5141 fn airStructFieldVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
51505142 const pt = self.pt;
51515143 const mod = pt.zcu;
51525144 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -5191,7 +5183,7 @@ const DeclGen = struct {
51915183 }
51925184 }
51935185
5194 fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5186 fn airFieldParentPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
51955187 const pt = self.pt;
51965188 const mod = pt.zcu;
51975189 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -5225,7 +5217,7 @@ const DeclGen = struct {
52255217 }
52265218
52275219 fn structFieldPtr(
5228 self: *DeclGen,
5220 self: *NavGen,
52295221 result_ptr_ty: Type,
52305222 object_ptr_ty: Type,
52315223 object_ptr: IdRef,
......@@ -5273,7 +5265,7 @@ const DeclGen = struct {
52735265 }
52745266 }
52755267
5276 fn airStructFieldPtrIndex(self: *DeclGen, inst: Air.Inst.Index, field_index: u32) !?IdRef {
5268 fn airStructFieldPtrIndex(self: *NavGen, inst: Air.Inst.Index, field_index: u32) !?IdRef {
52775269 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
52785270 const struct_ptr = try self.resolve(ty_op.operand);
52795271 const struct_ptr_ty = self.typeOf(ty_op.operand);
......@@ -5294,7 +5286,7 @@ const DeclGen = struct {
52945286 // which is in the Generic address space. The variable is actually
52955287 // placed in the Function address space.
52965288 fn alloc(
5297 self: *DeclGen,
5289 self: *NavGen,
52985290 ty: Type,
52995291 options: AllocOptions,
53005292 ) !IdRef {
......@@ -5326,7 +5318,7 @@ const DeclGen = struct {
53265318 }
53275319 }
53285320
5329 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5321 fn airAlloc(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
53305322 const mod = self.pt.zcu;
53315323 const ptr_ty = self.typeOfIndex(inst);
53325324 assert(ptr_ty.ptrAddressSpace(mod) == .generic);
......@@ -5334,7 +5326,7 @@ const DeclGen = struct {
53345326 return try self.alloc(child_ty, .{});
53355327 }
53365328
5337 fn airArg(self: *DeclGen) IdRef {
5329 fn airArg(self: *NavGen) IdRef {
53385330 defer self.next_arg_index += 1;
53395331 return self.args.items[self.next_arg_index];
53405332 }
......@@ -5343,7 +5335,7 @@ const DeclGen = struct {
53435335 /// block to jump to. This function emits instructions, so it should be emitted
53445336 /// inside the merge block of the block.
53455337 /// This function should only be called with structured control flow generation.
5346 fn structuredNextBlock(self: *DeclGen, incoming: []const ControlFlow.Structured.Block.Incoming) !IdRef {
5338 fn structuredNextBlock(self: *NavGen, incoming: []const ControlFlow.Structured.Block.Incoming) !IdRef {
53475339 assert(self.control_flow == .structured);
53485340
53495341 const result_id = self.spv.allocId();
......@@ -5362,7 +5354,7 @@ const DeclGen = struct {
53625354 /// Jumps to the block with the target block-id. This function must only be called when
53635355 /// terminating a body, there should be no instructions after it.
53645356 /// This function should only be called with structured control flow generation.
5365 fn structuredBreak(self: *DeclGen, target_block: IdRef) !void {
5357 fn structuredBreak(self: *NavGen, target_block: IdRef) !void {
53665358 assert(self.control_flow == .structured);
53675359
53685360 const sblock = self.control_flow.structured.block_stack.getLast();
......@@ -5393,7 +5385,7 @@ const DeclGen = struct {
53935385 /// should still be emitted to the block that should follow this structured body.
53945386 /// This function should only be called with structured control flow generation.
53955387 fn genStructuredBody(
5396 self: *DeclGen,
5388 self: *NavGen,
53975389 /// This parameter defines the method that this structured body is exited with.
53985390 block_merge_type: union(enum) {
53995391 /// Using selection; early exits from this body are surrounded with
......@@ -5487,13 +5479,13 @@ const DeclGen = struct {
54875479 }
54885480 }
54895481
5490 fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5482 fn airBlock(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
54915483 const inst_datas = self.air.instructions.items(.data);
54925484 const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);
54935485 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
54945486 }
54955487
5496 fn lowerBlock(self: *DeclGen, inst: Air.Inst.Index, body: []const Air.Inst.Index) !?IdRef {
5488 fn lowerBlock(self: *NavGen, inst: Air.Inst.Index, body: []const Air.Inst.Index) !?IdRef {
54975489 // In AIR, a block doesn't really define an entry point like a block, but
54985490 // more like a scope that breaks can jump out of and "return" a value from.
54995491 // This cannot be directly modelled in SPIR-V, so in a block instruction,
......@@ -5633,7 +5625,7 @@ const DeclGen = struct {
56335625 return null;
56345626 }
56355627
5636 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {
5628 fn airBr(self: *NavGen, inst: Air.Inst.Index) !void {
56375629 const pt = self.pt;
56385630 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
56395631 const operand_ty = self.typeOf(br.operand);
......@@ -5670,7 +5662,7 @@ const DeclGen = struct {
56705662 }
56715663 }
56725664
5673 fn airCondBr(self: *DeclGen, inst: Air.Inst.Index) !void {
5665 fn airCondBr(self: *NavGen, inst: Air.Inst.Index) !void {
56745666 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
56755667 const cond_br = self.air.extraData(Air.CondBr, pl_op.payload);
56765668 const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[cond_br.end..][0..cond_br.data.then_body_len]);
......@@ -5730,7 +5722,7 @@ const DeclGen = struct {
57305722 }
57315723 }
57325724
5733 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {
5725 fn airLoop(self: *NavGen, inst: Air.Inst.Index) !void {
57345726 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
57355727 const loop = self.air.extraData(Air.Block, ty_pl.payload);
57365728 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
......@@ -5777,7 +5769,7 @@ const DeclGen = struct {
57775769 }
57785770 }
57795771
5780 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5772 fn airLoad(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
57815773 const mod = self.pt.zcu;
57825774 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57835775 const ptr_ty = self.typeOf(ty_op.operand);
......@@ -5788,7 +5780,7 @@ const DeclGen = struct {
57885780 return try self.load(elem_ty, operand, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
57895781 }
57905782
5791 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
5783 fn airStore(self: *NavGen, inst: Air.Inst.Index) !void {
57925784 const mod = self.pt.zcu;
57935785 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
57945786 const ptr_ty = self.typeOf(bin_op.lhs);
......@@ -5799,14 +5791,13 @@ const DeclGen = struct {
57995791 try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
58005792 }
58015793
5802 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
5794 fn airRet(self: *NavGen, inst: Air.Inst.Index) !void {
58035795 const pt = self.pt;
58045796 const mod = pt.zcu;
58055797 const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
58065798 const ret_ty = self.typeOf(operand);
58075799 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5808 const decl = mod.declPtr(self.decl_index);
5809 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
5800 const fn_info = mod.typeToFunc(mod.navValue(self.owner_nav).typeOf(mod)).?;
58105801 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
58115802 // Functions with an empty error set are emitted with an error code
58125803 // return type and return zero so they can be function pointers coerced
......@@ -5822,7 +5813,7 @@ const DeclGen = struct {
58225813 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
58235814 }
58245815
5825 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
5816 fn airRetLoad(self: *NavGen, inst: Air.Inst.Index) !void {
58265817 const pt = self.pt;
58275818 const mod = pt.zcu;
58285819 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
......@@ -5830,8 +5821,7 @@ const DeclGen = struct {
58305821 const ret_ty = ptr_ty.childType(mod);
58315822
58325823 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5833 const decl = mod.declPtr(self.decl_index);
5834 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
5824 const fn_info = mod.typeToFunc(mod.navValue(self.owner_nav).typeOf(mod)).?;
58355825 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
58365826 // Functions with an empty error set are emitted with an error code
58375827 // return type and return zero so they can be function pointers coerced
......@@ -5850,7 +5840,7 @@ const DeclGen = struct {
58505840 });
58515841 }
58525842
5853 fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5843 fn airTry(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
58545844 const mod = self.pt.zcu;
58555845 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
58565846 const err_union_id = try self.resolve(pl_op.operand);
......@@ -5920,7 +5910,7 @@ const DeclGen = struct {
59205910 return try self.extractField(payload_ty, err_union_id, eu_layout.payloadFieldIndex());
59215911 }
59225912
5923 fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5913 fn airErrUnionErr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
59245914 const mod = self.pt.zcu;
59255915 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59265916 const operand_id = try self.resolve(ty_op.operand);
......@@ -5943,7 +5933,7 @@ const DeclGen = struct {
59435933 return try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
59445934 }
59455935
5946 fn airErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5936 fn airErrUnionPayload(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
59475937 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59485938 const operand_id = try self.resolve(ty_op.operand);
59495939 const payload_ty = self.typeOfIndex(inst);
......@@ -5956,7 +5946,7 @@ const DeclGen = struct {
59565946 return try self.extractField(payload_ty, operand_id, eu_layout.payloadFieldIndex());
59575947 }
59585948
5959 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5949 fn airWrapErrUnionErr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
59605950 const mod = self.pt.zcu;
59615951 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59625952 const err_union_ty = self.typeOfIndex(inst);
......@@ -5981,7 +5971,7 @@ const DeclGen = struct {
59815971 return try self.constructStruct(err_union_ty, &types, &members);
59825972 }
59835973
5984 fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
5974 fn airWrapErrUnionPayload(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
59855975 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59865976 const err_union_ty = self.typeOfIndex(inst);
59875977 const operand_id = try self.resolve(ty_op.operand);
......@@ -6003,7 +5993,7 @@ const DeclGen = struct {
60035993 return try self.constructStruct(err_union_ty, &types, &members);
60045994 }
60055995
6006 fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef {
5996 fn airIsNull(self: *NavGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef {
60075997 const pt = self.pt;
60085998 const mod = pt.zcu;
60095999 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
......@@ -6080,7 +6070,7 @@ const DeclGen = struct {
60806070 };
60816071 }
60826072
6083 fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef {
6073 fn airIsErr(self: *NavGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef {
60846074 const mod = self.pt.zcu;
60856075 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
60866076 const operand_id = try self.resolve(un_op);
......@@ -6113,7 +6103,7 @@ const DeclGen = struct {
61136103 return result_id;
61146104 }
61156105
6116 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6106 fn airUnwrapOptional(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
61176107 const pt = self.pt;
61186108 const mod = pt.zcu;
61196109 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -6130,7 +6120,7 @@ const DeclGen = struct {
61306120 return try self.extractField(payload_ty, operand_id, 0);
61316121 }
61326122
6133 fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6123 fn airUnwrapOptionalPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
61346124 const pt = self.pt;
61356125 const mod = pt.zcu;
61366126 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -6155,7 +6145,7 @@ const DeclGen = struct {
61556145 return try self.accessChain(result_ty_id, operand_id, &.{0});
61566146 }
61576147
6158 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6148 fn airWrapOptional(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
61596149 const pt = self.pt;
61606150 const mod = pt.zcu;
61616151 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
......@@ -6178,7 +6168,7 @@ const DeclGen = struct {
61786168 return try self.constructStruct(optional_ty, &types, &members);
61796169 }
61806170
6181 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
6171 fn airSwitchBr(self: *NavGen, inst: Air.Inst.Index) !void {
61826172 const pt = self.pt;
61836173 const mod = pt.zcu;
61846174 const target = self.getTarget();
......@@ -6347,16 +6337,15 @@ const DeclGen = struct {
63476337 }
63486338 }
63496339
6350 fn airUnreach(self: *DeclGen) !void {
6340 fn airUnreach(self: *NavGen) !void {
63516341 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
63526342 }
63536343
6354 fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
6344 fn airDbgStmt(self: *NavGen, inst: Air.Inst.Index) !void {
63556345 const pt = self.pt;
63566346 const mod = pt.zcu;
63576347 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
6358 const decl = mod.declPtr(self.decl_index);
6359 const path = decl.getFileScope(mod).sub_file_path;
6348 const path = mod.navFileScope(self.owner_nav).sub_file_path;
63606349 try self.func.body.emit(self.spv.gpa, .OpLine, .{
63616350 .file = try self.spv.resolveString(path),
63626351 .line = self.base_line + dbg_stmt.line + 1,
......@@ -6364,25 +6353,24 @@ const DeclGen = struct {
63646353 });
63656354 }
63666355
6367 fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6356 fn airDbgInlineBlock(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
63686357 const mod = self.pt.zcu;
63696358 const inst_datas = self.air.instructions.items(.data);
63706359 const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload);
6371 const decl = mod.funcOwnerDeclPtr(extra.data.func);
63726360 const old_base_line = self.base_line;
63736361 defer self.base_line = old_base_line;
6374 self.base_line = decl.navSrcLine(mod);
6362 self.base_line = mod.navSrcLine(mod.funcInfo(extra.data.func).owner_nav);
63756363 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
63766364 }
63776365
6378 fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void {
6366 fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void {
63796367 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
63806368 const target_id = try self.resolve(pl_op.operand);
63816369 const name = self.air.nullTerminatedString(pl_op.payload);
63826370 try self.spv.debugName(target_id, name);
63836371 }
63846372
6385 fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6373 fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
63866374 const mod = self.pt.zcu;
63876375 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
63886376 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
......@@ -6465,7 +6453,7 @@ const DeclGen = struct {
64656453 // TODO: Translate proper error locations.
64666454 assert(as.errors.items.len != 0);
64676455 assert(self.error_msg == null);
6468 const src_loc = mod.declPtr(self.decl_index).navSrcLoc(mod);
6456 const src_loc = mod.navSrcLoc(self.owner_nav);
64696457 self.error_msg = try Zcu.ErrorMsg.create(mod.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
64706458 const notes = try mod.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len);
64716459
......@@ -6511,7 +6499,7 @@ const DeclGen = struct {
65116499 return null;
65126500 }
65136501
6514 fn airCall(self: *DeclGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {
6502 fn airCall(self: *NavGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !?IdRef {
65156503 _ = modifier;
65166504
65176505 const pt = self.pt;
......@@ -6566,7 +6554,7 @@ const DeclGen = struct {
65666554 return result_id;
65676555 }
65686556
6569 fn builtin3D(self: *DeclGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef {
6557 fn builtin3D(self: *NavGen, result_ty: Type, builtin: spec.BuiltIn, dimension: u32, out_of_range_value: anytype) !IdRef {
65706558 if (dimension >= 3) {
65716559 return try self.constInt(result_ty, out_of_range_value, .direct);
65726560 }
......@@ -6582,7 +6570,7 @@ const DeclGen = struct {
65826570 return try self.extractVectorComponent(result_ty, vec, dimension);
65836571 }
65846572
6585 fn airWorkItemId(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6573 fn airWorkItemId(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
65866574 if (self.liveness.isUnused(inst)) return null;
65876575 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
65886576 const dimension = pl_op.payload;
......@@ -6593,7 +6581,7 @@ const DeclGen = struct {
65936581 return try result.materialize(self);
65946582 }
65956583
6596 fn airWorkGroupSize(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6584 fn airWorkGroupSize(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
65976585 if (self.liveness.isUnused(inst)) return null;
65986586 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
65996587 const dimension = pl_op.payload;
......@@ -6604,7 +6592,7 @@ const DeclGen = struct {
66046592 return try result.materialize(self);
66056593 }
66066594
6607 fn airWorkGroupId(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
6595 fn airWorkGroupId(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
66086596 if (self.liveness.isUnused(inst)) return null;
66096597 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
66106598 const dimension = pl_op.payload;
......@@ -6615,12 +6603,12 @@ const DeclGen = struct {
66156603 return try result.materialize(self);
66166604 }
66176605
6618 fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {
6606 fn typeOf(self: *NavGen, inst: Air.Inst.Ref) Type {
66196607 const mod = self.pt.zcu;
66206608 return self.air.typeOf(inst, &mod.intern_pool);
66216609 }
66226610
6623 fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type {
6611 fn typeOfIndex(self: *NavGen, inst: Air.Inst.Index) Type {
66246612 const mod = self.pt.zcu;
66256613 return self.air.typeOfIndex(inst, &mod.intern_pool);
66266614 }
src/link.zig+31-57
......@@ -216,8 +216,8 @@ pub const File = struct {
216216 }
217217 }
218218
219 pub fn cast(base: *File, comptime T: type) ?*T {
220 return if (base.tag == T.base_tag) @fieldParentPtr("base", base) else null;
219 pub fn cast(base: *File, comptime tag: Tag) if (dev.env.supports(tag.devFeature())) ?*tag.Type() else ?noreturn {
220 return if (dev.env.supports(tag.devFeature()) and base.tag == tag) @fieldParentPtr("base", base) else null;
221221 }
222222
223223 pub fn makeWritable(base: *File) !void {
......@@ -231,7 +231,7 @@ pub const File = struct {
231231 const emit = base.emit;
232232 if (base.child_pid) |pid| {
233233 if (builtin.os.tag == .windows) {
234 base.cast(Coff).?.ptraceAttach(pid) catch |err| {
234 base.cast(.coff).?.ptraceAttach(pid) catch |err| {
235235 log.warn("attaching failed with error: {s}", .{@errorName(err)});
236236 };
237237 } else {
......@@ -249,7 +249,7 @@ pub const File = struct {
249249 .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {
250250 log.warn("ptrace failure: {s}", .{@errorName(err)});
251251 },
252 .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| {
252 .macos => base.cast(.macho).?.ptraceAttach(pid) catch |err| {
253253 log.warn("attaching failed with error: {s}", .{@errorName(err)});
254254 },
255255 .windows => unreachable,
......@@ -317,10 +317,10 @@ pub const File = struct {
317317
318318 if (base.child_pid) |pid| {
319319 switch (builtin.os.tag) {
320 .macos => base.cast(MachO).?.ptraceDetach(pid) catch |err| {
320 .macos => base.cast(.macho).?.ptraceDetach(pid) catch |err| {
321321 log.warn("detaching failed with error: {s}", .{@errorName(err)});
322322 },
323 .windows => base.cast(Coff).?.ptraceDetach(pid),
323 .windows => base.cast(.coff).?.ptraceDetach(pid),
324324 else => return error.HotSwapUnavailableOnHostOperatingSystem,
325325 }
326326 }
......@@ -329,7 +329,7 @@ pub const File = struct {
329329 }
330330 }
331331
332 pub const UpdateDeclError = error{
332 pub const UpdateNavError = error{
333333 OutOfMemory,
334334 Overflow,
335335 Underflow,
......@@ -367,27 +367,12 @@ pub const File = struct {
367367 HotSwapUnavailableOnHostOperatingSystem,
368368 };
369369
370 /// Called from within the CodeGen to lower a local variable instantion as an unnamed
371 /// constant. Returns the symbol index of the lowered constant in the read-only section
372 /// of the final binary.
373 pub fn lowerUnnamedConst(base: *File, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 {
374 switch (base.tag) {
375 .spirv => unreachable,
376 .c => unreachable,
377 .nvptx => unreachable,
378 inline else => |tag| {
379 dev.check(tag.devFeature());
380 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUnnamedConst(pt, val, decl_index);
381 },
382 }
383 }
384
385370 /// Called from within CodeGen to retrieve the symbol index of a global symbol.
386371 /// If no symbol exists yet with this name, a new undefined global symbol will
387372 /// be created. This symbol may get resolved once all relocatables are (re-)linked.
388373 /// Optionally, it is possible to specify where to expect the symbol defined if it
389374 /// is an import.
390 pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateDeclError!u32 {
375 pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateNavError!u32 {
391376 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });
392377 switch (base.tag) {
393378 .plan9 => unreachable,
......@@ -401,14 +386,14 @@ pub const File = struct {
401386 }
402387 }
403388
404 /// May be called before or after updateExports for any given Decl.
405 pub fn updateDecl(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
406 const decl = pt.zcu.declPtr(decl_index);
407 assert(decl.has_tv);
389 /// May be called before or after updateExports for any given Nav.
390 pub fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void {
391 const nav = pt.zcu.intern_pool.getNav(nav_index);
392 assert(nav.status == .resolved);
408393 switch (base.tag) {
409394 inline else => |tag| {
410395 dev.check(tag.devFeature());
411 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDecl(pt, decl_index);
396 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateNav(pt, nav_index);
412397 },
413398 }
414399 }
......@@ -420,7 +405,7 @@ pub const File = struct {
420405 func_index: InternPool.Index,
421406 air: Air,
422407 liveness: Liveness,
423 ) UpdateDeclError!void {
408 ) UpdateNavError!void {
424409 switch (base.tag) {
425410 inline else => |tag| {
426411 dev.check(tag.devFeature());
......@@ -429,14 +414,16 @@ pub const File = struct {
429414 }
430415 }
431416
432 pub fn updateDeclLineNumber(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
433 const decl = pt.zcu.declPtr(decl_index);
434 assert(decl.has_tv);
417 pub fn updateNavLineNumber(
418 base: *File,
419 pt: Zcu.PerThread,
420 nav_index: InternPool.Nav.Index,
421 ) UpdateNavError!void {
435422 switch (base.tag) {
436423 .spirv, .nvptx => {},
437424 inline else => |tag| {
438425 dev.check(tag.devFeature());
439 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateDeclLineNumber(pt, decl_index);
426 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateNavineNumber(pt, nav_index);
440427 },
441428 }
442429 }
......@@ -675,52 +662,50 @@ pub const File = struct {
675662 addend: u32,
676663 };
677664
678 /// Get allocated `Decl`'s address in virtual memory.
665 /// Get allocated `Nav`'s address in virtual memory.
679666 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's
680667 /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the
681 /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
682 /// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate
668 /// `Nav`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
669 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
683670 /// the block/atom.
684 pub fn getDeclVAddr(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 {
671 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 {
685672 switch (base.tag) {
686673 .c => unreachable,
687674 .spirv => unreachable,
688675 .nvptx => unreachable,
689676 inline else => |tag| {
690677 dev.check(tag.devFeature());
691 return @as(*tag.Type(), @fieldParentPtr("base", base)).getDeclVAddr(pt, decl_index, reloc_info);
678 return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(pt, nav_index, reloc_info);
692679 },
693680 }
694681 }
695682
696 pub const LowerResult = @import("codegen.zig").Result;
697
698 pub fn lowerAnonDecl(
683 pub fn lowerUav(
699684 base: *File,
700685 pt: Zcu.PerThread,
701686 decl_val: InternPool.Index,
702687 decl_align: InternPool.Alignment,
703688 src_loc: Zcu.LazySrcLoc,
704 ) !LowerResult {
689 ) !@import("codegen.zig").GenResult {
705690 switch (base.tag) {
706691 .c => unreachable,
707692 .spirv => unreachable,
708693 .nvptx => unreachable,
709694 inline else => |tag| {
710695 dev.check(tag.devFeature());
711 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerAnonDecl(pt, decl_val, decl_align, src_loc);
696 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align, src_loc);
712697 },
713698 }
714699 }
715700
716 pub fn getAnonDeclVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {
701 pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {
717702 switch (base.tag) {
718703 .c => unreachable,
719704 .spirv => unreachable,
720705 .nvptx => unreachable,
721706 inline else => |tag| {
722707 dev.check(tag.devFeature());
723 return @as(*tag.Type(), @fieldParentPtr("base", base)).getAnonDeclVAddr(decl_val, reloc_info);
708 return @as(*tag.Type(), @fieldParentPtr("base", base)).getUavVAddr(decl_val, reloc_info);
724709 },
725710 }
726711 }
......@@ -964,18 +949,7 @@ pub const File = struct {
964949 pub const Kind = enum { code, const_data };
965950
966951 kind: Kind,
967 ty: Type,
968
969 pub fn initDecl(kind: Kind, decl: ?InternPool.DeclIndex, mod: *Zcu) LazySymbol {
970 return .{ .kind = kind, .ty = if (decl) |decl_index|
971 mod.declPtr(decl_index).val.toType()
972 else
973 Type.anyerror };
974 }
975
976 pub fn getDecl(self: LazySymbol, mod: *Zcu) InternPool.OptionalDeclIndex {
977 return InternPool.OptionalDeclIndex.init(self.ty.getOwnerDeclOrNull(mod));
978 }
952 ty: InternPool.Index,
979953 };
980954
981955 pub fn effectiveOutputMode(
src/link/C.zig+112-130
......@@ -19,28 +19,27 @@ const Value = @import("../Value.zig");
1919const Air = @import("../Air.zig");
2020const Liveness = @import("../Liveness.zig");
2121
22pub const base_tag: link.File.Tag = .c;
2322pub const zig_h = "#include \"zig.h\"\n";
2423
2524base: link.File,
2625/// This linker backend does not try to incrementally link output C source code.
2726/// Instead, it tracks all declarations in this table, and iterates over it
2827/// in the flush function, stitching pre-rendered pieces of C code together.
29decl_table: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, DeclBlock) = .{},
28navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvBlock) = .{},
3029/// All the string bytes of rendered C code, all squished into one array.
3130/// While in progress, a separate buffer is used, and then when finished, the
3231/// buffer is copied into this one.
3332string_bytes: std.ArrayListUnmanaged(u8) = .{},
3433/// Tracks all the anonymous decls that are used by all the decls so they can
3534/// be rendered during flush().
36anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{},
37/// Sparse set of anon decls that are overaligned. Underaligned anon decls are
35uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, AvBlock) = .{},
36/// Sparse set of uavs that are overaligned. Underaligned anon decls are
3837/// lowered the same as ABI-aligned anon decls. The keys here are a subset of
39/// the keys of `anon_decls`.
40aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{},
38/// the keys of `uavs`.
39aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{},
4140
42exported_decls: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, ExportedBlock) = .{},
43exported_values: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock) = .{},
41exported_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, ExportedBlock) = .{},
42exported_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock) = .{},
4443
4544/// Optimization, `updateDecl` reuses this buffer rather than creating a new
4645/// one with every call.
......@@ -67,7 +66,7 @@ const String = extern struct {
6766};
6867
6968/// Per-declaration data.
70pub const DeclBlock = struct {
69pub const AvBlock = struct {
7170 code: String = String.empty,
7271 fwd_decl: String = String.empty,
7372 /// Each `Decl` stores a set of used `CType`s. In `flush()`, we iterate
......@@ -76,10 +75,10 @@ pub const DeclBlock = struct {
7675 /// May contain string references to ctype_pool
7776 lazy_fns: codegen.LazyFnMap = .{},
7877
79 fn deinit(db: *DeclBlock, gpa: Allocator) void {
80 db.lazy_fns.deinit(gpa);
81 db.ctype_pool.deinit(gpa);
82 db.* = undefined;
78 fn deinit(ab: *AvBlock, gpa: Allocator) void {
79 ab.lazy_fns.deinit(gpa);
80 ab.ctype_pool.deinit(gpa);
81 ab.* = undefined;
8382 }
8483};
8584
......@@ -158,16 +157,16 @@ pub fn createEmpty(
158157pub fn deinit(self: *C) void {
159158 const gpa = self.base.comp.gpa;
160159
161 for (self.decl_table.values()) |*db| {
160 for (self.navs.values()) |*db| {
162161 db.deinit(gpa);
163162 }
164 self.decl_table.deinit(gpa);
163 self.navs.deinit(gpa);
165164
166 for (self.anon_decls.values()) |*db| {
165 for (self.uavs.values()) |*db| {
167166 db.deinit(gpa);
168167 }
169 self.anon_decls.deinit(gpa);
170 self.aligned_anon_decls.deinit(gpa);
168 self.uavs.deinit(gpa);
169 self.aligned_uavs.deinit(gpa);
171170
172171 self.string_bytes.deinit(gpa);
173172 self.fwd_decl_buf.deinit(gpa);
......@@ -194,9 +193,7 @@ pub fn updateFunc(
194193 const zcu = pt.zcu;
195194 const gpa = zcu.gpa;
196195 const func = zcu.funcInfo(func_index);
197 const decl_index = func.owner_decl;
198 const decl = zcu.declPtr(decl_index);
199 const gop = try self.decl_table.getOrPut(gpa, decl_index);
196 const gop = try self.navs.getOrPut(gpa, func.owner_nav);
200197 if (!gop.found_existing) gop.value_ptr.* = .{};
201198 const ctype_pool = &gop.value_ptr.ctype_pool;
202199 const lazy_fns = &gop.value_ptr.lazy_fns;
......@@ -208,8 +205,6 @@ pub fn updateFunc(
208205 fwd_decl.clearRetainingCapacity();
209206 code.clearRetainingCapacity();
210207
211 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
212
213208 var function: codegen.Function = .{
214209 .value_map = codegen.CValueMap.init(gpa),
215210 .air = air,
......@@ -219,15 +214,15 @@ pub fn updateFunc(
219214 .dg = .{
220215 .gpa = gpa,
221216 .pt = pt,
222 .mod = file_scope.mod,
217 .mod = zcu.navFileScope(func.owner_nav).mod,
223218 .error_msg = null,
224 .pass = .{ .decl = decl_index },
225 .is_naked_fn = decl.typeOf(zcu).fnCallingConvention(zcu) == .Naked,
219 .pass = .{ .nav = func.owner_nav },
220 .is_naked_fn = zcu.navValue(func.owner_nav).typeOf(zcu).fnCallingConvention(zcu) == .Naked,
226221 .fwd_decl = fwd_decl.toManaged(gpa),
227222 .ctype_pool = ctype_pool.*,
228223 .scratch = .{},
229 .anon_decl_deps = self.anon_decls,
230 .aligned_anon_decls = self.aligned_anon_decls,
224 .uav_deps = self.uavs,
225 .aligned_uavs = self.aligned_uavs,
231226 },
232227 .code = code.toManaged(gpa),
233228 .indent_writer = undefined, // set later so we can get a pointer to object.code
......@@ -236,8 +231,8 @@ pub fn updateFunc(
236231 };
237232 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
238233 defer {
239 self.anon_decls = function.object.dg.anon_decl_deps;
240 self.aligned_anon_decls = function.object.dg.aligned_anon_decls;
234 self.uavs = function.object.dg.uav_deps;
235 self.aligned_uavs = function.object.dg.aligned_uavs;
241236 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();
242237 ctype_pool.* = function.object.dg.ctype_pool.move();
243238 ctype_pool.freeUnusedCapacity(gpa);
......@@ -248,13 +243,10 @@ pub fn updateFunc(
248243 function.deinit();
249244 }
250245
251 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
246 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
252247 codegen.genFunc(&function) catch |err| switch (err) {
253248 error.AnalysisFail => {
254 zcu.failed_analysis.putAssumeCapacityNoClobber(
255 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
256 function.object.dg.error_msg.?,
257 );
249 zcu.failed_codegen.putAssumeCapacityNoClobber(func.owner_nav, function.object.dg.error_msg.?);
258250 return;
259251 },
260252 else => |e| return e,
......@@ -263,9 +255,9 @@ pub fn updateFunc(
263255 gop.value_ptr.code = try self.addString(function.object.code.items);
264256}
265257
266fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
258fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {
267259 const gpa = self.base.comp.gpa;
268 const anon_decl = self.anon_decls.keys()[i];
260 const uav = self.uavs.keys()[i];
269261
270262 const fwd_decl = &self.fwd_decl_buf;
271263 const code = &self.code_buf;
......@@ -278,21 +270,21 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
278270 .pt = pt,
279271 .mod = pt.zcu.root_mod,
280272 .error_msg = null,
281 .pass = .{ .anon = anon_decl },
273 .pass = .{ .uav = uav },
282274 .is_naked_fn = false,
283275 .fwd_decl = fwd_decl.toManaged(gpa),
284276 .ctype_pool = codegen.CType.Pool.empty,
285277 .scratch = .{},
286 .anon_decl_deps = self.anon_decls,
287 .aligned_anon_decls = self.aligned_anon_decls,
278 .uav_deps = self.uavs,
279 .aligned_uavs = self.aligned_uavs,
288280 },
289281 .code = code.toManaged(gpa),
290282 .indent_writer = undefined, // set later so we can get a pointer to object.code
291283 };
292284 object.indent_writer = .{ .underlying_writer = object.code.writer() };
293285 defer {
294 self.anon_decls = object.dg.anon_decl_deps;
295 self.aligned_anon_decls = object.dg.aligned_anon_decls;
286 self.uavs = object.dg.uav_deps;
287 self.aligned_uavs = object.dg.aligned_uavs;
296288 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
297289 object.dg.ctype_pool.deinit(object.dg.gpa);
298290 object.dg.scratch.deinit(gpa);
......@@ -300,8 +292,8 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
300292 }
301293 try object.dg.ctype_pool.init(gpa);
302294
303 const c_value: codegen.CValue = .{ .constant = Value.fromInterned(anon_decl) };
304 const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;
295 const c_value: codegen.CValue = .{ .constant = Value.fromInterned(uav) };
296 const alignment: Alignment = self.aligned_uavs.get(uav) orelse .none;
305297 codegen.genDeclValue(&object, c_value.constant, c_value, alignment, .none) catch |err| switch (err) {
306298 error.AnalysisFail => {
307299 @panic("TODO: C backend AnalysisFail on anonymous decl");
......@@ -312,23 +304,22 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
312304 };
313305
314306 object.dg.ctype_pool.freeUnusedCapacity(gpa);
315 object.dg.anon_decl_deps.values()[i] = .{
307 object.dg.uav_deps.values()[i] = .{
316308 .code = try self.addString(object.code.items),
317309 .fwd_decl = try self.addString(object.dg.fwd_decl.items),
318310 .ctype_pool = object.dg.ctype_pool.move(),
319311 };
320312}
321313
322pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
314pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
323315 const tracy = trace(@src());
324316 defer tracy.end();
325317
326318 const gpa = self.base.comp.gpa;
327319
328320 const zcu = pt.zcu;
329 const decl = zcu.declPtr(decl_index);
330 const gop = try self.decl_table.getOrPut(gpa, decl_index);
331 errdefer _ = self.decl_table.pop();
321 const gop = try self.navs.getOrPut(gpa, nav_index);
322 errdefer _ = self.navs.pop();
332323 if (!gop.found_existing) gop.value_ptr.* = .{};
333324 const ctype_pool = &gop.value_ptr.ctype_pool;
334325 const fwd_decl = &self.fwd_decl_buf;
......@@ -338,29 +329,27 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
338329 fwd_decl.clearRetainingCapacity();
339330 code.clearRetainingCapacity();
340331
341 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
342
343332 var object: codegen.Object = .{
344333 .dg = .{
345334 .gpa = gpa,
346335 .pt = pt,
347 .mod = file_scope.mod,
336 .mod = zcu.navFileScope(nav_index).mod,
348337 .error_msg = null,
349 .pass = .{ .decl = decl_index },
338 .pass = .{ .nav = nav_index },
350339 .is_naked_fn = false,
351340 .fwd_decl = fwd_decl.toManaged(gpa),
352341 .ctype_pool = ctype_pool.*,
353342 .scratch = .{},
354 .anon_decl_deps = self.anon_decls,
355 .aligned_anon_decls = self.aligned_anon_decls,
343 .uav_deps = self.uavs,
344 .aligned_uavs = self.aligned_uavs,
356345 },
357346 .code = code.toManaged(gpa),
358347 .indent_writer = undefined, // set later so we can get a pointer to object.code
359348 };
360349 object.indent_writer = .{ .underlying_writer = object.code.writer() };
361350 defer {
362 self.anon_decls = object.dg.anon_decl_deps;
363 self.aligned_anon_decls = object.dg.aligned_anon_decls;
351 self.uavs = object.dg.uav_deps;
352 self.aligned_uavs = object.dg.aligned_uavs;
364353 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
365354 ctype_pool.* = object.dg.ctype_pool.move();
366355 ctype_pool.freeUnusedCapacity(gpa);
......@@ -368,13 +357,10 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
368357 code.* = object.code.moveToUnmanaged();
369358 }
370359
371 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
360 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
372361 codegen.genDecl(&object) catch |err| switch (err) {
373362 error.AnalysisFail => {
374 zcu.failed_analysis.putAssumeCapacityNoClobber(
375 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
376 object.dg.error_msg.?,
377 );
363 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, object.dg.error_msg.?);
378364 return;
379365 },
380366 else => |e| return e,
......@@ -383,12 +369,12 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
383369 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
384370}
385371
386pub fn updateDeclLineNumber(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
372pub fn updateNavLineNumber(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
387373 // The C backend does not have the ability to fix line numbers without re-generating
388374 // the entire Decl.
389375 _ = self;
390376 _ = pt;
391 _ = decl_index;
377 _ = nav_index;
392378}
393379
394380pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
......@@ -422,12 +408,13 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
422408 const comp = self.base.comp;
423409 const gpa = comp.gpa;
424410 const zcu = self.base.comp.module.?;
411 const ip = &zcu.intern_pool;
425412 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = tid };
426413
427414 {
428415 var i: usize = 0;
429 while (i < self.anon_decls.count()) : (i += 1) {
430 try updateAnonDecl(self, pt, i);
416 while (i < self.uavs.count()) : (i += 1) {
417 try self.updateUav(pt, i);
431418 }
432419 }
433420
......@@ -484,30 +471,28 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
484471 }
485472 }
486473
487 for (self.anon_decls.keys(), self.anon_decls.values()) |value, *decl_block| try self.flushDeclBlock(
474 for (self.uavs.keys(), self.uavs.values()) |uav, *av_block| try self.flushAvBlock(
488475 pt,
489476 zcu.root_mod,
490477 &f,
491 decl_block,
492 self.exported_values.getPtr(value),
478 av_block,
479 self.exported_uavs.getPtr(uav),
493480 export_names,
494481 .none,
495482 );
496483
497 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, *decl_block| {
498 const decl = zcu.declPtr(decl_index);
499 const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none;
500 const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod;
501 try self.flushDeclBlock(
502 pt,
503 mod,
504 &f,
505 decl_block,
506 self.exported_decls.getPtr(decl_index),
507 export_names,
508 extern_name,
509 );
510 }
484 for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock(
485 pt,
486 zcu.navFileScope(nav).mod,
487 &f,
488 av_block,
489 self.exported_navs.getPtr(nav),
490 export_names,
491 if (ip.indexToKey(zcu.navValue(nav).toIntern()) == .@"extern")
492 ip.getNav(nav).name.toOptional()
493 else
494 .none,
495 );
511496 }
512497
513498 {
......@@ -516,12 +501,12 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
516501 try f.ctype_pool.init(gpa);
517502 try self.flushCTypes(zcu, &f, .flush, &f.lazy_ctype_pool);
518503
519 for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| {
520 try self.flushCTypes(zcu, &f, .{ .anon = anon_decl }, &decl_block.ctype_pool);
504 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| {
505 try self.flushCTypes(zcu, &f, .{ .uav = uav }, &av_block.ctype_pool);
521506 }
522507
523 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {
524 try self.flushCTypes(zcu, &f, .{ .decl = decl_index }, &decl_block.ctype_pool);
508 for (self.navs.keys(), self.navs.values()) |nav, av_block| {
509 try self.flushCTypes(zcu, &f, .{ .nav = nav }, &av_block.ctype_pool);
525510 }
526511 }
527512
......@@ -539,26 +524,21 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
539524 f.file_size += lazy_fwd_decl_len;
540525
541526 // Now the code.
542 try f.all_buffers.ensureUnusedCapacity(gpa, 1 + (self.anon_decls.count() + self.decl_table.count()) * 2);
527 try f.all_buffers.ensureUnusedCapacity(gpa, 1 + (self.uavs.count() + self.navs.count()) * 2);
543528 f.appendBufAssumeCapacity(self.lazy_code_buf.items);
544 for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| f.appendCodeAssumeCapacity(
545 if (self.exported_values.contains(anon_decl))
546 .default
547 else switch (zcu.intern_pool.indexToKey(anon_decl)) {
548 .extern_func => .zig_extern,
549 .variable => |variable| if (variable.is_extern) .zig_extern else .static,
529 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| f.appendCodeAssumeCapacity(
530 if (self.exported_uavs.contains(uav)) .default else switch (ip.indexToKey(uav)) {
531 .@"extern" => .zig_extern,
550532 else => .static,
551533 },
552 self.getString(decl_block.code),
534 self.getString(av_block.code),
553535 );
554 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| f.appendCodeAssumeCapacity(
555 if (self.exported_decls.contains(decl_index))
556 .default
557 else if (zcu.declPtr(decl_index).isExtern(zcu))
558 .zig_extern
559 else
560 .static,
561 self.getString(decl_block.code),
536 for (self.navs.keys(), self.navs.values()) |nav, av_block| f.appendCodeAssumeCapacity(
537 if (self.exported_navs.contains(nav)) .default else switch (ip.indexToKey(zcu.navValue(nav).toIntern())) {
538 .@"extern" => .zig_extern,
539 else => .static,
540 },
541 self.getString(av_block.code),
562542 );
563543
564544 const file = self.base.file.?;
......@@ -689,16 +669,16 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F
689669 .fwd_decl = fwd_decl.toManaged(gpa),
690670 .ctype_pool = ctype_pool.*,
691671 .scratch = .{},
692 .anon_decl_deps = self.anon_decls,
693 .aligned_anon_decls = self.aligned_anon_decls,
672 .uav_deps = self.uavs,
673 .aligned_uavs = self.aligned_uavs,
694674 },
695675 .code = code.toManaged(gpa),
696676 .indent_writer = undefined, // set later so we can get a pointer to object.code
697677 };
698678 object.indent_writer = .{ .underlying_writer = object.code.writer() };
699679 defer {
700 self.anon_decls = object.dg.anon_decl_deps;
701 self.aligned_anon_decls = object.dg.aligned_anon_decls;
680 self.uavs = object.dg.uav_deps;
681 self.aligned_uavs = object.dg.aligned_uavs;
702682 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
703683 ctype_pool.* = object.dg.ctype_pool.move();
704684 ctype_pool.freeUnusedCapacity(gpa);
......@@ -736,8 +716,8 @@ fn flushLazyFn(
736716 .fwd_decl = fwd_decl.toManaged(gpa),
737717 .ctype_pool = ctype_pool.*,
738718 .scratch = .{},
739 .anon_decl_deps = .{},
740 .aligned_anon_decls = .{},
719 .uav_deps = .{},
720 .aligned_uavs = .{},
741721 },
742722 .code = code.toManaged(gpa),
743723 .indent_writer = undefined, // set later so we can get a pointer to object.code
......@@ -746,8 +726,8 @@ fn flushLazyFn(
746726 defer {
747727 // If this assert trips just handle the anon_decl_deps the same as
748728 // `updateFunc()` does.
749 assert(object.dg.anon_decl_deps.count() == 0);
750 assert(object.dg.aligned_anon_decls.count() == 0);
729 assert(object.dg.uav_deps.count() == 0);
730 assert(object.dg.aligned_uavs.count() == 0);
751731 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
752732 ctype_pool.* = object.dg.ctype_pool.move();
753733 ctype_pool.freeUnusedCapacity(gpa);
......@@ -781,31 +761,33 @@ fn flushLazyFns(
781761 }
782762}
783763
784fn flushDeclBlock(
764fn flushAvBlock(
785765 self: *C,
786766 pt: Zcu.PerThread,
787767 mod: *Module,
788768 f: *Flush,
789 decl_block: *const DeclBlock,
769 av_block: *const AvBlock,
790770 exported_block: ?*const ExportedBlock,
791771 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
792772 extern_name: InternPool.OptionalNullTerminatedString,
793773) FlushDeclError!void {
794774 const gpa = self.base.comp.gpa;
795 try self.flushLazyFns(pt, mod, f, &decl_block.ctype_pool, decl_block.lazy_fns);
775 try self.flushLazyFns(pt, mod, f, &av_block.ctype_pool, av_block.lazy_fns);
796776 try f.all_buffers.ensureUnusedCapacity(gpa, 1);
797777 // avoid emitting extern decls that are already exported
798778 if (extern_name.unwrap()) |name| if (export_names.contains(name)) return;
799779 f.appendBufAssumeCapacity(self.getString(if (exported_block) |exported|
800780 exported.fwd_decl
801781 else
802 decl_block.fwd_decl));
782 av_block.fwd_decl));
803783}
804784
805785pub fn flushEmitH(zcu: *Zcu) !void {
806786 const tracy = trace(@src());
807787 defer tracy.end();
808788
789 if (true) return; // emit-h is regressed
790
809791 const emit_h = zcu.emit_h orelse return;
810792
811793 // We collect a list of buffers to write, and write them all at once with pwritev 😎
......@@ -854,17 +836,17 @@ pub fn updateExports(
854836 const zcu = pt.zcu;
855837 const gpa = zcu.gpa;
856838 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {
857 .decl_index => |decl_index| .{
858 zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod,
859 .{ .decl = decl_index },
860 self.decl_table.getPtr(decl_index).?,
861 (try self.exported_decls.getOrPut(gpa, decl_index)).value_ptr,
839 .nav => |nav| .{
840 zcu.navFileScope(nav).mod,
841 .{ .nav = nav },
842 self.navs.getPtr(nav).?,
843 (try self.exported_navs.getOrPut(gpa, nav)).value_ptr,
862844 },
863 .value => |value| .{
845 .uav => |uav| .{
864846 zcu.root_mod,
865 .{ .anon = value },
866 self.anon_decls.getPtr(value).?,
867 (try self.exported_values.getOrPut(gpa, value)).value_ptr,
847 .{ .uav = uav },
848 self.uavs.getPtr(uav).?,
849 (try self.exported_uavs.getOrPut(gpa, uav)).value_ptr,
868850 },
869851 };
870852 const ctype_pool = &decl_block.ctype_pool;
......@@ -880,12 +862,12 @@ pub fn updateExports(
880862 .fwd_decl = fwd_decl.toManaged(gpa),
881863 .ctype_pool = decl_block.ctype_pool,
882864 .scratch = .{},
883 .anon_decl_deps = .{},
884 .aligned_anon_decls = .{},
865 .uav_deps = .{},
866 .aligned_uavs = .{},
885867 };
886868 defer {
887 assert(dg.anon_decl_deps.count() == 0);
888 assert(dg.aligned_anon_decls.count() == 0);
869 assert(dg.uav_deps.count() == 0);
870 assert(dg.aligned_uavs.count() == 0);
889871 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();
890872 ctype_pool.* = dg.ctype_pool.move();
891873 ctype_pool.freeUnusedCapacity(gpa);
......@@ -901,7 +883,7 @@ pub fn deleteExport(
901883 _: InternPool.NullTerminatedString,
902884) void {
903885 switch (exported) {
904 .decl_index => |decl_index| _ = self.exported_decls.swapRemove(decl_index),
905 .value => |value| _ = self.exported_values.swapRemove(value),
886 .nav => |nav| _ = self.exported_navs.swapRemove(nav),
887 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),
906888 }
907889}
src/link/Coff.zig+177-223
......@@ -65,8 +65,8 @@ imports_count_dirty: bool = true,
6565/// Table of tracked LazySymbols.
6666lazy_syms: LazySymbolTable = .{},
6767
68/// Table of tracked Decls.
69decls: DeclTable = .{},
68/// Table of tracked `Nav`s.
69navs: NavTable = .{},
7070
7171/// List of atoms that are either synthetic or map directly to the Zig source program.
7272atoms: std.ArrayListUnmanaged(Atom) = .{},
......@@ -74,27 +74,7 @@ atoms: std.ArrayListUnmanaged(Atom) = .{},
7474/// Table of atoms indexed by the symbol index.
7575atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{},
7676
77/// Table of unnamed constants associated with a parent `Decl`.
78/// We store them here so that we can free the constants whenever the `Decl`
79/// needs updating or is freed.
80///
81/// For example,
82///
83/// ```zig
84/// const Foo = struct{
85/// a: u8,
86/// };
87///
88/// pub fn main() void {
89/// var foo = Foo{ .a = 1 };
90/// _ = foo;
91/// }
92/// ```
93///
94/// value assigned to label `foo` is an unnamed constant belonging/associated
95/// with `Decl` `main`, and lives as long as that `Decl`.
96unnamed_const_atoms: UnnamedConstTable = .{},
97anon_decls: AnonDeclTable = .{},
77uavs: UavTable = .{},
9878
9979/// A table of relocations indexed by the owning them `Atom`.
10080/// Note that once we refactor `Atom`'s lifetime and ownership rules,
......@@ -120,11 +100,10 @@ const HotUpdateState = struct {
120100 loaded_base_address: ?std.os.windows.HMODULE = null,
121101};
122102
123const DeclTable = std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);
124const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);
103const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
104const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata);
125105const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));
126106const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));
127const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Atom.Index));
128107
129108const default_file_alignment: u16 = 0x200;
130109const default_size_of_stack_reserve: u32 = 0x1000000;
......@@ -155,7 +134,7 @@ const Section = struct {
155134 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
156135};
157136
158const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
137const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
159138
160139const LazySymbolMetadata = struct {
161140 const State = enum { unused, pending_flush, flushed };
......@@ -165,17 +144,17 @@ const LazySymbolMetadata = struct {
165144 rdata_state: State = .unused,
166145};
167146
168const DeclMetadata = struct {
147const AvMetadata = struct {
169148 atom: Atom.Index,
170149 section: u16,
171150 /// A list of all exports aliases of this Decl.
172151 exports: std.ArrayListUnmanaged(u32) = .{},
173152
174 fn deinit(m: *DeclMetadata, allocator: Allocator) void {
153 fn deinit(m: *AvMetadata, allocator: Allocator) void {
175154 m.exports.deinit(allocator);
176155 }
177156
178 fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 {
157 fn getExport(m: AvMetadata, coff_file: *const Coff, name: []const u8) ?u32 {
179158 for (m.exports.items) |exp| {
180159 if (mem.eql(u8, name, coff_file.getSymbolName(.{
181160 .sym_index = exp,
......@@ -185,7 +164,7 @@ const DeclMetadata = struct {
185164 return null;
186165 }
187166
188 fn getExportPtr(m: *DeclMetadata, coff_file: *Coff, name: []const u8) ?*u32 {
167 fn getExportPtr(m: *AvMetadata, coff_file: *Coff, name: []const u8) ?*u32 {
189168 for (m.exports.items) |*exp| {
190169 if (mem.eql(u8, name, coff_file.getSymbolName(.{
191170 .sym_index = exp.*,
......@@ -486,24 +465,19 @@ pub fn deinit(self: *Coff) void {
486465
487466 self.lazy_syms.deinit(gpa);
488467
489 for (self.decls.values()) |*metadata| {
468 for (self.navs.values()) |*metadata| {
490469 metadata.deinit(gpa);
491470 }
492 self.decls.deinit(gpa);
471 self.navs.deinit(gpa);
493472
494473 self.atom_by_index_table.deinit(gpa);
495474
496 for (self.unnamed_const_atoms.values()) |*atoms| {
497 atoms.deinit(gpa);
498 }
499 self.unnamed_const_atoms.deinit(gpa);
500
501475 {
502 var it = self.anon_decls.iterator();
476 var it = self.uavs.iterator();
503477 while (it.next()) |entry| {
504478 entry.value_ptr.exports.deinit(gpa);
505479 }
506 self.anon_decls.deinit(gpa);
480 self.uavs.deinit(gpa);
507481 }
508482
509483 for (self.relocs.values()) |*relocs| {
......@@ -1132,23 +1106,20 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,
11321106 const tracy = trace(@src());
11331107 defer tracy.end();
11341108
1135 const mod = pt.zcu;
1136 const func = mod.funcInfo(func_index);
1137 const decl_index = func.owner_decl;
1138 const decl = mod.declPtr(decl_index);
1109 const zcu = pt.zcu;
1110 const gpa = zcu.gpa;
1111 const func = zcu.funcInfo(func_index);
11391112
1140 const atom_index = try self.getOrCreateAtomForDecl(decl_index);
1141 self.freeUnnamedConsts(decl_index);
1113 const atom_index = try self.getOrCreateAtomForNav(func.owner_nav);
11421114 Atom.freeRelocations(self, atom_index);
11431115
1144 const gpa = self.base.comp.gpa;
11451116 var code_buffer = std.ArrayList(u8).init(gpa);
11461117 defer code_buffer.deinit();
11471118
11481119 const res = try codegen.generateFunction(
11491120 &self.base,
11501121 pt,
1151 decl.navSrcLoc(mod),
1122 zcu.navSrcLoc(func.owner_nav),
11521123 func_index,
11531124 air,
11541125 liveness,
......@@ -1158,45 +1129,16 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,
11581129 const code = switch (res) {
11591130 .ok => code_buffer.items,
11601131 .fail => |em| {
1161 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
1162 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1132 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, em);
11631133 return;
11641134 },
11651135 };
11661136
1167 try self.updateDeclCode(pt, decl_index, code, .FUNCTION);
1137 try self.updateNavCode(pt, func.owner_nav, code, .FUNCTION);
11681138
11691139 // Exports will be updated by `Zcu.processExports` after the update.
11701140}
11711141
1172pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
1173 const mod = pt.zcu;
1174 const gpa = mod.gpa;
1175 const decl = mod.declPtr(decl_index);
1176 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
1177 if (!gop.found_existing) {
1178 gop.value_ptr.* = .{};
1179 }
1180 const unnamed_consts = gop.value_ptr;
1181 const index = unnamed_consts.items.len;
1182 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{
1183 decl.fqn.fmt(&mod.intern_pool), index,
1184 });
1185 defer gpa.free(sym_name);
1186 const ty = val.typeOf(mod);
1187 const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) {
1188 .ok => |atom_index| atom_index,
1189 .fail => |em| {
1190 decl.analysis = .codegen_failure;
1191 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1192 log.err("{s}", .{em.msg});
1193 return error.CodegenFail;
1194 },
1195 };
1196 try unnamed_consts.append(gpa, atom_index);
1197 return self.getAtom(atom_index).getSymbolIndex().?;
1198}
1199
12001142const LowerConstResult = union(enum) {
12011143 ok: Atom.Index,
12021144 fail: *Module.ErrorMsg,
......@@ -1246,57 +1188,62 @@ fn lowerConst(
12461188 return .{ .ok = atom_index };
12471189}
12481190
1249pub fn updateDecl(
1191pub fn updateNav(
12501192 self: *Coff,
12511193 pt: Zcu.PerThread,
1252 decl_index: InternPool.DeclIndex,
1253) link.File.UpdateDeclError!void {
1254 const mod = pt.zcu;
1194 nav_index: InternPool.Nav.Index,
1195) link.File.UpdateNavError!void {
12551196 if (build_options.skip_non_native and builtin.object_format != .coff) {
12561197 @panic("Attempted to compile for object format that was disabled by build configuration");
12571198 }
1258 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
1199 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav_index);
12591200 const tracy = trace(@src());
12601201 defer tracy.end();
12611202
1262 const decl = mod.declPtr(decl_index);
1263
1264 if (decl.val.getExternFunc(mod)) |_| {
1265 return;
1266 }
1267
1268 const gpa = self.base.comp.gpa;
1269 if (decl.isExtern(mod)) {
1270 // TODO make this part of getGlobalSymbol
1271 const variable = decl.getOwnedVariable(mod).?;
1272 const name = decl.name.toSlice(&mod.intern_pool);
1273 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);
1274 const global_index = try self.getGlobalSymbol(name, lib_name);
1275 try self.need_got_table.put(gpa, global_index, {});
1276 return;
1277 }
1203 const zcu = pt.zcu;
1204 const gpa = zcu.gpa;
1205 const ip = &zcu.intern_pool;
1206 const nav = ip.getNav(nav_index);
1207
1208 const init_val = switch (ip.indexToKey(nav.status.resolved.val)) {
1209 .variable => |variable| variable.init,
1210 .@"extern" => |@"extern"| {
1211 if (ip.isFunctionType(nav.typeOf(ip))) return;
1212 // TODO make this part of getGlobalSymbol
1213 const name = nav.name.toSlice(ip);
1214 const lib_name = @"extern".lib_name.toSlice(ip);
1215 const global_index = try self.getGlobalSymbol(name, lib_name);
1216 try self.need_got_table.put(gpa, global_index, {});
1217 return;
1218 },
1219 else => nav.status.resolved.val,
1220 };
12781221
1279 const atom_index = try self.getOrCreateAtomForDecl(decl_index);
1222 const atom_index = try self.getOrCreateAtomForNav(nav_index);
12801223 Atom.freeRelocations(self, atom_index);
12811224 const atom = self.getAtom(atom_index);
12821225
12831226 var code_buffer = std.ArrayList(u8).init(gpa);
12841227 defer code_buffer.deinit();
12851228
1286 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
1287 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{
1288 .parent_atom_index = atom.getSymbolIndex().?,
1289 });
1229 const res = try codegen.generateSymbol(
1230 &self.base,
1231 pt,
1232 zcu.navSrcLoc(nav_index),
1233 Value.fromInterned(init_val),
1234 &code_buffer,
1235 .none,
1236 .{ .parent_atom_index = atom.getSymbolIndex().? },
1237 );
12901238 const code = switch (res) {
12911239 .ok => code_buffer.items,
12921240 .fail => |em| {
1293 decl.analysis = .codegen_failure;
1294 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1241 try zcu.failed_codegen.put(gpa, nav_index, em);
12951242 return;
12961243 },
12971244 };
12981245
1299 try self.updateDeclCode(pt, decl_index, code, .NULL);
1246 try self.updateNavCode(pt, nav_index, code, .NULL);
13001247
13011248 // Exports will be updated by `Zcu.processExports` after the update.
13021249}
......@@ -1317,14 +1264,14 @@ fn updateLazySymbolAtom(
13171264
13181265 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
13191266 @tagName(sym.kind),
1320 sym.ty.fmt(pt),
1267 Type.fromInterned(sym.ty).fmt(pt),
13211268 });
13221269 defer gpa.free(name);
13231270
13241271 const atom = self.getAtomPtr(atom_index);
13251272 const local_sym_index = atom.getSymbolIndex().?;
13261273
1327 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1274 const src = Type.fromInterned(sym.ty).srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
13281275 const res = try codegen.generateLazySymbol(
13291276 &self.base,
13301277 pt,
......@@ -1362,52 +1309,55 @@ fn updateLazySymbolAtom(
13621309 try self.writeAtom(atom_index, code);
13631310}
13641311
1365pub fn getOrCreateAtomForLazySymbol(self: *Coff, pt: Zcu.PerThread, sym: link.File.LazySymbol) !Atom.Index {
1366 const gpa = self.base.comp.gpa;
1367 const mod = self.base.comp.module.?;
1368 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod));
1312pub fn getOrCreateAtomForLazySymbol(
1313 self: *Coff,
1314 pt: Zcu.PerThread,
1315 lazy_sym: link.File.LazySymbol,
1316) !Atom.Index {
1317 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
13691318 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
13701319 if (!gop.found_existing) gop.value_ptr.* = .{};
1371 const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
1372 .code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },
1373 .const_data => .{ .atom = &gop.value_ptr.rdata_atom, .state = &gop.value_ptr.rdata_state },
1320 const atom_ptr, const state_ptr = switch (lazy_sym.kind) {
1321 .code => .{ &gop.value_ptr.text_atom, &gop.value_ptr.text_state },
1322 .const_data => .{ &gop.value_ptr.rdata_atom, &gop.value_ptr.rdata_state },
13741323 };
1375 switch (metadata.state.*) {
1376 .unused => metadata.atom.* = try self.createAtom(),
1377 .pending_flush => return metadata.atom.*,
1324 switch (state_ptr.*) {
1325 .unused => atom_ptr.* = try self.createAtom(),
1326 .pending_flush => return atom_ptr.*,
13781327 .flushed => {},
13791328 }
1380 metadata.state.* = .pending_flush;
1381 const atom = metadata.atom.*;
1329 state_ptr.* = .pending_flush;
1330 const atom = atom_ptr.*;
13821331 // anyerror needs to be deferred until flushModule
1383 if (sym.getDecl(mod) != .none) try self.updateLazySymbolAtom(pt, sym, atom, switch (sym.kind) {
1332 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbolAtom(pt, lazy_sym, atom, switch (lazy_sym.kind) {
13841333 .code => self.text_section_index.?,
13851334 .const_data => self.rdata_section_index.?,
13861335 });
13871336 return atom;
13881337}
13891338
1390pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !Atom.Index {
1339pub fn getOrCreateAtomForNav(self: *Coff, nav_index: InternPool.Nav.Index) !Atom.Index {
13911340 const gpa = self.base.comp.gpa;
1392 const gop = try self.decls.getOrPut(gpa, decl_index);
1341 const gop = try self.navs.getOrPut(gpa, nav_index);
13931342 if (!gop.found_existing) {
13941343 gop.value_ptr.* = .{
13951344 .atom = try self.createAtom(),
1396 .section = self.getDeclOutputSection(decl_index),
1345 .section = self.getNavOutputSection(nav_index),
13971346 .exports = .{},
13981347 };
13991348 }
14001349 return gop.value_ptr.atom;
14011350}
14021351
1403fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
1404 const decl = self.base.comp.module.?.declPtr(decl_index);
1405 const mod = self.base.comp.module.?;
1406 const ty = decl.typeOf(mod);
1407 const zig_ty = ty.zigTypeTag(mod);
1408 const val = decl.val;
1352fn getNavOutputSection(self: *Coff, nav_index: InternPool.Nav.Index) u16 {
1353 const zcu = self.base.comp.module.?;
1354 const ip = &zcu.intern_pool;
1355 const nav = ip.getNav(nav_index);
1356 const ty = Type.fromInterned(nav.typeOf(ip));
1357 const zig_ty = ty.zigTypeTag(zcu);
1358 const val = Value.fromInterned(nav.status.resolved.val);
14091359 const index: u16 = blk: {
1410 if (val.isUndefDeep(mod)) {
1360 if (val.isUndefDeep(zcu)) {
14111361 // TODO in release-fast and release-small, we should put undef in .bss
14121362 break :blk self.data_section_index.?;
14131363 }
......@@ -1416,7 +1366,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
14161366 // TODO: what if this is a function pointer?
14171367 .Fn => break :blk self.text_section_index.?,
14181368 else => {
1419 if (val.getVariable(mod)) |_| {
1369 if (val.getVariable(zcu)) |_| {
14201370 break :blk self.data_section_index.?;
14211371 }
14221372 break :blk self.rdata_section_index.?;
......@@ -1426,31 +1376,41 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
14261376 return index;
14271377}
14281378
1429fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void {
1430 const mod = pt.zcu;
1431 const decl = mod.declPtr(decl_index);
1379fn updateNavCode(
1380 self: *Coff,
1381 pt: Zcu.PerThread,
1382 nav_index: InternPool.Nav.Index,
1383 code: []u8,
1384 complex_type: coff.ComplexType,
1385) !void {
1386 const zcu = pt.zcu;
1387 const ip = &zcu.intern_pool;
1388 const nav = ip.getNav(nav_index);
14321389
1433 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(&mod.intern_pool), decl });
1434 const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
1390 log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
14351391
1436 const decl_metadata = self.decls.get(decl_index).?;
1437 const atom_index = decl_metadata.atom;
1392 const required_alignment = pt.navAlignment(nav_index).max(
1393 target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
1394 );
1395
1396 const nav_metadata = self.navs.get(nav_index).?;
1397 const atom_index = nav_metadata.atom;
14381398 const atom = self.getAtom(atom_index);
14391399 const sym_index = atom.getSymbolIndex().?;
1440 const sect_index = decl_metadata.section;
1400 const sect_index = nav_metadata.section;
14411401 const code_len = @as(u32, @intCast(code.len));
14421402
14431403 if (atom.size != 0) {
14441404 const sym = atom.getSymbolPtr(self);
1445 try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
1405 try self.setSymbolName(sym, nav.fqn.toSlice(ip));
14461406 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
14471407 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14481408
14491409 const capacity = atom.capacity(self);
1450 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);
1410 const need_realloc = code.len > capacity or !required_alignment.check(sym.value);
14511411 if (need_realloc) {
1452 const vaddr = try self.growAtom(atom_index, code_len, required_alignment);
1453 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), sym.value, vaddr });
1412 const vaddr = try self.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
1413 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
14541414 log.debug(" (required alignment 0x{x}", .{required_alignment});
14551415
14561416 if (vaddr != sym.value) {
......@@ -1466,13 +1426,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14661426 self.getAtomPtr(atom_index).size = code_len;
14671427 } else {
14681428 const sym = atom.getSymbolPtr(self);
1469 try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
1429 try self.setSymbolName(sym, nav.fqn.toSlice(ip));
14701430 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
14711431 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14721432
1473 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
1433 const vaddr = try self.allocateAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
14741434 errdefer self.freeAtom(atom_index);
1475 log.debug("allocated atom for {} at 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), vaddr });
1435 log.debug("allocated atom for {} at 0x{x}", .{ nav.fqn.fmt(ip), vaddr });
14761436 self.getAtomPtr(atom_index).size = code_len;
14771437 sym.value = vaddr;
14781438
......@@ -1482,28 +1442,15 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14821442 try self.writeAtom(atom_index, code);
14831443}
14841444
1485fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void {
1486 const gpa = self.base.comp.gpa;
1487 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
1488 for (unnamed_consts.items) |atom_index| {
1489 self.freeAtom(atom_index);
1490 }
1491 unnamed_consts.clearAndFree(gpa);
1492}
1493
1494pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void {
1495 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
1445pub fn freeNav(self: *Coff, nav_index: InternPool.NavIndex) void {
1446 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav_index);
14961447
14971448 const gpa = self.base.comp.gpa;
1498 const mod = self.base.comp.module.?;
1499 const decl = mod.declPtr(decl_index);
1449 log.debug("freeDecl 0x{x}", .{nav_index});
15001450
1501 log.debug("freeDecl {*}", .{decl});
1502
1503 if (self.decls.fetchOrderedRemove(decl_index)) |const_kv| {
1451 if (self.decls.fetchOrderedRemove(nav_index)) |const_kv| {
15041452 var kv = const_kv;
15051453 self.freeAtom(kv.value.atom);
1506 self.freeUnnamedConsts(decl_index);
15071454 kv.value.exports.deinit(gpa);
15081455 }
15091456}
......@@ -1528,20 +1475,21 @@ pub fn updateExports(
15281475 // detect the default subsystem.
15291476 for (export_indices) |export_idx| {
15301477 const exp = mod.all_exports.items[export_idx];
1531 const exported_decl_index = switch (exp.exported) {
1532 .decl_index => |i| i,
1533 .value => continue,
1478 const exported_nav_index = switch (exp.exported) {
1479 .nav => |nav| nav,
1480 .uav => continue,
15341481 };
1535 const exported_decl = mod.declPtr(exported_decl_index);
1536 if (exported_decl.getOwnedFunction(mod) == null) continue;
1537 const winapi_cc = switch (target.cpu.arch) {
1538 .x86 => std.builtin.CallingConvention.Stdcall,
1539 else => std.builtin.CallingConvention.C,
1482 const exported_nav = ip.getNav(exported_nav_index);
1483 const exported_ty = exported_nav.typeOf(ip);
1484 if (!ip.isFunctionType(exported_ty)) continue;
1485 const winapi_cc: std.builtin.CallingConvention = switch (target.cpu.arch) {
1486 .x86 => .Stdcall,
1487 else => .C,
15401488 };
1541 const decl_cc = exported_decl.typeOf(mod).fnCallingConvention(mod);
1542 if (decl_cc == .C and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) {
1489 const exported_cc = Type.fromInterned(exported_ty).fnCallingConvention(mod);
1490 if (exported_cc == .C and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) {
15431491 mod.stage1_flags.have_c_main = true;
1544 } else if (decl_cc == winapi_cc and target.os.tag == .windows) {
1492 } else if (exported_cc == winapi_cc and target.os.tag == .windows) {
15451493 if (exp.opts.name.eqlSlice("WinMain", ip)) {
15461494 mod.stage1_flags.have_winmain = true;
15471495 } else if (exp.opts.name.eqlSlice("wWinMain", ip)) {
......@@ -1562,15 +1510,15 @@ pub fn updateExports(
15621510 const gpa = comp.gpa;
15631511
15641512 const metadata = switch (exported) {
1565 .decl_index => |decl_index| blk: {
1566 _ = try self.getOrCreateAtomForDecl(decl_index);
1567 break :blk self.decls.getPtr(decl_index).?;
1513 .nav => |nav| blk: {
1514 _ = try self.getOrCreateAtomForNav(nav);
1515 break :blk self.navs.getPtr(nav).?;
15681516 },
1569 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1517 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
15701518 const first_exp = mod.all_exports.items[export_indices[0]];
1571 const res = try self.lowerAnonDecl(pt, value, .none, first_exp.src);
1519 const res = try self.lowerUav(pt, uav, .none, first_exp.src);
15721520 switch (res) {
1573 .ok => {},
1521 .mcv => {},
15741522 .fail => |em| {
15751523 // TODO maybe it's enough to return an error here and let Module.processExportsInner
15761524 // handle the error?
......@@ -1579,7 +1527,7 @@ pub fn updateExports(
15791527 return;
15801528 },
15811529 }
1582 break :blk self.anon_decls.getPtr(value).?;
1530 break :blk self.uavs.getPtr(uav).?;
15831531 },
15841532 };
15851533 const atom_index = metadata.atom;
......@@ -1654,9 +1602,9 @@ pub fn deleteExport(
16541602) void {
16551603 if (self.llvm_object) |_| return;
16561604 const metadata = switch (exported) {
1657 .decl_index => |decl_index| self.decls.getPtr(decl_index) orelse return,
1658 .value => |value| self.anon_decls.getPtr(value) orelse return,
1659 };
1605 .nav => |nav| self.navs.getPtr(nav),
1606 .uav => |uav| self.uavs.getPtr(uav),
1607 } orelse return;
16601608 const mod = self.base.comp.module.?;
16611609 const name_slice = name.toSlice(&mod.intern_pool);
16621610 const sym_index = metadata.getExportPtr(self, name_slice) orelse return;
......@@ -1748,7 +1696,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
17481696 // anyerror needs to wait for everything to be flushed.
17491697 if (metadata.text_state != .unused) self.updateLazySymbolAtom(
17501698 pt,
1751 link.File.LazySymbol.initDecl(.code, null, pt.zcu),
1699 .{ .kind = .code, .ty = .anyerror_type },
17521700 metadata.text_atom,
17531701 self.text_section_index.?,
17541702 ) catch |err| return switch (err) {
......@@ -1757,7 +1705,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
17571705 };
17581706 if (metadata.rdata_state != .unused) self.updateLazySymbolAtom(
17591707 pt,
1760 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),
1708 .{ .kind = .const_data, .ty = .anyerror_type },
17611709 metadata.rdata_atom,
17621710 self.rdata_section_index.?,
17631711 ) catch |err| return switch (err) {
......@@ -1856,22 +1804,20 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
18561804 assert(!self.imports_count_dirty);
18571805}
18581806
1859pub fn getDeclVAddr(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
1807pub fn getNavVAddr(
1808 self: *Coff,
1809 pt: Zcu.PerThread,
1810 nav_index: InternPool.Nav.Index,
1811 reloc_info: link.File.RelocInfo,
1812) !u64 {
18601813 assert(self.llvm_object == null);
18611814 const zcu = pt.zcu;
18621815 const ip = &zcu.intern_pool;
1863 const decl = zcu.declPtr(decl_index);
1864 log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index });
1865 const sym_index = if (decl.isExtern(zcu)) blk: {
1866 const name = decl.name.toSlice(ip);
1867 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|
1868 ext_fn.lib_name.toSlice(ip)
1869 else
1870 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);
1871 break :blk try self.getGlobalSymbol(name, lib_name);
1872 } else blk: {
1873 const this_atom_index = try self.getOrCreateAtomForDecl(decl_index);
1874 break :blk self.getAtom(this_atom_index).getSymbolIndex().?;
1816 const nav = ip.getNav(nav_index);
1817 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1818 const sym_index = switch (ip.indexToKey(nav.status.resolved.val)) {
1819 .@"extern" => |@"extern"| try self.getGlobalSymbol(nav.name.toSlice(ip), @"extern".lib_name.toSlice(ip)),
1820 else => self.getAtom(try self.getOrCreateAtomForNav(nav_index)).getSymbolIndex().?,
18751821 };
18761822 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
18771823 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
......@@ -1888,36 +1834,36 @@ pub fn getDeclVAddr(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclI
18881834 return 0;
18891835}
18901836
1891pub fn lowerAnonDecl(
1837pub fn lowerUav(
18921838 self: *Coff,
18931839 pt: Zcu.PerThread,
1894 decl_val: InternPool.Index,
1840 uav: InternPool.Index,
18951841 explicit_alignment: InternPool.Alignment,
18961842 src_loc: Module.LazySrcLoc,
1897) !codegen.Result {
1898 const gpa = self.base.comp.gpa;
1899 const mod = self.base.comp.module.?;
1900 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
1901 const decl_alignment = switch (explicit_alignment) {
1902 .none => ty.abiAlignment(pt),
1843) !codegen.GenResult {
1844 const zcu = pt.zcu;
1845 const gpa = zcu.gpa;
1846 const val = Value.fromInterned(uav);
1847 const uav_alignment = switch (explicit_alignment) {
1848 .none => val.typeOf(zcu).abiAlignment(pt),
19031849 else => explicit_alignment,
19041850 };
1905 if (self.anon_decls.get(decl_val)) |metadata| {
1906 const existing_addr = self.getAtom(metadata.atom).getSymbol(self).value;
1907 if (decl_alignment.check(existing_addr))
1908 return .ok;
1851 if (self.uavs.get(uav)) |metadata| {
1852 const atom = self.getAtom(metadata.atom);
1853 const existing_addr = atom.getSymbol(self).value;
1854 if (uav_alignment.check(existing_addr))
1855 return .{ .mcv = .{ .load_direct = atom.getSymbolIndex().? } };
19091856 }
19101857
1911 const val = Value.fromInterned(decl_val);
19121858 var name_buf: [32]u8 = undefined;
19131859 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1914 @intFromEnum(decl_val),
1860 @intFromEnum(uav),
19151861 }) catch unreachable;
19161862 const res = self.lowerConst(
19171863 pt,
19181864 name,
19191865 val,
1920 decl_alignment,
1866 uav_alignment,
19211867 self.rdata_section_index.?,
19221868 src_loc,
19231869 ) catch |err| switch (err) {
......@@ -1933,14 +1879,23 @@ pub fn lowerAnonDecl(
19331879 .ok => |atom_index| atom_index,
19341880 .fail => |em| return .{ .fail = em },
19351881 };
1936 try self.anon_decls.put(gpa, decl_val, .{ .atom = atom_index, .section = self.rdata_section_index.? });
1937 return .ok;
1882 try self.uavs.put(gpa, uav, .{
1883 .atom = atom_index,
1884 .section = self.rdata_section_index.?,
1885 });
1886 return .{ .mcv = .{
1887 .load_direct = self.getAtom(atom_index).getSymbolIndex().?,
1888 } };
19381889}
19391890
1940pub fn getAnonDeclVAddr(self: *Coff, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1891pub fn getUavVAddr(
1892 self: *Coff,
1893 uav: InternPool.Index,
1894 reloc_info: link.File.RelocInfo,
1895) !u64 {
19411896 assert(self.llvm_object == null);
19421897
1943 const this_atom_index = self.anon_decls.get(decl_val).?.atom;
1898 const this_atom_index = self.uavs.get(uav).?.atom;
19441899 const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?;
19451900 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
19461901 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
......@@ -2760,6 +2715,7 @@ const Allocator = std.mem.Allocator;
27602715const codegen = @import("../codegen.zig");
27612716const link = @import("../link.zig");
27622717const lld = @import("Coff/lld.zig");
2718const target_util = @import("../target.zig");
27632719const trace = @import("../tracy.zig").trace;
27642720
27652721const Air = @import("../Air.zig");
......@@ -2781,6 +2737,4 @@ const Value = @import("../Value.zig");
27812737const AnalUnit = InternPool.AnalUnit;
27822738const dev = @import("../dev.zig");
27832739
2784pub const base_tag: link.File.Tag = .coff;
2785
27862740const msdos_stub = @embedFile("msdos-stub.bin");
src/link/Dwarf.zig+475-564
......@@ -9,7 +9,7 @@ src_fn_free_list: std.AutoHashMapUnmanaged(Atom.Index, void) = .{},
99src_fn_first_index: ?Atom.Index = null,
1010src_fn_last_index: ?Atom.Index = null,
1111src_fns: std.ArrayListUnmanaged(Atom) = .{},
12src_fn_decls: AtomTable = .{},
12src_fn_navs: AtomTable = .{},
1313
1414/// A list of `Atom`s whose corresponding .debug_info tags have surplus capacity.
1515/// This is the same concept as `text_block_free_list`; see those doc comments.
......@@ -17,7 +17,7 @@ di_atom_free_list: std.AutoHashMapUnmanaged(Atom.Index, void) = .{},
1717di_atom_first_index: ?Atom.Index = null,
1818di_atom_last_index: ?Atom.Index = null,
1919di_atoms: std.ArrayListUnmanaged(Atom) = .{},
20di_atom_decls: AtomTable = .{},
20di_atom_navs: AtomTable = .{},
2121
2222dbg_line_header: DbgLineHeader,
2323
......@@ -27,7 +27,7 @@ abbrev_table_offset: ?u64 = null,
2727/// Table of debug symbol names.
2828strtab: StringTable = .{},
2929
30/// Quick lookup array of all defined source files referenced by at least one Decl.
30/// Quick lookup array of all defined source files referenced by at least one Nav.
3131/// They will end up in the DWARF debug_line header as two lists:
3232/// * []include_directory
3333/// * []file_names
......@@ -35,13 +35,13 @@ di_files: std.AutoArrayHashMapUnmanaged(*const Zcu.File, void) = .{},
3535
3636global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
3737
38const AtomTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index);
38const AtomTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, Atom.Index);
3939
4040const Atom = struct {
41 /// Offset into .debug_info pointing to the tag for this Decl, or
41 /// Offset into .debug_info pointing to the tag for this Nav, or
4242 /// offset from the beginning of the Debug Line Program header that contains this function.
4343 off: u32,
44 /// Size of the .debug_info tag for this Decl, not including padding, or
44 /// Size of the .debug_info tag for this Nav, not including padding, or
4545 /// size of the line number program component belonging to this function, not
4646 /// including padding.
4747 len: u32,
......@@ -61,14 +61,14 @@ const DbgLineHeader = struct {
6161 opcode_base: u8,
6262};
6363
64/// Represents state of the analysed Decl.
65/// Includes Decl's abbrev table of type Types, matching arena
64/// Represents state of the analysed Nav.
65/// Includes Nav's abbrev table of type Types, matching arena
6666/// and a set of relocations that will be resolved once this
67/// Decl's inner Atom is assigned an offset within the DWARF section.
68pub const DeclState = struct {
67/// Nav's inner Atom is assigned an offset within the DWARF section.
68pub const NavState = struct {
6969 dwarf: *Dwarf,
7070 pt: Zcu.PerThread,
71 di_atom_decls: *const AtomTable,
71 di_atom_navs: *const AtomTable,
7272 dbg_line_func: InternPool.Index,
7373 dbg_line: std.ArrayList(u8),
7474 dbg_info: std.ArrayList(u8),
......@@ -78,20 +78,20 @@ pub const DeclState = struct {
7878 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation),
7979 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation),
8080
81 pub fn deinit(self: *DeclState) void {
82 const gpa = self.dwarf.allocator;
83 self.dbg_line.deinit();
84 self.dbg_info.deinit();
85 self.abbrev_type_arena.deinit();
86 self.abbrev_table.deinit(gpa);
87 self.abbrev_resolver.deinit(gpa);
88 self.abbrev_relocs.deinit(gpa);
89 self.exprloc_relocs.deinit(gpa);
81 pub fn deinit(ns: *NavState) void {
82 const gpa = ns.dwarf.allocator;
83 ns.dbg_line.deinit();
84 ns.dbg_info.deinit();
85 ns.abbrev_type_arena.deinit();
86 ns.abbrev_table.deinit(gpa);
87 ns.abbrev_resolver.deinit(gpa);
88 ns.abbrev_relocs.deinit(gpa);
89 ns.exprloc_relocs.deinit(gpa);
9090 }
9191
9292 /// Adds local type relocation of the form: @offset => @this + addend
9393 /// @this signifies the offset within the .debug_abbrev section of the containing atom.
94 fn addTypeRelocLocal(self: *DeclState, atom_index: Atom.Index, offset: u32, addend: u32) !void {
94 fn addTypeRelocLocal(self: *NavState, atom_index: Atom.Index, offset: u32, addend: u32) !void {
9595 log.debug("{x}: @this + {x}", .{ offset, addend });
9696 try self.abbrev_relocs.append(self.dwarf.allocator, .{
9797 .target = null,
......@@ -104,7 +104,7 @@ pub const DeclState = struct {
104104 /// Adds global type relocation of the form: @offset => @symbol + 0
105105 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
106106 /// which we use as our target of the relocation.
107 fn addTypeRelocGlobal(self: *DeclState, atom_index: Atom.Index, ty: Type, offset: u32) !void {
107 fn addTypeRelocGlobal(self: *NavState, atom_index: Atom.Index, ty: Type, offset: u32) !void {
108108 const gpa = self.dwarf.allocator;
109109 const resolv = self.abbrev_resolver.get(ty.toIntern()) orelse blk: {
110110 const sym_index: u32 = @intCast(self.abbrev_table.items.len);
......@@ -127,7 +127,7 @@ pub const DeclState = struct {
127127 }
128128
129129 fn addDbgInfoType(
130 self: *DeclState,
130 self: *NavState,
131131 pt: Zcu.PerThread,
132132 atom_index: Atom.Index,
133133 ty: Type,
......@@ -550,15 +550,15 @@ pub const DeclState = struct {
550550 };
551551
552552 pub fn genArgDbgInfo(
553 self: *DeclState,
553 self: *NavState,
554554 name: [:0]const u8,
555555 ty: Type,
556 owner_decl: InternPool.DeclIndex,
556 owner_nav: InternPool.Nav.Index,
557557 loc: DbgInfoLoc,
558558 ) error{OutOfMemory}!void {
559559 const pt = self.pt;
560560 const dbg_info = &self.dbg_info;
561 const atom_index = self.di_atom_decls.get(owner_decl).?;
561 const atom_index = self.di_atom_navs.get(owner_nav).?;
562562 const name_with_null = name.ptr[0 .. name.len + 1];
563563
564564 switch (loc) {
......@@ -639,6 +639,7 @@ pub const DeclState = struct {
639639 leb128.writeIleb128(dbg_info.writer(), info.offset) catch unreachable;
640640 },
641641 .wasm_local => |value| {
642 @import("../dev.zig").check(.wasm_linker);
642643 const leb_size = link.File.Wasm.getUleb128Size(value);
643644 try dbg_info.ensureUnusedCapacity(3 + leb_size);
644645 // wasm locations are encoded as follow:
......@@ -665,15 +666,15 @@ pub const DeclState = struct {
665666 }
666667
667668 pub fn genVarDbgInfo(
668 self: *DeclState,
669 self: *NavState,
669670 name: [:0]const u8,
670671 ty: Type,
671 owner_decl: InternPool.DeclIndex,
672 owner_nav: InternPool.Nav.Index,
672673 is_ptr: bool,
673674 loc: DbgInfoLoc,
674675 ) error{OutOfMemory}!void {
675676 const dbg_info = &self.dbg_info;
676 const atom_index = self.di_atom_decls.get(owner_decl).?;
677 const atom_index = self.di_atom_navs.get(owner_nav).?;
677678 const name_with_null = name.ptr[0 .. name.len + 1];
678679 try dbg_info.append(@intFromEnum(AbbrevCode.variable));
679680 const gpa = self.dwarf.allocator;
......@@ -881,7 +882,7 @@ pub const DeclState = struct {
881882 }
882883
883884 pub fn advancePCAndLine(
884 self: *DeclState,
885 self: *NavState,
885886 delta_line: i33,
886887 delta_pc: u64,
887888 ) error{OutOfMemory}!void {
......@@ -921,21 +922,21 @@ pub const DeclState = struct {
921922 }
922923 }
923924
924 pub fn setColumn(self: *DeclState, column: u32) error{OutOfMemory}!void {
925 pub fn setColumn(self: *NavState, column: u32) error{OutOfMemory}!void {
925926 try self.dbg_line.ensureUnusedCapacity(1 + 5);
926927 self.dbg_line.appendAssumeCapacity(DW.LNS.set_column);
927928 leb128.writeUleb128(self.dbg_line.writer(), column + 1) catch unreachable;
928929 }
929930
930 pub fn setPrologueEnd(self: *DeclState) error{OutOfMemory}!void {
931 pub fn setPrologueEnd(self: *NavState) error{OutOfMemory}!void {
931932 try self.dbg_line.append(DW.LNS.set_prologue_end);
932933 }
933934
934 pub fn setEpilogueBegin(self: *DeclState) error{OutOfMemory}!void {
935 pub fn setEpilogueBegin(self: *NavState) error{OutOfMemory}!void {
935936 try self.dbg_line.append(DW.LNS.set_epilogue_begin);
936937 }
937938
938 pub fn setInlineFunc(self: *DeclState, func: InternPool.Index) error{OutOfMemory}!void {
939 pub fn setInlineFunc(self: *NavState, func: InternPool.Index) error{OutOfMemory}!void {
939940 const zcu = self.pt.zcu;
940941 if (self.dbg_line_func == func) return;
941942
......@@ -944,15 +945,15 @@ pub const DeclState = struct {
944945 const old_func_info = zcu.funcInfo(self.dbg_line_func);
945946 const new_func_info = zcu.funcInfo(func);
946947
947 const old_file = try self.dwarf.addDIFile(zcu, old_func_info.owner_decl);
948 const new_file = try self.dwarf.addDIFile(zcu, new_func_info.owner_decl);
948 const old_file = try self.dwarf.addDIFile(zcu, old_func_info.owner_nav);
949 const new_file = try self.dwarf.addDIFile(zcu, new_func_info.owner_nav);
949950 if (old_file != new_file) {
950951 self.dbg_line.appendAssumeCapacity(DW.LNS.set_file);
951952 leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file);
952953 }
953954
954 const old_src_line: i33 = zcu.declPtr(old_func_info.owner_decl).navSrcLine(zcu);
955 const new_src_line: i33 = zcu.declPtr(new_func_info.owner_decl).navSrcLine(zcu);
955 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
956 const new_src_line: i33 = zcu.navSrcLine(new_func_info.owner_nav);
956957 if (new_src_line != old_src_line) {
957958 self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
958959 leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line);
......@@ -1064,31 +1065,31 @@ pub fn deinit(self: *Dwarf) void {
10641065
10651066 self.src_fn_free_list.deinit(gpa);
10661067 self.src_fns.deinit(gpa);
1067 self.src_fn_decls.deinit(gpa);
1068 self.src_fn_navs.deinit(gpa);
10681069
10691070 self.di_atom_free_list.deinit(gpa);
10701071 self.di_atoms.deinit(gpa);
1071 self.di_atom_decls.deinit(gpa);
1072 self.di_atom_navs.deinit(gpa);
10721073
10731074 self.strtab.deinit(gpa);
10741075 self.di_files.deinit(gpa);
10751076 self.global_abbrev_relocs.deinit(gpa);
10761077}
10771078
1078/// Initializes Decl's state and its matching output buffers.
1079/// Call this before `commitDeclState`.
1080pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !DeclState {
1079/// Initializes Nav's state and its matching output buffers.
1080/// Call this before `commitNavState`.
1081pub fn initNavState(self: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !NavState {
10811082 const tracy = trace(@src());
10821083 defer tracy.end();
10831084
1084 const decl = pt.zcu.declPtr(decl_index);
1085 log.debug("initDeclState {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
1085 const nav = pt.zcu.intern_pool.getNav(nav_index);
1086 log.debug("initNavState {}", .{nav.fqn.fmt(&pt.zcu.intern_pool)});
10861087
10871088 const gpa = self.allocator;
1088 var decl_state: DeclState = .{
1089 var nav_state: NavState = .{
10891090 .dwarf = self,
10901091 .pt = pt,
1091 .di_atom_decls = &self.di_atom_decls,
1092 .di_atom_navs = &self.di_atom_navs,
10921093 .dbg_line_func = undefined,
10931094 .dbg_line = std.ArrayList(u8).init(gpa),
10941095 .dbg_info = std.ArrayList(u8).init(gpa),
......@@ -1098,30 +1099,30 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
10981099 .abbrev_relocs = .{},
10991100 .exprloc_relocs = .{},
11001101 };
1101 errdefer decl_state.deinit();
1102 const dbg_line_buffer = &decl_state.dbg_line;
1103 const dbg_info_buffer = &decl_state.dbg_info;
1102 errdefer nav_state.deinit();
1103 const dbg_line_buffer = &nav_state.dbg_line;
1104 const dbg_info_buffer = &nav_state.dbg_info;
11041105
1105 const di_atom_index = try self.getOrCreateAtomForDecl(.di_atom, decl_index);
1106 const di_atom_index = try self.getOrCreateAtomForNav(.di_atom, nav_index);
11061107
1107 assert(decl.has_tv);
1108 const nav_val = Value.fromInterned(nav.status.resolved.val);
11081109
1109 switch (decl.typeOf(pt.zcu).zigTypeTag(pt.zcu)) {
1110 switch (nav_val.typeOf(pt.zcu).zigTypeTag(pt.zcu)) {
11101111 .Fn => {
1111 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
1112 _ = try self.getOrCreateAtomForNav(.src_fn, nav_index);
11121113
11131114 // For functions we need to add a prologue to the debug line program.
11141115 const ptr_width_bytes = self.ptrWidthBytes();
11151116 try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1);
11161117
1117 decl_state.dbg_line_func = decl.val.toIntern();
1118 const func = decl.val.getFunction(pt.zcu).?;
1119 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1120 decl.navSrcLine(pt.zcu),
1118 nav_state.dbg_line_func = nav_val.toIntern();
1119 const func = nav_val.getFunction(pt.zcu).?;
1120 log.debug("src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1121 pt.zcu.navSrcLine(nav_index),
11211122 func.lbrace_line,
11221123 func.rbrace_line,
11231124 });
1124 const line: u28 = @intCast(decl.navSrcLine(pt.zcu) + func.lbrace_line);
1125 const line: u28 = @intCast(pt.zcu.navSrcLine(nav_index) + func.lbrace_line);
11251126
11261127 dbg_line_buffer.appendSliceAssumeCapacity(&.{
11271128 DW.LNS.extended_op,
......@@ -1143,7 +1144,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
11431144 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
11441145 // Once we support more than one source file, this will have the ability to be more
11451146 // than one possible value.
1146 const file_index = try self.addDIFile(pt.zcu, decl_index);
1147 const file_index = try self.addDIFile(pt.zcu, nav_index);
11471148 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index);
11481149
11491150 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column);
......@@ -1154,12 +1155,12 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
11541155 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
11551156
11561157 // .debug_info subprogram
1157 const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);
1158 const decl_linkage_name_slice = decl.fqn.toSlice(&pt.zcu.intern_pool);
1158 const nav_name_slice = nav.name.toSlice(&pt.zcu.intern_pool);
1159 const nav_linkage_name_slice = nav.fqn.toSlice(&pt.zcu.intern_pool);
11591160 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +
1160 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));
1161 (nav_name_slice.len + 1) + (nav_linkage_name_slice.len + 1));
11611162
1162 const fn_ret_type = decl.typeOf(pt.zcu).fnReturnType(pt.zcu);
1163 const fn_ret_type = nav_val.typeOf(pt.zcu).fnReturnType(pt.zcu);
11631164 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(pt);
11641165 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(
11651166 @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid),
......@@ -1172,14 +1173,14 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
11721173 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
11731174 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); // DW.AT.high_pc, DW.FORM.data4
11741175 if (fn_ret_has_bits) {
1175 try decl_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @intCast(dbg_info_buffer.items.len));
1176 try nav_state.addTypeRelocGlobal(di_atom_index, fn_ret_type, @intCast(dbg_info_buffer.items.len));
11761177 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); // DW.AT.type, DW.FORM.ref4
11771178 }
11781179 dbg_info_buffer.appendSliceAssumeCapacity(
1179 decl_name_slice[0 .. decl_name_slice.len + 1],
1180 nav_name_slice[0 .. nav_name_slice.len + 1],
11801181 ); // DW.AT.name, DW.FORM.string
11811182 dbg_info_buffer.appendSliceAssumeCapacity(
1182 decl_linkage_name_slice[0 .. decl_linkage_name_slice.len + 1],
1183 nav_linkage_name_slice[0 .. nav_linkage_name_slice.len + 1],
11831184 ); // DW.AT.linkage_name, DW.FORM.string
11841185 },
11851186 else => {
......@@ -1187,37 +1188,36 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
11871188 },
11881189 }
11891190
1190 return decl_state;
1191 return nav_state;
11911192}
11921193
1193pub fn commitDeclState(
1194pub fn commitNavState(
11941195 self: *Dwarf,
11951196 pt: Zcu.PerThread,
1196 decl_index: InternPool.DeclIndex,
1197 nav_index: InternPool.Nav.Index,
11971198 sym_addr: u64,
11981199 sym_size: u64,
1199 decl_state: *DeclState,
1200 nav_state: *NavState,
12001201) !void {
12011202 const tracy = trace(@src());
12021203 defer tracy.end();
12031204
12041205 const gpa = self.allocator;
12051206 const zcu = pt.zcu;
1206 const decl = zcu.declPtr(decl_index);
12071207 const ip = &zcu.intern_pool;
1208 const namespace = zcu.namespacePtr(decl.src_namespace);
1209 const target = namespace.fileScope(zcu).mod.resolved_target.result;
1208 const nav = ip.getNav(nav_index);
1209 const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
12101210 const target_endian = target.cpu.arch.endian();
12111211
1212 var dbg_line_buffer = &decl_state.dbg_line;
1213 var dbg_info_buffer = &decl_state.dbg_info;
1212 var dbg_line_buffer = &nav_state.dbg_line;
1213 var dbg_info_buffer = &nav_state.dbg_info;
12141214
1215 assert(decl.has_tv);
1216 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
1215 const nav_val = Value.fromInterned(nav.status.resolved.val);
1216 switch (nav_val.typeOf(zcu).zigTypeTag(zcu)) {
12171217 .Fn => {
1218 try decl_state.setInlineFunc(decl.val.toIntern());
1218 try nav_state.setInlineFunc(nav_val.toIntern());
12191219
1220 // Since the Decl is a function, we need to update the .debug_line program.
1220 // Since the Nav is a function, we need to update the .debug_line program.
12211221 // Perform the relocations based on vaddr.
12221222 switch (self.ptr_width) {
12231223 .p32 => {
......@@ -1254,10 +1254,10 @@ pub fn commitDeclState(
12541254
12551255 // Now we have the full contents and may allocate a region to store it.
12561256
1257 // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for
1257 // This logic is nearly identical to the logic below in `updateNavDebugInfo` for
12581258 // `TextBlock` and the .debug_info. If you are editing this logic, you
12591259 // probably need to edit that logic too.
1260 const src_fn_index = self.src_fn_decls.get(decl_index).?;
1260 const src_fn_index = self.src_fn_navs.get(nav_index).?;
12611261 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);
12621262 src_fn.len = @intCast(dbg_line_buffer.items.len);
12631263
......@@ -1275,33 +1275,26 @@ pub fn commitDeclState(
12751275 next.prev_index = src_fn.prev_index;
12761276 src_fn.next_index = null;
12771277 // Populate where it used to be with NOPs.
1278 switch (self.bin_file.tag) {
1279 .elf => {
1280 const elf_file = self.bin_file.cast(File.Elf).?;
1281 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
1282 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1283 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1284 },
1285 .macho => {
1286 const macho_file = self.bin_file.cast(File.MachO).?;
1287 if (macho_file.base.isRelocatable()) {
1288 const debug_line_sect = &macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
1289 const file_pos = debug_line_sect.offset + src_fn.off;
1290 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1291 } else {
1292 const d_sym = macho_file.getDebugSymbols().?;
1293 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1294 const file_pos = debug_line_sect.offset + src_fn.off;
1295 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1296 }
1297 },
1298 .wasm => {
1299 // const wasm_file = self.bin_file.cast(File.Wasm).?;
1300 // const debug_line = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
1301 // writeDbgLineNopsBuffered(debug_line.items, src_fn.off, 0, &.{}, src_fn.len);
1302 },
1303 else => unreachable,
1304 }
1278 if (self.bin_file.cast(.elf)) |elf_file| {
1279 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
1280 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1281 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1282 } else if (self.bin_file.cast(.macho)) |macho_file| {
1283 if (macho_file.base.isRelocatable()) {
1284 const debug_line_sect = &macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
1285 const file_pos = debug_line_sect.offset + src_fn.off;
1286 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1287 } else {
1288 const d_sym = macho_file.getDebugSymbols().?;
1289 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1290 const file_pos = debug_line_sect.offset + src_fn.off;
1291 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1292 }
1293 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1294 _ = wasm_file;
1295 // const debug_line = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
1296 // writeDbgLineNopsBuffered(debug_line.items, src_fn.off, 0, &.{}, src_fn.len);
1297 } else unreachable;
13051298 // TODO Look at the free list before appending at the end.
13061299 src_fn.prev_index = last_index;
13071300 const last = self.getAtomPtr(.src_fn, last_index);
......@@ -1342,76 +1335,67 @@ pub fn commitDeclState(
13421335
13431336 // We only have support for one compilation unit so far, so the offsets are directly
13441337 // from the .debug_line section.
1345 switch (self.bin_file.tag) {
1346 .elf => {
1347 const elf_file = self.bin_file.cast(File.Elf).?;
1348 const shdr_index = elf_file.debug_line_section_index.?;
1349 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
1350 const debug_line_sect = elf_file.shdrs.items[shdr_index];
1351 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1338 if (self.bin_file.cast(.elf)) |elf_file| {
1339 const shdr_index = elf_file.debug_line_section_index.?;
1340 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
1341 const debug_line_sect = elf_file.shdrs.items[shdr_index];
1342 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1343 try pwriteDbgLineNops(
1344 elf_file.base.file.?,
1345 file_pos,
1346 prev_padding_size,
1347 dbg_line_buffer.items,
1348 next_padding_size,
1349 );
1350 } else if (self.bin_file.cast(.macho)) |macho_file| {
1351 if (macho_file.base.isRelocatable()) {
1352 const sect_index = macho_file.debug_line_sect_index.?;
1353 try macho_file.growSection(sect_index, needed_size);
1354 const sect = macho_file.sections.items(.header)[sect_index];
1355 const file_pos = sect.offset + src_fn.off;
13521356 try pwriteDbgLineNops(
1353 elf_file.base.file.?,
1357 macho_file.base.file.?,
13541358 file_pos,
13551359 prev_padding_size,
13561360 dbg_line_buffer.items,
13571361 next_padding_size,
13581362 );
1359 },
1360
1361 .macho => {
1362 const macho_file = self.bin_file.cast(File.MachO).?;
1363 if (macho_file.base.isRelocatable()) {
1364 const sect_index = macho_file.debug_line_sect_index.?;
1365 try macho_file.growSection(sect_index, needed_size);
1366 const sect = macho_file.sections.items(.header)[sect_index];
1367 const file_pos = sect.offset + src_fn.off;
1368 try pwriteDbgLineNops(
1369 macho_file.base.file.?,
1370 file_pos,
1371 prev_padding_size,
1372 dbg_line_buffer.items,
1373 next_padding_size,
1374 );
1375 } else {
1376 const d_sym = macho_file.getDebugSymbols().?;
1377 const sect_index = d_sym.debug_line_section_index.?;
1378 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1379 const sect = d_sym.getSection(sect_index);
1380 const file_pos = sect.offset + src_fn.off;
1381 try pwriteDbgLineNops(
1382 d_sym.file,
1383 file_pos,
1384 prev_padding_size,
1385 dbg_line_buffer.items,
1386 next_padding_size,
1387 );
1388 }
1389 },
1390
1391 .wasm => {
1392 // const wasm_file = self.bin_file.cast(File.Wasm).?;
1393 // const atom = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?);
1394 // const debug_line = &atom.code;
1395 // const segment_size = debug_line.items.len;
1396 // if (needed_size != segment_size) {
1397 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});
1398 // if (needed_size > segment_size) {
1399 // log.debug(" allocating {d} bytes for 'debug line' information", .{needed_size - segment_size});
1400 // try debug_line.resize(self.allocator, needed_size);
1401 // @memset(debug_line.items[segment_size..], 0);
1402 // }
1403 // debug_line.items.len = needed_size;
1404 // }
1405 // writeDbgLineNopsBuffered(
1406 // debug_line.items,
1407 // src_fn.off,
1408 // prev_padding_size,
1409 // dbg_line_buffer.items,
1410 // next_padding_size,
1411 // );
1412 },
1413 else => unreachable,
1414 }
1363 } else {
1364 const d_sym = macho_file.getDebugSymbols().?;
1365 const sect_index = d_sym.debug_line_section_index.?;
1366 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1367 const sect = d_sym.getSection(sect_index);
1368 const file_pos = sect.offset + src_fn.off;
1369 try pwriteDbgLineNops(
1370 d_sym.file,
1371 file_pos,
1372 prev_padding_size,
1373 dbg_line_buffer.items,
1374 next_padding_size,
1375 );
1376 }
1377 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1378 _ = wasm_file;
1379 // const atom = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?);
1380 // const debug_line = &atom.code;
1381 // const segment_size = debug_line.items.len;
1382 // if (needed_size != segment_size) {
1383 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});
1384 // if (needed_size > segment_size) {
1385 // log.debug(" allocating {d} bytes for 'debug line' information", .{needed_size - segment_size});
1386 // try debug_line.resize(self.allocator, needed_size);
1387 // @memset(debug_line.items[segment_size..], 0);
1388 // }
1389 // debug_line.items.len = needed_size;
1390 // }
1391 // writeDbgLineNopsBuffered(
1392 // debug_line.items,
1393 // src_fn.off,
1394 // prev_padding_size,
1395 // dbg_line_buffer.items,
1396 // next_padding_size,
1397 // );
1398 } else unreachable;
14151399
14161400 // .debug_info - End the TAG.subprogram children.
14171401 try dbg_info_buffer.append(0);
......@@ -1422,27 +1406,27 @@ pub fn commitDeclState(
14221406 if (dbg_info_buffer.items.len == 0)
14231407 return;
14241408
1425 const di_atom_index = self.di_atom_decls.get(decl_index).?;
1426 if (decl_state.abbrev_table.items.len > 0) {
1427 // Now we emit the .debug_info types of the Decl. These will count towards the size of
1409 const di_atom_index = self.di_atom_navs.get(nav_index).?;
1410 if (nav_state.abbrev_table.items.len > 0) {
1411 // Now we emit the .debug_info types of the Nav. These will count towards the size of
14281412 // the buffer, so we have to do it before computing the offset, and we can't perform the actual
14291413 // relocations yet.
14301414 var sym_index: usize = 0;
1431 while (sym_index < decl_state.abbrev_table.items.len) : (sym_index += 1) {
1432 const symbol = &decl_state.abbrev_table.items[sym_index];
1415 while (sym_index < nav_state.abbrev_table.items.len) : (sym_index += 1) {
1416 const symbol = &nav_state.abbrev_table.items[sym_index];
14331417 const ty = symbol.type;
14341418 if (ip.isErrorSetType(ty.toIntern())) continue;
14351419
14361420 symbol.offset = @intCast(dbg_info_buffer.items.len);
1437 try decl_state.addDbgInfoType(pt, di_atom_index, ty);
1421 try nav_state.addDbgInfoType(pt, di_atom_index, ty);
14381422 }
14391423 }
14401424
1441 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));
1425 try self.updateNavDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));
14421426
1443 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
1427 while (nav_state.abbrev_relocs.popOrNull()) |reloc| {
14441428 if (reloc.target) |reloc_target| {
1445 const symbol = decl_state.abbrev_table.items[reloc_target];
1429 const symbol = nav_state.abbrev_table.items[reloc_target];
14461430 const ty = symbol.type;
14471431 if (ip.isErrorSetType(ty.toIntern())) {
14481432 log.debug("resolving %{d} deferred until flush", .{reloc_target});
......@@ -1479,38 +1463,35 @@ pub fn commitDeclState(
14791463 }
14801464 }
14811465
1482 while (decl_state.exprloc_relocs.popOrNull()) |reloc| {
1483 switch (self.bin_file.tag) {
1484 .macho => {
1485 const macho_file = self.bin_file.cast(File.MachO).?;
1486 if (macho_file.base.isRelocatable()) {
1487 // TODO
1488 } else {
1489 const d_sym = macho_file.getDebugSymbols().?;
1490 try d_sym.relocs.append(d_sym.allocator, .{
1491 .type = switch (reloc.type) {
1492 .direct_load => .direct_load,
1493 .got_load => .got_load,
1494 },
1495 .target = reloc.target,
1496 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
1497 .addend = 0,
1498 });
1499 }
1500 },
1501 .elf => {}, // TODO
1502 else => unreachable,
1503 }
1466 while (nav_state.exprloc_relocs.popOrNull()) |reloc| {
1467 if (self.bin_file.cast(.elf)) |elf_file| {
1468 _ = elf_file; // TODO
1469 } else if (self.bin_file.cast(.macho)) |macho_file| {
1470 if (macho_file.base.isRelocatable()) {
1471 // TODO
1472 } else {
1473 const d_sym = macho_file.getDebugSymbols().?;
1474 try d_sym.relocs.append(d_sym.allocator, .{
1475 .type = switch (reloc.type) {
1476 .direct_load => .direct_load,
1477 .got_load => .got_load,
1478 },
1479 .target = reloc.target,
1480 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
1481 .addend = 0,
1482 });
1483 }
1484 } else unreachable;
15041485 }
15051486
1506 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
1487 try self.writeNavDebugInfo(di_atom_index, dbg_info_buffer.items);
15071488}
15081489
1509fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) !void {
1490fn updateNavDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) !void {
15101491 const tracy = trace(@src());
15111492 defer tracy.end();
15121493
1513 // This logic is nearly identical to the logic above in `updateDecl` for
1494 // This logic is nearly identical to the logic above in `updateNav` for
15141495 // `SrcFn` and the line number programs. If you are editing this logic, you
15151496 // probably need to edit that logic too.
15161497 const gpa = self.allocator;
......@@ -1521,7 +1502,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
15211502 if (atom_index == last_index) break :blk;
15221503 if (atom.next_index) |next_index| {
15231504 const next = self.getAtomPtr(.di_atom, next_index);
1524 // Update existing Decl - non-last item.
1505 // Update existing Nav - non-last item.
15251506 if (atom.off + atom.len + min_nop_size > next.off) {
15261507 // It grew too big, so we move it to a new location.
15271508 if (atom.prev_index) |prev_index| {
......@@ -1531,34 +1512,27 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
15311512 next.prev_index = atom.prev_index;
15321513 atom.next_index = null;
15331514 // Populate where it used to be with NOPs.
1534 switch (self.bin_file.tag) {
1535 .elf => {
1536 const elf_file = self.bin_file.cast(File.Elf).?;
1537 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
1538 const file_pos = debug_info_sect.sh_offset + atom.off;
1539 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1540 },
1541 .macho => {
1542 const macho_file = self.bin_file.cast(File.MachO).?;
1543 if (macho_file.base.isRelocatable()) {
1544 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
1545 const file_pos = debug_info_sect.offset + atom.off;
1546 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1547 } else {
1548 const d_sym = macho_file.getDebugSymbols().?;
1549 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
1550 const file_pos = debug_info_sect.offset + atom.off;
1551 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1552 }
1553 },
1554 .wasm => {
1555 // const wasm_file = self.bin_file.cast(File.Wasm).?;
1556 // const debug_info_index = wasm_file.debug_info_atom.?;
1557 // const debug_info = &wasm_file.getAtomPtr(debug_info_index).code;
1558 // try writeDbgInfoNopsToArrayList(gpa, debug_info, atom.off, 0, &.{0}, atom.len, false);
1559 },
1560 else => unreachable,
1561 }
1515 if (self.bin_file.cast(.elf)) |elf_file| {
1516 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
1517 const file_pos = debug_info_sect.sh_offset + atom.off;
1518 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1519 } else if (self.bin_file.cast(.macho)) |macho_file| {
1520 if (macho_file.base.isRelocatable()) {
1521 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
1522 const file_pos = debug_info_sect.offset + atom.off;
1523 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1524 } else {
1525 const d_sym = macho_file.getDebugSymbols().?;
1526 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
1527 const file_pos = debug_info_sect.offset + atom.off;
1528 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1529 }
1530 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1531 _ = wasm_file;
1532 // const debug_info_index = wasm_file.debug_info_atom.?;
1533 // const debug_info = &wasm_file.getAtomPtr(debug_info_index).code;
1534 // try writeDbgInfoNopsToArrayList(gpa, debug_info, atom.off, 0, &.{0}, atom.len, false);
1535 } else unreachable;
15621536 // TODO Look at the free list before appending at the end.
15631537 atom.prev_index = last_index;
15641538 const last = self.getAtomPtr(.di_atom, last_index);
......@@ -1568,7 +1542,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
15681542 atom.off = last.off + padToIdeal(last.len);
15691543 }
15701544 } else if (atom.prev_index == null) {
1571 // Append new Decl.
1545 // Append new Nav.
15721546 // TODO Look at the free list before appending at the end.
15731547 atom.prev_index = last_index;
15741548 const last = self.getAtomPtr(.di_atom, last_index);
......@@ -1578,7 +1552,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
15781552 atom.off = last.off + padToIdeal(last.len);
15791553 }
15801554 } else {
1581 // This is the first Decl of the .debug_info
1555 // This is the first Nav of the .debug_info
15821556 self.di_atom_first_index = atom_index;
15831557 self.di_atom_last_index = atom_index;
15841558
......@@ -1586,19 +1560,19 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
15861560 }
15871561}
15881562
1589fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []const u8) !void {
1563fn writeNavDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []const u8) !void {
15901564 const tracy = trace(@src());
15911565 defer tracy.end();
15921566
1593 // This logic is nearly identical to the logic above in `updateDecl` for
1567 // This logic is nearly identical to the logic above in `updateNav` for
15941568 // `SrcFn` and the line number programs. If you are editing this logic, you
15951569 // probably need to edit that logic too.
15961570
15971571 const atom = self.getAtom(.di_atom, atom_index);
1598 const last_decl_index = self.di_atom_last_index.?;
1599 const last_decl = self.getAtom(.di_atom, last_decl_index);
1600 // +1 for a trailing zero to end the children of the decl tag.
1601 const needed_size = last_decl.off + last_decl.len + 1;
1572 const last_nav_index = self.di_atom_last_index.?;
1573 const last_nav = self.getAtom(.di_atom, last_nav_index);
1574 // +1 for a trailing zero to end the children of the nav tag.
1575 const needed_size = last_nav.off + last_nav.len + 1;
16021576 const prev_padding_size: u32 = if (atom.prev_index) |prev_index| blk: {
16031577 const prev = self.getAtom(.di_atom, prev_index);
16041578 break :blk atom.off - (prev.off + prev.len);
......@@ -1608,107 +1582,99 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons
16081582 break :blk next.off - (atom.off + atom.len);
16091583 } else 0;
16101584
1611 // To end the children of the decl tag.
1585 // To end the children of the nav tag.
16121586 const trailing_zero = atom.next_index == null;
16131587
16141588 // We only have support for one compilation unit so far, so the offsets are directly
16151589 // from the .debug_info section.
1616 switch (self.bin_file.tag) {
1617 .elf => {
1618 const elf_file = self.bin_file.cast(File.Elf).?;
1619 const shdr_index = elf_file.debug_info_section_index.?;
1620 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
1621 const debug_info_sect = &elf_file.shdrs.items[shdr_index];
1622 const file_pos = debug_info_sect.sh_offset + atom.off;
1590 if (self.bin_file.cast(.elf)) |elf_file| {
1591 const shdr_index = elf_file.debug_info_section_index.?;
1592 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
1593 const debug_info_sect = &elf_file.shdrs.items[shdr_index];
1594 const file_pos = debug_info_sect.sh_offset + atom.off;
1595 try pwriteDbgInfoNops(
1596 elf_file.base.file.?,
1597 file_pos,
1598 prev_padding_size,
1599 dbg_info_buf,
1600 next_padding_size,
1601 trailing_zero,
1602 );
1603 } else if (self.bin_file.cast(.macho)) |macho_file| {
1604 if (macho_file.base.isRelocatable()) {
1605 const sect_index = macho_file.debug_info_sect_index.?;
1606 try macho_file.growSection(sect_index, needed_size);
1607 const sect = macho_file.sections.items(.header)[sect_index];
1608 const file_pos = sect.offset + atom.off;
16231609 try pwriteDbgInfoNops(
1624 elf_file.base.file.?,
1610 macho_file.base.file.?,
16251611 file_pos,
16261612 prev_padding_size,
16271613 dbg_info_buf,
16281614 next_padding_size,
16291615 trailing_zero,
16301616 );
1631 },
1632
1633 .macho => {
1634 const macho_file = self.bin_file.cast(File.MachO).?;
1635 if (macho_file.base.isRelocatable()) {
1636 const sect_index = macho_file.debug_info_sect_index.?;
1637 try macho_file.growSection(sect_index, needed_size);
1638 const sect = macho_file.sections.items(.header)[sect_index];
1639 const file_pos = sect.offset + atom.off;
1640 try pwriteDbgInfoNops(
1641 macho_file.base.file.?,
1642 file_pos,
1643 prev_padding_size,
1644 dbg_info_buf,
1645 next_padding_size,
1646 trailing_zero,
1647 );
1648 } else {
1649 const d_sym = macho_file.getDebugSymbols().?;
1650 const sect_index = d_sym.debug_info_section_index.?;
1651 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1652 const sect = d_sym.getSection(sect_index);
1653 const file_pos = sect.offset + atom.off;
1654 try pwriteDbgInfoNops(
1655 d_sym.file,
1656 file_pos,
1657 prev_padding_size,
1658 dbg_info_buf,
1659 next_padding_size,
1660 trailing_zero,
1661 );
1662 }
1663 },
1664
1665 .wasm => {
1666 // const wasm_file = self.bin_file.cast(File.Wasm).?;
1667 // const info_atom = wasm_file.debug_info_atom.?;
1668 // const debug_info = &wasm_file.getAtomPtr(info_atom).code;
1669 // const segment_size = debug_info.items.len;
1670 // if (needed_size != segment_size) {
1671 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});
1672 // if (needed_size > segment_size) {
1673 // log.debug(" allocating {d} bytes for 'debug info' information", .{needed_size - segment_size});
1674 // try debug_info.resize(self.allocator, needed_size);
1675 // @memset(debug_info.items[segment_size..], 0);
1676 // }
1677 // debug_info.items.len = needed_size;
1678 // }
1679 // log.debug(" writeDbgInfoNopsToArrayList debug_info_len={d} offset={d} content_len={d} next_padding_size={d}", .{
1680 // debug_info.items.len, atom.off, dbg_info_buf.len, next_padding_size,
1681 // });
1682 // try writeDbgInfoNopsToArrayList(
1683 // gpa,
1684 // debug_info,
1685 // atom.off,
1686 // prev_padding_size,
1687 // dbg_info_buf,
1688 // next_padding_size,
1689 // trailing_zero,
1690 // );
1691 },
1692 else => unreachable,
1693 }
1617 } else {
1618 const d_sym = macho_file.getDebugSymbols().?;
1619 const sect_index = d_sym.debug_info_section_index.?;
1620 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1621 const sect = d_sym.getSection(sect_index);
1622 const file_pos = sect.offset + atom.off;
1623 try pwriteDbgInfoNops(
1624 d_sym.file,
1625 file_pos,
1626 prev_padding_size,
1627 dbg_info_buf,
1628 next_padding_size,
1629 trailing_zero,
1630 );
1631 }
1632 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1633 _ = wasm_file;
1634 // const info_atom = wasm_file.debug_info_atom.?;
1635 // const debug_info = &wasm_file.getAtomPtr(info_atom).code;
1636 // const segment_size = debug_info.items.len;
1637 // if (needed_size != segment_size) {
1638 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});
1639 // if (needed_size > segment_size) {
1640 // log.debug(" allocating {d} bytes for 'debug info' information", .{needed_size - segment_size});
1641 // try debug_info.resize(self.allocator, needed_size);
1642 // @memset(debug_info.items[segment_size..], 0);
1643 // }
1644 // debug_info.items.len = needed_size;
1645 // }
1646 // log.debug(" writeDbgInfoNopsToArrayList debug_info_len={d} offset={d} content_len={d} next_padding_size={d}", .{
1647 // debug_info.items.len, atom.off, dbg_info_buf.len, next_padding_size,
1648 // });
1649 // try writeDbgInfoNopsToArrayList(
1650 // gpa,
1651 // debug_info,
1652 // atom.off,
1653 // prev_padding_size,
1654 // dbg_info_buf,
1655 // next_padding_size,
1656 // trailing_zero,
1657 // );
1658 } else unreachable;
16941659}
16951660
1696pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void {
1661pub fn updateNavLineNumber(self: *Dwarf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !void {
16971662 const tracy = trace(@src());
16981663 defer tracy.end();
16991664
1700 const atom_index = try self.getOrCreateAtomForDecl(.src_fn, decl_index);
1665 const atom_index = try self.getOrCreateAtomForNav(.src_fn, nav_index);
17011666 const atom = self.getAtom(.src_fn, atom_index);
17021667 if (atom.len == 0) return;
17031668
1704 const decl = zcu.declPtr(decl_index);
1705 const func = decl.val.getFunction(zcu).?;
1706 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1707 decl.navSrcLine(zcu),
1669 const nav = zcu.intern_pool.getNav(nav_index);
1670 const nav_val = Value.fromInterned(nav.status.resolved.val);
1671 const func = nav_val.getFunction(zcu).?;
1672 log.debug("src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1673 zcu.navSrcLine(nav_index),
17081674 func.lbrace_line,
17091675 func.rbrace_line,
17101676 });
1711 const line: u28 = @intCast(decl.navSrcLine(zcu) + func.lbrace_line);
1677 const line: u28 = @intCast(zcu.navSrcLine(nav_index) + func.lbrace_line);
17121678 var data: [4]u8 = undefined;
17131679 leb128.writeUnsignedFixed(4, &data, line);
17141680
......@@ -1742,11 +1708,11 @@ pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.Decl
17421708 }
17431709}
17441710
1745pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void {
1711pub fn freeNav(self: *Dwarf, nav_index: InternPool.Nav.Index) void {
17461712 const gpa = self.allocator;
17471713
17481714 // Free SrcFn atom
1749 if (self.src_fn_decls.fetchRemove(decl_index)) |kv| {
1715 if (self.src_fn_navs.fetchRemove(nav_index)) |kv| {
17501716 const src_fn_index = kv.value;
17511717 const src_fn = self.getAtom(.src_fn, src_fn_index);
17521718 _ = self.src_fn_free_list.remove(src_fn_index);
......@@ -1773,7 +1739,7 @@ pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void {
17731739 }
17741740
17751741 // Free DI atom
1776 if (self.di_atom_decls.fetchRemove(decl_index)) |kv| {
1742 if (self.di_atom_navs.fetchRemove(nav_index)) |kv| {
17771743 const di_atom_index = kv.value;
17781744 const di_atom = self.getAtomPtr(.di_atom, di_atom_index);
17791745
......@@ -1930,40 +1896,33 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
19301896 self.abbrev_table_offset = abbrev_offset;
19311897
19321898 const needed_size = abbrev_buf.len;
1933 switch (self.bin_file.tag) {
1934 .elf => {
1935 const elf_file = self.bin_file.cast(File.Elf).?;
1936 const shdr_index = elf_file.debug_abbrev_section_index.?;
1937 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, false);
1938 const debug_abbrev_sect = &elf_file.shdrs.items[shdr_index];
1939 const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;
1940 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1941 },
1942 .macho => {
1943 const macho_file = self.bin_file.cast(File.MachO).?;
1944 if (macho_file.base.isRelocatable()) {
1945 const sect_index = macho_file.debug_abbrev_sect_index.?;
1946 try macho_file.growSection(sect_index, needed_size);
1947 const sect = macho_file.sections.items(.header)[sect_index];
1948 const file_pos = sect.offset + abbrev_offset;
1949 try macho_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1950 } else {
1951 const d_sym = macho_file.getDebugSymbols().?;
1952 const sect_index = d_sym.debug_abbrev_section_index.?;
1953 try d_sym.growSection(sect_index, needed_size, false, macho_file);
1954 const sect = d_sym.getSection(sect_index);
1955 const file_pos = sect.offset + abbrev_offset;
1956 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);
1957 }
1958 },
1959 .wasm => {
1960 // const wasm_file = self.bin_file.cast(File.Wasm).?;
1961 // const debug_abbrev = &wasm_file.getAtomPtr(wasm_file.debug_abbrev_atom.?).code;
1962 // try debug_abbrev.resize(gpa, needed_size);
1963 // debug_abbrev.items[0..abbrev_buf.len].* = abbrev_buf;
1964 },
1965 else => unreachable,
1966 }
1899 if (self.bin_file.cast(.elf)) |elf_file| {
1900 const shdr_index = elf_file.debug_abbrev_section_index.?;
1901 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, false);
1902 const debug_abbrev_sect = &elf_file.shdrs.items[shdr_index];
1903 const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;
1904 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1905 } else if (self.bin_file.cast(.macho)) |macho_file| {
1906 if (macho_file.base.isRelocatable()) {
1907 const sect_index = macho_file.debug_abbrev_sect_index.?;
1908 try macho_file.growSection(sect_index, needed_size);
1909 const sect = macho_file.sections.items(.header)[sect_index];
1910 const file_pos = sect.offset + abbrev_offset;
1911 try macho_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1912 } else {
1913 const d_sym = macho_file.getDebugSymbols().?;
1914 const sect_index = d_sym.debug_abbrev_section_index.?;
1915 try d_sym.growSection(sect_index, needed_size, false, macho_file);
1916 const sect = d_sym.getSection(sect_index);
1917 const file_pos = sect.offset + abbrev_offset;
1918 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);
1919 }
1920 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1921 _ = wasm_file;
1922 // const debug_abbrev = &wasm_file.getAtomPtr(wasm_file.debug_abbrev_atom.?).code;
1923 // try debug_abbrev.resize(gpa, needed_size);
1924 // debug_abbrev.items[0..abbrev_buf.len].* = abbrev_buf;
1925 } else unreachable;
19671926}
19681927
19691928fn dbgInfoHeaderBytes(self: *Dwarf) usize {
......@@ -2027,37 +1986,30 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Zcu, low_pc: u64, high_pc: u64) !v
20271986 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99, target_endian);
20281987
20291988 if (di_buf.items.len > first_dbg_info_off) {
2030 // Move the first N decls to the end to make more padding for the header.
1989 // Move the first N navs to the end to make more padding for the header.
20311990 @panic("TODO: handle .debug_info header exceeding its padding");
20321991 }
20331992 const jmp_amt = first_dbg_info_off - di_buf.items.len;
2034 switch (self.bin_file.tag) {
2035 .elf => {
2036 const elf_file = self.bin_file.cast(File.Elf).?;
2037 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
2038 const file_pos = debug_info_sect.sh_offset;
2039 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
2040 },
2041 .macho => {
2042 const macho_file = self.bin_file.cast(File.MachO).?;
2043 if (macho_file.base.isRelocatable()) {
2044 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2045 const file_pos = debug_info_sect.offset;
2046 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
2047 } else {
2048 const d_sym = macho_file.getDebugSymbols().?;
2049 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);
2050 const file_pos = debug_info_sect.offset;
2051 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
2052 }
2053 },
2054 .wasm => {
2055 // const wasm_file = self.bin_file.cast(File.Wasm).?;
2056 // const debug_info = &wasm_file.getAtomPtr(wasm_file.debug_info_atom.?).code;
2057 // try writeDbgInfoNopsToArrayList(self.allocator, debug_info, 0, 0, di_buf.items, jmp_amt, false);
2058 },
2059 else => unreachable,
2060 }
1993 if (self.bin_file.cast(.elf)) |elf_file| {
1994 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
1995 const file_pos = debug_info_sect.sh_offset;
1996 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
1997 } else if (self.bin_file.cast(.macho)) |macho_file| {
1998 if (macho_file.base.isRelocatable()) {
1999 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2000 const file_pos = debug_info_sect.offset;
2001 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
2002 } else {
2003 const d_sym = macho_file.getDebugSymbols().?;
2004 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);
2005 const file_pos = debug_info_sect.offset;
2006 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
2007 }
2008 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2009 _ = wasm_file;
2010 // const debug_info = &wasm_file.getAtomPtr(wasm_file.debug_info_atom.?).code;
2011 // try writeDbgInfoNopsToArrayList(self.allocator, debug_info, 0, 0, di_buf.items, jmp_amt, false);
2012 } else unreachable;
20612013}
20622014
20632015fn resolveCompilationDir(zcu: *Zcu, buffer: *[std.fs.max_path_bytes]u8) []const u8 {
......@@ -2360,40 +2312,33 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
23602312 }
23612313
23622314 const needed_size: u32 = @intCast(di_buf.items.len);
2363 switch (self.bin_file.tag) {
2364 .elf => {
2365 const elf_file = self.bin_file.cast(File.Elf).?;
2366 const shdr_index = elf_file.debug_aranges_section_index.?;
2367 try elf_file.growNonAllocSection(shdr_index, needed_size, 16, false);
2368 const debug_aranges_sect = &elf_file.shdrs.items[shdr_index];
2369 const file_pos = debug_aranges_sect.sh_offset;
2370 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2371 },
2372 .macho => {
2373 const macho_file = self.bin_file.cast(File.MachO).?;
2374 if (macho_file.base.isRelocatable()) {
2375 const sect_index = macho_file.debug_aranges_sect_index.?;
2376 try macho_file.growSection(sect_index, needed_size);
2377 const sect = macho_file.sections.items(.header)[sect_index];
2378 const file_pos = sect.offset;
2379 try macho_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2380 } else {
2381 const d_sym = macho_file.getDebugSymbols().?;
2382 const sect_index = d_sym.debug_aranges_section_index.?;
2383 try d_sym.growSection(sect_index, needed_size, false, macho_file);
2384 const sect = d_sym.getSection(sect_index);
2385 const file_pos = sect.offset;
2386 try d_sym.file.pwriteAll(di_buf.items, file_pos);
2387 }
2388 },
2389 .wasm => {
2390 // const wasm_file = self.bin_file.cast(File.Wasm).?;
2391 // const debug_ranges = &wasm_file.getAtomPtr(wasm_file.debug_ranges_atom.?).code;
2392 // try debug_ranges.resize(gpa, needed_size);
2393 // @memcpy(debug_ranges.items[0..di_buf.items.len], di_buf.items);
2394 },
2395 else => unreachable,
2396 }
2315 if (self.bin_file.cast(.elf)) |elf_file| {
2316 const shdr_index = elf_file.debug_aranges_section_index.?;
2317 try elf_file.growNonAllocSection(shdr_index, needed_size, 16, false);
2318 const debug_aranges_sect = &elf_file.shdrs.items[shdr_index];
2319 const file_pos = debug_aranges_sect.sh_offset;
2320 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2321 } else if (self.bin_file.cast(.macho)) |macho_file| {
2322 if (macho_file.base.isRelocatable()) {
2323 const sect_index = macho_file.debug_aranges_sect_index.?;
2324 try macho_file.growSection(sect_index, needed_size);
2325 const sect = macho_file.sections.items(.header)[sect_index];
2326 const file_pos = sect.offset;
2327 try macho_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2328 } else {
2329 const d_sym = macho_file.getDebugSymbols().?;
2330 const sect_index = d_sym.debug_aranges_section_index.?;
2331 try d_sym.growSection(sect_index, needed_size, false, macho_file);
2332 const sect = d_sym.getSection(sect_index);
2333 const file_pos = sect.offset;
2334 try d_sym.file.pwriteAll(di_buf.items, file_pos);
2335 }
2336 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2337 _ = wasm_file;
2338 // const debug_ranges = &wasm_file.getAtomPtr(wasm_file.debug_ranges_atom.?).code;
2339 // try debug_ranges.resize(gpa, needed_size);
2340 // @memcpy(debug_ranges.items[0..di_buf.items.len], di_buf.items);
2341 } else unreachable;
23972342}
23982343
23992344pub fn writeDbgLineHeader(self: *Dwarf) !void {
......@@ -2502,60 +2447,52 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
25022447
25032448 var src_fn_index = first_fn_index;
25042449
2505 var buffer = try gpa.alloc(u8, last_fn.off + last_fn.len - first_fn.off);
2450 const buffer = try gpa.alloc(u8, last_fn.off + last_fn.len - first_fn.off);
25062451 defer gpa.free(buffer);
25072452
2508 switch (self.bin_file.tag) {
2509 .elf => {
2510 const elf_file = self.bin_file.cast(File.Elf).?;
2511 const shdr_index = elf_file.debug_line_section_index.?;
2512 const needed_size = elf_file.shdrs.items[shdr_index].sh_size + delta;
2513 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
2514 const file_pos = elf_file.shdrs.items[shdr_index].sh_offset + first_fn.off;
2453 if (self.bin_file.cast(.elf)) |elf_file| {
2454 const shdr_index = elf_file.debug_line_section_index.?;
2455 const needed_size = elf_file.shdrs.items[shdr_index].sh_size + delta;
2456 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
2457 const file_pos = elf_file.shdrs.items[shdr_index].sh_offset + first_fn.off;
25152458
2516 const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
2517 if (amt != buffer.len) return error.InputOutput;
2459 const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
2460 if (amt != buffer.len) return error.InputOutput;
25182461
2519 try elf_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2520 },
2521 .macho => {
2522 const macho_file = self.bin_file.cast(File.MachO).?;
2523 if (macho_file.base.isRelocatable()) {
2524 const sect_index = macho_file.debug_line_sect_index.?;
2525 const needed_size: u32 = @intCast(macho_file.sections.items(.header)[sect_index].size + delta);
2526 try macho_file.growSection(sect_index, needed_size);
2527 const file_pos = macho_file.sections.items(.header)[sect_index].offset + first_fn.off;
2462 try elf_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2463 } else if (self.bin_file.cast(.macho)) |macho_file| {
2464 if (macho_file.base.isRelocatable()) {
2465 const sect_index = macho_file.debug_line_sect_index.?;
2466 const needed_size: u32 = @intCast(macho_file.sections.items(.header)[sect_index].size + delta);
2467 try macho_file.growSection(sect_index, needed_size);
2468 const file_pos = macho_file.sections.items(.header)[sect_index].offset + first_fn.off;
25282469
2529 const amt = try macho_file.base.file.?.preadAll(buffer, file_pos);
2530 if (amt != buffer.len) return error.InputOutput;
2470 const amt = try macho_file.base.file.?.preadAll(buffer, file_pos);
2471 if (amt != buffer.len) return error.InputOutput;
25312472
2532 try macho_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2533 } else {
2534 const d_sym = macho_file.getDebugSymbols().?;
2535 const sect_index = d_sym.debug_line_section_index.?;
2536 const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta);
2537 try d_sym.growSection(sect_index, needed_size, true, macho_file);
2538 const file_pos = d_sym.getSection(sect_index).offset + first_fn.off;
2473 try macho_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2474 } else {
2475 const d_sym = macho_file.getDebugSymbols().?;
2476 const sect_index = d_sym.debug_line_section_index.?;
2477 const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta);
2478 try d_sym.growSection(sect_index, needed_size, true, macho_file);
2479 const file_pos = d_sym.getSection(sect_index).offset + first_fn.off;
25392480
2540 const amt = try d_sym.file.preadAll(buffer, file_pos);
2541 if (amt != buffer.len) return error.InputOutput;
2481 const amt = try d_sym.file.preadAll(buffer, file_pos);
2482 if (amt != buffer.len) return error.InputOutput;
25422483
2543 try d_sym.file.pwriteAll(buffer, file_pos + delta);
2544 }
2545 },
2546 .wasm => {
2547 _ = &buffer;
2548 // const wasm_file = self.bin_file.cast(File.Wasm).?;
2549 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
2550 // {
2551 // const src = debug_line.items[first_fn.off..];
2552 // @memcpy(buffer[0..src.len], src);
2553 // }
2554 // try debug_line.resize(self.allocator, debug_line.items.len + delta);
2555 // @memcpy(debug_line.items[first_fn.off + delta ..][0..buffer.len], buffer);
2556 },
2557 else => unreachable,
2558 }
2484 try d_sym.file.pwriteAll(buffer, file_pos + delta);
2485 }
2486 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2487 _ = wasm_file;
2488 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
2489 // {
2490 // const src = debug_line.items[first_fn.off..];
2491 // @memcpy(buffer[0..src.len], src);
2492 // }
2493 // try debug_line.resize(self.allocator, debug_line.items.len + delta);
2494 // @memcpy(debug_line.items[first_fn.off + delta ..][0..buffer.len], buffer);
2495 } else unreachable;
25592496
25602497 while (true) {
25612498 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);
......@@ -2580,33 +2517,26 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
25802517
25812518 // We use NOPs because consumers empirically do not respect the header length field.
25822519 const jmp_amt = self.getDebugLineProgramOff().? - di_buf.items.len;
2583 switch (self.bin_file.tag) {
2584 .elf => {
2585 const elf_file = self.bin_file.cast(File.Elf).?;
2586 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
2587 const file_pos = debug_line_sect.sh_offset;
2588 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2589 },
2590 .macho => {
2591 const macho_file = self.bin_file.cast(File.MachO).?;
2592 if (macho_file.base.isRelocatable()) {
2593 const debug_line_sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
2594 const file_pos = debug_line_sect.offset;
2595 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2596 } else {
2597 const d_sym = macho_file.getDebugSymbols().?;
2598 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);
2599 const file_pos = debug_line_sect.offset;
2600 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2601 }
2602 },
2603 .wasm => {
2604 // const wasm_file = self.bin_file.cast(File.Wasm).?;
2605 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
2606 // writeDbgLineNopsBuffered(debug_line.items, 0, 0, di_buf.items, jmp_amt);
2607 },
2608 else => unreachable,
2609 }
2520 if (self.bin_file.cast(.elf)) |elf_file| {
2521 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
2522 const file_pos = debug_line_sect.sh_offset;
2523 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2524 } else if (self.bin_file.cast(.macho)) |macho_file| {
2525 if (macho_file.base.isRelocatable()) {
2526 const debug_line_sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
2527 const file_pos = debug_line_sect.offset;
2528 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2529 } else {
2530 const d_sym = macho_file.getDebugSymbols().?;
2531 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);
2532 const file_pos = debug_line_sect.offset;
2533 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2534 }
2535 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2536 _ = wasm_file;
2537 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
2538 // writeDbgLineNopsBuffered(debug_line.items, 0, 0, di_buf.items, jmp_amt);
2539 } else unreachable;
26102540}
26112541
26122542fn getDebugInfoOff(self: Dwarf) ?u32 {
......@@ -2704,85 +2634,66 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {
27042634 );
27052635
27062636 const di_atom_index = try self.createAtom(.di_atom);
2707 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});
2708 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));
2709 log.debug("writeDeclDebugInfo in flushModule", .{});
2710 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
2711
2712 const file_pos = switch (self.bin_file.tag) {
2713 .elf => pos: {
2714 const elf_file = self.bin_file.cast(File.Elf).?;
2715 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
2716 break :pos debug_info_sect.sh_offset;
2717 },
2718 .macho => pos: {
2719 const macho_file = self.bin_file.cast(File.MachO).?;
2720 if (macho_file.base.isRelocatable()) {
2721 const debug_info_sect = &macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2722 break :pos debug_info_sect.offset;
2723 } else {
2724 const d_sym = macho_file.getDebugSymbols().?;
2725 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2726 break :pos debug_info_sect.offset;
2727 }
2728 },
2637 log.debug("updateNavDebugInfoAllocation in flushModule", .{});
2638 try self.updateNavDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));
2639 log.debug("writeNavDebugInfo in flushModule", .{});
2640 try self.writeNavDebugInfo(di_atom_index, dbg_info_buffer.items);
2641
2642 const file_pos = if (self.bin_file.cast(.elf)) |elf_file| pos: {
2643 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
2644 break :pos debug_info_sect.sh_offset;
2645 } else if (self.bin_file.cast(.macho)) |macho_file| pos: {
2646 if (macho_file.base.isRelocatable()) {
2647 const debug_info_sect = &macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2648 break :pos debug_info_sect.offset;
2649 } else {
2650 const d_sym = macho_file.getDebugSymbols().?;
2651 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2652 break :pos debug_info_sect.offset;
2653 }
2654 } else if (self.bin_file.cast(.wasm)) |_|
27292655 // for wasm, the offset is always 0 as we write to memory first
2730 .wasm => 0,
2731 else => unreachable,
2732 };
2656 0
2657 else
2658 unreachable;
27332659
27342660 var buf: [@sizeOf(u32)]u8 = undefined;
27352661 mem.writeInt(u32, &buf, self.getAtom(.di_atom, di_atom_index).off, target.cpu.arch.endian());
27362662
27372663 while (self.global_abbrev_relocs.popOrNull()) |reloc| {
27382664 const atom = self.getAtom(.di_atom, reloc.atom_index);
2739 switch (self.bin_file.tag) {
2740 .elf => {
2741 const elf_file = self.bin_file.cast(File.Elf).?;
2742 try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2743 },
2744 .macho => {
2745 const macho_file = self.bin_file.cast(File.MachO).?;
2746 if (macho_file.base.isRelocatable()) {
2747 try macho_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2748 } else {
2749 const d_sym = macho_file.getDebugSymbols().?;
2750 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2751 }
2752 },
2753 .wasm => {
2754 // const wasm_file = self.bin_file.cast(File.Wasm).?;
2755 // const debug_info = wasm_file.getAtomPtr(wasm_file.debug_info_atom.?).code;
2756 // debug_info.items[atom.off + reloc.offset ..][0..buf.len].* = buf;
2757 },
2758 else => unreachable,
2759 }
2665 if (self.bin_file.cast(.elf)) |elf_file| {
2666 try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2667 } else if (self.bin_file.cast(.macho)) |macho_file| {
2668 if (macho_file.base.isRelocatable()) {
2669 try macho_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2670 } else {
2671 const d_sym = macho_file.getDebugSymbols().?;
2672 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2673 }
2674 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2675 _ = wasm_file;
2676 // const debug_info = wasm_file.getAtomPtr(wasm_file.debug_info_atom.?).code;
2677 // debug_info.items[atom.off + reloc.offset ..][0..buf.len].* = buf;
2678 } else unreachable;
27602679 }
27612680 }
27622681}
27632682
2764fn addDIFile(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !u28 {
2765 const decl = zcu.declPtr(decl_index);
2766 const file_scope = decl.getFileScope(zcu);
2683fn addDIFile(self: *Dwarf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !u28 {
2684 const file_scope = zcu.navFileScope(nav_index);
27672685 const gop = try self.di_files.getOrPut(self.allocator, file_scope);
27682686 if (!gop.found_existing) {
2769 switch (self.bin_file.tag) {
2770 .elf => {
2771 const elf_file = self.bin_file.cast(File.Elf).?;
2772 elf_file.markDirty(elf_file.debug_line_section_index.?);
2773 },
2774 .macho => {
2775 const macho_file = self.bin_file.cast(File.MachO).?;
2776 if (macho_file.base.isRelocatable()) {
2777 macho_file.markDirty(macho_file.debug_line_sect_index.?);
2778 } else {
2779 const d_sym = macho_file.getDebugSymbols().?;
2780 d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file);
2781 }
2782 },
2783 .wasm => {},
2784 else => unreachable,
2785 }
2687 if (self.bin_file.cast(.elf)) |elf_file| {
2688 elf_file.markDirty(elf_file.debug_line_section_index.?);
2689 } else if (self.bin_file.cast(.macho)) |macho_file| {
2690 if (macho_file.base.isRelocatable()) {
2691 macho_file.markDirty(macho_file.debug_line_sect_index.?);
2692 } else {
2693 const d_sym = macho_file.getDebugSymbols().?;
2694 d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file);
2695 }
2696 } else if (self.bin_file.cast(.wasm)) |_| {} else unreachable;
27862697 }
27872698 return @intCast(gop.index + 1);
27882699}
......@@ -2909,17 +2820,17 @@ fn createAtom(self: *Dwarf, comptime kind: Kind) !Atom.Index {
29092820 return index;
29102821}
29112822
2912fn getOrCreateAtomForDecl(self: *Dwarf, comptime kind: Kind, decl_index: InternPool.DeclIndex) !Atom.Index {
2823fn getOrCreateAtomForNav(self: *Dwarf, comptime kind: Kind, nav_index: InternPool.Nav.Index) !Atom.Index {
29132824 switch (kind) {
29142825 .src_fn => {
2915 const gop = try self.src_fn_decls.getOrPut(self.allocator, decl_index);
2826 const gop = try self.src_fn_navs.getOrPut(self.allocator, nav_index);
29162827 if (!gop.found_existing) {
29172828 gop.value_ptr.* = try self.createAtom(kind);
29182829 }
29192830 return gop.value_ptr.*;
29202831 },
29212832 .di_atom => {
2922 const gop = try self.di_atom_decls.getOrPut(self.allocator, decl_index);
2833 const gop = try self.di_atom_navs.getOrPut(self.allocator, nav_index);
29232834 if (!gop.found_existing) {
29242835 gop.value_ptr.* = try self.createAtom(kind);
29252836 }
src/link/Elf.zig+18-22
......@@ -478,24 +478,24 @@ pub fn deinit(self: *Elf) void {
478478 self.comdat_group_sections.deinit(gpa);
479479}
480480
481pub fn getDeclVAddr(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
481pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
482482 assert(self.llvm_object == null);
483 return self.zigObjectPtr().?.getDeclVAddr(self, pt, decl_index, reloc_info);
483 return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info);
484484}
485485
486pub fn lowerAnonDecl(
486pub fn lowerUav(
487487 self: *Elf,
488488 pt: Zcu.PerThread,
489 decl_val: InternPool.Index,
489 uav: InternPool.Index,
490490 explicit_alignment: InternPool.Alignment,
491491 src_loc: Zcu.LazySrcLoc,
492) !codegen.Result {
493 return self.zigObjectPtr().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc);
492) !codegen.GenResult {
493 return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment, src_loc);
494494}
495495
496pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
496pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
497497 assert(self.llvm_object == null);
498 return self.zigObjectPtr().?.getAnonDeclVAddr(self, decl_val, reloc_info);
498 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);
499499}
500500
501501/// Returns end pos of collision, if any.
......@@ -2913,9 +2913,9 @@ pub fn writeElfHeader(self: *Elf) !void {
29132913 try self.base.file.?.pwriteAll(hdr_buf[0..index], 0);
29142914}
29152915
2916pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void {
2917 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
2918 return self.zigObjectPtr().?.freeDecl(self, decl_index);
2916pub fn freeNav(self: *Elf, nav: InternPool.Nav.Index) void {
2917 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav);
2918 return self.zigObjectPtr().?.freeNav(self, nav);
29192919}
29202920
29212921pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
......@@ -2926,20 +2926,16 @@ pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, a
29262926 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness);
29272927}
29282928
2929pub fn updateDecl(
2929pub fn updateNav(
29302930 self: *Elf,
29312931 pt: Zcu.PerThread,
2932 decl_index: InternPool.DeclIndex,
2933) link.File.UpdateDeclError!void {
2932 nav: InternPool.Nav.Index,
2933) link.File.UpdateNavError!void {
29342934 if (build_options.skip_non_native and builtin.object_format != .elf) {
29352935 @panic("Attempted to compile for object format that was disabled by build configuration");
29362936 }
2937 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
2938 return self.zigObjectPtr().?.updateDecl(self, pt, decl_index);
2939}
2940
2941pub fn lowerUnnamedConst(self: *Elf, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
2942 return self.zigObjectPtr().?.lowerUnnamedConst(self, pt, val, decl_index);
2937 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
2938 return self.zigObjectPtr().?.updateNav(self, pt, nav);
29432939}
29442940
29452941pub fn updateExports(
......@@ -2955,9 +2951,9 @@ pub fn updateExports(
29552951 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
29562952}
29572953
2958pub fn updateDeclLineNumber(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
2954pub fn updateNavLineNumber(self: *Elf, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
29592955 if (self.llvm_object) |_| return;
2960 return self.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);
2956 return self.zigObjectPtr().?.updateNavLineNumber(pt, nav);
29612957}
29622958
29632959pub fn deleteExport(
src/link/Elf/ZigObject.zig+223-322
......@@ -32,35 +32,14 @@ dwarf: ?Dwarf = null,
3232/// Table of tracked LazySymbols.
3333lazy_syms: LazySymbolTable = .{},
3434
35/// Table of tracked Decls.
36decls: DeclTable = .{},
35/// Table of tracked `Nav`s.
36navs: NavTable = .{},
3737
3838/// TLS variables indexed by Atom.Index.
3939tls_variables: TlsTable = .{},
4040
41/// Table of unnamed constants associated with a parent `Decl`.
42/// We store them here so that we can free the constants whenever the `Decl`
43/// needs updating or is freed.
44///
45/// For example,
46///
47/// ```zig
48/// const Foo = struct{
49/// a: u8,
50/// };
51///
52/// pub fn main() void {
53/// var foo = Foo{ .a = 1 };
54/// _ = foo;
55/// }
56/// ```
57///
58/// value assigned to label `foo` is an unnamed constant belonging/associated
59/// with `Decl` `main`, and lives as long as that `Decl`.
60unnamed_consts: UnnamedConstTable = .{},
61
62/// Table of tracked AnonDecls.
63anon_decls: AnonDeclTable = .{},
41/// Table of tracked `Uav`s.
42uavs: UavTable = .{},
6443
6544debug_strtab_dirty: bool = false,
6645debug_abbrev_section_dirty: bool = false,
......@@ -124,29 +103,21 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
124103 self.relocs.deinit(allocator);
125104
126105 {
127 var it = self.decls.iterator();
106 var it = self.navs.iterator();
128107 while (it.next()) |entry| {
129108 entry.value_ptr.exports.deinit(allocator);
130109 }
131 self.decls.deinit(allocator);
110 self.navs.deinit(allocator);
132111 }
133112
134113 self.lazy_syms.deinit(allocator);
135114
136115 {
137 var it = self.unnamed_consts.valueIterator();
138 while (it.next()) |syms| {
139 syms.deinit(allocator);
140 }
141 self.unnamed_consts.deinit(allocator);
142 }
143
144 {
145 var it = self.anon_decls.iterator();
116 var it = self.uavs.iterator();
146117 while (it.next()) |entry| {
147118 entry.value_ptr.exports.deinit(allocator);
148119 }
149 self.anon_decls.deinit(allocator);
120 self.uavs.deinit(allocator);
150121 }
151122
152123 for (self.tls_variables.values()) |*tlv| {
......@@ -161,7 +132,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
161132
162133pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
163134 // Handle any lazy symbols that were emitted by incremental compilation.
164 if (self.lazy_syms.getPtr(.none)) |metadata| {
135 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {
165136 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };
166137
167138 // Most lazy symbols can be updated on first use, but
......@@ -169,7 +140,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
169140 if (metadata.text_state != .unused) self.updateLazySymbol(
170141 elf_file,
171142 pt,
172 link.File.LazySymbol.initDecl(.code, null, pt.zcu),
143 .{ .kind = .code, .ty = .anyerror_type },
173144 metadata.text_symbol_index,
174145 ) catch |err| return switch (err) {
175146 error.CodegenFail => error.FlushFailure,
......@@ -178,7 +149,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
178149 if (metadata.rodata_state != .unused) self.updateLazySymbol(
179150 elf_file,
180151 pt,
181 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),
152 .{ .kind = .const_data, .ty = .anyerror_type },
182153 metadata.rodata_symbol_index,
183154 ) catch |err| return switch (err) {
184155 error.CodegenFail => error.FlushFailure,
......@@ -661,25 +632,25 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8
661632 return code;
662633}
663634
664pub fn getDeclVAddr(
635pub fn getNavVAddr(
665636 self: *ZigObject,
666637 elf_file: *Elf,
667638 pt: Zcu.PerThread,
668 decl_index: InternPool.DeclIndex,
639 nav_index: InternPool.Nav.Index,
669640 reloc_info: link.File.RelocInfo,
670641) !u64 {
671642 const zcu = pt.zcu;
672643 const ip = &zcu.intern_pool;
673 const decl = zcu.declPtr(decl_index);
674 log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index });
675 const this_sym_index = if (decl.isExtern(zcu)) blk: {
676 const name = decl.name.toSlice(ip);
677 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|
678 ext_fn.lib_name.toSlice(ip)
679 else
680 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);
681 break :blk try self.getGlobalSymbol(elf_file, name, lib_name);
682 } else try self.getOrCreateMetadataForDecl(elf_file, decl_index);
644 const nav = ip.getNav(nav_index);
645 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
646 const this_sym_index = switch (ip.indexToKey(nav.status.resolved.val)) {
647 .@"extern" => |@"extern"| try self.getGlobalSymbol(
648 elf_file,
649 nav.name.toSlice(ip),
650 @"extern".lib_name.toSlice(ip),
651 ),
652 else => try self.getOrCreateMetadataForNav(elf_file, nav_index),
653 };
683654 const this_sym = self.symbol(this_sym_index);
684655 const vaddr = this_sym.address(.{}, elf_file);
685656 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
......@@ -692,13 +663,13 @@ pub fn getDeclVAddr(
692663 return @intCast(vaddr);
693664}
694665
695pub fn getAnonDeclVAddr(
666pub fn getUavVAddr(
696667 self: *ZigObject,
697668 elf_file: *Elf,
698 decl_val: InternPool.Index,
669 uav: InternPool.Index,
699670 reloc_info: link.File.RelocInfo,
700671) !u64 {
701 const sym_index = self.anon_decls.get(decl_val).?.symbol_index;
672 const sym_index = self.uavs.get(uav).?.symbol_index;
702673 const sym = self.symbol(sym_index);
703674 const vaddr = sym.address(.{}, elf_file);
704675 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
......@@ -711,43 +682,43 @@ pub fn getAnonDeclVAddr(
711682 return @intCast(vaddr);
712683}
713684
714pub fn lowerAnonDecl(
685pub fn lowerUav(
715686 self: *ZigObject,
716687 elf_file: *Elf,
717688 pt: Zcu.PerThread,
718 decl_val: InternPool.Index,
689 uav: InternPool.Index,
719690 explicit_alignment: InternPool.Alignment,
720 src_loc: Module.LazySrcLoc,
721) !codegen.Result {
722 const gpa = elf_file.base.comp.gpa;
723 const mod = elf_file.base.comp.module.?;
724 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
725 const decl_alignment = switch (explicit_alignment) {
726 .none => ty.abiAlignment(pt),
691 src_loc: Zcu.LazySrcLoc,
692) !codegen.GenResult {
693 const zcu = pt.zcu;
694 const gpa = zcu.gpa;
695 const val = Value.fromInterned(uav);
696 const uav_alignment = switch (explicit_alignment) {
697 .none => val.typeOf(zcu).abiAlignment(pt),
727698 else => explicit_alignment,
728699 };
729 if (self.anon_decls.get(decl_val)) |metadata| {
730 const existing_alignment = self.symbol(metadata.symbol_index).atom(elf_file).?.alignment;
731 if (decl_alignment.order(existing_alignment).compare(.lte))
732 return .ok;
700 if (self.uavs.get(uav)) |metadata| {
701 const sym = self.symbol(metadata.symbol_index);
702 const existing_alignment = sym.atom(elf_file).?.alignment;
703 if (uav_alignment.order(existing_alignment).compare(.lte))
704 return .{ .mcv = .{ .load_symbol = metadata.symbol_index } };
733705 }
734706
735 const val = Value.fromInterned(decl_val);
736707 var name_buf: [32]u8 = undefined;
737708 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
738 @intFromEnum(decl_val),
709 @intFromEnum(uav),
739710 }) catch unreachable;
740711 const res = self.lowerConst(
741712 elf_file,
742713 pt,
743714 name,
744715 val,
745 decl_alignment,
716 uav_alignment,
746717 elf_file.zig_data_rel_ro_section_index.?,
747718 src_loc,
748719 ) catch |err| switch (err) {
749720 error.OutOfMemory => return error.OutOfMemory,
750 else => |e| return .{ .fail = try Module.ErrorMsg.create(
721 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
751722 gpa,
752723 src_loc,
753724 "unable to lower constant value: {s}",
......@@ -758,8 +729,8 @@ pub fn lowerAnonDecl(
758729 .ok => |sym_index| sym_index,
759730 .fail => |em| return .{ .fail = em },
760731 };
761 try self.anon_decls.put(gpa, decl_val, .{ .symbol_index = sym_index });
762 return .ok;
732 try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index });
733 return .{ .mcv = .{ .load_symbol = sym_index } };
763734}
764735
765736pub fn getOrCreateMetadataForLazySymbol(
......@@ -768,51 +739,32 @@ pub fn getOrCreateMetadataForLazySymbol(
768739 pt: Zcu.PerThread,
769740 lazy_sym: link.File.LazySymbol,
770741) !Symbol.Index {
771 const mod = pt.zcu;
772 const gpa = mod.gpa;
773 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
742 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
774743 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
775744 if (!gop.found_existing) gop.value_ptr.* = .{};
776 const metadata: struct {
777 symbol_index: *Symbol.Index,
778 state: *LazySymbolMetadata.State,
779 } = switch (lazy_sym.kind) {
780 .code => .{
781 .symbol_index = &gop.value_ptr.text_symbol_index,
782 .state = &gop.value_ptr.text_state,
783 },
784 .const_data => .{
785 .symbol_index = &gop.value_ptr.rodata_symbol_index,
786 .state = &gop.value_ptr.rodata_state,
787 },
745 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
746 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },
747 .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state },
788748 };
789 switch (metadata.state.*) {
749 switch (state_ptr.*) {
790750 .unused => {
751 const gpa = elf_file.base.comp.gpa;
791752 const symbol_index = try self.newSymbolWithAtom(gpa, 0);
792753 const sym = self.symbol(symbol_index);
793754 sym.flags.needs_zig_got = true;
794 metadata.symbol_index.* = symbol_index;
755 symbol_index_ptr.* = symbol_index;
795756 },
796 .pending_flush => return metadata.symbol_index.*,
757 .pending_flush => return symbol_index_ptr.*,
797758 .flushed => {},
798759 }
799 metadata.state.* = .pending_flush;
800 const symbol_index = metadata.symbol_index.*;
760 state_ptr.* = .pending_flush;
761 const symbol_index = symbol_index_ptr.*;
801762 // anyerror needs to be deferred until flushModule
802 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);
763 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);
803764 return symbol_index;
804765}
805766
806fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void {
807 const gpa = elf_file.base.comp.gpa;
808 const unnamed_consts = self.unnamed_consts.getPtr(decl_index) orelse return;
809 for (unnamed_consts.items) |sym_index| {
810 self.freeDeclMetadata(elf_file, sym_index);
811 }
812 unnamed_consts.clearAndFree(gpa);
813}
814
815fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void {
767fn freeNavMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void {
816768 const sym = self.symbol(sym_index);
817769 sym.atom(elf_file).?.free(elf_file);
818770 log.debug("adding %{d} to local symbols free list", .{sym_index});
......@@ -820,38 +772,37 @@ fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) v
820772 // TODO free GOT entry here
821773}
822774
823pub fn freeDecl(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void {
775pub fn freeNav(self: *ZigObject, elf_file: *Elf, nav_index: InternPool.Nav.Index) void {
824776 const gpa = elf_file.base.comp.gpa;
825777
826 log.debug("freeDecl ({d})", .{decl_index});
778 log.debug("freeNav ({d})", .{nav_index});
827779
828 if (self.decls.fetchRemove(decl_index)) |const_kv| {
780 if (self.navs.fetchRemove(nav_index)) |const_kv| {
829781 var kv = const_kv;
830782 const sym_index = kv.value.symbol_index;
831 self.freeDeclMetadata(elf_file, sym_index);
832 self.freeUnnamedConsts(elf_file, decl_index);
783 self.freeNavMetadata(elf_file, sym_index);
833784 kv.value.exports.deinit(gpa);
834785 }
835786
836787 if (self.dwarf) |*dw| {
837 dw.freeDecl(decl_index);
788 dw.freeNav(nav_index);
838789 }
839790}
840791
841pub fn getOrCreateMetadataForDecl(
792pub fn getOrCreateMetadataForNav(
842793 self: *ZigObject,
843794 elf_file: *Elf,
844 decl_index: InternPool.DeclIndex,
795 nav_index: InternPool.Nav.Index,
845796) !Symbol.Index {
846797 const gpa = elf_file.base.comp.gpa;
847 const gop = try self.decls.getOrPut(gpa, decl_index);
798 const gop = try self.navs.getOrPut(gpa, nav_index);
848799 if (!gop.found_existing) {
849800 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
850801 const symbol_index = try self.newSymbolWithAtom(gpa, 0);
851 const mod = elf_file.base.comp.module.?;
852 const decl = mod.declPtr(decl_index);
802 const zcu = elf_file.base.comp.module.?;
803 const nav_val = Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.resolved.val);
853804 const sym = self.symbol(symbol_index);
854 if (decl.getOwnedVariable(mod)) |variable| {
805 if (nav_val.getVariable(zcu)) |variable| {
855806 if (variable.is_threadlocal and any_non_single_threaded) {
856807 sym.flags.is_tls = true;
857808 }
......@@ -864,89 +815,81 @@ pub fn getOrCreateMetadataForDecl(
864815 return gop.value_ptr.symbol_index;
865816}
866817
867fn getDeclShdrIndex(
818fn getNavShdrIndex(
868819 self: *ZigObject,
869820 elf_file: *Elf,
870 decl: *const Module.Decl,
821 zcu: *Zcu,
822 nav_index: InternPool.Nav.Index,
871823 code: []const u8,
872824) error{OutOfMemory}!u32 {
873825 _ = self;
874 const mod = elf_file.base.comp.module.?;
826 const ip = &zcu.intern_pool;
875827 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
876 const shdr_index = switch (decl.typeOf(mod).zigTypeTag(mod)) {
877 .Fn => elf_file.zig_text_section_index.?,
878 else => blk: {
879 if (decl.getOwnedVariable(mod)) |variable| {
880 if (variable.is_threadlocal and any_non_single_threaded) {
881 const is_all_zeroes = for (code) |byte| {
882 if (byte != 0) break false;
883 } else true;
884 if (is_all_zeroes) break :blk elf_file.sectionByName(".tbss") orelse try elf_file.addSection(.{
885 .type = elf.SHT_NOBITS,
886 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
887 .name = try elf_file.insertShString(".tbss"),
888 .offset = std.math.maxInt(u64),
889 });
890
891 break :blk elf_file.sectionByName(".tdata") orelse try elf_file.addSection(.{
892 .type = elf.SHT_PROGBITS,
893 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
894 .name = try elf_file.insertShString(".tdata"),
895 .offset = std.math.maxInt(u64),
896 });
897 }
898 if (variable.is_const) break :blk elf_file.zig_data_rel_ro_section_index.?;
899 if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
900 // TODO: get the optimize_mode from the Module that owns the decl instead
901 // of using the root module here.
902 break :blk switch (elf_file.base.comp.root_mod.optimize_mode) {
903 .Debug, .ReleaseSafe => elf_file.zig_data_section_index.?,
904 .ReleaseFast, .ReleaseSmall => elf_file.zig_bss_section_index.?,
905 };
906 }
907 // TODO I blatantly copied the logic from the Wasm linker, but is there a less
908 // intrusive check for all zeroes than this?
909 const is_all_zeroes = for (code) |byte| {
910 if (byte != 0) break false;
911 } else true;
912 if (is_all_zeroes) break :blk elf_file.zig_bss_section_index.?;
913 break :blk elf_file.zig_data_section_index.?;
914 }
915 break :blk elf_file.zig_data_rel_ro_section_index.?;
916 },
828 const nav_val = zcu.navValue(nav_index);
829 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return elf_file.zig_text_section_index.?;
830 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
831 .variable => |variable| .{ false, variable.is_threadlocal, variable.init },
832 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
833 else => .{ true, false, nav_val.toIntern() },
917834 };
918 return shdr_index;
835 if (any_non_single_threaded and is_threadlocal) {
836 for (code) |byte| {
837 if (byte != 0) break;
838 } else return elf_file.sectionByName(".tbss") orelse try elf_file.addSection(.{
839 .type = elf.SHT_NOBITS,
840 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
841 .name = try elf_file.insertShString(".tbss"),
842 .offset = std.math.maxInt(u64),
843 });
844 return elf_file.sectionByName(".tdata") orelse try elf_file.addSection(.{
845 .type = elf.SHT_PROGBITS,
846 .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS,
847 .name = try elf_file.insertShString(".tdata"),
848 .offset = std.math.maxInt(u64),
849 });
850 }
851 if (is_const) return elf_file.zig_data_rel_ro_section_index.?;
852 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
853 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
854 .Debug, .ReleaseSafe => elf_file.zig_data_section_index.?,
855 .ReleaseFast, .ReleaseSmall => elf_file.zig_bss_section_index.?,
856 };
857 for (code) |byte| {
858 if (byte != 0) break;
859 } else return elf_file.zig_bss_section_index.?;
860 return elf_file.zig_data_section_index.?;
919861}
920862
921fn updateDeclCode(
863fn updateNavCode(
922864 self: *ZigObject,
923865 elf_file: *Elf,
924866 pt: Zcu.PerThread,
925 decl_index: InternPool.DeclIndex,
867 nav_index: InternPool.Nav.Index,
926868 sym_index: Symbol.Index,
927869 shdr_index: u32,
928870 code: []const u8,
929871 stt_bits: u8,
930872) !void {
931 const gpa = elf_file.base.comp.gpa;
932 const mod = pt.zcu;
933 const ip = &mod.intern_pool;
934 const decl = mod.declPtr(decl_index);
873 const zcu = pt.zcu;
874 const gpa = zcu.gpa;
875 const ip = &zcu.intern_pool;
876 const nav = ip.getNav(nav_index);
935877
936 log.debug("updateDeclCode {}({d})", .{ decl.fqn.fmt(ip), decl_index });
878 log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index });
937879
938 const required_alignment = decl.getAlignment(pt).max(
939 target_util.minFunctionAlignment(mod.getTarget()),
880 const required_alignment = pt.navAlignment(nav_index).max(
881 target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
940882 );
941883
942884 const sym = self.symbol(sym_index);
943885 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
944886 const atom_ptr = sym.atom(elf_file).?;
945 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
887 const name_offset = try self.strtab.insert(gpa, nav.fqn.toSlice(ip));
946888
947889 atom_ptr.alive = true;
948890 atom_ptr.name_offset = name_offset;
949891 atom_ptr.output_section_index = shdr_index;
892
950893 sym.name_offset = name_offset;
951894 esym.st_name = name_offset;
952895 esym.st_info |= stt_bits;
......@@ -962,7 +905,7 @@ fn updateDeclCode(
962905 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));
963906 if (need_realloc) {
964907 try atom_ptr.grow(elf_file);
965 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom_ptr.value });
908 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom_ptr.value });
966909 if (old_vaddr != atom_ptr.value) {
967910 sym.value = 0;
968911 esym.st_value = 0;
......@@ -979,7 +922,7 @@ fn updateDeclCode(
979922 }
980923 } else {
981924 try atom_ptr.allocate(elf_file);
982 errdefer self.freeDeclMetadata(elf_file, sym_index);
925 errdefer self.freeNavMetadata(elf_file, sym_index);
983926
984927 sym.value = 0;
985928 sym.flags.needs_zig_got = true;
......@@ -1023,24 +966,24 @@ fn updateTlv(
1023966 self: *ZigObject,
1024967 elf_file: *Elf,
1025968 pt: Zcu.PerThread,
1026 decl_index: InternPool.DeclIndex,
969 nav_index: InternPool.Nav.Index,
1027970 sym_index: Symbol.Index,
1028971 shndx: u32,
1029972 code: []const u8,
1030973) !void {
1031 const mod = pt.zcu;
1032 const ip = &mod.intern_pool;
1033 const gpa = mod.gpa;
1034 const decl = mod.declPtr(decl_index);
974 const zcu = pt.zcu;
975 const ip = &zcu.intern_pool;
976 const gpa = zcu.gpa;
977 const nav = ip.getNav(nav_index);
1035978
1036 log.debug("updateTlv {}({d})", .{ decl.fqn.fmt(ip), decl_index });
979 log.debug("updateTlv {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1037980
1038 const required_alignment = decl.getAlignment(pt);
981 const required_alignment = pt.navAlignment(nav_index);
1039982
1040983 const sym = self.symbol(sym_index);
1041984 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
1042985 const atom_ptr = sym.atom(elf_file).?;
1043 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
986 const name_offset = try self.strtab.insert(gpa, nav.fqn.toSlice(ip));
1044987
1045988 sym.value = 0;
1046989 sym.name_offset = name_offset;
......@@ -1049,6 +992,7 @@ fn updateTlv(
1049992 atom_ptr.alive = true;
1050993 atom_ptr.name_offset = name_offset;
1051994
995 sym.name_offset = name_offset;
1052996 esym.st_value = 0;
1053997 esym.st_name = name_offset;
1054998 esym.st_info = elf.STT_TLS;
......@@ -1086,53 +1030,49 @@ pub fn updateFunc(
10861030 const tracy = trace(@src());
10871031 defer tracy.end();
10881032
1089 const mod = pt.zcu;
1090 const ip = &mod.intern_pool;
1033 const zcu = pt.zcu;
1034 const ip = &zcu.intern_pool;
10911035 const gpa = elf_file.base.comp.gpa;
1092 const func = mod.funcInfo(func_index);
1093 const decl_index = func.owner_decl;
1094 const decl = mod.declPtr(decl_index);
1036 const func = zcu.funcInfo(func_index);
10951037
1096 log.debug("updateFunc {}({d})", .{ decl.fqn.fmt(ip), decl_index });
1038 log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
10971039
1098 const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
1099 self.freeUnnamedConsts(elf_file, decl_index);
1040 const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);
11001041 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
11011042
11021043 var code_buffer = std.ArrayList(u8).init(gpa);
11031044 defer code_buffer.deinit();
11041045
1105 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
1106 defer if (decl_state) |*ds| ds.deinit();
1046 var dwarf_state = if (self.dwarf) |*dw| try dw.initNavState(pt, func.owner_nav) else null;
1047 defer if (dwarf_state) |*ds| ds.deinit();
11071048
11081049 const res = try codegen.generateFunction(
11091050 &elf_file.base,
11101051 pt,
1111 decl.navSrcLoc(mod),
1052 zcu.navSrcLoc(func.owner_nav),
11121053 func_index,
11131054 air,
11141055 liveness,
11151056 &code_buffer,
1116 if (decl_state) |*ds| .{ .dwarf = ds } else .none,
1057 if (dwarf_state) |*ds| .{ .dwarf = ds } else .none,
11171058 );
11181059
11191060 const code = switch (res) {
11201061 .ok => code_buffer.items,
11211062 .fail => |em| {
1122 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
1123 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1063 try zcu.failed_codegen.put(gpa, func.owner_nav, em);
11241064 return;
11251065 },
11261066 };
11271067
1128 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);
1129 try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC);
1068 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, code);
1069 try self.updateNavCode(elf_file, pt, func.owner_nav, sym_index, shndx, code, elf.STT_FUNC);
11301070
1131 if (decl_state) |*ds| {
1071 if (dwarf_state) |*ds| {
11321072 const sym = self.symbol(sym_index);
1133 try self.dwarf.?.commitDeclState(
1073 try self.dwarf.?.commitNavState(
11341074 pt,
1135 decl_index,
1075 func.owner_nav,
11361076 @intCast(sym.address(.{}, elf_file)),
11371077 sym.atom(elf_file).?.size,
11381078 ds,
......@@ -1142,78 +1082,80 @@ pub fn updateFunc(
11421082 // Exports will be updated by `Zcu.processExports` after the update.
11431083}
11441084
1145pub fn updateDecl(
1085pub fn updateNav(
11461086 self: *ZigObject,
11471087 elf_file: *Elf,
11481088 pt: Zcu.PerThread,
1149 decl_index: InternPool.DeclIndex,
1150) link.File.UpdateDeclError!void {
1089 nav_index: InternPool.Nav.Index,
1090) link.File.UpdateNavError!void {
11511091 const tracy = trace(@src());
11521092 defer tracy.end();
11531093
1154 const mod = pt.zcu;
1155 const ip = &mod.intern_pool;
1156 const decl = mod.declPtr(decl_index);
1157
1158 log.debug("updateDecl {}({d})", .{ decl.fqn.fmt(ip), decl_index });
1159
1160 if (decl.val.getExternFunc(mod)) |_| return;
1161 if (decl.isExtern(mod)) {
1162 // Extern variable gets a .got entry only.
1163 const variable = decl.getOwnedVariable(mod).?;
1164 const name = decl.name.toSlice(&mod.intern_pool);
1165 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);
1166 const sym_index = try self.getGlobalSymbol(elf_file, name, lib_name);
1167 self.symbol(sym_index).flags.needs_got = true;
1168 return;
1169 }
1094 const zcu = pt.zcu;
1095 const ip = &zcu.intern_pool;
1096 const nav = ip.getNav(nav_index);
1097
1098 log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1099
1100 const nav_val = zcu.navValue(nav_index);
1101 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
1102 .variable => |variable| Value.fromInterned(variable.init),
1103 .@"extern" => |@"extern"| {
1104 if (ip.isFunctionType(@"extern".ty)) return;
1105 // Extern variable gets a .got entry only.
1106 const sym_index = try self.getGlobalSymbol(
1107 elf_file,
1108 nav.name.toSlice(ip),
1109 @"extern".lib_name.toSlice(ip),
1110 );
1111 self.symbol(sym_index).flags.needs_got = true;
1112 return;
1113 },
1114 else => nav_val,
1115 };
11701116
1171 const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
1117 const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);
11721118 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
11731119
1174 const gpa = elf_file.base.comp.gpa;
1175 var code_buffer = std.ArrayList(u8).init(gpa);
1120 var code_buffer = std.ArrayList(u8).init(zcu.gpa);
11761121 defer code_buffer.deinit();
11771122
1178 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
1179 defer if (decl_state) |*ds| ds.deinit();
1123 var nav_state: ?Dwarf.NavState = if (self.dwarf) |*dw| try dw.initNavState(pt, nav_index) else null;
1124 defer if (nav_state) |*ns| ns.deinit();
11801125
11811126 // TODO implement .debug_info for global variables
1182 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
1183 const res = if (decl_state) |*ds|
1184 try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{
1185 .dwarf = ds,
1186 }, .{
1187 .parent_atom_index = sym_index,
1188 })
1189 else
1190 try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{
1191 .parent_atom_index = sym_index,
1192 });
1127 const res = try codegen.generateSymbol(
1128 &elf_file.base,
1129 pt,
1130 zcu.navSrcLoc(nav_index),
1131 nav_init,
1132 &code_buffer,
1133 if (nav_state) |*ns| .{ .dwarf = ns } else .none,
1134 .{ .parent_atom_index = sym_index },
1135 );
11931136
11941137 const code = switch (res) {
11951138 .ok => code_buffer.items,
11961139 .fail => |em| {
1197 decl.analysis = .codegen_failure;
1198 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1140 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
11991141 return;
12001142 },
12011143 };
12021144
1203 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);
1145 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, code);
12041146 if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0)
1205 try self.updateTlv(elf_file, pt, decl_index, sym_index, shndx, code)
1147 try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code)
12061148 else
1207 try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_OBJECT);
1149 try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
12081150
1209 if (decl_state) |*ds| {
1151 if (nav_state) |*ns| {
12101152 const sym = self.symbol(sym_index);
1211 try self.dwarf.?.commitDeclState(
1153 try self.dwarf.?.commitNavState(
12121154 pt,
1213 decl_index,
1155 nav_index,
12141156 @intCast(sym.address(.{}, elf_file)),
12151157 sym.atom(elf_file).?.size,
1216 ds,
1158 ns,
12171159 );
12181160 }
12191161
......@@ -1237,13 +1179,13 @@ fn updateLazySymbol(
12371179 const name_str_index = blk: {
12381180 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
12391181 @tagName(sym.kind),
1240 sym.ty.fmt(pt),
1182 Type.fromInterned(sym.ty).fmt(pt),
12411183 });
12421184 defer gpa.free(name);
12431185 break :blk try self.strtab.insert(gpa, name);
12441186 };
12451187
1246 const src = sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1188 const src = Type.fromInterned(sym.ty).srcLocOrNull(mod) orelse Zcu.LazySrcLoc.unneeded;
12471189 const res = try codegen.generateLazySymbol(
12481190 &elf_file.base,
12491191 pt,
......@@ -1280,7 +1222,7 @@ fn updateLazySymbol(
12801222 atom_ptr.output_section_index = output_section_index;
12811223
12821224 try atom_ptr.allocate(elf_file);
1283 errdefer self.freeDeclMetadata(elf_file, symbol_index);
1225 errdefer self.freeNavMetadata(elf_file, symbol_index);
12841226
12851227 local_sym.value = 0;
12861228 local_sym.flags.needs_zig_got = true;
......@@ -1296,49 +1238,9 @@ fn updateLazySymbol(
12961238 try elf_file.base.file.?.pwriteAll(code, file_offset);
12971239}
12981240
1299pub fn lowerUnnamedConst(
1300 self: *ZigObject,
1301 elf_file: *Elf,
1302 pt: Zcu.PerThread,
1303 val: Value,
1304 decl_index: InternPool.DeclIndex,
1305) !u32 {
1306 const gpa = elf_file.base.comp.gpa;
1307 const mod = elf_file.base.comp.module.?;
1308 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);
1309 if (!gop.found_existing) {
1310 gop.value_ptr.* = .{};
1311 }
1312 const unnamed_consts = gop.value_ptr;
1313 const decl = mod.declPtr(decl_index);
1314 const index = unnamed_consts.items.len;
1315 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
1316 defer gpa.free(name);
1317 const ty = val.typeOf(mod);
1318 const sym_index = switch (try self.lowerConst(
1319 elf_file,
1320 pt,
1321 name,
1322 val,
1323 ty.abiAlignment(pt),
1324 elf_file.zig_data_rel_ro_section_index.?,
1325 decl.navSrcLoc(mod),
1326 )) {
1327 .ok => |sym_index| sym_index,
1328 .fail => |em| {
1329 decl.analysis = .codegen_failure;
1330 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1331 log.err("{s}", .{em.msg});
1332 return error.CodegenFail;
1333 },
1334 };
1335 try unnamed_consts.append(gpa, sym_index);
1336 return sym_index;
1337}
1338
13391241const LowerConstResult = union(enum) {
13401242 ok: Symbol.Index,
1341 fail: *Module.ErrorMsg,
1243 fail: *Zcu.ErrorMsg,
13421244};
13431245
13441246fn lowerConst(
......@@ -1349,7 +1251,7 @@ fn lowerConst(
13491251 val: Value,
13501252 required_alignment: InternPool.Alignment,
13511253 output_section_index: u32,
1352 src_loc: Module.LazySrcLoc,
1254 src_loc: Zcu.LazySrcLoc,
13531255) !LowerConstResult {
13541256 const gpa = pt.zcu.gpa;
13551257
......@@ -1384,7 +1286,8 @@ fn lowerConst(
13841286 atom_ptr.output_section_index = output_section_index;
13851287
13861288 try atom_ptr.allocate(elf_file);
1387 errdefer self.freeDeclMetadata(elf_file, sym_index);
1289 // TODO rename and re-audit this method
1290 errdefer self.freeNavMetadata(elf_file, sym_index);
13881291
13891292 const shdr = elf_file.shdrs.items[output_section_index];
13901293 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
......@@ -1397,7 +1300,7 @@ pub fn updateExports(
13971300 self: *ZigObject,
13981301 elf_file: *Elf,
13991302 pt: Zcu.PerThread,
1400 exported: Module.Exported,
1303 exported: Zcu.Exported,
14011304 export_indices: []const u32,
14021305) link.File.UpdateExportsError!void {
14031306 const tracy = trace(@src());
......@@ -1406,24 +1309,24 @@ pub fn updateExports(
14061309 const mod = pt.zcu;
14071310 const gpa = elf_file.base.comp.gpa;
14081311 const metadata = switch (exported) {
1409 .decl_index => |decl_index| blk: {
1410 _ = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
1411 break :blk self.decls.getPtr(decl_index).?;
1312 .nav => |nav| blk: {
1313 _ = try self.getOrCreateMetadataForNav(elf_file, nav);
1314 break :blk self.navs.getPtr(nav).?;
14121315 },
1413 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1316 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
14141317 const first_exp = mod.all_exports.items[export_indices[0]];
1415 const res = try self.lowerAnonDecl(elf_file, pt, value, .none, first_exp.src);
1318 const res = try self.lowerUav(elf_file, pt, uav, .none, first_exp.src);
14161319 switch (res) {
1417 .ok => {},
1320 .mcv => {},
14181321 .fail => |em| {
1419 // TODO maybe it's enough to return an error here and let Module.processExportsInner
1322 // TODO maybe it's enough to return an error here and let Zcu.processExportsInner
14201323 // handle the error?
14211324 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
14221325 mod.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);
14231326 return;
14241327 },
14251328 }
1426 break :blk self.anon_decls.getPtr(value).?;
1329 break :blk self.uavs.getPtr(uav).?;
14271330 },
14281331 };
14291332 const sym_index = metadata.symbol_index;
......@@ -1436,7 +1339,7 @@ pub fn updateExports(
14361339 if (exp.opts.section.unwrap()) |section_name| {
14371340 if (!section_name.eqlSlice(".text", &mod.intern_pool)) {
14381341 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
1439 mod.failed_exports.putAssumeCapacityNoClobber(export_idx, try Module.ErrorMsg.create(
1342 mod.failed_exports.putAssumeCapacityNoClobber(export_idx, try Zcu.ErrorMsg.create(
14401343 gpa,
14411344 exp.src,
14421345 "Unimplemented: ExportOptions.section",
......@@ -1451,7 +1354,7 @@ pub fn updateExports(
14511354 .weak => elf.STB_WEAK,
14521355 .link_once => {
14531356 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
1454 mod.failed_exports.putAssumeCapacityNoClobber(export_idx, try Module.ErrorMsg.create(
1357 mod.failed_exports.putAssumeCapacityNoClobber(export_idx, try Zcu.ErrorMsg.create(
14551358 gpa,
14561359 exp.src,
14571360 "Unimplemented: GlobalLinkage.LinkOnce",
......@@ -1487,21 +1390,22 @@ pub fn updateExports(
14871390 }
14881391}
14891392
1490/// Must be called only after a successful call to `updateDecl`.
1491pub fn updateDeclLineNumber(
1393/// Must be called only after a successful call to `updateNav`.
1394pub fn updateNavLineNumber(
14921395 self: *ZigObject,
14931396 pt: Zcu.PerThread,
1494 decl_index: InternPool.DeclIndex,
1397 nav_index: InternPool.Nav.Index,
14951398) !void {
14961399 const tracy = trace(@src());
14971400 defer tracy.end();
14981401
1499 const decl = pt.zcu.declPtr(decl_index);
1402 const ip = &pt.zcu.intern_pool;
1403 const nav = ip.getNav(nav_index);
15001404
1501 log.debug("updateDeclLineNumber {}({d})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl_index });
1405 log.debug("updateNavLineNumber {}({d})", .{ nav.fqn.fmt(ip), nav_index });
15021406
15031407 if (self.dwarf) |*dw| {
1504 try dw.updateDeclLineNumber(pt.zcu, decl_index);
1408 try dw.updateNavLineNumber(pt.zcu, nav_index);
15051409 }
15061410}
15071411
......@@ -1512,9 +1416,9 @@ pub fn deleteExport(
15121416 name: InternPool.NullTerminatedString,
15131417) void {
15141418 const metadata = switch (exported) {
1515 .decl_index => |decl_index| self.decls.getPtr(decl_index) orelse return,
1516 .value => |value| self.anon_decls.getPtr(value) orelse return,
1517 };
1419 .nav => |nav| self.navs.getPtr(nav),
1420 .uav => |uav| self.uavs.getPtr(uav),
1421 } orelse return;
15181422 const mod = elf_file.base.comp.module.?;
15191423 const exp_name = name.toSlice(&mod.intern_pool);
15201424 const esym_index = metadata.@"export"(self, exp_name) orelse return;
......@@ -1754,14 +1658,14 @@ const LazySymbolMetadata = struct {
17541658 rodata_state: State = .unused,
17551659};
17561660
1757const DeclMetadata = struct {
1661const AvMetadata = struct {
17581662 symbol_index: Symbol.Index,
1759 /// A list of all exports aliases of this Decl.
1663 /// A list of all exports aliases of this Av.
17601664 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
17611665
1762 fn @"export"(m: DeclMetadata, zo: *ZigObject, name: []const u8) ?*u32 {
1666 fn @"export"(m: AvMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 {
17631667 for (m.exports.items) |*exp| {
1764 const exp_name = zo.getString(zo.symbol(exp.*).name_offset);
1668 const exp_name = zig_object.getString(zig_object.symbol(exp.*).name_offset);
17651669 if (mem.eql(u8, name, exp_name)) return exp;
17661670 }
17671671 return null;
......@@ -1778,10 +1682,9 @@ const TlsVariable = struct {
17781682};
17791683
17801684const AtomList = std.ArrayListUnmanaged(Atom.Index);
1781const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index));
1782const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);
1783const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);
1784const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
1685const NavTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1686const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata);
1687const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
17851688const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
17861689
17871690const assert = std.debug.assert;
......@@ -1792,8 +1695,8 @@ const link = @import("../../link.zig");
17921695const log = std.log.scoped(.link);
17931696const mem = std.mem;
17941697const relocation = @import("relocation.zig");
1795const trace = @import("../../tracy.zig").trace;
17961698const target_util = @import("../../target.zig");
1699const trace = @import("../../tracy.zig").trace;
17971700const std = @import("std");
17981701
17991702const Air = @import("../../Air.zig");
......@@ -1806,8 +1709,6 @@ const File = @import("file.zig").File;
18061709const InternPool = @import("../../InternPool.zig");
18071710const Liveness = @import("../../Liveness.zig");
18081711const Zcu = @import("../../Zcu.zig");
1809/// Deprecated.
1810const Module = Zcu;
18111712const Object = @import("Object.zig");
18121713const Symbol = @import("Symbol.zig");
18131714const StringTable = @import("../StringTable.zig");
src/link/MachO.zig+16-22
......@@ -2998,21 +2998,17 @@ pub fn updateFunc(self: *MachO, pt: Zcu.PerThread, func_index: InternPool.Index,
29982998 return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness);
29992999}
30003000
3001pub fn lowerUnnamedConst(self: *MachO, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
3002 return self.getZigObject().?.lowerUnnamedConst(self, pt, val, decl_index);
3003}
3004
3005pub fn updateDecl(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
3001pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
30063002 if (build_options.skip_non_native and builtin.object_format != .macho) {
30073003 @panic("Attempted to compile for object format that was disabled by build configuration");
30083004 }
3009 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
3010 return self.getZigObject().?.updateDecl(self, pt, decl_index);
3005 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
3006 return self.getZigObject().?.updateNav(self, pt, nav);
30113007}
30123008
3013pub fn updateDeclLineNumber(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
3009pub fn updateNavLineNumber(self: *MachO, pt: Zcu.PerThread, nav: InternPool.NavIndex) !void {
30143010 if (self.llvm_object) |_| return;
3015 return self.getZigObject().?.updateDeclLineNumber(pt, decl_index);
3011 return self.getZigObject().?.updateNavLineNumber(pt, nav);
30163012}
30173013
30183014pub fn updateExports(
......@@ -3037,29 +3033,29 @@ pub fn deleteExport(
30373033 return self.getZigObject().?.deleteExport(self, exported, name);
30383034}
30393035
3040pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {
3041 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
3042 return self.getZigObject().?.freeDecl(decl_index);
3036pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {
3037 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav);
3038 return self.getZigObject().?.freeNav(nav);
30433039}
30443040
3045pub fn getDeclVAddr(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 {
3041pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
30463042 assert(self.llvm_object == null);
3047 return self.getZigObject().?.getDeclVAddr(self, pt, decl_index, reloc_info);
3043 return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info);
30483044}
30493045
3050pub fn lowerAnonDecl(
3046pub fn lowerUav(
30513047 self: *MachO,
30523048 pt: Zcu.PerThread,
3053 decl_val: InternPool.Index,
3049 uav: InternPool.Index,
30543050 explicit_alignment: InternPool.Alignment,
30553051 src_loc: Module.LazySrcLoc,
3056) !codegen.Result {
3057 return self.getZigObject().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc);
3052) !codegen.GenResult {
3053 return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment, src_loc);
30583054}
30593055
3060pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
3056pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
30613057 assert(self.llvm_object == null);
3062 return self.getZigObject().?.getAnonDeclVAddr(self, decl_val, reloc_info);
3058 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);
30633059}
30643060
30653061pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {
......@@ -4051,8 +4047,6 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {
40514047
40524048const default_entry_symbol_name = "_main";
40534049
4054pub const base_tag: link.File.Tag = link.File.Tag.macho;
4055
40564050const Section = struct {
40574051 header: macho.section_64,
40584052 segment_id: u8,
src/link/MachO/Atom.zig+20
......@@ -992,6 +992,8 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r
992992 const tracy = trace(@src());
993993 defer tracy.end();
994994
995 relocs_log.debug("{x}: {s}", .{ self.getAddress(macho_file), self.getName(macho_file) });
996
995997 const cpu_arch = macho_file.getTarget().cpu.arch;
996998 const relocs = self.getRelocs(macho_file);
997999
......@@ -1015,6 +1017,24 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r
10151017 addend += target;
10161018 }
10171019
1020 switch (rel.tag) {
1021 .local => relocs_log.debug(" {}: [{x} => {d}({s},{s})] + {x}", .{
1022 rel.fmtPretty(cpu_arch),
1023 r_address,
1024 r_symbolnum,
1025 macho_file.sections.items(.header)[r_symbolnum - 1].segName(),
1026 macho_file.sections.items(.header)[r_symbolnum - 1].sectName(),
1027 addend,
1028 }),
1029 .@"extern" => relocs_log.debug(" {}: [{x} => {d}({s})] + {x}", .{
1030 rel.fmtPretty(cpu_arch),
1031 r_address,
1032 r_symbolnum,
1033 rel.getTargetSymbol(self, macho_file).getName(macho_file),
1034 addend,
1035 }),
1036 }
1037
10181038 switch (cpu_arch) {
10191039 .aarch64 => {
10201040 if (rel.type == .unsigned) switch (rel.meta.length) {
src/link/MachO/ZigObject.zig+225-329
......@@ -19,32 +19,11 @@ atoms_extra: std.ArrayListUnmanaged(u32) = .{},
1919/// Table of tracked LazySymbols.
2020lazy_syms: LazySymbolTable = .{},
2121
22/// Table of tracked Decls.
23decls: DeclTable = .{},
24
25/// Table of unnamed constants associated with a parent `Decl`.
26/// We store them here so that we can free the constants whenever the `Decl`
27/// needs updating or is freed.
28///
29/// For example,
30///
31/// ```zig
32/// const Foo = struct{
33/// a: u8,
34/// };
35///
36/// pub fn main() void {
37/// var foo = Foo{ .a = 1 };
38/// _ = foo;
39/// }
40/// ```
41///
42/// value assigned to label `foo` is an unnamed constant belonging/associated
43/// with `Decl` `main`, and lives as long as that `Decl`.
44unnamed_consts: UnnamedConstTable = .{},
45
46/// Table of tracked AnonDecls.
47anon_decls: AnonDeclTable = .{},
22/// Table of tracked Navs.
23navs: NavTable = .{},
24
25/// Table of tracked Uavs.
26uavs: UavTable = .{},
4827
4928/// TLV initializers indexed by Atom.Index.
5029tlv_initializers: TlvInitializerTable = .{},
......@@ -100,31 +79,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
10079 self.atoms_indexes.deinit(allocator);
10180 self.atoms_extra.deinit(allocator);
10281
103 {
104 var it = self.decls.iterator();
105 while (it.next()) |entry| {
106 entry.value_ptr.exports.deinit(allocator);
107 }
108 self.decls.deinit(allocator);
82 for (self.navs.values()) |*meta| {
83 meta.exports.deinit(allocator);
10984 }
85 self.navs.deinit(allocator);
11086
11187 self.lazy_syms.deinit(allocator);
11288
113 {
114 var it = self.unnamed_consts.valueIterator();
115 while (it.next()) |syms| {
116 syms.deinit(allocator);
117 }
118 self.unnamed_consts.deinit(allocator);
119 }
120
121 {
122 var it = self.anon_decls.iterator();
123 while (it.next()) |entry| {
124 entry.value_ptr.exports.deinit(allocator);
125 }
126 self.anon_decls.deinit(allocator);
89 for (self.uavs.values()) |*meta| {
90 meta.exports.deinit(allocator);
12791 }
92 self.uavs.deinit(allocator);
12893
12994 for (self.relocs.items) |*list| {
13095 list.deinit(allocator);
......@@ -601,7 +566,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se
601566
602567pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) !void {
603568 // Handle any lazy symbols that were emitted by incremental compilation.
604 if (self.lazy_syms.getPtr(.none)) |metadata| {
569 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {
605570 const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid };
606571
607572 // Most lazy symbols can be updated on first use, but
......@@ -609,7 +574,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
609574 if (metadata.text_state != .unused) self.updateLazySymbol(
610575 macho_file,
611576 pt,
612 link.File.LazySymbol.initDecl(.code, null, pt.zcu),
577 .{ .kind = .code, .ty = .anyerror_type },
613578 metadata.text_symbol_index,
614579 ) catch |err| return switch (err) {
615580 error.CodegenFail => error.FlushFailure,
......@@ -618,7 +583,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
618583 if (metadata.const_state != .unused) self.updateLazySymbol(
619584 macho_file,
620585 pt,
621 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),
586 .{ .kind = .const_data, .ty = .anyerror_type },
622587 metadata.const_symbol_index,
623588 ) catch |err| return switch (err) {
624589 error.CodegenFail => error.FlushFailure,
......@@ -691,25 +656,25 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
691656 assert(!self.debug_strtab_dirty);
692657}
693658
694pub fn getDeclVAddr(
659pub fn getNavVAddr(
695660 self: *ZigObject,
696661 macho_file: *MachO,
697662 pt: Zcu.PerThread,
698 decl_index: InternPool.DeclIndex,
663 nav_index: InternPool.Nav.Index,
699664 reloc_info: link.File.RelocInfo,
700665) !u64 {
701666 const zcu = pt.zcu;
702667 const ip = &zcu.intern_pool;
703 const decl = zcu.declPtr(decl_index);
704 log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index });
705 const sym_index = if (decl.isExtern(zcu)) blk: {
706 const name = decl.name.toSlice(ip);
707 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|
708 ext_fn.lib_name.toSlice(ip)
709 else
710 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);
711 break :blk try self.getGlobalSymbol(macho_file, name, lib_name);
712 } else try self.getOrCreateMetadataForDecl(macho_file, decl_index);
668 const nav = ip.getNav(nav_index);
669 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
670 const sym_index = switch (ip.indexToKey(nav.status.resolved.val)) {
671 .@"extern" => |@"extern"| try self.getGlobalSymbol(
672 macho_file,
673 nav.name.toSlice(ip),
674 @"extern".lib_name.toSlice(ip),
675 ),
676 else => try self.getOrCreateMetadataForNav(macho_file, nav_index),
677 };
713678 const sym = self.symbols.items[sym_index];
714679 const vaddr = sym.getAddress(.{}, macho_file);
715680 const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
......@@ -729,13 +694,13 @@ pub fn getDeclVAddr(
729694 return vaddr;
730695}
731696
732pub fn getAnonDeclVAddr(
697pub fn getUavVAddr(
733698 self: *ZigObject,
734699 macho_file: *MachO,
735 decl_val: InternPool.Index,
700 uav: InternPool.Index,
736701 reloc_info: link.File.RelocInfo,
737702) !u64 {
738 const sym_index = self.anon_decls.get(decl_val).?.symbol_index;
703 const sym_index = self.uavs.get(uav).?.symbol_index;
739704 const sym = self.symbols.items[sym_index];
740705 const vaddr = sym.getAddress(.{}, macho_file);
741706 const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
......@@ -755,42 +720,43 @@ pub fn getAnonDeclVAddr(
755720 return vaddr;
756721}
757722
758pub fn lowerAnonDecl(
723pub fn lowerUav(
759724 self: *ZigObject,
760725 macho_file: *MachO,
761726 pt: Zcu.PerThread,
762 decl_val: InternPool.Index,
727 uav: InternPool.Index,
763728 explicit_alignment: Atom.Alignment,
764 src_loc: Module.LazySrcLoc,
765) !codegen.Result {
766 const gpa = macho_file.base.comp.gpa;
767 const mod = macho_file.base.comp.module.?;
768 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
769 const decl_alignment = switch (explicit_alignment) {
770 .none => ty.abiAlignment(pt),
729 src_loc: Zcu.LazySrcLoc,
730) !codegen.GenResult {
731 const zcu = pt.zcu;
732 const gpa = zcu.gpa;
733 const val = Value.fromInterned(uav);
734 const uav_alignment = switch (explicit_alignment) {
735 .none => val.typeOf(zcu).abiAlignment(pt),
771736 else => explicit_alignment,
772737 };
773 if (self.anon_decls.get(decl_val)) |metadata| {
774 const existing_alignment = self.symbols.items[metadata.symbol_index].getAtom(macho_file).?.alignment;
775 if (decl_alignment.order(existing_alignment).compare(.lte))
776 return .ok;
738 if (self.uavs.get(uav)) |metadata| {
739 const sym = self.symbols.items[metadata.symbol_index];
740 const existing_alignment = sym.getAtom(macho_file).?.alignment;
741 if (uav_alignment.order(existing_alignment).compare(.lte))
742 return .{ .mcv = .{ .load_symbol = sym.nlist_idx } };
777743 }
778744
779745 var name_buf: [32]u8 = undefined;
780746 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
781 @intFromEnum(decl_val),
747 @intFromEnum(uav),
782748 }) catch unreachable;
783749 const res = self.lowerConst(
784750 macho_file,
785751 pt,
786752 name,
787 Value.fromInterned(decl_val),
788 decl_alignment,
753 val,
754 uav_alignment,
789755 macho_file.zig_const_sect_index.?,
790756 src_loc,
791757 ) catch |err| switch (err) {
792758 error.OutOfMemory => return error.OutOfMemory,
793 else => |e| return .{ .fail = try Module.ErrorMsg.create(
759 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
794760 gpa,
795761 src_loc,
796762 "unable to lower constant value: {s}",
......@@ -801,20 +767,13 @@ pub fn lowerAnonDecl(
801767 .ok => |sym_index| sym_index,
802768 .fail => |em| return .{ .fail = em },
803769 };
804 try self.anon_decls.put(gpa, decl_val, .{ .symbol_index = sym_index });
805 return .ok;
806}
807
808fn freeUnnamedConsts(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.DeclIndex) void {
809 const gpa = macho_file.base.comp.gpa;
810 const unnamed_consts = self.unnamed_consts.getPtr(decl_index) orelse return;
811 for (unnamed_consts.items) |sym_index| {
812 self.freeDeclMetadata(macho_file, sym_index);
813 }
814 unnamed_consts.clearAndFree(gpa);
770 try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index });
771 return .{ .mcv = .{
772 .load_symbol = self.symbols.items[sym_index].nlist_idx,
773 } };
815774}
816775
817fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void {
776fn freeNavMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void {
818777 const sym = self.symbols.items[sym_index];
819778 sym.getAtom(macho_file).?.free(macho_file);
820779 log.debug("adding %{d} to local symbols free list", .{sym_index});
......@@ -822,18 +781,14 @@ fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Inde
822781 // TODO free GOT entry here
823782}
824783
825pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.DeclIndex) void {
784pub fn freeNav(self: *ZigObject, macho_file: *MachO, nav_index: InternPool.Nav.Index) void {
826785 const gpa = macho_file.base.comp.gpa;
827 const mod = macho_file.base.comp.module.?;
828 const decl = mod.declPtr(decl_index);
786 log.debug("freeNav 0x{x}", .{nav_index});
829787
830 log.debug("freeDecl {*}", .{decl});
831
832 if (self.decls.fetchRemove(decl_index)) |const_kv| {
788 if (self.navs.fetchRemove(nav_index)) |const_kv| {
833789 var kv = const_kv;
834790 const sym_index = kv.value.symbol_index;
835 self.freeDeclMetadata(macho_file, sym_index);
836 self.freeUnnamedConsts(macho_file, decl_index);
791 self.freeNavMetadata(macho_file, sym_index);
837792 kv.value.exports.deinit(gpa);
838793 }
839794
......@@ -851,51 +806,46 @@ pub fn updateFunc(
851806 const tracy = trace(@src());
852807 defer tracy.end();
853808
854 const mod = pt.zcu;
855 const gpa = mod.gpa;
856 const func = mod.funcInfo(func_index);
857 const decl_index = func.owner_decl;
858 const decl = mod.declPtr(decl_index);
809 const zcu = pt.zcu;
810 const gpa = zcu.gpa;
811 const func = zcu.funcInfo(func_index);
859812
860 const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
861 self.freeUnnamedConsts(macho_file, decl_index);
813 const sym_index = try self.getOrCreateMetadataForNav(macho_file, func.owner_nav);
862814 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
863815
864816 var code_buffer = std.ArrayList(u8).init(gpa);
865817 defer code_buffer.deinit();
866818
867 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
868 defer if (decl_state) |*ds| ds.deinit();
819 var dwarf_state = if (self.dwarf) |*dw| try dw.initNavState(pt, func.owner_nav) else null;
820 defer if (dwarf_state) |*ds| ds.deinit();
869821
870 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
871822 const res = try codegen.generateFunction(
872823 &macho_file.base,
873824 pt,
874 decl.navSrcLoc(mod),
825 zcu.navSrcLoc(func.owner_nav),
875826 func_index,
876827 air,
877828 liveness,
878829 &code_buffer,
879 dio,
830 if (dwarf_state) |*ds| .{ .dwarf = ds } else .none,
880831 );
881832
882833 const code = switch (res) {
883834 .ok => code_buffer.items,
884835 .fail => |em| {
885 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
886 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
836 try zcu.failed_codegen.put(gpa, func.owner_nav, em);
887837 return;
888838 },
889839 };
890840
891 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
892 try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code);
841 const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);
842 try self.updateNavCode(macho_file, pt, func.owner_nav, sym_index, sect_index, code);
893843
894 if (decl_state) |*ds| {
844 if (dwarf_state) |*ds| {
895845 const sym = self.symbols.items[sym_index];
896 try self.dwarf.?.commitDeclState(
846 try self.dwarf.?.commitNavState(
897847 pt,
898 decl_index,
848 func.owner_nav,
899849 sym.getAddress(.{}, macho_file),
900850 sym.getAtom(macho_file).?.size,
901851 ds,
......@@ -905,96 +855,98 @@ pub fn updateFunc(
905855 // Exports will be updated by `Zcu.processExports` after the update.
906856}
907857
908pub fn updateDecl(
858pub fn updateNav(
909859 self: *ZigObject,
910860 macho_file: *MachO,
911861 pt: Zcu.PerThread,
912 decl_index: InternPool.DeclIndex,
913) link.File.UpdateDeclError!void {
862 nav_index: InternPool.Nav.Index,
863) link.File.UpdateNavError!void {
914864 const tracy = trace(@src());
915865 defer tracy.end();
916866
917 const mod = pt.zcu;
918 const decl = mod.declPtr(decl_index);
919
920 if (decl.val.getExternFunc(mod)) |_| {
921 return;
922 }
923
924 if (decl.isExtern(mod)) {
925 // Extern variable gets a __got entry only
926 const variable = decl.getOwnedVariable(mod).?;
927 const name = decl.name.toSlice(&mod.intern_pool);
928 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);
929 const index = try self.getGlobalSymbol(macho_file, name, lib_name);
930 const sym = &self.symbols.items[index];
931 sym.setSectionFlags(.{ .needs_got = true });
932 return;
933 }
867 const zcu = pt.zcu;
868 const ip = &zcu.intern_pool;
869 const nav_val = zcu.navValue(nav_index);
870 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
871 .variable => |variable| Value.fromInterned(variable.init),
872 .@"extern" => |@"extern"| {
873 if (ip.isFunctionType(@"extern".ty)) return;
874 // Extern variable gets a __got entry only
875 const name = @"extern".name.toSlice(ip);
876 const lib_name = @"extern".lib_name.toSlice(ip);
877 const index = try self.getGlobalSymbol(macho_file, name, lib_name);
878 const sym = &self.symbols.items[index];
879 sym.setSectionFlags(.{ .needs_got = true });
880 return;
881 },
882 else => nav_val,
883 };
934884
935 const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
885 const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index);
936886 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
937887
938 const gpa = macho_file.base.comp.gpa;
939 var code_buffer = std.ArrayList(u8).init(gpa);
888 var code_buffer = std.ArrayList(u8).init(zcu.gpa);
940889 defer code_buffer.deinit();
941890
942 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;
943 defer if (decl_state) |*ds| ds.deinit();
891 var nav_state: ?Dwarf.NavState = if (self.dwarf) |*dw| try dw.initNavState(pt, nav_index) else null;
892 defer if (nav_state) |*ns| ns.deinit();
944893
945 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
946 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
947 const res = try codegen.generateSymbol(&macho_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, dio, .{
948 .parent_atom_index = sym_index,
949 });
894 const res = try codegen.generateSymbol(
895 &macho_file.base,
896 pt,
897 zcu.navSrcLoc(nav_index),
898 nav_init,
899 &code_buffer,
900 if (nav_state) |*ns| .{ .dwarf = ns } else .none,
901 .{ .parent_atom_index = sym_index },
902 );
950903
951904 const code = switch (res) {
952905 .ok => code_buffer.items,
953906 .fail => |em| {
954 decl.analysis = .codegen_failure;
955 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
907 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
956908 return;
957909 },
958910 };
959 if (isThreadlocal(macho_file, decl_index)) {
960 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
961 try self.updateTlv(macho_file, pt, decl_index, sym_index, sect_index, code);
962 } else {
963 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);
964 try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code);
965 }
911 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
912 if (isThreadlocal(macho_file, nav_index))
913 try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)
914 else
915 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
966916
967 if (decl_state) |*ds| {
917 if (nav_state) |*ns| {
968918 const sym = self.symbols.items[sym_index];
969 try self.dwarf.?.commitDeclState(
919 try self.dwarf.?.commitNavState(
970920 pt,
971 decl_index,
921 nav_index,
972922 sym.getAddress(.{}, macho_file),
973923 sym.getAtom(macho_file).?.size,
974 ds,
924 ns,
975925 );
976926 }
977927
978928 // Exports will be updated by `Zcu.processExports` after the update.
979929}
980930
981fn updateDeclCode(
931fn updateNavCode(
982932 self: *ZigObject,
983933 macho_file: *MachO,
984934 pt: Zcu.PerThread,
985 decl_index: InternPool.DeclIndex,
935 nav_index: InternPool.Nav.Index,
986936 sym_index: Symbol.Index,
987937 sect_index: u8,
988938 code: []const u8,
989939) !void {
990 const gpa = macho_file.base.comp.gpa;
991 const mod = pt.zcu;
992 const ip = &mod.intern_pool;
993 const decl = mod.declPtr(decl_index);
940 const zcu = pt.zcu;
941 const gpa = zcu.gpa;
942 const ip = &zcu.intern_pool;
943 const nav = ip.getNav(nav_index);
994944
995 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
945 log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
996946
997 const required_alignment = decl.getAlignment(pt);
947 const required_alignment = pt.navAlignment(nav_index).max(
948 target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
949 );
998950
999951 const sect = &macho_file.sections.items(.header)[sect_index];
1000952 const sym = &self.symbols.items[sym_index];
......@@ -1004,7 +956,7 @@ fn updateDeclCode(
1004956 sym.out_n_sect = sect_index;
1005957 atom.out_n_sect = sect_index;
1006958
1007 const sym_name = try std.fmt.allocPrintZ(gpa, "_{s}", .{decl.fqn.toSlice(ip)});
959 const sym_name = try std.fmt.allocPrintZ(gpa, "_{s}", .{nav.fqn.toSlice(ip)});
1008960 defer gpa.free(sym_name);
1009961 sym.name = try self.addString(gpa, sym_name);
1010962 atom.setAlive(true);
......@@ -1025,7 +977,7 @@ fn updateDeclCode(
1025977
1026978 if (need_realloc) {
1027979 try atom.grow(macho_file);
1028 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom.value });
980 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), old_vaddr, atom.value });
1029981 if (old_vaddr != atom.value) {
1030982 sym.value = 0;
1031983 nlist.n_value = 0;
......@@ -1045,7 +997,7 @@ fn updateDeclCode(
1045997 }
1046998 } else {
1047999 try atom.allocate(macho_file);
1048 errdefer self.freeDeclMetadata(macho_file, sym_index);
1000 errdefer self.freeNavMetadata(macho_file, sym_index);
10491001
10501002 sym.value = 0;
10511003 sym.setSectionFlags(.{ .needs_zig_got = true });
......@@ -1070,27 +1022,27 @@ fn updateTlv(
10701022 self: *ZigObject,
10711023 macho_file: *MachO,
10721024 pt: Zcu.PerThread,
1073 decl_index: InternPool.DeclIndex,
1025 nav_index: InternPool.Nav.Index,
10741026 sym_index: Symbol.Index,
10751027 sect_index: u8,
10761028 code: []const u8,
10771029) !void {
10781030 const ip = &pt.zcu.intern_pool;
1079 const decl = pt.zcu.declPtr(decl_index);
1031 const nav = ip.getNav(nav_index);
10801032
1081 log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
1033 log.debug("updateTlv {} (0x{x})", .{ nav.fqn.fmt(ip), nav_index });
10821034
10831035 // 1. Lower TLV initializer
10841036 const init_sym_index = try self.createTlvInitializer(
10851037 macho_file,
1086 decl.fqn.toSlice(ip),
1087 decl.getAlignment(pt),
1038 nav.fqn.toSlice(ip),
1039 pt.navAlignment(nav_index),
10881040 sect_index,
10891041 code,
10901042 );
10911043
10921044 // 2. Create TLV descriptor
1093 try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl.fqn.toSlice(ip));
1045 try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, nav.fqn.toSlice(ip));
10941046}
10951047
10961048fn createTlvInitializer(
......@@ -1197,102 +1149,52 @@ fn createTlvDescriptor(
11971149 });
11981150}
11991151
1200fn getDeclOutputSection(
1152fn getNavOutputSection(
12011153 self: *ZigObject,
12021154 macho_file: *MachO,
1203 decl: *const Module.Decl,
1155 zcu: *Zcu,
1156 nav_index: InternPool.Nav.Index,
12041157 code: []const u8,
12051158) error{OutOfMemory}!u8 {
12061159 _ = self;
1207 const mod = macho_file.base.comp.module.?;
1160 const ip = &zcu.intern_pool;
12081161 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
1209 const sect_id: u8 = switch (decl.typeOf(mod).zigTypeTag(mod)) {
1210 .Fn => macho_file.zig_text_sect_index.?,
1211 else => blk: {
1212 if (decl.getOwnedVariable(mod)) |variable| {
1213 if (variable.is_threadlocal and any_non_single_threaded) {
1214 const is_all_zeroes = for (code) |byte| {
1215 if (byte != 0) break false;
1216 } else true;
1217 if (is_all_zeroes) break :blk macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
1218 "__DATA",
1219 "__thread_bss",
1220 .{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
1221 );
1222 break :blk macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
1223 "__DATA",
1224 "__thread_data",
1225 .{ .flags = macho.S_THREAD_LOCAL_REGULAR },
1226 );
1227 }
1228
1229 if (variable.is_const) break :blk macho_file.zig_const_sect_index.?;
1230 if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
1231 // TODO: get the optimize_mode from the Module that owns the decl instead
1232 // of using the root module here.
1233 break :blk switch (macho_file.base.comp.root_mod.optimize_mode) {
1234 .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?,
1235 .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?,
1236 };
1237 }
1238
1239 // TODO I blatantly copied the logic from the Wasm linker, but is there a less
1240 // intrusive check for all zeroes than this?
1241 const is_all_zeroes = for (code) |byte| {
1242 if (byte != 0) break false;
1243 } else true;
1244 if (is_all_zeroes) break :blk macho_file.zig_bss_sect_index.?;
1245 break :blk macho_file.zig_data_sect_index.?;
1246 }
1247 break :blk macho_file.zig_const_sect_index.?;
1248 },
1162 const nav_val = zcu.navValue(nav_index);
1163 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?;
1164 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
1165 .variable => |variable| .{ false, variable.is_threadlocal, variable.init },
1166 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
1167 else => .{ true, false, nav_val.toIntern() },
12491168 };
1250 return sect_id;
1251}
1252
1253pub fn lowerUnnamedConst(
1254 self: *ZigObject,
1255 macho_file: *MachO,
1256 pt: Zcu.PerThread,
1257 val: Value,
1258 decl_index: InternPool.DeclIndex,
1259) !u32 {
1260 const mod = pt.zcu;
1261 const gpa = mod.gpa;
1262 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);
1263 if (!gop.found_existing) {
1264 gop.value_ptr.* = .{};
1169 if (any_non_single_threaded and is_threadlocal) {
1170 for (code) |byte| {
1171 if (byte != 0) break;
1172 } else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
1173 "__DATA",
1174 "__thread_bss",
1175 .{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
1176 );
1177 return macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
1178 "__DATA",
1179 "__thread_data",
1180 .{ .flags = macho.S_THREAD_LOCAL_REGULAR },
1181 );
12651182 }
1266 const unnamed_consts = gop.value_ptr;
1267 const decl = mod.declPtr(decl_index);
1268 const index = unnamed_consts.items.len;
1269 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
1270 defer gpa.free(name);
1271 const sym_index = switch (try self.lowerConst(
1272 macho_file,
1273 pt,
1274 name,
1275 val,
1276 val.typeOf(mod).abiAlignment(pt),
1277 macho_file.zig_const_sect_index.?,
1278 decl.navSrcLoc(mod),
1279 )) {
1280 .ok => |sym_index| sym_index,
1281 .fail => |em| {
1282 decl.analysis = .codegen_failure;
1283 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1284 log.err("{s}", .{em.msg});
1285 return error.CodegenFail;
1286 },
1287 };
1288 const sym = self.symbols.items[sym_index];
1289 try unnamed_consts.append(gpa, sym.atom_ref.index);
1290 return sym_index;
1183 if (is_const) return macho_file.zig_const_sect_index.?;
1184 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
1185 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
1186 .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?,
1187 .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?,
1188 };
1189 for (code) |byte| {
1190 if (byte != 0) break;
1191 } else return macho_file.zig_bss_sect_index.?;
1192 return macho_file.zig_data_sect_index.?;
12911193}
12921194
12931195const LowerConstResult = union(enum) {
12941196 ok: Symbol.Index,
1295 fail: *Module.ErrorMsg,
1197 fail: *Zcu.ErrorMsg,
12961198};
12971199
12981200fn lowerConst(
......@@ -1303,7 +1205,7 @@ fn lowerConst(
13031205 val: Value,
13041206 required_alignment: Atom.Alignment,
13051207 output_section_index: u8,
1306 src_loc: Module.LazySrcLoc,
1208 src_loc: Zcu.LazySrcLoc,
13071209) !LowerConstResult {
13081210 const gpa = macho_file.base.comp.gpa;
13091211
......@@ -1338,7 +1240,7 @@ fn lowerConst(
13381240
13391241 try atom.allocate(macho_file);
13401242 // TODO rename and re-audit this method
1341 errdefer self.freeDeclMetadata(macho_file, sym_index);
1243 errdefer self.freeNavMetadata(macho_file, sym_index);
13421244
13431245 const sect = macho_file.sections.items(.header)[output_section_index];
13441246 const file_offset = sect.offset + atom.value;
......@@ -1351,7 +1253,7 @@ pub fn updateExports(
13511253 self: *ZigObject,
13521254 macho_file: *MachO,
13531255 pt: Zcu.PerThread,
1354 exported: Module.Exported,
1256 exported: Zcu.Exported,
13551257 export_indices: []const u32,
13561258) link.File.UpdateExportsError!void {
13571259 const tracy = trace(@src());
......@@ -1360,24 +1262,24 @@ pub fn updateExports(
13601262 const mod = pt.zcu;
13611263 const gpa = macho_file.base.comp.gpa;
13621264 const metadata = switch (exported) {
1363 .decl_index => |decl_index| blk: {
1364 _ = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
1365 break :blk self.decls.getPtr(decl_index).?;
1265 .nav => |nav| blk: {
1266 _ = try self.getOrCreateMetadataForNav(macho_file, nav);
1267 break :blk self.navs.getPtr(nav).?;
13661268 },
1367 .value => |value| self.anon_decls.getPtr(value) orelse blk: {
1269 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
13681270 const first_exp = mod.all_exports.items[export_indices[0]];
1369 const res = try self.lowerAnonDecl(macho_file, pt, value, .none, first_exp.src);
1271 const res = try self.lowerUav(macho_file, pt, uav, .none, first_exp.src);
13701272 switch (res) {
1371 .ok => {},
1273 .mcv => {},
13721274 .fail => |em| {
1373 // TODO maybe it's enough to return an error here and let Module.processExportsInner
1275 // TODO maybe it's enough to return an error here and let Zcu.processExportsInner
13741276 // handle the error?
13751277 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
13761278 mod.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);
13771279 return;
13781280 },
13791281 }
1380 break :blk self.anon_decls.getPtr(value).?;
1282 break :blk self.uavs.getPtr(uav).?;
13811283 },
13821284 };
13831285 const sym_index = metadata.symbol_index;
......@@ -1389,7 +1291,7 @@ pub fn updateExports(
13891291 if (exp.opts.section.unwrap()) |section_name| {
13901292 if (!section_name.eqlSlice("__text", &mod.intern_pool)) {
13911293 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
1392 mod.failed_exports.putAssumeCapacityNoClobber(export_idx, try Module.ErrorMsg.create(
1294 mod.failed_exports.putAssumeCapacityNoClobber(export_idx, try Zcu.ErrorMsg.create(
13931295 gpa,
13941296 exp.src,
13951297 "Unimplemented: ExportOptions.section",
......@@ -1399,7 +1301,7 @@ pub fn updateExports(
13991301 }
14001302 }
14011303 if (exp.opts.linkage == .link_once) {
1402 try mod.failed_exports.putNoClobber(mod.gpa, export_idx, try Module.ErrorMsg.create(
1304 try mod.failed_exports.putNoClobber(mod.gpa, export_idx, try Zcu.ErrorMsg.create(
14031305 gpa,
14041306 exp.src,
14051307 "Unimplemented: GlobalLinkage.link_once",
......@@ -1454,8 +1356,8 @@ fn updateLazySymbol(
14541356 lazy_sym: link.File.LazySymbol,
14551357 symbol_index: Symbol.Index,
14561358) !void {
1457 const gpa = macho_file.base.comp.gpa;
1458 const mod = macho_file.base.comp.module.?;
1359 const zcu = pt.zcu;
1360 const gpa = zcu.gpa;
14591361
14601362 var required_alignment: Atom.Alignment = .none;
14611363 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1464,13 +1366,13 @@ fn updateLazySymbol(
14641366 const name_str = blk: {
14651367 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
14661368 @tagName(lazy_sym.kind),
1467 lazy_sym.ty.fmt(pt),
1369 Type.fromInterned(lazy_sym.ty).fmt(pt),
14681370 });
14691371 defer gpa.free(name);
14701372 break :blk try self.addString(gpa, name);
14711373 };
14721374
1473 const src = lazy_sym.ty.srcLocOrNull(mod) orelse Module.LazySrcLoc.unneeded;
1375 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
14741376 const res = try codegen.generateLazySymbol(
14751377 &macho_file.base,
14761378 pt,
......@@ -1511,7 +1413,7 @@ fn updateLazySymbol(
15111413 atom.out_n_sect = output_section_index;
15121414
15131415 try atom.allocate(macho_file);
1514 errdefer self.freeDeclMetadata(macho_file, symbol_index);
1416 errdefer self.freeNavMetadata(macho_file, symbol_index);
15151417
15161418 sym.value = 0;
15171419 sym.setSectionFlags(.{ .needs_zig_got = true });
......@@ -1527,10 +1429,14 @@ fn updateLazySymbol(
15271429 try macho_file.base.file.?.pwriteAll(code, file_offset);
15281430}
15291431
1530/// Must be called only after a successful call to `updateDecl`.
1531pub fn updateDeclLineNumber(self: *ZigObject, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1432/// Must be called only after a successful call to `updateNav`.
1433pub fn updateNavLineNumber(
1434 self: *ZigObject,
1435 pt: Zcu.PerThread,
1436 nav_index: InternPool.Nav.Index,
1437) !void {
15321438 if (self.dwarf) |*dw| {
1533 try dw.updateDeclLineNumber(pt.zcu, decl_index);
1439 try dw.updateNavLineNumber(pt.zcu, nav_index);
15341440 }
15351441}
15361442
......@@ -1543,9 +1449,9 @@ pub fn deleteExport(
15431449 const mod = macho_file.base.comp.module.?;
15441450
15451451 const metadata = switch (exported) {
1546 .decl_index => |decl_index| self.decls.getPtr(decl_index) orelse return,
1547 .value => |value| self.anon_decls.getPtr(value) orelse return,
1548 };
1452 .nav => |nav| self.navs.getPtr(nav),
1453 .uav => |uav| self.uavs.getPtr(uav),
1454 } orelse return;
15491455 const nlist_index = metadata.@"export"(self, name.toSlice(&mod.intern_pool)) orelse return;
15501456
15511457 log.debug("deleting export '{}'", .{name.fmt(&mod.intern_pool)});
......@@ -1577,17 +1483,17 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
15771483 return lookup_gop.value_ptr.*;
15781484}
15791485
1580pub fn getOrCreateMetadataForDecl(
1486pub fn getOrCreateMetadataForNav(
15811487 self: *ZigObject,
15821488 macho_file: *MachO,
1583 decl_index: InternPool.DeclIndex,
1489 nav_index: InternPool.Nav.Index,
15841490) !Symbol.Index {
15851491 const gpa = macho_file.base.comp.gpa;
1586 const gop = try self.decls.getOrPut(gpa, decl_index);
1492 const gop = try self.navs.getOrPut(gpa, nav_index);
15871493 if (!gop.found_existing) {
15881494 const sym_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);
15891495 const sym = &self.symbols.items[sym_index];
1590 if (isThreadlocal(macho_file, decl_index)) {
1496 if (isThreadlocal(macho_file, nav_index)) {
15911497 sym.flags.tlv = true;
15921498 } else {
15931499 sym.setSectionFlags(.{ .needs_zig_got = true });
......@@ -1603,47 +1509,39 @@ pub fn getOrCreateMetadataForLazySymbol(
16031509 pt: Zcu.PerThread,
16041510 lazy_sym: link.File.LazySymbol,
16051511) !Symbol.Index {
1606 const mod = pt.zcu;
1607 const gpa = mod.gpa;
1608 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
1512 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
16091513 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
16101514 if (!gop.found_existing) gop.value_ptr.* = .{};
1611 const metadata: struct {
1612 symbol_index: *Symbol.Index,
1613 state: *LazySymbolMetadata.State,
1614 } = switch (lazy_sym.kind) {
1615 .code => .{
1616 .symbol_index = &gop.value_ptr.text_symbol_index,
1617 .state = &gop.value_ptr.text_state,
1618 },
1619 .const_data => .{
1620 .symbol_index = &gop.value_ptr.const_symbol_index,
1621 .state = &gop.value_ptr.const_state,
1622 },
1515 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
1516 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },
1517 .const_data => .{ &gop.value_ptr.const_symbol_index, &gop.value_ptr.const_state },
16231518 };
1624 switch (metadata.state.*) {
1519 switch (state_ptr.*) {
16251520 .unused => {
1626 const symbol_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);
1521 const symbol_index = try self.newSymbolWithAtom(pt.zcu.gpa, .{}, macho_file);
16271522 const sym = &self.symbols.items[symbol_index];
16281523 sym.setSectionFlags(.{ .needs_zig_got = true });
1629 metadata.symbol_index.* = symbol_index;
1524 symbol_index_ptr.* = symbol_index;
16301525 },
1631 .pending_flush => return metadata.symbol_index.*,
1526 .pending_flush => return symbol_index_ptr.*,
16321527 .flushed => {},
16331528 }
1634 metadata.state.* = .pending_flush;
1635 const symbol_index = metadata.symbol_index.*;
1529 state_ptr.* = .pending_flush;
1530 const symbol_index = symbol_index_ptr.*;
16361531 // anyerror needs to be deferred until flushModule
1637 if (lazy_sym.getDecl(mod) != .none) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);
1532 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);
16381533 return symbol_index;
16391534}
16401535
1641fn isThreadlocal(macho_file: *MachO, decl_index: InternPool.DeclIndex) bool {
1642 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
1643 const zcu = macho_file.base.comp.module.?;
1644 const decl = zcu.declPtr(decl_index);
1645 const variable = decl.getOwnedVariable(zcu) orelse return false;
1646 return variable.is_threadlocal and any_non_single_threaded;
1536fn isThreadlocal(macho_file: *MachO, nav_index: InternPool.Nav.Index) bool {
1537 if (!macho_file.base.comp.config.any_non_single_threaded)
1538 return false;
1539 const ip = &macho_file.base.comp.module.?.intern_pool;
1540 return switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) {
1541 .variable => |variable| variable.is_threadlocal,
1542 .@"extern" => |@"extern"| @"extern".is_threadlocal,
1543 else => false,
1544 };
16471545}
16481546
16491547fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index {
......@@ -1848,12 +1746,12 @@ fn formatAtoms(
18481746 }
18491747}
18501748
1851const DeclMetadata = struct {
1749const AvMetadata = struct {
18521750 symbol_index: Symbol.Index,
1853 /// A list of all exports aliases of this Decl.
1751 /// A list of all exports aliases of this Av.
18541752 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
18551753
1856 fn @"export"(m: DeclMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 {
1754 fn @"export"(m: AvMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 {
18571755 for (m.exports.items) |*exp| {
18581756 const nlist = zig_object.symtab.items(.nlist)[exp.*];
18591757 const exp_name = zig_object.strtab.getAssumeExists(nlist.n_strx);
......@@ -1880,10 +1778,9 @@ const TlvInitializer = struct {
18801778 }
18811779};
18821780
1883const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);
1884const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index));
1885const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);
1886const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
1781const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1782const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);
1783const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
18871784const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));
18881785const TlvInitializerTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlvInitializer);
18891786
......@@ -1894,6 +1791,7 @@ const link = @import("../../link.zig");
18941791const log = std.log.scoped(.link);
18951792const macho = std.macho;
18961793const mem = std.mem;
1794const target_util = @import("../../target.zig");
18971795const trace = @import("../../tracy.zig").trace;
18981796const std = @import("std");
18991797
......@@ -1908,8 +1806,6 @@ const Liveness = @import("../../Liveness.zig");
19081806const MachO = @import("../MachO.zig");
19091807const Nlist = Object.Nlist;
19101808const Zcu = @import("../../Zcu.zig");
1911/// Deprecated.
1912const Module = Zcu;
19131809const Object = @import("Object.zig");
19141810const Relocation = @import("Relocation.zig");
19151811const Symbol = @import("Symbol.zig");
src/link/NvPtx.zig+2-2
......@@ -86,8 +86,8 @@ pub fn updateFunc(self: *NvPtx, pt: Zcu.PerThread, func_index: InternPool.Index,
8686 try self.llvm_object.updateFunc(pt, func_index, air, liveness);
8787}
8888
89pub fn updateDecl(self: *NvPtx, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
90 return self.llvm_object.updateDecl(pt, decl_index);
89pub fn updateNav(self: *NvPtx, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
90 return self.llvm_object.updateNav(pt, nav);
9191}
9292
9393pub fn updateExports(
src/link/Plan9.zig+191-336
......@@ -24,8 +24,6 @@ const Allocator = std.mem.Allocator;
2424const log = std.log.scoped(.link);
2525const assert = std.debug.assert;
2626
27pub const base_tag = .plan9;
28
2927base: link.File,
3028sixtyfour_bit: bool,
3129bases: Bases,
......@@ -53,40 +51,19 @@ path_arena: std.heap.ArenaAllocator,
5351/// The debugger looks for the first file (aout.Sym.Type.z) preceeding the text symbol
5452/// of the function to know what file it came from.
5553/// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place)
56fn_decl_table: std.AutoArrayHashMapUnmanaged(
57 *Zcu.File,
58 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, FnDeclOutput) = .{} },
54fn_nav_table: std.AutoArrayHashMapUnmanaged(
55 Zcu.File.Index,
56 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, FnNavOutput) = .{} },
5957) = .{},
6058/// the code is modified when relocated, so that is why it is mutable
61data_decl_table: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, []u8) = .{},
59data_nav_table: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u8) = .{},
6260/// When `updateExports` is called, we store the export indices here, to be used
6361/// during flush.
64decl_exports: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, []u32) = .{},
65
66/// Table of unnamed constants associated with a parent `Decl`.
67/// We store them here so that we can free the constants whenever the `Decl`
68/// needs updating or is freed.
69///
70/// For example,
71///
72/// ```zig
73/// const Foo = struct{
74/// a: u8,
75/// };
76///
77/// pub fn main() void {
78/// var foo = Foo{ .a = 1 };
79/// _ = foo;
80/// }
81/// ```
82///
83/// value assigned to label `foo` is an unnamed constant belonging/associated
84/// with `Decl` `main`, and lives as long as that `Decl`.
85unnamed_const_atoms: UnnamedConstTable = .{},
62nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u32) = .{},
8663
8764lazy_syms: LazySymbolTable = .{},
8865
89anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
66uavs: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
9067
9168relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},
9269hdr: aout.ExecHdr = undefined,
......@@ -104,7 +81,7 @@ got_index_free_list: std.ArrayListUnmanaged(usize) = .{},
10481syms_index_free_list: std.ArrayListUnmanaged(usize) = .{},
10582
10683atoms: std.ArrayListUnmanaged(Atom) = .{},
107decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata) = .{},
84navs: std.AutoHashMapUnmanaged(InternPool.Nav.Index, NavMetadata) = .{},
10885
10986/// Indices of the three "special" symbols into atoms
11087etext_edata_end_atom_indices: [3]?Atom.Index = .{ null, null, null },
......@@ -131,9 +108,7 @@ const Bases = struct {
131108 data: u64,
132109};
133110
134const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Atom.Index));
135
136const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
111const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
137112
138113const LazySymbolMetadata = struct {
139114 const State = enum { unused, pending_flush, flushed };
......@@ -161,7 +136,7 @@ pub const Atom = struct {
161136 /// offset into got
162137 got_index: ?usize,
163138 /// We include the code here to be use in relocs
164 /// In the case of unnamed_const_atoms and lazy_syms, this atom owns the code.
139 /// In the case of lazy_syms, this atom owns the code.
165140 /// But, in the case of function and data decls, they own the code and this field
166141 /// is just a pointer for convience.
167142 code: CodePtr,
......@@ -170,22 +145,23 @@ pub const Atom = struct {
170145 code_ptr: ?[*]u8,
171146 other: union {
172147 code_len: usize,
173 decl_index: InternPool.DeclIndex,
148 nav_index: InternPool.Nav.Index,
174149 },
175150 fn fromSlice(slice: []u8) CodePtr {
176151 return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } };
177152 }
178153 fn getCode(self: CodePtr, plan9: *const Plan9) []u8 {
179 const mod = plan9.base.comp.module.?;
154 const zcu = plan9.base.comp.module.?;
155 const ip = &zcu.intern_pool;
180156 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {
181 const decl_index = self.other.decl_index;
182 const decl = mod.declPtr(decl_index);
183 if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) {
184 const table = plan9.fn_decl_table.get(decl.getFileScope(mod)).?.functions;
185 const output = table.get(decl_index).?;
157 const nav_index = self.other.nav_index;
158 const nav = ip.getNav(nav_index);
159 if (ip.isFunctionType(nav.typeOf(ip))) {
160 const table = plan9.fn_nav_table.get(zcu.navFileScopeIndex(nav_index)).?.functions;
161 const output = table.get(nav_index).?;
186162 break :blk output.code;
187163 } else {
188 break :blk plan9.data_decl_table.get(decl_index).?;
164 break :blk plan9.data_nav_table.get(nav_index).?;
189165 }
190166 };
191167 }
......@@ -241,11 +217,11 @@ pub const DebugInfoOutput = struct {
241217 pc_quanta: u8,
242218};
243219
244const DeclMetadata = struct {
220const NavMetadata = struct {
245221 index: Atom.Index,
246222 exports: std.ArrayListUnmanaged(usize) = .{},
247223
248 fn getExport(m: DeclMetadata, p9: *const Plan9, name: []const u8) ?usize {
224 fn getExport(m: NavMetadata, p9: *const Plan9, name: []const u8) ?usize {
249225 for (m.exports.items) |exp| {
250226 const sym = p9.syms.items[exp];
251227 if (mem.eql(u8, name, sym.name)) return exp;
......@@ -254,7 +230,7 @@ const DeclMetadata = struct {
254230 }
255231};
256232
257const FnDeclOutput = struct {
233const FnNavOutput = struct {
258234 /// this code is modified when relocated so it is mutable
259235 code: []u8,
260236 /// this might have to be modified in the linker, so thats why its mutable
......@@ -338,18 +314,18 @@ pub fn createEmpty(
338314 return self;
339315}
340316
341fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !void {
317fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void {
342318 const gpa = self.base.comp.gpa;
343319 const mod = self.base.comp.module.?;
344 const decl = mod.declPtr(decl_index);
345 const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope(mod));
320 const file_scope = mod.navFileScopeIndex(nav_index);
321 const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope);
346322 if (fn_map_res.found_existing) {
347 if (try fn_map_res.value_ptr.functions.fetchPut(gpa, decl_index, out)) |old_entry| {
323 if (try fn_map_res.value_ptr.functions.fetchPut(gpa, nav_index, out)) |old_entry| {
348324 gpa.free(old_entry.value.code);
349325 gpa.free(old_entry.value.lineinfo);
350326 }
351327 } else {
352 const file = decl.getFileScope(mod);
328 const file = mod.fileByIndex(file_scope);
353329 const arena = self.path_arena.allocator();
354330 // each file gets a symbol
355331 fn_map_res.value_ptr.* = .{
......@@ -359,7 +335,7 @@ fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !voi
359335 break :blk @as(u32, @intCast(self.syms.items.len - 1));
360336 },
361337 };
362 try fn_map_res.value_ptr.functions.put(gpa, decl_index, out);
338 try fn_map_res.value_ptr.functions.put(gpa, nav_index, out);
363339
364340 var a = std.ArrayList(u8).init(arena);
365341 errdefer a.deinit();
......@@ -418,11 +394,8 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
418394 const gpa = mod.gpa;
419395 const target = self.base.comp.root_mod.resolved_target.result;
420396 const func = mod.funcInfo(func_index);
421 const decl_index = func.owner_decl;
422 const decl = mod.declPtr(decl_index);
423 self.freeUnnamedConsts(decl_index);
424397
425 const atom_idx = try self.seeDecl(decl_index);
398 const atom_idx = try self.seeNav(pt, func.owner_nav);
426399
427400 var code_buffer = std.ArrayList(u8).init(gpa);
428401 defer code_buffer.deinit();
......@@ -439,7 +412,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
439412 const res = try codegen.generateFunction(
440413 &self.base,
441414 pt,
442 decl.navSrcLoc(mod),
415 mod.navSrcLoc(func.owner_nav),
443416 func_index,
444417 air,
445418 liveness,
......@@ -449,128 +422,72 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
449422 const code = switch (res) {
450423 .ok => try code_buffer.toOwnedSlice(),
451424 .fail => |em| {
452 func.setAnalysisState(&mod.intern_pool, .codegen_failure);
453 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
425 try mod.failed_codegen.put(gpa, func.owner_nav, em);
454426 return;
455427 },
456428 };
457429 self.getAtomPtr(atom_idx).code = .{
458430 .code_ptr = null,
459 .other = .{ .decl_index = decl_index },
431 .other = .{ .nav_index = func.owner_nav },
460432 };
461 const out: FnDeclOutput = .{
433 const out: FnNavOutput = .{
462434 .code = code,
463435 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),
464436 .start_line = dbg_info_output.start_line.?,
465437 .end_line = dbg_info_output.end_line,
466438 };
467 try self.putFn(decl_index, out);
468 return self.updateFinish(decl_index);
439 try self.putFn(func.owner_nav, out);
440 return self.updateFinish(pt, func.owner_nav);
469441}
470442
471pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
472 const mod = pt.zcu;
473 const gpa = mod.gpa;
474 _ = try self.seeDecl(decl_index);
475 var code_buffer = std.ArrayList(u8).init(gpa);
476 defer code_buffer.deinit();
477
478 const decl = mod.declPtr(decl_index);
479
480 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
481 if (!gop.found_existing) {
482 gop.value_ptr.* = .{};
483 }
484 const unnamed_consts = gop.value_ptr;
485
486 const index = unnamed_consts.items.len;
487 // name is freed when the unnamed const is freed
488 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
489
490 const sym_index = try self.allocateSymbolIndex();
491 const new_atom_idx = try self.createAtom();
492 const info: Atom = .{
493 .type = .d,
494 .offset = null,
495 .sym_index = sym_index,
496 .got_index = self.allocateGotIndex(),
497 .code = undefined, // filled in later
498 };
499 const sym: aout.Sym = .{
500 .value = undefined,
501 .type = info.type,
502 .name = name,
503 };
504 self.syms.items[info.sym_index.?] = sym;
505
506 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), val, &code_buffer, .{
507 .none = {},
508 }, .{
509 .parent_atom_index = new_atom_idx,
510 });
511 const code = switch (res) {
512 .ok => code_buffer.items,
513 .fail => |em| {
514 decl.analysis = .codegen_failure;
515 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
516 log.err("{s}", .{em.msg});
517 return error.CodegenFail;
443pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
444 const zcu = pt.zcu;
445 const gpa = zcu.gpa;
446 const ip = &zcu.intern_pool;
447 const nav = ip.getNav(nav_index);
448 const nav_val = zcu.navValue(nav_index);
449 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
450 .variable => |variable| Value.fromInterned(variable.init),
451 .@"extern" => {
452 log.debug("found extern decl: {}", .{nav.name.fmt(ip)});
453 return;
518454 },
455 else => nav_val,
519456 };
520 // duped_code is freed when the unnamed const is freed
521 const duped_code = try gpa.dupe(u8, code);
522 errdefer gpa.free(duped_code);
523 const new_atom = self.getAtomPtr(new_atom_idx);
524 new_atom.* = info;
525 new_atom.code = .{ .code_ptr = duped_code.ptr, .other = .{ .code_len = duped_code.len } };
526 try unnamed_consts.append(gpa, new_atom_idx);
527 // we return the new_atom_idx to codegen
528 return new_atom_idx;
529}
530
531pub fn updateDecl(self: *Plan9, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
532 const gpa = self.base.comp.gpa;
533 const mod = pt.zcu;
534 const decl = mod.declPtr(decl_index);
535
536 if (decl.isExtern(mod)) {
537 log.debug("found extern decl: {}", .{decl.name.fmt(&mod.intern_pool)});
538 return;
539 }
540 const atom_idx = try self.seeDecl(decl_index);
457 const atom_idx = try self.seeNav(pt, nav_index);
541458
542459 var code_buffer = std.ArrayList(u8).init(gpa);
543460 defer code_buffer.deinit();
544 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
545461 // TODO we need the symbol index for symbol in the table of locals for the containing atom
546 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{
547 .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)),
462 const res = try codegen.generateSymbol(&self.base, pt, zcu.navSrcLoc(nav_index), nav_init, &code_buffer, .none, .{
463 .parent_atom_index = @intCast(atom_idx),
548464 });
549465 const code = switch (res) {
550466 .ok => code_buffer.items,
551467 .fail => |em| {
552 decl.analysis = .codegen_failure;
553 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
468 try zcu.failed_codegen.put(gpa, nav_index, em);
554469 return;
555470 },
556471 };
557 try self.data_decl_table.ensureUnusedCapacity(gpa, 1);
472 try self.data_nav_table.ensureUnusedCapacity(gpa, 1);
558473 const duped_code = try gpa.dupe(u8, code);
559 self.getAtomPtr(self.decls.get(decl_index).?.index).code = .{ .code_ptr = null, .other = .{ .decl_index = decl_index } };
560 if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| {
474 self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } };
475 if (self.data_nav_table.fetchPutAssumeCapacity(nav_index, duped_code)) |old_entry| {
561476 gpa.free(old_entry.value);
562477 }
563 return self.updateFinish(decl_index);
478 return self.updateFinish(pt, nav_index);
564479}
480
565481/// called at the end of update{Decl,Func}
566fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
567 const gpa = self.base.comp.gpa;
568 const mod = self.base.comp.module.?;
569 const decl = mod.declPtr(decl_index);
570 const is_fn = (decl.typeOf(mod).zigTypeTag(mod) == .Fn);
482fn updateFinish(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
483 const zcu = pt.zcu;
484 const gpa = zcu.gpa;
485 const ip = &zcu.intern_pool;
486 const nav = ip.getNav(nav_index);
487 const is_fn = ip.isFunctionType(nav.typeOf(ip));
571488 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
572489
573 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);
490 const atom = self.getAtomPtr(self.navs.get(nav_index).?.index);
574491 // write the internal linker metadata
575492 atom.type = sym_t;
576493 // write the symbol
......@@ -578,7 +495,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
578495 const sym: aout.Sym = .{
579496 .value = undefined, // the value of stuff gets filled in in flushModule
580497 .type = atom.type,
581 .name = try gpa.dupe(u8, decl.name.toSlice(&mod.intern_pool)),
498 .name = try gpa.dupe(u8, nav.name.toSlice(ip)),
582499 };
583500
584501 if (atom.sym_index) |s| {
......@@ -643,29 +560,24 @@ fn externCount(self: *Plan9) usize {
643560 }
644561 return extern_atom_count;
645562}
646// counts decls, unnamed consts, and lazy syms
563// counts decls, and lazy syms
647564fn atomCount(self: *Plan9) usize {
648 var fn_decl_count: usize = 0;
649 var itf_files = self.fn_decl_table.iterator();
565 var fn_nav_count: usize = 0;
566 var itf_files = self.fn_nav_table.iterator();
650567 while (itf_files.next()) |ent| {
651568 // get the submap
652569 var submap = ent.value_ptr.functions;
653 fn_decl_count += submap.count();
654 }
655 const data_decl_count = self.data_decl_table.count();
656 var unnamed_const_count: usize = 0;
657 var it_unc = self.unnamed_const_atoms.iterator();
658 while (it_unc.next()) |unnamed_consts| {
659 unnamed_const_count += unnamed_consts.value_ptr.items.len;
570 fn_nav_count += submap.count();
660571 }
572 const data_nav_count = self.data_nav_table.count();
661573 var lazy_atom_count: usize = 0;
662574 var it_lazy = self.lazy_syms.iterator();
663575 while (it_lazy.next()) |kv| {
664576 lazy_atom_count += kv.value_ptr.numberOfAtoms();
665577 }
666 const anon_atom_count = self.anon_decls.count();
578 const uav_atom_count = self.uavs.count();
667579 const extern_atom_count = self.externCount();
668 return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;
580 return data_nav_count + fn_nav_count + lazy_atom_count + extern_atom_count + uav_atom_count;
669581}
670582
671583pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
......@@ -700,7 +612,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
700612 // anyerror needs to wait for everything to be flushed.
701613 if (metadata.text_state != .unused) self.updateLazySymbolAtom(
702614 pt,
703 File.LazySymbol.initDecl(.code, null, pt.zcu),
615 .{ .kind = .code, .ty = .anyerror_type },
704616 metadata.text_atom,
705617 ) catch |err| return switch (err) {
706618 error.CodegenFail => error.FlushFailure,
......@@ -708,7 +620,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
708620 };
709621 if (metadata.rodata_state != .unused) self.updateLazySymbolAtom(
710622 pt,
711 File.LazySymbol.initDecl(.const_data, null, pt.zcu),
623 .{ .kind = .const_data, .ty = .anyerror_type },
712624 metadata.rodata_atom,
713625 ) catch |err| return switch (err) {
714626 error.CodegenFail => error.FlushFailure,
......@@ -734,7 +646,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
734646
735647 var hdr_buf: [40]u8 = undefined;
736648 // account for the fat header
737 const hdr_size = if (self.sixtyfour_bit) @as(usize, 40) else 32;
649 const hdr_size: usize = if (self.sixtyfour_bit) 40 else 32;
738650 const hdr_slice: []u8 = hdr_buf[0..hdr_size];
739651 var foff = hdr_size;
740652 iovecs[0] = .{ .base = hdr_slice.ptr, .len = hdr_slice.len };
......@@ -746,13 +658,13 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
746658 // text
747659 {
748660 var linecount: i64 = -1;
749 var it_file = self.fn_decl_table.iterator();
661 var it_file = self.fn_nav_table.iterator();
750662 while (it_file.next()) |fentry| {
751663 var it = fentry.value_ptr.functions.iterator();
752664 while (it.next()) |entry| {
753 const decl_index = entry.key_ptr.*;
754 const decl = pt.zcu.declPtr(decl_index);
755 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);
665 const nav_index = entry.key_ptr.*;
666 const nav = pt.zcu.intern_pool.getNav(nav_index);
667 const atom = self.getAtomPtr(self.navs.get(nav_index).?.index);
756668 const out = entry.value_ptr.*;
757669 {
758670 // connect the previous decl to the next
......@@ -771,15 +683,15 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
771683 const off = self.getAddr(text_i, .t);
772684 text_i += out.code.len;
773685 atom.offset = off;
774 log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&pt.zcu.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
686 log.debug("write text nav 0x{x} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ nav_index, nav.name.fmt(&pt.zcu.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
775687 if (!self.sixtyfour_bit) {
776 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
688 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @intCast(off), target.cpu.arch.endian());
777689 } else {
778690 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
779691 }
780692 self.syms.items[atom.sym_index.?].value = off;
781 if (self.decl_exports.get(decl_index)) |export_indices| {
782 try self.addDeclExports(pt.zcu, decl_index, export_indices);
693 if (self.nav_exports.get(nav_index)) |export_indices| {
694 try self.addNavExports(pt.zcu, nav_index, export_indices);
783695 }
784696 }
785697 }
......@@ -826,10 +738,10 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
826738 // data
827739 var data_i: u64 = got_size;
828740 {
829 var it = self.data_decl_table.iterator();
741 var it = self.data_nav_table.iterator();
830742 while (it.next()) |entry| {
831 const decl_index = entry.key_ptr.*;
832 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);
743 const nav_index = entry.key_ptr.*;
744 const atom = self.getAtomPtr(self.navs.get(nav_index).?.index);
833745 const code = entry.value_ptr.*;
834746
835747 foff += code.len;
......@@ -844,35 +756,13 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
844756 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
845757 }
846758 self.syms.items[atom.sym_index.?].value = off;
847 if (self.decl_exports.get(decl_index)) |export_indices| {
848 try self.addDeclExports(pt.zcu, decl_index, export_indices);
759 if (self.nav_exports.get(nav_index)) |export_indices| {
760 try self.addNavExports(pt.zcu, nav_index, export_indices);
849761 }
850762 }
851 // write the unnamed constants after the other data decls
852 var it_unc = self.unnamed_const_atoms.iterator();
853 while (it_unc.next()) |unnamed_consts| {
854 for (unnamed_consts.value_ptr.items) |atom_idx| {
855 const atom = self.getAtomPtr(atom_idx);
856 const code = atom.code.getOwnedCode().?; // unnamed consts must own their code
857 log.debug("write unnamed const: ({s})", .{self.syms.items[atom.sym_index.?].name});
858 foff += code.len;
859 iovecs[iovecs_i] = .{ .base = code.ptr, .len = code.len };
860 iovecs_i += 1;
861 const off = self.getAddr(data_i, .d);
862 data_i += code.len;
863 atom.offset = off;
864 if (!self.sixtyfour_bit) {
865 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
866 } else {
867 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
868 }
869 self.syms.items[atom.sym_index.?].value = off;
870 }
871 }
872 // the anon decls
873763 {
874 var it_anon = self.anon_decls.iterator();
875 while (it_anon.next()) |kv| {
764 var it_uav = self.uavs.iterator();
765 while (it_uav.next()) |kv| {
876766 const atom = self.getAtomPtr(kv.value_ptr.*);
877767 const code = atom.code.getOwnedCode().?;
878768 log.debug("write anon decl: {s}", .{self.syms.items[atom.sym_index.?].name});
......@@ -1011,14 +901,14 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
1011901 // write it all!
1012902 try file.pwritevAll(iovecs, 0);
1013903}
1014fn addDeclExports(
904fn addNavExports(
1015905 self: *Plan9,
1016906 mod: *Zcu,
1017 decl_index: InternPool.DeclIndex,
907 nav_index: InternPool.Nav.Index,
1018908 export_indices: []const u32,
1019909) !void {
1020910 const gpa = self.base.comp.gpa;
1021 const metadata = self.decls.getPtr(decl_index).?;
911 const metadata = self.navs.getPtr(nav_index).?;
1022912 const atom = self.getAtom(metadata.index);
1023913
1024914 for (export_indices) |export_idx| {
......@@ -1031,7 +921,7 @@ fn addDeclExports(
1031921 {
1032922 try mod.failed_exports.put(mod.gpa, export_idx, try Zcu.ErrorMsg.create(
1033923 gpa,
1034 mod.declPtr(decl_index).navSrcLoc(mod),
924 mod.navSrcLoc(nav_index),
1035925 "plan9 does not support extra sections",
1036926 .{},
1037927 ));
......@@ -1090,7 +980,6 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1090980 }
1091981 kv.value.exports.deinit(gpa);
1092982 }
1093 self.freeUnnamedConsts(decl_index);
1094983 {
1095984 const atom_index = self.decls.get(decl_index).?.index;
1096985 const relocs = self.relocs.getPtr(atom_index) orelse return;
......@@ -1098,18 +987,6 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1098987 assert(self.relocs.remove(atom_index));
1099988 }
1100989}
1101fn freeUnnamedConsts(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1102 const gpa = self.base.comp.gpa;
1103 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
1104 for (unnamed_consts.items) |atom_idx| {
1105 const atom = self.getAtom(atom_idx);
1106 gpa.free(self.syms.items[atom.sym_index.?].name);
1107 self.syms.items[atom.sym_index.?] = aout.Sym.undefined_symbol;
1108 self.syms_index_free_list.append(gpa, atom.sym_index.?) catch {};
1109 }
1110 unnamed_consts.clearAndFree(gpa);
1111}
1112
1113990fn createAtom(self: *Plan9) !Atom.Index {
1114991 const gpa = self.base.comp.gpa;
1115992 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
......@@ -1124,9 +1001,11 @@ fn createAtom(self: *Plan9) !Atom.Index {
11241001 return index;
11251002}
11261003
1127pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {
1128 const gpa = self.base.comp.gpa;
1129 const gop = try self.decls.getOrPut(gpa, decl_index);
1004pub fn seeNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !Atom.Index {
1005 const zcu = pt.zcu;
1006 const ip = &zcu.intern_pool;
1007 const gpa = zcu.gpa;
1008 const gop = try self.navs.getOrPut(gpa, nav_index);
11301009 if (!gop.found_existing) {
11311010 const index = try self.createAtom();
11321011 self.getAtomPtr(index).got_index = self.allocateGotIndex();
......@@ -1137,23 +1016,22 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {
11371016 }
11381017 const atom_idx = gop.value_ptr.index;
11391018 // handle externs here because they might not get updateDecl called on them
1140 const mod = self.base.comp.module.?;
1141 const decl = mod.declPtr(decl_index);
1142 if (decl.isExtern(mod)) {
1019 const nav = ip.getNav(nav_index);
1020 if (ip.indexToKey(nav.status.resolved.val) == .@"extern") {
11431021 // this is a "phantom atom" - it is never actually written to disk, just convenient for us to store stuff about externs
1144 if (decl.name.eqlSlice("etext", &mod.intern_pool)) {
1022 if (nav.name.eqlSlice("etext", ip)) {
11451023 self.etext_edata_end_atom_indices[0] = atom_idx;
1146 } else if (decl.name.eqlSlice("edata", &mod.intern_pool)) {
1024 } else if (nav.name.eqlSlice("edata", ip)) {
11471025 self.etext_edata_end_atom_indices[1] = atom_idx;
1148 } else if (decl.name.eqlSlice("end", &mod.intern_pool)) {
1026 } else if (nav.name.eqlSlice("end", ip)) {
11491027 self.etext_edata_end_atom_indices[2] = atom_idx;
11501028 }
1151 try self.updateFinish(decl_index);
1152 log.debug("seeDecl(extern) for {} (got_addr=0x{x})", .{
1153 decl.name.fmt(&mod.intern_pool),
1029 try self.updateFinish(pt, nav_index);
1030 log.debug("seeNav(extern) for {} (got_addr=0x{x})", .{
1031 nav.name.fmt(ip),
11541032 self.getAtom(atom_idx).getOffsetTableAddress(self),
11551033 });
1156 } else log.debug("seeDecl for {}", .{decl.name.fmt(&mod.intern_pool)});
1034 } else log.debug("seeNav for {}", .{nav.name.fmt(ip)});
11571035 return atom_idx;
11581036}
11591037
......@@ -1165,45 +1043,41 @@ pub fn updateExports(
11651043) !void {
11661044 const gpa = self.base.comp.gpa;
11671045 switch (exported) {
1168 .value => @panic("TODO: plan9 updateExports handling values"),
1169 .decl_index => |decl_index| {
1170 _ = try self.seeDecl(decl_index);
1171 if (self.decl_exports.fetchSwapRemove(decl_index)) |kv| {
1046 .uav => @panic("TODO: plan9 updateExports handling values"),
1047 .nav => |nav| {
1048 _ = try self.seeNav(pt, nav);
1049 if (self.nav_exports.fetchSwapRemove(nav)) |kv| {
11721050 gpa.free(kv.value);
11731051 }
1174 try self.decl_exports.ensureUnusedCapacity(gpa, 1);
1052 try self.nav_exports.ensureUnusedCapacity(gpa, 1);
11751053 const duped_indices = try gpa.dupe(u32, export_indices);
1176 self.decl_exports.putAssumeCapacityNoClobber(decl_index, duped_indices);
1054 self.nav_exports.putAssumeCapacityNoClobber(nav, duped_indices);
11771055 },
11781056 }
11791057 // all proper work is done in flush
1180 _ = pt;
11811058}
11821059
1183pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol) !Atom.Index {
1184 const gpa = pt.zcu.gpa;
1185 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?));
1060pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, lazy_sym: File.LazySymbol) !Atom.Index {
1061 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
11861062 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
11871063
11881064 if (!gop.found_existing) gop.value_ptr.* = .{};
11891065
1190 const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
1191 .code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },
1192 .const_data => .{ .atom = &gop.value_ptr.rodata_atom, .state = &gop.value_ptr.rodata_state },
1066 const atom_ptr, const state_ptr = switch (lazy_sym.kind) {
1067 .code => .{ &gop.value_ptr.text_atom, &gop.value_ptr.text_state },
1068 .const_data => .{ &gop.value_ptr.rodata_atom, &gop.value_ptr.rodata_state },
11931069 };
1194 switch (metadata.state.*) {
1195 .unused => metadata.atom.* = try self.createAtom(),
1196 .pending_flush => return metadata.atom.*,
1070 switch (state_ptr.*) {
1071 .unused => atom_ptr.* = try self.createAtom(),
1072 .pending_flush => return atom_ptr.*,
11971073 .flushed => {},
11981074 }
1199 metadata.state.* = .pending_flush;
1200 const atom = metadata.atom.*;
1075 state_ptr.* = .pending_flush;
1076 const atom = atom_ptr.*;
12011077 _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self);
12021078 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);
12031079 // anyerror needs to be deferred until flushModule
1204 if (sym.getDecl(self.base.comp.module.?) != .none) {
1205 try self.updateLazySymbolAtom(pt, sym, atom);
1206 }
1080 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbolAtom(pt, lazy_sym, atom);
12071081 return atom;
12081082}
12091083
......@@ -1217,7 +1091,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a
12171091 // create the symbol for the name
12181092 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
12191093 @tagName(sym.kind),
1220 sym.ty.fmt(pt),
1094 Type.fromInterned(sym.ty).fmt(pt),
12211095 });
12221096
12231097 const symbol: aout.Sym = .{
......@@ -1228,7 +1102,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a
12281102 self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;
12291103
12301104 // generate the code
1231 const src = sym.ty.srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;
1105 const src = Type.fromInterned(sym.ty).srcLocOrNull(pt.zcu) orelse Zcu.LazySrcLoc.unneeded;
12321106 const res = try codegen.generateLazySymbol(
12331107 &self.base,
12341108 pt,
......@@ -1264,12 +1138,6 @@ pub fn deinit(self: *Plan9) void {
12641138 }
12651139 self.relocs.deinit(gpa);
12661140 }
1267 // free the unnamed consts
1268 var it_unc = self.unnamed_const_atoms.iterator();
1269 while (it_unc.next()) |kv| {
1270 self.freeUnnamedConsts(kv.key_ptr.*);
1271 }
1272 self.unnamed_const_atoms.deinit(gpa);
12731141 var it_lzc = self.lazy_syms.iterator();
12741142 while (it_lzc.next()) |kv| {
12751143 if (kv.value_ptr.text_state != .unused)
......@@ -1278,7 +1146,7 @@ pub fn deinit(self: *Plan9) void {
12781146 gpa.free(self.syms.items[self.getAtom(kv.value_ptr.rodata_atom).sym_index.?].name);
12791147 }
12801148 self.lazy_syms.deinit(gpa);
1281 var itf_files = self.fn_decl_table.iterator();
1149 var itf_files = self.fn_nav_table.iterator();
12821150 while (itf_files.next()) |ent| {
12831151 // get the submap
12841152 var submap = ent.value_ptr.functions;
......@@ -1289,21 +1157,21 @@ pub fn deinit(self: *Plan9) void {
12891157 gpa.free(entry.value_ptr.lineinfo);
12901158 }
12911159 }
1292 self.fn_decl_table.deinit(gpa);
1293 var itd = self.data_decl_table.iterator();
1160 self.fn_nav_table.deinit(gpa);
1161 var itd = self.data_nav_table.iterator();
12941162 while (itd.next()) |entry| {
12951163 gpa.free(entry.value_ptr.*);
12961164 }
1297 var it_anon = self.anon_decls.iterator();
1298 while (it_anon.next()) |entry| {
1165 var it_uav = self.uavs.iterator();
1166 while (it_uav.next()) |entry| {
12991167 const sym_index = self.getAtom(entry.value_ptr.*).sym_index.?;
13001168 gpa.free(self.syms.items[sym_index].name);
13011169 }
1302 self.data_decl_table.deinit(gpa);
1303 for (self.decl_exports.values()) |export_indices| {
1170 self.data_nav_table.deinit(gpa);
1171 for (self.nav_exports.values()) |export_indices| {
13041172 gpa.free(export_indices);
13051173 }
1306 self.decl_exports.deinit(gpa);
1174 self.nav_exports.deinit(gpa);
13071175 self.syms.deinit(gpa);
13081176 self.got_index_free_list.deinit(gpa);
13091177 self.syms_index_free_list.deinit(gpa);
......@@ -1317,11 +1185,11 @@ pub fn deinit(self: *Plan9) void {
13171185 self.atoms.deinit(gpa);
13181186
13191187 {
1320 var it = self.decls.iterator();
1188 var it = self.navs.iterator();
13211189 while (it.next()) |entry| {
13221190 entry.value_ptr.exports.deinit(gpa);
13231191 }
1324 self.decls.deinit(gpa);
1192 self.navs.deinit(gpa);
13251193 }
13261194}
13271195
......@@ -1402,17 +1270,17 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
14021270
14031271 // write the data symbols
14041272 {
1405 var it = self.data_decl_table.iterator();
1273 var it = self.data_nav_table.iterator();
14061274 while (it.next()) |entry| {
1407 const decl_index = entry.key_ptr.*;
1408 const decl_metadata = self.decls.get(decl_index).?;
1409 const atom = self.getAtom(decl_metadata.index);
1275 const nav_index = entry.key_ptr.*;
1276 const nav_metadata = self.navs.get(nav_index).?;
1277 const atom = self.getAtom(nav_metadata.index);
14101278 const sym = self.syms.items[atom.sym_index.?];
14111279 try self.writeSym(writer, sym);
1412 if (self.decl_exports.get(decl_index)) |export_indices| {
1280 if (self.nav_exports.get(nav_index)) |export_indices| {
14131281 for (export_indices) |export_idx| {
14141282 const exp = mod.all_exports.items[export_idx];
1415 if (decl_metadata.getExport(self, exp.opts.name.toSlice(ip))) |exp_i| {
1283 if (nav_metadata.getExport(self, exp.opts.name.toSlice(ip))) |exp_i| {
14161284 try self.writeSym(writer, self.syms.items[exp_i]);
14171285 }
14181286 }
......@@ -1429,22 +1297,11 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
14291297 try self.writeSym(writer, sym);
14301298 }
14311299 }
1432 // unnamed consts
1433 {
1434 var it = self.unnamed_const_atoms.iterator();
1435 while (it.next()) |kv| {
1436 const consts = kv.value_ptr;
1437 for (consts.items) |atom_index| {
1438 const sym = self.syms.items[self.getAtom(atom_index).sym_index.?];
1439 try self.writeSym(writer, sym);
1440 }
1441 }
1442 }
14431300 // text symbols are the hardest:
14441301 // the file of a text symbol is the .z symbol before it
14451302 // so we have to write everything in the right order
14461303 {
1447 var it_file = self.fn_decl_table.iterator();
1304 var it_file = self.fn_nav_table.iterator();
14481305 while (it_file.next()) |fentry| {
14491306 var symidx_and_submap = fentry.value_ptr;
14501307 // write the z symbols
......@@ -1454,15 +1311,15 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
14541311 // write all the decls come from the file of the z symbol
14551312 var submap_it = symidx_and_submap.functions.iterator();
14561313 while (submap_it.next()) |entry| {
1457 const decl_index = entry.key_ptr.*;
1458 const decl_metadata = self.decls.get(decl_index).?;
1459 const atom = self.getAtom(decl_metadata.index);
1314 const nav_index = entry.key_ptr.*;
1315 const nav_metadata = self.navs.get(nav_index).?;
1316 const atom = self.getAtom(nav_metadata.index);
14601317 const sym = self.syms.items[atom.sym_index.?];
14611318 try self.writeSym(writer, sym);
1462 if (self.decl_exports.get(decl_index)) |export_indices| {
1319 if (self.nav_exports.get(nav_index)) |export_indices| {
14631320 for (export_indices) |export_idx| {
14641321 const exp = mod.all_exports.items[export_idx];
1465 if (decl_metadata.getExport(self, exp.opts.name.toSlice(ip))) |exp_i| {
1322 if (nav_metadata.getExport(self, exp.opts.name.toSlice(ip))) |exp_i| {
14661323 const s = self.syms.items[exp_i];
14671324 if (mem.eql(u8, s.name, "_start"))
14681325 self.entry_val = s.value;
......@@ -1500,31 +1357,31 @@ pub fn updateDeclLineNumber(self: *Plan9, pt: Zcu.PerThread, decl_index: InternP
15001357 _ = decl_index;
15011358}
15021359
1503pub fn getDeclVAddr(
1360pub fn getNavVAddr(
15041361 self: *Plan9,
15051362 pt: Zcu.PerThread,
1506 decl_index: InternPool.DeclIndex,
1363 nav_index: InternPool.Nav.Index,
15071364 reloc_info: link.File.RelocInfo,
15081365) !u64 {
15091366 const ip = &pt.zcu.intern_pool;
1510 const decl = pt.zcu.declPtr(decl_index);
1511 log.debug("getDeclVAddr for {}", .{decl.name.fmt(ip)});
1512 if (decl.isExtern(pt.zcu)) {
1513 if (decl.name.eqlSlice("etext", ip)) {
1367 const nav = ip.getNav(nav_index);
1368 log.debug("getDeclVAddr for {}", .{nav.name.fmt(ip)});
1369 if (ip.indexToKey(nav.status.resolved.val) == .@"extern") {
1370 if (nav.name.eqlSlice("etext", ip)) {
15141371 try self.addReloc(reloc_info.parent_atom_index, .{
15151372 .target = undefined,
15161373 .offset = reloc_info.offset,
15171374 .addend = reloc_info.addend,
15181375 .type = .special_etext,
15191376 });
1520 } else if (decl.name.eqlSlice("edata", ip)) {
1377 } else if (nav.name.eqlSlice("edata", ip)) {
15211378 try self.addReloc(reloc_info.parent_atom_index, .{
15221379 .target = undefined,
15231380 .offset = reloc_info.offset,
15241381 .addend = reloc_info.addend,
15251382 .type = .special_edata,
15261383 });
1527 } else if (decl.name.eqlSlice("end", ip)) {
1384 } else if (nav.name.eqlSlice("end", ip)) {
15281385 try self.addReloc(reloc_info.parent_atom_index, .{
15291386 .target = undefined,
15301387 .offset = reloc_info.offset,
......@@ -1536,7 +1393,7 @@ pub fn getDeclVAddr(
15361393 return undefined;
15371394 }
15381395 // otherwise, we just add a relocation
1539 const atom_index = try self.seeDecl(decl_index);
1396 const atom_index = try self.seeNav(pt, nav_index);
15401397 // the parent_atom_index in this case is just the decl_index of the parent
15411398 try self.addReloc(reloc_info.parent_atom_index, .{
15421399 .target = atom_index,
......@@ -1546,15 +1403,14 @@ pub fn getDeclVAddr(
15461403 return undefined;
15471404}
15481405
1549pub fn lowerAnonDecl(
1406pub fn lowerUav(
15501407 self: *Plan9,
15511408 pt: Zcu.PerThread,
1552 decl_val: InternPool.Index,
1409 uav: InternPool.Index,
15531410 explicit_alignment: InternPool.Alignment,
15541411 src_loc: Zcu.LazySrcLoc,
1555) !codegen.Result {
1412) !codegen.GenResult {
15561413 _ = explicit_alignment;
1557 // This is basically the same as lowerUnnamedConst.
15581414 // example:
15591415 // const ty = mod.intern_pool.typeOf(decl_val).toType();
15601416 // const val = decl_val.toValue();
......@@ -1564,41 +1420,40 @@ pub fn lowerAnonDecl(
15641420 // to put it in some location.
15651421 // ...
15661422 const gpa = self.base.comp.gpa;
1567 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
1568 if (!gop.found_existing) {
1569 const val = Value.fromInterned(decl_val);
1570 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
1571
1572 const index = try self.createAtom();
1573 const got_index = self.allocateGotIndex();
1574 gop.value_ptr.* = index;
1575 // we need to free name latex
1576 var code_buffer = std.ArrayList(u8).init(gpa);
1577 const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
1578 const code = switch (res) {
1579 .ok => code_buffer.items,
1580 .fail => |em| return .{ .fail = em },
1581 };
1582 const atom_ptr = self.getAtomPtr(index);
1583 atom_ptr.* = .{
1584 .type = .d,
1585 .offset = undefined,
1586 .sym_index = null,
1587 .got_index = got_index,
1588 .code = Atom.CodePtr.fromSlice(code),
1589 };
1590 _ = try atom_ptr.getOrCreateSymbolTableEntry(self);
1591 self.syms.items[atom_ptr.sym_index.?] = .{
1592 .type = .d,
1593 .value = undefined,
1594 .name = name,
1595 };
1596 }
1597 return .ok;
1423 const gop = try self.uavs.getOrPut(gpa, uav);
1424 if (gop.found_existing) return .{ .mcv = .{ .load_direct = gop.value_ptr.* } };
1425 const val = Value.fromInterned(uav);
1426 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(uav)});
1427
1428 const index = try self.createAtom();
1429 const got_index = self.allocateGotIndex();
1430 gop.value_ptr.* = index;
1431 // we need to free name latex
1432 var code_buffer = std.ArrayList(u8).init(gpa);
1433 const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
1434 const code = switch (res) {
1435 .ok => code_buffer.items,
1436 .fail => |em| return .{ .fail = em },
1437 };
1438 const atom_ptr = self.getAtomPtr(index);
1439 atom_ptr.* = .{
1440 .type = .d,
1441 .offset = undefined,
1442 .sym_index = null,
1443 .got_index = got_index,
1444 .code = Atom.CodePtr.fromSlice(code),
1445 };
1446 _ = try atom_ptr.getOrCreateSymbolTableEntry(self);
1447 self.syms.items[atom_ptr.sym_index.?] = .{
1448 .type = .d,
1449 .value = undefined,
1450 .name = name,
1451 };
1452 return .{ .mcv = .{ .load_direct = index } };
15981453}
15991454
1600pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1601 const atom_index = self.anon_decls.get(decl_val).?;
1455pub fn getUavVAddr(self: *Plan9, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1456 const atom_index = self.uavs.get(uav).?;
16021457 try self.addReloc(reloc_info.parent_atom_index, .{
16031458 .target = atom_index,
16041459 .offset = reloc_info.offset,
src/link/SpirV.zig+20-20
......@@ -36,6 +36,7 @@ const trace = @import("../tracy.zig").trace;
3636const build_options = @import("build_options");
3737const Air = @import("../Air.zig");
3838const Liveness = @import("../Liveness.zig");
39const Type = @import("../Type.zig");
3940const Value = @import("../Value.zig");
4041
4142const SpvModule = @import("../codegen/spirv/Module.zig");
......@@ -50,8 +51,6 @@ base: link.File,
5051
5152object: codegen.Object,
5253
53pub const base_tag: link.File.Tag = .spirv;
54
5554pub fn createEmpty(
5655 arena: Allocator,
5756 comp: *Compilation,
......@@ -128,22 +127,22 @@ pub fn updateFunc(self: *SpirV, pt: Zcu.PerThread, func_index: InternPool.Index,
128127 @panic("Attempted to compile for architecture that was disabled by build configuration");
129128 }
130129
130 const ip = &pt.zcu.intern_pool;
131131 const func = pt.zcu.funcInfo(func_index);
132 const decl = pt.zcu.declPtr(func.owner_decl);
133 log.debug("lowering function {}", .{decl.name.fmt(&pt.zcu.intern_pool)});
132 log.debug("lowering function {}", .{ip.getNav(func.owner_nav).name.fmt(ip)});
134133
135134 try self.object.updateFunc(pt, func_index, air, liveness);
136135}
137136
138pub fn updateDecl(self: *SpirV, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
137pub fn updateNav(self: *SpirV, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
139138 if (build_options.skip_non_native) {
140139 @panic("Attempted to compile for architecture that was disabled by build configuration");
141140 }
142141
143 const decl = pt.zcu.declPtr(decl_index);
144 log.debug("lowering declaration {}", .{decl.name.fmt(&pt.zcu.intern_pool)});
142 const ip = &pt.zcu.intern_pool;
143 log.debug("lowering declaration {}", .{ip.getNav(nav).name.fmt(ip)});
145144
146 try self.object.updateDecl(pt, decl_index);
145 try self.object.updateNav(pt, nav);
147146}
148147
149148pub fn updateExports(
......@@ -152,19 +151,20 @@ pub fn updateExports(
152151 exported: Zcu.Exported,
153152 export_indices: []const u32,
154153) !void {
155 const mod = pt.zcu;
156 const decl_index = switch (exported) {
157 .decl_index => |i| i,
158 .value => |val| {
159 _ = val;
154 const zcu = pt.zcu;
155 const ip = &zcu.intern_pool;
156 const nav_index = switch (exported) {
157 .nav => |nav| nav,
158 .uav => |uav| {
159 _ = uav;
160160 @panic("TODO: implement SpirV linker code for exporting a constant value");
161161 },
162162 };
163 const decl = mod.declPtr(decl_index);
164 if (decl.val.isFuncBody(mod)) {
165 const target = mod.getTarget();
166 const spv_decl_index = try self.object.resolveDecl(mod, decl_index);
167 const execution_model = switch (decl.typeOf(mod).fnCallingConvention(mod)) {
163 const nav_ty = ip.getNav(nav_index).typeOf(ip);
164 if (ip.isFunctionType(nav_ty)) {
165 const target = zcu.getTarget();
166 const spv_decl_index = try self.object.resolveNav(zcu, nav_index);
167 const execution_model = switch (Type.fromInterned(nav_ty).fnCallingConvention(zcu)) {
168168 .Vertex => spec.ExecutionModel.Vertex,
169169 .Fragment => spec.ExecutionModel.Fragment,
170170 .Kernel => spec.ExecutionModel.Kernel,
......@@ -177,10 +177,10 @@ pub fn updateExports(
177177 (is_vulkan and (execution_model == .Fragment or execution_model == .Vertex)))
178178 {
179179 for (export_indices) |export_idx| {
180 const exp = mod.all_exports.items[export_idx];
180 const exp = zcu.all_exports.items[export_idx];
181181 try self.object.spv.declareEntryPoint(
182182 spv_decl_index,
183 exp.opts.name.toSlice(&mod.intern_pool),
183 exp.opts.name.toSlice(ip),
184184 execution_model,
185185 );
186186 }
src/link/Wasm.zig+21-30
......@@ -39,8 +39,6 @@ const ZigObject = @import("Wasm/ZigObject.zig");
3939pub const Atom = @import("Wasm/Atom.zig");
4040pub const Relocation = types.Relocation;
4141
42pub const base_tag: link.File.Tag = .wasm;
43
4442base: link.File,
4543/// Symbol name of the entry function to export
4644entry_name: ?[]const u8,
......@@ -1451,19 +1449,19 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index,
14511449 try wasm.zigObjectPtr().?.updateFunc(wasm, pt, func_index, air, liveness);
14521450}
14531451
1454// Generate code for the Decl, storing it in memory to be later written to
1452// Generate code for the "Nav", storing it in memory to be later written to
14551453// the file on flush().
1456pub fn updateDecl(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1454pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
14571455 if (build_options.skip_non_native and builtin.object_format != .wasm) {
14581456 @panic("Attempted to compile for object format that was disabled by build configuration");
14591457 }
1460 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);
1461 try wasm.zigObjectPtr().?.updateDecl(wasm, pt, decl_index);
1458 if (wasm.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
1459 try wasm.zigObjectPtr().?.updateNav(wasm, pt, nav);
14621460}
14631461
1464pub fn updateDeclLineNumber(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
1462pub fn updateNavLineNumber(wasm: *Wasm, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
14651463 if (wasm.llvm_object) |_| return;
1466 try wasm.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);
1464 try wasm.zigObjectPtr().?.updateNavLineNumber(pt, nav);
14671465}
14681466
14691467/// From a given symbol location, returns its `wasm.GlobalType`.
......@@ -1505,13 +1503,6 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
15051503 return wasm.func_types.items[wasm.functions.get(.{ .file = loc.file, .index = symbol.index }).?.func.type_index];
15061504}
15071505
1508/// Lowers a constant typed value to a local symbol and atom.
1509/// Returns the symbol index of the local
1510/// The given `decl` is the parent decl whom owns the constant.
1511pub fn lowerUnnamedConst(wasm: *Wasm, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {
1512 return wasm.zigObjectPtr().?.lowerUnnamedConst(wasm, pt, val, decl_index);
1513}
1514
15151506/// Returns the symbol index from a symbol of which its flag is set global,
15161507/// such as an exported or imported symbol.
15171508/// If the symbol does not yet exist, creates a new one symbol instead
......@@ -1521,29 +1512,29 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !Sy
15211512 return wasm.zigObjectPtr().?.getGlobalSymbol(wasm.base.comp.gpa, name);
15221513}
15231514
1524/// For a given decl, find the given symbol index's atom, and create a relocation for the type.
1515/// For a given `Nav`, find the given symbol index's atom, and create a relocation for the type.
15251516/// Returns the given pointer address
1526pub fn getDeclVAddr(
1517pub fn getNavVAddr(
15271518 wasm: *Wasm,
15281519 pt: Zcu.PerThread,
1529 decl_index: InternPool.DeclIndex,
1520 nav: InternPool.Nav.Index,
15301521 reloc_info: link.File.RelocInfo,
15311522) !u64 {
1532 return wasm.zigObjectPtr().?.getDeclVAddr(wasm, pt, decl_index, reloc_info);
1523 return wasm.zigObjectPtr().?.getNavVAddr(wasm, pt, nav, reloc_info);
15331524}
15341525
1535pub fn lowerAnonDecl(
1526pub fn lowerUav(
15361527 wasm: *Wasm,
15371528 pt: Zcu.PerThread,
1538 decl_val: InternPool.Index,
1529 uav: InternPool.Index,
15391530 explicit_alignment: Alignment,
15401531 src_loc: Zcu.LazySrcLoc,
1541) !codegen.Result {
1542 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, pt, decl_val, explicit_alignment, src_loc);
1532) !codegen.GenResult {
1533 return wasm.zigObjectPtr().?.lowerUav(wasm, pt, uav, explicit_alignment, src_loc);
15431534}
15441535
1545pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1546 return wasm.zigObjectPtr().?.getAnonDeclVAddr(wasm, decl_val, reloc_info);
1536pub fn getUavVAddr(wasm: *Wasm, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1537 return wasm.zigObjectPtr().?.getUavVAddr(wasm, uav, reloc_info);
15471538}
15481539
15491540pub fn deleteExport(
......@@ -4018,11 +4009,11 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
40184009 return index;
40194010}
40204011
4021/// For the given `decl_index`, stores the corresponding type representing the function signature.
4012/// For the given `nav`, stores the corresponding type representing the function signature.
40224013/// Asserts declaration has an associated `Atom`.
40234014/// Returns the index into the list of types.
4024pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {
4025 return wasm.zigObjectPtr().?.storeDeclType(wasm.base.comp.gpa, decl_index, func_type);
4015pub fn storeNavType(wasm: *Wasm, nav: InternPool.Nav.Index, func_type: std.wasm.Type) !u32 {
4016 return wasm.zigObjectPtr().?.storeDeclType(wasm.base.comp.gpa, nav, func_type);
40264017}
40274018
40284019/// Returns the symbol index of the error name table.
......@@ -4036,8 +4027,8 @@ pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 {
40364027/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
40374028/// When the index was not found, a new `Atom` will be created, and its index will be returned.
40384029/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
4039pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !Atom.Index {
4040 return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
4030pub fn getOrCreateAtomForNav(wasm_file: *Wasm, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !Atom.Index {
4031 return wasm_file.zigObjectPtr().?.getOrCreateAtomForNav(wasm_file, pt, nav);
40414032}
40424033
40434034/// Verifies all resolved symbols and checks whether itself needs to be marked alive,
src/link/Wasm/ZigObject.zig+174-223
......@@ -6,9 +6,9 @@
66path: []const u8,
77/// Index within the list of relocatable objects of the linker driver.
88index: File.Index,
9/// Map of all `Decl` that are currently alive.
10/// Each index maps to the corresponding `DeclInfo`.
11decls_map: std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclInfo) = .{},
9/// Map of all `Nav` that are currently alive.
10/// Each index maps to the corresponding `NavInfo`.
11navs: std.AutoHashMapUnmanaged(InternPool.Nav.Index, NavInfo) = .{},
1212/// List of function type signatures for this Zig module.
1313func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},
1414/// List of `std.wasm.Func`. Each entry contains the function signature,
......@@ -36,7 +36,7 @@ segment_free_list: std.ArrayListUnmanaged(u32) = .{},
3636/// File encapsulated string table, used to deduplicate strings within the generated file.
3737string_table: StringTable = .{},
3838/// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index.
39anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
39uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
4040/// List of atom indexes of functions that are generated by the backend.
4141synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{},
4242/// Represents the symbol index of the error name table
......@@ -86,12 +86,12 @@ debug_str_index: ?u32 = null,
8686/// The index of the segment representing the custom '.debug_pubtypes' section.
8787debug_abbrev_index: ?u32 = null,
8888
89const DeclInfo = struct {
89const NavInfo = struct {
9090 atom: Atom.Index = .null,
9191 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
9292
93 fn @"export"(di: DeclInfo, zig_object: *const ZigObject, name: []const u8) ?Symbol.Index {
94 for (di.exports.items) |sym_index| {
93 fn @"export"(ni: NavInfo, zig_object: *const ZigObject, name: []const u8) ?Symbol.Index {
94 for (ni.exports.items) |sym_index| {
9595 const sym_name_index = zig_object.symbol(sym_index).name;
9696 const sym_name = zig_object.string_table.getAssumeExists(sym_name_index);
9797 if (std.mem.eql(u8, name, sym_name)) {
......@@ -101,14 +101,14 @@ const DeclInfo = struct {
101101 return null;
102102 }
103103
104 fn appendExport(di: *DeclInfo, gpa: std.mem.Allocator, sym_index: Symbol.Index) !void {
105 return di.exports.append(gpa, sym_index);
104 fn appendExport(ni: *NavInfo, gpa: std.mem.Allocator, sym_index: Symbol.Index) !void {
105 return ni.exports.append(gpa, sym_index);
106106 }
107107
108 fn deleteExport(di: *DeclInfo, sym_index: Symbol.Index) void {
109 for (di.exports.items, 0..) |idx, index| {
108 fn deleteExport(ni: *NavInfo, sym_index: Symbol.Index) void {
109 for (ni.exports.items, 0..) |idx, index| {
110110 if (idx == sym_index) {
111 _ = di.exports.swapRemove(index);
111 _ = ni.exports.swapRemove(index);
112112 return;
113113 }
114114 }
......@@ -155,19 +155,19 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
155155 }
156156
157157 {
158 var it = zig_object.decls_map.valueIterator();
159 while (it.next()) |decl_info| {
160 const atom = wasm_file.getAtomPtr(decl_info.atom);
158 var it = zig_object.navs.valueIterator();
159 while (it.next()) |nav_info| {
160 const atom = wasm_file.getAtomPtr(nav_info.atom);
161161 for (atom.locals.items) |local_index| {
162162 const local_atom = wasm_file.getAtomPtr(local_index);
163163 local_atom.deinit(gpa);
164164 }
165165 atom.deinit(gpa);
166 decl_info.exports.deinit(gpa);
166 nav_info.exports.deinit(gpa);
167167 }
168168 }
169169 {
170 for (zig_object.anon_decls.values()) |atom_index| {
170 for (zig_object.uavs.values()) |atom_index| {
171171 const atom = wasm_file.getAtomPtr(atom_index);
172172 for (atom.locals.items) |local_index| {
173173 const local_atom = wasm_file.getAtomPtr(local_index);
......@@ -201,8 +201,8 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
201201 zig_object.atom_types.deinit(gpa);
202202 zig_object.functions.deinit(gpa);
203203 zig_object.imports.deinit(gpa);
204 zig_object.decls_map.deinit(gpa);
205 zig_object.anon_decls.deinit(gpa);
204 zig_object.navs.deinit(gpa);
205 zig_object.uavs.deinit(gpa);
206206 zig_object.symbols.deinit(gpa);
207207 zig_object.symbols_free_list.deinit(gpa);
208208 zig_object.segment_info.deinit(gpa);
......@@ -236,34 +236,35 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In
236236 return index;
237237}
238238
239// Generate code for the Decl, storing it in memory to be later written to
239// Generate code for the `Nav`, storing it in memory to be later written to
240240// the file on flush().
241pub fn updateDecl(
241pub fn updateNav(
242242 zig_object: *ZigObject,
243243 wasm_file: *Wasm,
244244 pt: Zcu.PerThread,
245 decl_index: InternPool.DeclIndex,
245 nav_index: InternPool.Nav.Index,
246246) !void {
247 const mod = pt.zcu;
248 const decl = mod.declPtr(decl_index);
249 if (decl.val.getFunction(mod)) |_| {
250 return;
251 } else if (decl.val.getExternFunc(mod)) |_| {
252 return;
253 }
247 const zcu = pt.zcu;
248 const ip = &zcu.intern_pool;
249 const nav = ip.getNav(nav_index);
250
251 const is_extern, const lib_name, const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) {
252 .variable => |variable| .{ false, variable.lib_name, variable.init },
253 .func => return,
254 .@"extern" => |@"extern"| if (ip.isFunctionType(nav.typeOf(ip)))
255 return
256 else
257 .{ true, @"extern".lib_name, nav.status.resolved.val },
258 else => .{ false, .none, nav.status.resolved.val },
259 };
254260
255261 const gpa = wasm_file.base.comp.gpa;
256 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
262 const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index);
257263 const atom = wasm_file.getAtomPtr(atom_index);
258264 atom.clear();
259265
260 if (decl.isExtern(mod)) {
261 const variable = decl.getOwnedVariable(mod).?;
262 const name = decl.name.toSlice(&mod.intern_pool);
263 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);
264 return zig_object.addOrUpdateImport(wasm_file, name, atom.sym_index, lib_name, null);
265 }
266 const val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
266 if (is_extern)
267 return zig_object.addOrUpdateImport(wasm_file, nav.name.toSlice(ip), atom.sym_index, lib_name.toSlice(ip), null);
267268
268269 var code_writer = std.ArrayList(u8).init(gpa);
269270 defer code_writer.deinit();
......@@ -271,8 +272,8 @@ pub fn updateDecl(
271272 const res = try codegen.generateSymbol(
272273 &wasm_file.base,
273274 pt,
274 decl.navSrcLoc(mod),
275 val,
275 zcu.navSrcLoc(nav_index),
276 Value.fromInterned(nav_init),
276277 &code_writer,
277278 .none,
278279 .{ .parent_atom_index = @intFromEnum(atom.sym_index) },
......@@ -281,13 +282,12 @@ pub fn updateDecl(
281282 const code = switch (res) {
282283 .ok => code_writer.items,
283284 .fail => |em| {
284 decl.analysis = .codegen_failure;
285 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
285 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
286286 return;
287287 },
288288 };
289289
290 return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code);
290 return zig_object.finishUpdateNav(wasm_file, pt, nav_index, code);
291291}
292292
293293pub fn updateFunc(
......@@ -298,11 +298,10 @@ pub fn updateFunc(
298298 air: Air,
299299 liveness: Liveness,
300300) !void {
301 const gpa = wasm_file.base.comp.gpa;
301 const zcu = pt.zcu;
302 const gpa = zcu.gpa;
302303 const func = pt.zcu.funcInfo(func_index);
303 const decl_index = func.owner_decl;
304 const decl = pt.zcu.declPtr(decl_index);
305 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
304 const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, func.owner_nav);
306305 const atom = wasm_file.getAtomPtr(atom_index);
307306 atom.clear();
308307
......@@ -311,7 +310,7 @@ pub fn updateFunc(
311310 const result = try codegen.generateFunction(
312311 &wasm_file.base,
313312 pt,
314 decl.navSrcLoc(pt.zcu),
313 zcu.navSrcLoc(func.owner_nav),
315314 func_index,
316315 air,
317316 liveness,
......@@ -322,79 +321,75 @@ pub fn updateFunc(
322321 const code = switch (result) {
323322 .ok => code_writer.items,
324323 .fail => |em| {
325 decl.analysis = .codegen_failure;
326 try pt.zcu.failed_analysis.put(gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
324 try pt.zcu.failed_codegen.put(gpa, func.owner_nav, em);
327325 return;
328326 },
329327 };
330328
331 return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code);
329 return zig_object.finishUpdateNav(wasm_file, pt, func.owner_nav, code);
332330}
333331
334fn finishUpdateDecl(
332fn finishUpdateNav(
335333 zig_object: *ZigObject,
336334 wasm_file: *Wasm,
337335 pt: Zcu.PerThread,
338 decl_index: InternPool.DeclIndex,
336 nav_index: InternPool.Nav.Index,
339337 code: []const u8,
340338) !void {
341339 const zcu = pt.zcu;
342340 const ip = &zcu.intern_pool;
343341 const gpa = zcu.gpa;
344 const decl = zcu.declPtr(decl_index);
345 const decl_info = zig_object.decls_map.get(decl_index).?;
346 const atom_index = decl_info.atom;
342 const nav = ip.getNav(nav_index);
343 const nav_val = zcu.navValue(nav_index);
344 const nav_info = zig_object.navs.get(nav_index).?;
345 const atom_index = nav_info.atom;
347346 const atom = wasm_file.getAtomPtr(atom_index);
348347 const sym = zig_object.symbol(atom.sym_index);
349 sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(ip));
348 sym.name = try zig_object.string_table.insert(gpa, nav.fqn.toSlice(ip));
350349 try atom.code.appendSlice(gpa, code);
351350 atom.size = @intCast(code.len);
352351
353 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
354 .Fn => {
355 sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? });
356 sym.tag = .function;
357 },
358 else => {
359 const segment_name: []const u8 = if (decl.getOwnedVariable(zcu)) |variable| name: {
360 if (variable.is_const) {
361 break :name ".rodata.";
362 } else if (Value.fromInterned(variable.init).isUndefDeep(zcu)) {
363 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
364 const optimize_mode = decl_namespace.fileScope(zcu).mod.optimize_mode;
365 const is_initialized = switch (optimize_mode) {
366 .Debug, .ReleaseSafe => true,
367 .ReleaseFast, .ReleaseSmall => false,
368 };
369 if (is_initialized) {
370 break :name ".data.";
371 }
372 break :name ".bss.";
373 }
374 // when the decl is all zeroes, we store the atom in the bss segment,
375 // in all other cases it will be in the data segment.
376 for (atom.code.items) |byte| {
377 if (byte != 0) break :name ".data.";
378 }
379 break :name ".bss.";
380 } else ".rodata.";
381 if ((wasm_file.base.isObject() or wasm_file.base.comp.config.import_memory) and
382 std.mem.startsWith(u8, segment_name, ".bss"))
383 {
384 @memset(atom.code.items, 0);
352 if (ip.isFunctionType(nav.typeOf(ip))) {
353 sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? });
354 sym.tag = .function;
355 } else {
356 const is_const, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
357 .variable => |variable| .{ false, variable.init },
358 .@"extern" => |@"extern"| .{ @"extern".is_const, .none },
359 else => .{ true, nav_val.toIntern() },
360 };
361 const segment_name = name: {
362 if (is_const) break :name ".rodata.";
363
364 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) {
365 break :name switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
366 .Debug, .ReleaseSafe => ".data.",
367 .ReleaseFast, .ReleaseSmall => ".bss.",
368 };
385369 }
386 // Will be freed upon freeing of decl or after cleanup of Wasm binary.
387 const full_segment_name = try std.mem.concat(gpa, u8, &.{
388 segment_name,
389 decl.fqn.toSlice(ip),
390 });
391 errdefer gpa.free(full_segment_name);
392 sym.tag = .data;
393 sym.index = try zig_object.createDataSegment(gpa, full_segment_name, decl.alignment);
394 },
370 // when the decl is all zeroes, we store the atom in the bss segment,
371 // in all other cases it will be in the data segment.
372 for (atom.code.items) |byte| {
373 if (byte != 0) break :name ".data.";
374 }
375 break :name ".bss.";
376 };
377 if ((wasm_file.base.isObject() or wasm_file.base.comp.config.import_memory) and
378 std.mem.startsWith(u8, segment_name, ".bss"))
379 {
380 @memset(atom.code.items, 0);
381 }
382 // Will be freed upon freeing of decl or after cleanup of Wasm binary.
383 const full_segment_name = try std.mem.concat(gpa, u8, &.{
384 segment_name,
385 nav.fqn.toSlice(ip),
386 });
387 errdefer gpa.free(full_segment_name);
388 sym.tag = .data;
389 sym.index = try zig_object.createDataSegment(gpa, full_segment_name, pt.navAlignment(nav_index));
395390 }
396391 if (code.len == 0) return;
397 atom.alignment = decl.getAlignment(pt);
392 atom.alignment = pt.navAlignment(nav_index);
398393}
399394
400395/// Creates and initializes a new segment in the 'Data' section.
......@@ -420,50 +415,51 @@ fn createDataSegment(
420415 return segment_index;
421416}
422417
423/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
418/// For a given `InternPool.Nav.Index` returns its corresponding `Atom.Index`.
424419/// When the index was not found, a new `Atom` will be created, and its index will be returned.
425420/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
426pub fn getOrCreateAtomForDecl(
421pub fn getOrCreateAtomForNav(
427422 zig_object: *ZigObject,
428423 wasm_file: *Wasm,
429424 pt: Zcu.PerThread,
430 decl_index: InternPool.DeclIndex,
425 nav_index: InternPool.Nav.Index,
431426) !Atom.Index {
427 const ip = &pt.zcu.intern_pool;
432428 const gpa = pt.zcu.gpa;
433 const gop = try zig_object.decls_map.getOrPut(gpa, decl_index);
429 const gop = try zig_object.navs.getOrPut(gpa, nav_index);
434430 if (!gop.found_existing) {
435431 const sym_index = try zig_object.allocateSymbol(gpa);
436432 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
437 const decl = pt.zcu.declPtr(decl_index);
433 const nav = ip.getNav(nav_index);
438434 const sym = zig_object.symbol(sym_index);
439 sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(&pt.zcu.intern_pool));
435 sym.name = try zig_object.string_table.insert(gpa, nav.fqn.toSlice(ip));
440436 }
441437 return gop.value_ptr.atom;
442438}
443439
444pub fn lowerAnonDecl(
440pub fn lowerUav(
445441 zig_object: *ZigObject,
446442 wasm_file: *Wasm,
447443 pt: Zcu.PerThread,
448 decl_val: InternPool.Index,
444 uav: InternPool.Index,
449445 explicit_alignment: InternPool.Alignment,
450446 src_loc: Zcu.LazySrcLoc,
451) !codegen.Result {
447) !codegen.GenResult {
452448 const gpa = wasm_file.base.comp.gpa;
453 const gop = try zig_object.anon_decls.getOrPut(gpa, decl_val);
449 const gop = try zig_object.uavs.getOrPut(gpa, uav);
454450 if (!gop.found_existing) {
455451 var name_buf: [32]u8 = undefined;
456452 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
457 @intFromEnum(decl_val),
453 @intFromEnum(uav),
458454 }) catch unreachable;
459455
460 switch (try zig_object.lowerConst(wasm_file, pt, name, Value.fromInterned(decl_val), src_loc)) {
461 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,
456 switch (try zig_object.lowerConst(wasm_file, pt, name, Value.fromInterned(uav), src_loc)) {
457 .ok => |atom_index| zig_object.uavs.values()[gop.index] = atom_index,
462458 .fail => |em| return .{ .fail = em },
463459 }
464460 }
465461
466 const atom = wasm_file.getAtomPtr(zig_object.anon_decls.values()[gop.index]);
462 const atom = wasm_file.getAtomPtr(zig_object.uavs.values()[gop.index]);
467463 atom.alignment = switch (atom.alignment) {
468464 .none => explicit_alignment,
469465 else => switch (explicit_alignment) {
......@@ -471,53 +467,7 @@ pub fn lowerAnonDecl(
471467 else => atom.alignment.maxStrict(explicit_alignment),
472468 },
473469 };
474 return .ok;
475}
476
477/// Lowers a constant typed value to a local symbol and atom.
478/// Returns the symbol index of the local
479/// The given `decl` is the parent decl whom owns the constant.
480pub fn lowerUnnamedConst(
481 zig_object: *ZigObject,
482 wasm_file: *Wasm,
483 pt: Zcu.PerThread,
484 val: Value,
485 decl_index: InternPool.DeclIndex,
486) !u32 {
487 const mod = pt.zcu;
488 const gpa = mod.gpa;
489 std.debug.assert(val.typeOf(mod).zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
490 const decl = mod.declPtr(decl_index);
491
492 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
493 const parent_atom = wasm_file.getAtom(parent_atom_index);
494 const local_index = parent_atom.locals.items.len;
495 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{
496 decl.fqn.fmt(&mod.intern_pool), local_index,
497 });
498 defer gpa.free(name);
499
500 // We want to lower the source location of `decl`. However, when generating
501 // lazy functions (for e.g. `@tagName`), `decl` may correspond to a type
502 // rather than a `Nav`!
503 // The future split of `Decl` into `Nav` and `Cau` may require rethinking this
504 // logic. For now, just get the source location conditionally as needed.
505 const decl_src = if (decl.typeOf(mod).toIntern() == .type_type)
506 decl.val.toType().srcLoc(mod)
507 else
508 decl.navSrcLoc(mod);
509
510 switch (try zig_object.lowerConst(wasm_file, pt, name, val, decl_src)) {
511 .ok => |atom_index| {
512 try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
513 return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
514 },
515 .fail => |em| {
516 decl.analysis = .codegen_failure;
517 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
518 return error.CodegenFail;
519 },
520 }
470 return .{ .mcv = .{ .load_symbol = @intFromEnum(atom.sym_index) } };
521471}
522472
523473const LowerConstResult = union(enum) {
......@@ -782,36 +732,38 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
782732
783733/// For a given decl, find the given symbol index's atom, and create a relocation for the type.
784734/// Returns the given pointer address
785pub fn getDeclVAddr(
735pub fn getNavVAddr(
786736 zig_object: *ZigObject,
787737 wasm_file: *Wasm,
788738 pt: Zcu.PerThread,
789 decl_index: InternPool.DeclIndex,
739 nav_index: InternPool.Nav.Index,
790740 reloc_info: link.File.RelocInfo,
791741) !u64 {
792 const target = wasm_file.base.comp.root_mod.resolved_target.result;
793742 const zcu = pt.zcu;
794743 const ip = &zcu.intern_pool;
795744 const gpa = zcu.gpa;
796 const decl = zcu.declPtr(decl_index);
745 const nav = ip.getNav(nav_index);
746 const target = &zcu.navFileScope(nav_index).mod.resolved_target.result;
797747
798 const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
748 const target_atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index);
799749 const target_atom = wasm_file.getAtom(target_atom_index);
800750 const target_symbol_index = @intFromEnum(target_atom.sym_index);
801 if (decl.isExtern(zcu)) {
802 const name = decl.name.toSlice(ip);
803 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|
804 ext_fn.lib_name.toSlice(ip)
805 else
806 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);
807 try zig_object.addOrUpdateImport(wasm_file, name, target_atom.sym_index, lib_name, null);
751 switch (ip.indexToKey(nav.status.resolved.val)) {
752 .@"extern" => |@"extern"| try zig_object.addOrUpdateImport(
753 wasm_file,
754 nav.name.toSlice(ip),
755 target_atom.sym_index,
756 @"extern".lib_name.toSlice(ip),
757 null,
758 ),
759 else => {},
808760 }
809761
810762 std.debug.assert(reloc_info.parent_atom_index != 0);
811763 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
812764 const atom = wasm_file.getAtomPtr(atom_index);
813765 const is_wasm32 = target.cpu.arch == .wasm32;
814 if (decl.typeOf(pt.zcu).zigTypeTag(pt.zcu) == .Fn) {
766 if (ip.isFunctionType(ip.getNav(nav_index).typeOf(ip))) {
815767 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
816768 try atom.relocs.append(gpa, .{
817769 .index = target_symbol_index,
......@@ -834,22 +786,22 @@ pub fn getDeclVAddr(
834786 return target_symbol_index;
835787}
836788
837pub fn getAnonDeclVAddr(
789pub fn getUavVAddr(
838790 zig_object: *ZigObject,
839791 wasm_file: *Wasm,
840 decl_val: InternPool.Index,
792 uav: InternPool.Index,
841793 reloc_info: link.File.RelocInfo,
842794) !u64 {
843795 const gpa = wasm_file.base.comp.gpa;
844796 const target = wasm_file.base.comp.root_mod.resolved_target.result;
845 const atom_index = zig_object.anon_decls.get(decl_val).?;
797 const atom_index = zig_object.uavs.get(uav).?;
846798 const target_symbol_index = @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
847799
848800 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
849801 const parent_atom = wasm_file.getAtomPtr(parent_atom_index);
850802 const is_wasm32 = target.cpu.arch == .wasm32;
851803 const mod = wasm_file.base.comp.module.?;
852 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
804 const ty = Type.fromInterned(mod.intern_pool.typeOf(uav));
853805 if (ty.zigTypeTag(mod) == .Fn) {
854806 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
855807 try parent_atom.relocs.append(gpa, .{
......@@ -880,14 +832,14 @@ pub fn deleteExport(
880832 name: InternPool.NullTerminatedString,
881833) void {
882834 const mod = wasm_file.base.comp.module.?;
883 const decl_index = switch (exported) {
884 .decl_index => |decl_index| decl_index,
885 .value => @panic("TODO: implement Wasm linker code for exporting a constant value"),
835 const nav_index = switch (exported) {
836 .nav => |nav_index| nav_index,
837 .uav => @panic("TODO: implement Wasm linker code for exporting a constant value"),
886838 };
887 const decl_info = zig_object.decls_map.getPtr(decl_index) orelse return;
888 if (decl_info.@"export"(zig_object, name.toSlice(&mod.intern_pool))) |sym_index| {
839 const nav_info = zig_object.navs.getPtr(nav_index) orelse return;
840 if (nav_info.@"export"(zig_object, name.toSlice(&mod.intern_pool))) |sym_index| {
889841 const sym = zig_object.symbol(sym_index);
890 decl_info.deleteExport(sym_index);
842 nav_info.deleteExport(sym_index);
891843 std.debug.assert(zig_object.global_syms.remove(sym.name));
892844 std.debug.assert(wasm_file.symbol_atom.remove(.{ .file = zig_object.index, .index = sym_index }));
893845 zig_object.symbols_free_list.append(wasm_file.base.comp.gpa, sym_index) catch {};
......@@ -902,38 +854,39 @@ pub fn updateExports(
902854 exported: Zcu.Exported,
903855 export_indices: []const u32,
904856) !void {
905 const mod = pt.zcu;
906 const decl_index = switch (exported) {
907 .decl_index => |i| i,
908 .value => |val| {
909 _ = val;
857 const zcu = pt.zcu;
858 const ip = &zcu.intern_pool;
859 const nav_index = switch (exported) {
860 .nav => |nav| nav,
861 .uav => |uav| {
862 _ = uav;
910863 @panic("TODO: implement Wasm linker code for exporting a constant value");
911864 },
912865 };
913 const decl = mod.declPtr(decl_index);
914 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
915 const decl_info = zig_object.decls_map.getPtr(decl_index).?;
866 const nav = ip.getNav(nav_index);
867 const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index);
868 const nav_info = zig_object.navs.getPtr(nav_index).?;
916869 const atom = wasm_file.getAtom(atom_index);
917870 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
918 const gpa = mod.gpa;
919 log.debug("Updating exports for decl '{}'", .{decl.name.fmt(&mod.intern_pool)});
871 const gpa = zcu.gpa;
872 log.debug("Updating exports for decl '{}'", .{nav.name.fmt(ip)});
920873
921874 for (export_indices) |export_idx| {
922 const exp = mod.all_exports.items[export_idx];
923 if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {
924 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
875 const exp = zcu.all_exports.items[export_idx];
876 if (exp.opts.section.toSlice(ip)) |section| {
877 try zcu.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
925878 gpa,
926 decl.navSrcLoc(mod),
879 zcu.navSrcLoc(nav_index),
927880 "Unimplemented: ExportOptions.section '{s}'",
928881 .{section},
929882 ));
930883 continue;
931884 }
932885
933 const export_string = exp.opts.name.toSlice(&mod.intern_pool);
934 const sym_index = if (decl_info.@"export"(zig_object, export_string)) |idx| idx else index: {
886 const export_string = exp.opts.name.toSlice(ip);
887 const sym_index = if (nav_info.@"export"(zig_object, export_string)) |idx| idx else index: {
935888 const sym_index = try zig_object.allocateSymbol(gpa);
936 try decl_info.appendExport(gpa, sym_index);
889 try nav_info.appendExport(gpa, sym_index);
937890 break :index sym_index;
938891 };
939892
......@@ -954,9 +907,9 @@ pub fn updateExports(
954907 },
955908 .strong => {}, // symbols are strong by default
956909 .link_once => {
957 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
910 try zcu.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
958911 gpa,
959 decl.navSrcLoc(mod),
912 zcu.navSrcLoc(nav_index),
960913 "Unimplemented: LinkOnce",
961914 .{},
962915 ));
......@@ -972,21 +925,21 @@ pub fn updateExports(
972925 }
973926}
974927
975pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool.DeclIndex) void {
928pub fn freeNav(zig_object: *ZigObject, wasm_file: *Wasm, nav_index: InternPool.Nav.Index) void {
976929 const gpa = wasm_file.base.comp.gpa;
977930 const mod = wasm_file.base.comp.module.?;
978 const decl = mod.declPtr(decl_index);
979 const decl_info = zig_object.decls_map.getPtr(decl_index).?;
980 const atom_index = decl_info.atom;
931 const ip = &mod.intern_pool;
932 const nav_info = zig_object.navs.getPtr(nav_index).?;
933 const atom_index = nav_info.atom;
981934 const atom = wasm_file.getAtomPtr(atom_index);
982935 zig_object.symbols_free_list.append(gpa, atom.sym_index) catch {};
983 for (decl_info.exports.items) |exp_sym_index| {
936 for (nav_info.exports.items) |exp_sym_index| {
984937 const exp_sym = zig_object.symbol(exp_sym_index);
985938 exp_sym.tag = .dead;
986939 zig_object.symbols_free_list.append(exp_sym_index) catch {};
987940 }
988 decl_info.exports.deinit(gpa);
989 std.debug.assert(zig_object.decls_map.remove(decl_index));
941 nav_info.exports.deinit(gpa);
942 std.debug.assert(zig_object.navs.remove(nav_index));
990943 const sym = &zig_object.symbols.items[atom.sym_index];
991944 for (atom.locals.items) |local_atom_index| {
992945 const local_atom = wasm_file.getAtom(local_atom_index);
......@@ -1000,7 +953,8 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
1000953 segment.name = &.{}; // Ensure no accidental double free
1001954 }
1002955
1003 if (decl.isExtern(mod)) {
956 const nav_val = mod.navValue(nav_index).toIntern();
957 if (ip.indexToKey(nav_val) == .@"extern") {
1004958 std.debug.assert(zig_object.imports.remove(atom.sym_index));
1005959 }
1006960 std.debug.assert(wasm_file.symbol_atom.remove(atom.symbolLoc()));
......@@ -1014,17 +968,14 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
1014968 if (sym.isGlobal()) {
1015969 std.debug.assert(zig_object.global_syms.remove(atom.sym_index));
1016970 }
1017 switch (decl.typeOf(mod).zigTypeTag(mod)) {
1018 .Fn => {
1019 zig_object.functions_free_list.append(gpa, sym.index) catch {};
1020 std.debug.assert(zig_object.atom_types.remove(atom_index));
1021 },
1022 else => {
1023 zig_object.segment_free_list.append(gpa, sym.index) catch {};
1024 const segment = &zig_object.segment_info.items[sym.index];
1025 gpa.free(segment.name);
1026 segment.name = &.{}; // Prevent accidental double free
1027 },
971 if (ip.isFunctionType(ip.typeOf(nav_val))) {
972 zig_object.functions_free_list.append(gpa, sym.index) catch {};
973 std.debug.assert(zig_object.atom_types.remove(atom_index));
974 } else {
975 zig_object.segment_free_list.append(gpa, sym.index) catch {};
976 const segment = &zig_object.segment_info.items[sym.index];
977 gpa.free(segment.name);
978 segment.name = &.{}; // Prevent accidental double free
1028979 }
1029980}
1030981
......@@ -1182,10 +1133,10 @@ fn allocateDebugAtoms(zig_object: *ZigObject) !void {
11821133/// For the given `decl_index`, stores the corresponding type representing the function signature.
11831134/// Asserts declaration has an associated `Atom`.
11841135/// Returns the index into the list of types.
1185pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {
1186 const decl_info = zig_object.decls_map.get(decl_index).?;
1136pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, nav_index: InternPool.Nav.Index, func_type: std.wasm.Type) !u32 {
1137 const nav_info = zig_object.navs.get(nav_index).?;
11871138 const index = try zig_object.putOrGetFuncType(gpa, func_type);
1188 try zig_object.atom_types.put(gpa, decl_info.atom, index);
1139 try zig_object.atom_types.put(gpa, nav_info.atom, index);
11891140 return index;
11901141}
11911142
src/print_air.zig+1-1
......@@ -675,7 +675,7 @@ const Writer = struct {
675675 }
676676 }
677677 const asm_source = std.mem.sliceAsBytes(w.air.extra[extra_i..])[0..extra.data.source_len];
678 try s.print(", \"{s}\"", .{asm_source});
678 try s.print(", \"{}\"", .{std.zig.fmtEscapes(asm_source)});
679679 }
680680
681681 fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/print_value.zig+14-18
......@@ -90,12 +90,8 @@ pub fn print(
9090 else => try writer.writeAll(@tagName(simple_value)),
9191 },
9292 .variable => try writer.writeAll("(variable)"),
93 .extern_func => |extern_func| try writer.print("(extern function '{}')", .{
94 mod.declPtr(extern_func.decl).name.fmt(ip),
95 }),
96 .func => |func| try writer.print("(function '{}')", .{
97 mod.declPtr(func.owner_decl).name.fmt(ip),
98 }),
93 .@"extern" => |e| try writer.print("(extern '{}')", .{e.name.fmt(ip)}),
94 .func => |func| try writer.print("(function '{}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}),
9995 .int => |int| switch (int.storage) {
10096 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
10197 .lazy_align => |ty| if (have_sema) {
......@@ -138,8 +134,8 @@ pub fn print(
138134 .slice => |slice| {
139135 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
140136 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
141 .anon_decl, .comptime_alloc, .comptime_field => true,
142 .decl, .int => false,
137 .uav, .comptime_alloc, .comptime_field => true,
138 .nav, .int => false,
143139 };
144140 if (print_contents) {
145141 // TODO: eventually we want to load the slice as an array with `sema`, but that's
......@@ -157,8 +153,8 @@ pub fn print(
157153 .ptr => {
158154 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {
159155 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
160 .anon_decl, .comptime_alloc, .comptime_field => true,
161 .decl, .int => false,
156 .uav, .comptime_alloc, .comptime_field => true,
157 .nav, .int => false,
162158 };
163159 if (print_contents) {
164160 // TODO: eventually we want to load the pointer with `sema`, but that's
......@@ -294,11 +290,11 @@ fn printPtr(
294290 else => unreachable,
295291 };
296292
297 if (ptr.base_addr == .anon_decl) {
293 if (ptr.base_addr == .uav) {
298294 // If the value is an aggregate, we can potentially print it more nicely.
299 switch (pt.zcu.intern_pool.indexToKey(ptr.base_addr.anon_decl.val)) {
295 switch (pt.zcu.intern_pool.indexToKey(ptr.base_addr.uav.val)) {
300296 .aggregate => |agg| return printAggregate(
301 Value.fromInterned(ptr.base_addr.anon_decl.val),
297 Value.fromInterned(ptr.base_addr.uav.val),
302298 agg,
303299 true,
304300 writer,
......@@ -333,13 +329,13 @@ fn printPtrDerivation(
333329 int.ptr_ty.fmt(pt),
334330 int.addr,
335331 }),
336 .decl_ptr => |decl_index| {
337 try writer.print("{}", .{zcu.declPtr(decl_index).fqn.fmt(ip)});
332 .nav_ptr => |nav| {
333 try writer.print("{}", .{ip.getNav(nav).fqn.fmt(ip)});
338334 },
339 .anon_decl_ptr => |anon| {
340 const ty = Value.fromInterned(anon.val).typeOf(zcu);
335 .uav_ptr => |uav| {
336 const ty = Value.fromInterned(uav.val).typeOf(zcu);
341337 try writer.print("@as({}, ", .{ty.fmt(pt)});
342 try print(Value.fromInterned(anon.val), writer, level - 1, pt, have_sema, sema);
338 try print(Value.fromInterned(uav.val), writer, level - 1, pt, have_sema, sema);
343339 try writer.writeByte(')');
344340 },
345341 .comptime_alloc_ptr => |info| {
test/behavior/type_info.zig+3-3
......@@ -605,9 +605,9 @@ test "@typeInfo decls and usingnamespace" {
605605 };
606606 const decls = @typeInfo(B).Struct.decls;
607607 try expect(decls.len == 3);
608 try expectEqualStrings(decls[0].name, "x");
609 try expectEqualStrings(decls[1].name, "y");
610 try expectEqualStrings(decls[2].name, "z");
608 try expectEqualStrings(decls[0].name, "z");
609 try expectEqualStrings(decls[1].name, "x");
610 try expectEqualStrings(decls[2].name, "y");
611611}
612612
613613test "@typeInfo decls ignore dependency loops" {
test/behavior/usingnamespace.zig-4
......@@ -90,10 +90,6 @@ test {
9090 try expect(a.x == AA.c().expected);
9191}
9292
93comptime {
94 _ = @import("usingnamespace/file_1.zig");
95}
96
9793const Bar = struct {
9894 usingnamespace Mixin;
9995};
test/behavior/usingnamespace/file_0.zig deleted-1
......@@ -1 +0,0 @@
1pub const A = 123;
test/behavior/usingnamespace/file_1.zig deleted-12
......@@ -1,12 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const imports = @import("imports.zig");
4const builtin = @import("builtin");
5
6const A = 456;
7
8test {
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10
11 try expect(imports.A == 123);
12}
test/behavior/usingnamespace/imports.zig deleted-5
......@@ -1,5 +0,0 @@
1const file_0 = @import("file_0.zig");
2const file_1 = @import("file_1.zig");
3
4pub usingnamespace file_0;
5pub usingnamespace file_1;
test/cases/compile_errors/setAlignStack_in_inline_function.zig deleted-22
......@@ -1,22 +0,0 @@
1export fn entry() void {
2 foo();
3}
4inline fn foo() void {
5 @setAlignStack(16);
6}
7
8export fn entry1() void {
9 comptime bar();
10}
11fn bar() void {
12 @setAlignStack(16);
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :5:5: error: @setAlignStack in inline function
20// :2:8: note: called from here
21// :12:5: error: @setAlignStack in inline call
22// :9:17: note: called from here
test/cases/compile_errors/setAlignStack_set_twice.zig deleted-11
......@@ -1,11 +0,0 @@
1export fn entry() void {
2 @setAlignStack(16);
3 @setAlignStack(16);
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :3:5: error: multiple @setAlignStack in the same function body
11// :2:5: note: other instance here
test/cases/compile_errors/tagName_on_invalid_value_of_non-exhaustive_enum.zig+1-1
......@@ -8,5 +8,5 @@ test "enum" {
88// target=native
99// is_test=true
1010//
11// :3:9: error: no field with value '@enumFromInt(5)' in enum 'test.enum.E'
11// :3:9: error: no field with value '@enumFromInt(5)' in enum 'tmp.test.enum.E'
1212// :2:15: note: declared here