authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-11 15:07:06-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-11 15:07:06-07:00
logfc2924080694d68945308d394751a2ec4841b3c0
treec4b372662b0253de33483225d17a8a79c735ada5
parent531cd177e89c1edfcd2e52f74f220eb186a25f78
parent153e7d6235a7d74d0c02d51f84edc5c06ab7469d
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20964 from mlugg/the-great-decl-split-mk2

compiler: split `Decl` into `Nav` and `Cau`

49 files changed, 6455 insertions(+), 7288 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+964-523
......@@ -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 {
1103 return .{
1104 .gpa = gpa,
1105 .arena = &local.mutate.arena,
1106 .mutate = &local.mutate.caus,
1107 .list = &local.shared.caus,
1108 };
1109 }
1110
1111 pub fn getMutableNavs(local: *Local, gpa: Allocator) Navs.Mutable {
8491112 return .{
8501113 .gpa = gpa,
8511114 .arena = &local.mutate.arena,
852 .mutate = &local.mutate.decls.buckets_list,
853 .list = &local.shared.decls,
1115 .mutate = &local.mutate.navs,
1116 .list = &local.shared.navs,
8541117 };
8551118 }
8561119
857 /// Same pattern as with `getMutableDecls`.
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,10 +2879,13 @@ 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.
2638 namespace: OptionalNamespaceIndex,
2888 namespace: NamespaceIndex,
26392889 /// The enum tag type.
26402890 enum_tag_ty: Index,
26412891 /// List of field types in declaration order.
......@@ -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,9 +3214,12 @@ 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,
2968 /// `none` when the struct has no declarations.
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,
3222 /// `none` when the struct is `@TypeOf(.{})`.
29693223 namespace: OptionalNamespaceIndex,
29703224 /// Index of the `struct_decl` or `reify` ZIR instruction.
29713225 /// Only `none` when the struct is `@TypeOf(.{})`.
......@@ -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,9 @@ 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").?]);
3837 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);
35813838 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
35823839 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
35833840 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
......@@ -3622,11 +3879,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36223879 extra_index += fields_len;
36233880 break :i inits;
36243881 } else Index.Slice.empty;
3625 const namespace: OptionalNamespaceIndex = if (flags.has_namespace) n: {
3626 const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
3627 extra_index += 1;
3628 break :n n.toOptional();
3629 } else .none;
36303882 const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: {
36313883 const a: Alignment.Slice = .{
36323884 .tid = unwrapped_index.tid,
......@@ -3667,8 +3919,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36673919 return .{
36683920 .tid = unwrapped_index.tid,
36693921 .extra_index = item.data,
3670 .decl = decl.toOptional(),
3671 .namespace = namespace,
3922 .name = name,
3923 .cau = cau.toOptional(),
3924 .namespace = namespace.toOptional(),
36723925 .zir_index = zir_index.toOptional(),
36733926 .layout = if (flags.is_extern) .@"extern" else .auto,
36743927 .field_names = names,
......@@ -3683,10 +3936,11 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
36833936 };
36843937 },
36853938 .type_struct_packed, .type_struct_packed_inits => {
3686 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]);
3939 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]);
3940 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?]);
36873941 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
36883942 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
3689 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
3943 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
36903944 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);
36913945 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));
36923946 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
......@@ -3729,8 +3983,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
37293983 return .{
37303984 .tid = unwrapped_index.tid,
37313985 .extra_index = item.data,
3732 .decl = decl.toOptional(),
3733 .namespace = namespace,
3986 .name = name,
3987 .cau = cau.toOptional(),
3988 .namespace = namespace.toOptional(),
37343989 .zir_index = zir_index.toOptional(),
37353990 .layout = .@"packed",
37363991 .field_names = field_names,
......@@ -3749,10 +4004,14 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
37494004}
37504005
37514006const LoadedEnumType = struct {
3752 /// The Decl that corresponds to the enum itself.
3753 decl: DeclIndex,
4007 // TODO: the non-fqn will be needed by the new dwarf structure
4008 /// The name of this enum type.
4009 name: NullTerminatedString,
4010 /// The `Cau` within which type resolution occurs.
4011 /// `null` if this is a generated tag type.
4012 cau: Cau.Index.Optional,
37544013 /// Represents the declarations inside this enum.
3755 namespace: OptionalNamespaceIndex,
4014 namespace: NamespaceIndex,
37564015 /// An integer type which is used for the numerical value of the enum.
37574016 /// This field is present regardless of whether the enum has an
37584017 /// explicitly provided tag type or auto-numbered.
......@@ -3827,15 +4086,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38274086 .type_enum_auto => {
38284087 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
38294088 var extra_index: u32 = @intCast(extra.end);
3830 if (extra.data.zir_index == .none) {
4089 const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: {
38314090 extra_index += 1; // owner_union
3832 }
4091 break :cau .none;
4092 } else cau: {
4093 const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4094 extra_index += 1; // cau
4095 break :cau cau.toOptional();
4096 };
38334097 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
38344098 extra_index += 2; // type_hash: PackedU64
38354099 break :c 0;
38364100 } else extra.data.captures_len;
38374101 return .{
3838 .decl = extra.data.decl,
4102 .name = extra.data.name,
4103 .cau = cau,
38394104 .namespace = extra.data.namespace,
38404105 .tag_ty = extra.data.int_tag_type,
38414106 .names = .{
......@@ -3861,15 +4126,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38614126 };
38624127 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
38634128 var extra_index: u32 = @intCast(extra.end);
3864 if (extra.data.zir_index == .none) {
4129 const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: {
38654130 extra_index += 1; // owner_union
3866 }
4131 break :cau .none;
4132 } else cau: {
4133 const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4134 extra_index += 1; // cau
4135 break :cau cau.toOptional();
4136 };
38674137 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
38684138 extra_index += 2; // type_hash: PackedU64
38694139 break :c 0;
38704140 } else extra.data.captures_len;
38714141 return .{
3872 .decl = extra.data.decl,
4142 .name = extra.data.name,
4143 .cau = cau,
38734144 .namespace = extra.data.namespace,
38744145 .tag_ty = extra.data.int_tag_type,
38754146 .names = .{
......@@ -3896,10 +4167,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38964167
38974168/// Note that this type doubles as the payload for `Tag.type_opaque`.
38984169pub const LoadedOpaqueType = struct {
3899 /// The opaque's owner Decl.
3900 decl: DeclIndex,
39014170 /// Contains the declarations inside this opaque.
3902 namespace: OptionalNamespaceIndex,
4171 namespace: NamespaceIndex,
4172 // TODO: the non-fqn will be needed by the new dwarf structure
4173 /// The name of this opaque type.
4174 name: NullTerminatedString,
39034175 /// Index of the `opaque_decl` or `reify` instruction.
39044176 zir_index: TrackedInst.Index,
39054177 captures: CaptureValue.Slice,
......@@ -3915,7 +4187,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
39154187 else
39164188 extra.data.captures_len;
39174189 return .{
3918 .decl = extra.data.decl,
4190 .name = extra.data.name,
39194191 .namespace = extra.data.namespace,
39204192 .zir_index = extra.data.zir_index,
39214193 .captures = .{
......@@ -4216,10 +4488,10 @@ pub const Index = enum(u32) {
42164488
42174489 undef: DataIsIndex,
42184490 simple_value: void,
4219 ptr_decl: struct { data: *PtrDecl },
4491 ptr_nav: struct { data: *PtrNav },
42204492 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },
4221 ptr_anon_decl: struct { data: *PtrAnonDecl },
4222 ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned },
4493 ptr_uav: struct { data: *PtrUav },
4494 ptr_uav_aligned: struct { data: *PtrUavAligned },
42234495 ptr_comptime_field: struct { data: *PtrComptimeField },
42244496 ptr_int: struct { data: *PtrInt },
42254497 ptr_eu_payload: struct { data: *PtrBase },
......@@ -4255,7 +4527,7 @@ pub const Index = enum(u32) {
42554527 float_c_longdouble_f128: struct { data: *Float128 },
42564528 float_comptime_float: struct { data: *Float128 },
42574529 variable: struct { data: *Tag.Variable },
4258 extern_func: struct { data: *Key.ExternFunc },
4530 @"extern": struct { data: *Tag.Extern },
42594531 func_decl: struct {
42604532 const @"data.analysis.inferred_error_set" = opaque {};
42614533 data: *Tag.FuncDecl,
......@@ -4669,23 +4941,23 @@ pub const Tag = enum(u8) {
46694941 /// A value that can be represented with only an enum tag.
46704942 /// data is SimpleValue enum value.
46714943 simple_value,
4672 /// A pointer to a decl.
4673 /// data is extra index of `PtrDecl`, which contains the type and address.
4674 ptr_decl,
4944 /// A pointer to a `Nav`.
4945 /// data is extra index of `PtrNav`, which contains the type and address.
4946 ptr_nav,
46754947 /// A pointer to a decl that can be mutated at comptime.
46764948 /// data is extra index of `PtrComptimeAlloc`, which contains the type and address.
46774949 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
4950 /// A pointer to an anonymous addressable value.
4951 /// data is extra index of `PtrUav`, which contains the pointer type and decl value.
4952 /// The alignment of the uav is communicated via the pointer type.
4953 ptr_uav,
4954 /// A pointer to an unnamed addressable value.
4955 /// data is extra index of `PtrUavAligned`, which contains the pointer
46844956 /// type and decl value.
46854957 /// 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
4958 /// This encoding is only used when a pointer to a Uav is
46874959 /// coerced to a different pointer type with a different alignment.
4688 ptr_anon_decl_aligned,
4960 ptr_uav_aligned,
46894961 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.
46904962 ptr_comptime_field,
46914963 /// A pointer with an integer value.
......@@ -4800,9 +5072,10 @@ pub const Tag = enum(u8) {
48005072 /// A global variable.
48015073 /// data is extra index to Variable.
48025074 variable,
4803 /// An extern function.
4804 /// data is extra index to ExternFunc.
4805 extern_func,
5075 /// An extern function or variable.
5076 /// data is extra index to Extern.
5077 /// Some parts of the key are stored in `owner_nav`.
5078 @"extern",
48065079 /// A non-extern function corresponding directly to the AST node from whence it originated.
48075080 /// data is extra index to `FuncDecl`.
48085081 /// Only the owner Decl is used for hashing and equality because the other
......@@ -4843,7 +5116,6 @@ pub const Tag = enum(u8) {
48435116 const TypeValue = Key.TypeValue;
48445117 const Error = Key.Error;
48455118 const EnumTag = Key.EnumTag;
4846 const ExternFunc = Key.ExternFunc;
48475119 const Union = Key.Union;
48485120 const TypePointer = Key.PtrType;
48495121
......@@ -4877,10 +5149,10 @@ pub const Tag = enum(u8) {
48775149
48785150 .undef => unreachable,
48795151 .simple_value => unreachable,
4880 .ptr_decl => PtrDecl,
5152 .ptr_nav => PtrNav,
48815153 .ptr_comptime_alloc => PtrComptimeAlloc,
4882 .ptr_anon_decl => PtrAnonDecl,
4883 .ptr_anon_decl_aligned => PtrAnonDeclAligned,
5154 .ptr_uav => PtrUav,
5155 .ptr_uav_aligned => PtrUavAligned,
48845156 .ptr_comptime_field => PtrComptimeField,
48855157 .ptr_int => PtrInt,
48865158 .ptr_eu_payload => PtrBase,
......@@ -4916,7 +5188,7 @@ pub const Tag = enum(u8) {
49165188 .float_c_longdouble_f128 => unreachable,
49175189 .float_comptime_float => unreachable,
49185190 .variable => Variable,
4919 .extern_func => ExternFunc,
5191 .@"extern" => Extern,
49205192 .func_decl => FuncDecl,
49215193 .func_instance => FuncInstance,
49225194 .func_coerced => FuncCoerced,
......@@ -4933,21 +5205,29 @@ pub const Tag = enum(u8) {
49335205 ty: Index,
49345206 /// May be `none`.
49355207 init: Index,
4936 decl: DeclIndex,
5208 owner_nav: Nav.Index,
49375209 /// Library name if specified.
49385210 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.
49395211 lib_name: OptionalNullTerminatedString,
49405212 flags: Flags,
49415213
49425214 pub const Flags = packed struct(u32) {
4943 is_extern: bool,
49445215 is_const: bool,
49455216 is_threadlocal: bool,
49465217 is_weak_linkage: bool,
4947 _: u28 = 0,
5218 _: u29 = 0,
49485219 };
49495220 };
49505221
5222 pub const Extern = struct {
5223 // name, alignment, addrspace come from `owner_nav`.
5224 ty: Index,
5225 lib_name: OptionalNullTerminatedString,
5226 flags: Variable.Flags,
5227 owner_nav: Nav.Index,
5228 zir_index: TrackedInst.Index,
5229 };
5230
49515231 /// Trailing:
49525232 /// 0. element: Index for each len
49535233 /// len is determined by the aggregate type.
......@@ -4962,7 +5242,7 @@ pub const Tag = enum(u8) {
49625242 /// A `none` value marks that the inferred error set is not resolved yet.
49635243 pub const FuncDecl = struct {
49645244 analysis: FuncAnalysis,
4965 owner_decl: DeclIndex,
5245 owner_nav: Nav.Index,
49665246 ty: Index,
49675247 zir_body_inst: TrackedInst.Index,
49685248 lbrace_line: u32,
......@@ -4979,7 +5259,7 @@ pub const Tag = enum(u8) {
49795259 pub const FuncInstance = struct {
49805260 analysis: FuncAnalysis,
49815261 // Needed by the linker for codegen. Not part of hashing or equality.
4982 owner_decl: DeclIndex,
5262 owner_nav: Nav.Index,
49835263 ty: Index,
49845264 branch_quota: u32,
49855265 /// Points to a `FuncDecl`.
......@@ -5029,6 +5309,7 @@ pub const Tag = enum(u8) {
50295309 /// 3. field type: Index for each field; declaration order
50305310 /// 4. field align: Alignment for each field; declaration order
50315311 pub const TypeUnion = struct {
5312 name: NullTerminatedString,
50325313 flags: Flags,
50335314 /// This could be provided through the tag type, but it is more convenient
50345315 /// to store it directly. This is also necessary for `dumpStatsFallible` to
......@@ -5038,8 +5319,8 @@ pub const Tag = enum(u8) {
50385319 size: u32,
50395320 /// Only valid after .have_layout
50405321 padding: u32,
5041 decl: DeclIndex,
5042 namespace: OptionalNamespaceIndex,
5322 cau: Cau.Index,
5323 namespace: NamespaceIndex,
50435324 /// The enum that provides the list of field names and values.
50445325 tag_ty: Index,
50455326 zir_index: TrackedInst.Index,
......@@ -5068,10 +5349,11 @@ pub const Tag = enum(u8) {
50685349 /// 4. name: NullTerminatedString for each fields_len
50695350 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits
50705351 pub const TypeStructPacked = struct {
5071 decl: DeclIndex,
5352 name: NullTerminatedString,
5353 cau: Cau.Index,
50725354 zir_index: TrackedInst.Index,
50735355 fields_len: u32,
5074 namespace: OptionalNamespaceIndex,
5356 namespace: NamespaceIndex,
50755357 backing_int_ty: Index,
50765358 names_map: MapIndex,
50775359 flags: Flags,
......@@ -5110,18 +5392,18 @@ pub const Tag = enum(u8) {
51105392 /// name: NullTerminatedString // for each field in declared order
51115393 /// 5. if any_default_inits:
51125394 /// init: Index // for each field in declared order
5113 /// 6. if has_namespace:
5114 /// namespace: NamespaceIndex
5115 /// 7. if any_aligned_fields:
5395 /// 6. if any_aligned_fields:
51165396 /// align: Alignment // for each field in declared order
5117 /// 8. if any_comptime_fields:
5397 /// 7. if any_comptime_fields:
51185398 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0
5119 /// 9. if not is_extern:
5399 /// 8. if not is_extern:
51205400 /// field_index: RuntimeOrder // for each field in runtime order
5121 /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved
5401 /// 9. field_offset: u32 // for each field in declared order, undef until layout_resolved
51225402 pub const TypeStruct = struct {
5123 decl: DeclIndex,
5403 name: NullTerminatedString,
5404 cau: Cau.Index,
51245405 zir_index: TrackedInst.Index,
5406 namespace: NamespaceIndex,
51255407 fields_len: u32,
51265408 flags: Flags,
51275409 size: u32,
......@@ -5134,7 +5416,6 @@ pub const Tag = enum(u8) {
51345416 is_tuple: bool = false,
51355417 assumed_runtime_bits: bool = false,
51365418 assumed_pointer_aligned: bool = false,
5137 has_namespace: bool = false,
51385419 any_comptime_fields: bool = false,
51395420 any_default_inits: bool = false,
51405421 any_aligned_fields: bool = false,
......@@ -5157,17 +5438,16 @@ pub const Tag = enum(u8) {
51575438 // which `layout_resolved` does not ensure.
51585439 fully_resolved: bool = false,
51595440 is_reified: bool = false,
5160 _: u6 = 0,
5441 _: u7 = 0,
51615442 };
51625443 };
51635444
51645445 /// Trailing:
51655446 /// 0. capture: CaptureValue // for each `captures_len`
51665447 pub const TypeOpaque = struct {
5167 /// The opaque's owner Decl.
5168 decl: DeclIndex,
5448 name: NullTerminatedString,
51695449 /// Contains the declarations inside this opaque.
5170 namespace: OptionalNamespaceIndex,
5450 namespace: NamespaceIndex,
51715451 /// The index of the `opaque_decl` instruction.
51725452 zir_index: TrackedInst.Index,
51735453 /// `std.math.maxInt(u32)` indicates this type is reified.
......@@ -5188,29 +5468,19 @@ pub const FuncAnalysis = packed struct(u32) {
51885468 inferred_error_set: bool,
51895469 disable_instrumentation: bool,
51905470
5191 _: u13 = 0,
5471 _: u19 = 0,
51925472
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.
5473 pub const State = enum(u2) {
5474 /// The runtime function has never been referenced.
5475 /// As such, it has never been analyzed, nor is it queued for analysis.
5476 unreferenced,
5477 /// The runtime function has been referenced, but has not yet been analyzed.
5478 /// Its semantic analysis is queued.
51985479 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,
5480 /// The runtime function has been (or is currently being) semantically analyzed.
5481 /// To know if analysis succeeded, consult `zcu.[transitive_]failed_analysis`.
5482 /// To know if analysis is up-to-date, consult `zcu.[potentially_]outdated`.
5483 analyzed,
52145484 };
52155485};
52165486
......@@ -5477,17 +5747,16 @@ pub const Array = struct {
54775747
54785748/// Trailing:
54795749/// 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
5750/// 1. cau: Cau.Index // if `zir_index != .none`
5751/// 2. capture: CaptureValue // for each `captures_len`
5752/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5753/// 4. field name: NullTerminatedString for each fields_len; declaration order
5754/// 5. tag value: Index for each fields_len; declaration order
54845755pub const EnumExplicit = struct {
5485 /// The Decl that corresponds to the enum itself.
5486 decl: DeclIndex,
5756 name: NullTerminatedString,
54875757 /// `std.math.maxInt(u32)` indicates this type is reified.
54885758 captures_len: u32,
5489 /// This may be `none` if there are no declarations.
5490 namespace: OptionalNamespaceIndex,
5759 namespace: NamespaceIndex,
54915760 /// An integer type which is used for the numerical value of the enum, which
54925761 /// has been explicitly provided by the enum declaration.
54935762 int_tag_type: Index,
......@@ -5505,16 +5774,15 @@ pub const EnumExplicit = struct {
55055774
55065775/// Trailing:
55075776/// 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
5777/// 1. cau: Cau.Index // if `zir_index != .none`
5778/// 2. capture: CaptureValue // for each `captures_len`
5779/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5780/// 4. field name: NullTerminatedString for each fields_len; declaration order
55115781pub const EnumAuto = struct {
5512 /// The Decl that corresponds to the enum itself.
5513 decl: DeclIndex,
5782 name: NullTerminatedString,
55145783 /// `std.math.maxInt(u32)` indicates this type is reified.
55155784 captures_len: u32,
5516 /// This may be `none` if there are no declarations.
5517 namespace: OptionalNamespaceIndex,
5785 namespace: NamespaceIndex,
55185786 /// An integer type which is used for the numerical value of the enum, which
55195787 /// was inferred by Zig based on the number of tags.
55205788 int_tag_type: Index,
......@@ -5539,15 +5807,15 @@ pub const PackedU64 = packed struct(u64) {
55395807 }
55405808};
55415809
5542pub const PtrDecl = struct {
5810pub const PtrNav = struct {
55435811 ty: Index,
5544 decl: DeclIndex,
5812 nav: Nav.Index,
55455813 byte_offset_a: u32,
55465814 byte_offset_b: u32,
5547 fn init(ty: Index, decl: DeclIndex, byte_offset: u64) @This() {
5815 fn init(ty: Index, nav: Nav.Index, byte_offset: u64) @This() {
55485816 return .{
55495817 .ty = ty,
5550 .decl = decl,
5818 .nav = nav,
55515819 .byte_offset_a = @intCast(byte_offset >> 32),
55525820 .byte_offset_b = @truncate(byte_offset),
55535821 };
......@@ -5557,7 +5825,7 @@ pub const PtrDecl = struct {
55575825 }
55585826};
55595827
5560pub const PtrAnonDecl = struct {
5828pub const PtrUav = struct {
55615829 ty: Index,
55625830 val: Index,
55635831 byte_offset_a: u32,
......@@ -5575,7 +5843,7 @@ pub const PtrAnonDecl = struct {
55755843 }
55765844};
55775845
5578pub const PtrAnonDeclAligned = struct {
5846pub const PtrUavAligned = struct {
55795847 ty: Index,
55805848 val: Index,
55815849 /// Must be nonequal to `ty`. Only the alignment from this value is important.
......@@ -5805,8 +6073,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58056073 .tracked_insts = Local.TrackedInsts.empty,
58066074 .files = Local.List(File).empty,
58076075 .maps = Local.Maps.empty,
6076 .caus = Local.Caus.empty,
6077 .navs = Local.Navs.empty,
58086078
5809 .decls = Local.Decls.empty,
58106079 .namespaces = Local.Namespaces.empty,
58116080 },
58126081 .mutate = .{
......@@ -5819,8 +6088,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58196088 .tracked_insts = Local.ListMutate.empty,
58206089 .files = Local.ListMutate.empty,
58216090 .maps = Local.ListMutate.empty,
6091 .caus = Local.ListMutate.empty,
6092 .navs = Local.ListMutate.empty,
58226093
5823 .decls = Local.BucketListMutate.empty,
58246094 .namespaces = Local.BucketListMutate.empty,
58256095 },
58266096 });
......@@ -5878,8 +6148,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58786148
58796149pub fn deinit(ip: *InternPool, gpa: Allocator) void {
58806150 ip.src_hash_deps.deinit(gpa);
5881 ip.decl_val_deps.deinit(gpa);
5882 ip.func_ies_deps.deinit(gpa);
6151 ip.nav_val_deps.deinit(gpa);
6152 ip.interned_deps.deinit(gpa);
58836153 ip.namespace_deps.deinit(gpa);
58846154 ip.namespace_name_deps.deinit(gpa);
58856155
......@@ -5900,8 +6170,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
59006170 else
59016171 local.mutate.namespaces.last_bucket_len]) |*namespace|
59026172 {
5903 namespace.decls.deinit(gpa);
5904 namespace.usingnamespace_set.deinit(gpa);
6173 namespace.pub_decls.deinit(gpa);
6174 namespace.priv_decls.deinit(gpa);
6175 namespace.pub_usingnamespace.deinit(gpa);
6176 namespace.priv_usingnamespace.deinit(gpa);
6177 namespace.other_decls.deinit(gpa);
59056178 }
59066179 };
59076180 const maps = local.getMutableMaps(gpa);
......@@ -6082,14 +6355,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
60826355 if (extra.data.captures_len == std.math.maxInt(u32)) {
60836356 break :ns .{ .reified = .{
60846357 .zir_index = zir_index,
6085 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6358 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
60866359 } };
60876360 }
60886361 break :ns .{ .declared = .{
60896362 .zir_index = zir_index,
60906363 .captures = .{ .owned = .{
60916364 .tid = unwrapped_index.tid,
6092 .start = extra.end,
6365 .start = extra.end + 1,
60936366 .len = extra.data.captures_len,
60946367 } },
60956368 } };
......@@ -6106,14 +6379,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
61066379 if (extra.data.captures_len == std.math.maxInt(u32)) {
61076380 break :ns .{ .reified = .{
61086381 .zir_index = zir_index,
6109 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6382 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
61106383 } };
61116384 }
61126385 break :ns .{ .declared = .{
61136386 .zir_index = zir_index,
61146387 .captures = .{ .owned = .{
61156388 .tid = unwrapped_index.tid,
6116 .start = extra.end,
6389 .start = extra.end + 1,
61176390 .len = extra.data.captures_len,
61186391 } },
61196392 } };
......@@ -6132,24 +6405,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
61326405 .val = extra.val,
61336406 } };
61346407 },
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() } };
6408 .ptr_nav => {
6409 const info = extraData(unwrapped_index.getExtra(ip), PtrNav, data);
6410 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .nav = info.nav }, .byte_offset = info.byteOffset() } };
61386411 },
61396412 .ptr_comptime_alloc => {
61406413 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);
61416414 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
61426415 },
6143 .ptr_anon_decl => {
6144 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);
6145 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
6416 .ptr_uav => {
6417 const info = extraData(unwrapped_index.getExtra(ip), PtrUav, data);
6418 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
61466419 .val = info.val,
61476420 .orig_ty = info.ty,
61486421 } }, .byte_offset = info.byteOffset() } };
61496422 },
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 = .{
6423 .ptr_uav_aligned => {
6424 const info = extraData(unwrapped_index.getExtra(ip), PtrUavAligned, data);
6425 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
61536426 .val = info.val,
61546427 .orig_ty = info.orig_ty,
61556428 } }, .byte_offset = info.byteOffset() } };
......@@ -6293,15 +6566,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
62936566 return .{ .variable = .{
62946567 .ty = extra.ty,
62956568 .init = extra.init,
6296 .decl = extra.decl,
6569 .owner_nav = extra.owner_nav,
6570 .lib_name = extra.lib_name,
6571 .is_threadlocal = extra.flags.is_threadlocal,
6572 .is_weak_linkage = extra.flags.is_weak_linkage,
6573 } };
6574 },
6575 .@"extern" => {
6576 const extra = extraData(unwrapped_index.getExtra(ip), Tag.Extern, data);
6577 const nav = ip.getNav(extra.owner_nav);
6578 return .{ .@"extern" = .{
6579 .name = nav.name,
6580 .ty = extra.ty,
62976581 .lib_name = extra.lib_name,
6298 .is_extern = extra.flags.is_extern,
62996582 .is_const = extra.flags.is_const,
63006583 .is_threadlocal = extra.flags.is_threadlocal,
63016584 .is_weak_linkage = extra.flags.is_weak_linkage,
6585 .alignment = nav.status.resolved.alignment,
6586 .@"addrspace" = nav.status.resolved.@"addrspace",
6587 .zir_index = extra.zir_index,
6588 .owner_nav = extra.owner_nav,
63026589 } };
63036590 },
6304 .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) },
63056591 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
63066592 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
63076593 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },
......@@ -6513,7 +6799,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
65136799 .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?,
65146800 .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0,
65156801 .branch_quota_extra_index = 0,
6516 .owner_decl = func_decl.data.owner_decl,
6802 .owner_nav = func_decl.data.owner_nav,
65176803 .zir_body_inst = func_decl.data.zir_body_inst,
65186804 .lbrace_line = func_decl.data.lbrace_line,
65196805 .rbrace_line = func_decl.data.rbrace_line,
......@@ -6528,7 +6814,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
65286814 const extra_items = extra.view().items(.@"0");
65296815 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;
65306816 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").?]);
6817 const owner_nav: Nav.Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?]);
65326818 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);
65336819 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
65346820 const func_decl = ip.funcDeclInfo(generic_owner);
......@@ -6541,7 +6827,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
65416827 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,
65426828 .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0,
65436829 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,
6544 .owner_decl = owner_decl,
6830 .owner_nav = owner_nav,
65456831 .zir_body_inst = func_decl.zir_body_inst,
65466832 .lbrace_line = func_decl.lbrace_line,
65476833 .rbrace_line = func_decl.rbrace_line,
......@@ -6905,7 +7191,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69057191
69067192 .enum_type => unreachable, // use getEnumType() instead
69077193 .func_type => unreachable, // use getFuncType() instead
6908 .extern_func => unreachable, // use getExternFunc() instead
7194 .@"extern" => unreachable, // use getExtern() instead
69097195 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead
69107196
69117197 .variable => |variable| {
......@@ -6916,11 +7202,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69167202 .data = try addExtra(extra, Tag.Variable{
69177203 .ty = variable.ty,
69187204 .init = variable.init,
6919 .decl = variable.decl,
7205 .owner_nav = variable.owner_nav,
69207206 .lib_name = variable.lib_name,
69217207 .flags = .{
6922 .is_extern = variable.is_extern,
6923 .is_const = variable.is_const,
7208 .is_const = false,
69247209 .is_threadlocal = variable.is_threadlocal,
69257210 .is_weak_linkage = variable.is_weak_linkage,
69267211 },
......@@ -6945,29 +7230,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69457230 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
69467231 assert(ptr_type.flags.size != .Slice);
69477232 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)),
7233 .nav => |nav| .{
7234 .tag = .ptr_nav,
7235 .data = try addExtra(extra, PtrNav.init(ptr.ty, nav, ptr.byte_offset)),
69517236 },
69527237 .comptime_alloc => |alloc_index| .{
69537238 .tag = .ptr_comptime_alloc,
69547239 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
69557240 },
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) {
7241 .uav => |uav| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, uav.orig_ty)) item: {
7242 if (ptr.ty != uav.orig_ty) {
69587243 gop.cancel();
69597244 var new_key = key;
6960 new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty;
7245 new_key.ptr.base_addr.uav.orig_ty = ptr.ty;
69617246 gop = try ip.getOrPutKey(gpa, tid, new_key);
69627247 if (gop == .existing) return gop.existing;
69637248 }
69647249 break :item .{
6965 .tag = .ptr_anon_decl,
6966 .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),
7250 .tag = .ptr_uav,
7251 .data = try addExtra(extra, PtrUav.init(ptr.ty, uav.val, ptr.byte_offset)),
69677252 };
69687253 } 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)),
7254 .tag = .ptr_uav_aligned,
7255 .data = try addExtra(extra, PtrUavAligned.init(ptr.ty, uav.val, uav.orig_ty, ptr.byte_offset)),
69717256 },
69727257 .comptime_field => |field_val| item: {
69737258 assert(field_val != .none);
......@@ -7561,7 +7846,6 @@ pub const UnionTypeInit = struct {
75617846 assumed_pointer_aligned: bool,
75627847 alignment: Alignment,
75637848 },
7564 has_namespace: bool,
75657849 fields_len: u32,
75667850 enum_tag_ty: Index,
75677851 /// May have length 0 which leaves the values unset until later.
......@@ -7635,8 +7919,9 @@ pub fn getUnionType(
76357919 .fields_len = ini.fields_len,
76367920 .size = std.math.maxInt(u32),
76377921 .padding = std.math.maxInt(u32),
7638 .decl = undefined, // set by `finish`
7639 .namespace = .none, // set by `finish`
7922 .name = undefined, // set by `finish`
7923 .cau = undefined, // set by `finish`
7924 .namespace = undefined, // set by `finish`
76407925 .tag_ty = ini.enum_tag_ty,
76417926 .zir_index = switch (ini.key) {
76427927 inline else => |x| x.zir_index,
......@@ -7682,29 +7967,49 @@ pub fn getUnionType(
76827967 return .{ .wip = .{
76837968 .tid = tid,
76847969 .index = gop.put(),
7685 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
7686 .namespace_extra_index = if (ini.has_namespace)
7687 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?
7688 else
7689 null,
7970 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
7971 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "cau").?,
7972 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,
76907973 } };
76917974}
76927975
76937976pub const WipNamespaceType = struct {
76947977 tid: Zcu.PerThread.Id,
76957978 index: Index,
7696 decl_extra_index: u32,
7697 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);
7701 if (wip.namespace_extra_index) |i| {
7702 extra_items[i] = @intFromEnum(namespace.unwrap().?);
7979 type_name_extra_index: u32,
7980 cau_extra_index: ?u32,
7981 namespace_extra_index: u32,
7982
7983 pub fn setName(
7984 wip: WipNamespaceType,
7985 ip: *InternPool,
7986 type_name: NullTerminatedString,
7987 ) void {
7988 const extra = ip.getLocalShared(wip.tid).extra.acquire();
7989 const extra_items = extra.view().items(.@"0");
7990 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
7991 }
7992
7993 pub fn finish(
7994 wip: WipNamespaceType,
7995 ip: *InternPool,
7996 analysis_owner: Cau.Index.Optional,
7997 namespace: NamespaceIndex,
7998 ) Index {
7999 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8000 const extra_items = extra.view().items(.@"0");
8001
8002 if (wip.cau_extra_index) |i| {
8003 extra_items[i] = @intFromEnum(analysis_owner.unwrap().?);
77038004 } else {
7704 assert(namespace == .none);
8005 assert(analysis_owner == .none);
77058006 }
8007
8008 extra_items[wip.namespace_extra_index] = @intFromEnum(namespace);
8009
77068010 return wip.index;
77078011 }
8012
77088013 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
77098014 ip.remove(tid, wip.index);
77108015 }
......@@ -7725,7 +8030,6 @@ pub const StructTypeInit = struct {
77258030 any_default_inits: bool,
77268031 inits_resolved: bool,
77278032 any_aligned_fields: bool,
7728 has_namespace: bool,
77298033 key: union(enum) {
77308034 declared: struct {
77318035 zir_index: TrackedInst.Index,
......@@ -7784,10 +8088,11 @@ pub fn getStructType(
77848088 ini.fields_len + // names
77858089 ini.fields_len); // inits
77868090 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
7787 .decl = undefined, // set by `finish`
8091 .name = undefined, // set by `finish`
8092 .cau = undefined, // set by `finish`
77888093 .zir_index = zir_index,
77898094 .fields_len = ini.fields_len,
7790 .namespace = .none,
8095 .namespace = undefined, // set by `finish`
77918096 .backing_int_ty = .none,
77928097 .names_map = names_map,
77938098 .flags = .{
......@@ -7818,11 +8123,9 @@ pub fn getStructType(
78188123 return .{ .wip = .{
78198124 .tid = tid,
78208125 .index = gop.put(),
7821 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
7822 .namespace_extra_index = if (ini.has_namespace)
7823 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?
7824 else
7825 null,
8126 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
8127 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?,
8128 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,
78268129 } };
78278130 },
78288131 };
......@@ -7841,10 +8144,12 @@ pub fn getStructType(
78418144 // zig fmt: on
78428145 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
78438146 align_elements_len + comptime_elements_len +
7844 2); // names_map + namespace
8147 1); // names_map
78458148 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
7846 .decl = undefined, // set by `finish`
8149 .name = undefined, // set by `finish`
8150 .cau = undefined, // set by `finish`
78478151 .zir_index = zir_index,
8152 .namespace = undefined, // set by `finish`
78488153 .fields_len = ini.fields_len,
78498154 .size = std.math.maxInt(u32),
78508155 .flags = .{
......@@ -7855,7 +8160,6 @@ pub fn getStructType(
78558160 .is_tuple = ini.is_tuple,
78568161 .assumed_runtime_bits = false,
78578162 .assumed_pointer_aligned = false,
7858 .has_namespace = ini.has_namespace,
78598163 .any_comptime_fields = ini.any_comptime_fields,
78608164 .any_default_inits = ini.any_default_inits,
78618165 .any_aligned_fields = ini.any_aligned_fields,
......@@ -7891,10 +8195,6 @@ pub fn getStructType(
78918195 if (ini.any_default_inits) {
78928196 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
78938197 }
7894 const namespace_extra_index: ?u32 = if (ini.has_namespace) i: {
7895 extra.appendAssumeCapacity(undefined); // set by `finish`
7896 break :i @intCast(extra.mutate.len - 1);
7897 } else null;
78988198 if (ini.any_aligned_fields) {
78998199 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
79008200 }
......@@ -7908,8 +8208,9 @@ pub fn getStructType(
79088208 return .{ .wip = .{
79098209 .tid = tid,
79108210 .index = gop.put(),
7911 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
7912 .namespace_extra_index = namespace_extra_index,
8211 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
8212 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "cau").?,
8213 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,
79138214 } };
79148215}
79158216
......@@ -8047,34 +8348,71 @@ pub fn getFuncType(
80478348 return gop.put();
80488349}
80498350
8050pub fn getExternFunc(
8351/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
8352/// This will *not* queue the extern for codegen: see `Zcu.PerThread.getExtern` for a wrapper which does.
8353pub fn getExtern(
80518354 ip: *InternPool,
80528355 gpa: Allocator,
80538356 tid: Zcu.PerThread.Id,
8054 key: Key.ExternFunc,
8055) Allocator.Error!Index {
8056 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });
8357 /// `key.owner_nav` is ignored.
8358 key: Key.Extern,
8359) Allocator.Error!struct {
8360 index: Index,
8361 /// Only set if the `Nav` was newly created.
8362 new_nav: Nav.Index.Optional,
8363} {
8364 var gop = try ip.getOrPutKey(gpa, tid, .{ .@"extern" = key });
80578365 defer gop.deinit();
8058 if (gop == .existing) return gop.existing;
8366 if (gop == .existing) return .{
8367 .index = gop.existing,
8368 .new_nav = .none,
8369 };
80598370
80608371 const local = ip.getLocal(tid);
80618372 const items = local.getMutableItems(gpa);
8062 try items.ensureUnusedCapacity(1);
80638373 const extra = local.getMutableExtra(gpa);
8374 try items.ensureUnusedCapacity(1);
8375 try extra.ensureUnusedCapacity(@typeInfo(Tag.Extern).Struct.fields.len);
8376 try local.getMutableNavs(gpa).ensureUnusedCapacity(1);
80648377
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;
8378 // Predict the index the `@"extern" will live at, so we can construct the owner `Nav` before releasing the shard's mutex.
8379 const extern_index = Index.Unwrapped.wrap(.{
8380 .tid = tid,
8381 .index = items.mutate.len,
8382 }, ip);
8383 const owner_nav = ip.createNav(gpa, tid, .{
8384 .name = key.name,
8385 .fqn = key.name,
8386 .val = extern_index,
8387 .alignment = key.alignment,
8388 .@"linksection" = .none,
8389 .@"addrspace" = key.@"addrspace",
8390 }) catch unreachable; // capacity asserted above
8391 const extra_index = addExtraAssumeCapacity(extra, Tag.Extern{
8392 .ty = key.ty,
8393 .lib_name = key.lib_name,
8394 .flags = .{
8395 .is_const = key.is_const,
8396 .is_threadlocal = key.is_threadlocal,
8397 .is_weak_linkage = key.is_weak_linkage,
8398 },
8399 .zir_index = key.zir_index,
8400 .owner_nav = owner_nav,
8401 });
80688402 items.appendAssumeCapacity(.{
8069 .tag = .extern_func,
8403 .tag = .@"extern",
80708404 .data = extra_index,
80718405 });
8072 errdefer items.mutate.len -= 1;
8073 return gop.put();
8406 assert(gop.put() == extern_index);
8407
8408 return .{
8409 .index = extern_index,
8410 .new_nav = owner_nav.toOptional(),
8411 };
80748412}
80758413
80768414pub const GetFuncDeclKey = struct {
8077 owner_decl: DeclIndex,
8415 owner_nav: Nav.Index,
80788416 ty: Index,
80798417 zir_body_inst: TrackedInst.Index,
80808418 lbrace_line: u32,
......@@ -8105,7 +8443,7 @@ pub fn getFuncDecl(
81058443
81068444 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
81078445 .analysis = .{
8108 .state = if (key.cc == .Inline) .inline_only else .none,
8446 .state = .unreferenced,
81098447 .is_cold = false,
81108448 .is_noinline = key.is_noinline,
81118449 .calls_or_awaits_errorable_fn = false,
......@@ -8113,7 +8451,7 @@ pub fn getFuncDecl(
81138451 .inferred_error_set = false,
81148452 .disable_instrumentation = false,
81158453 },
8116 .owner_decl = key.owner_decl,
8454 .owner_nav = key.owner_nav,
81178455 .ty = key.ty,
81188456 .zir_body_inst = key.zir_body_inst,
81198457 .lbrace_line = key.lbrace_line,
......@@ -8140,7 +8478,7 @@ pub fn getFuncDecl(
81408478}
81418479
81428480pub const GetFuncDeclIesKey = struct {
8143 owner_decl: DeclIndex,
8481 owner_nav: Nav.Index,
81448482 param_types: []Index,
81458483 noalias_bits: u32,
81468484 comptime_bits: u32,
......@@ -8209,7 +8547,7 @@ pub fn getFuncDeclIes(
82098547
82108548 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
82118549 .analysis = .{
8212 .state = if (key.cc == .Inline) .inline_only else .none,
8550 .state = .unreferenced,
82138551 .is_cold = false,
82148552 .is_noinline = key.is_noinline,
82158553 .calls_or_awaits_errorable_fn = false,
......@@ -8217,7 +8555,7 @@ pub fn getFuncDeclIes(
82178555 .inferred_error_set = true,
82188556 .disable_instrumentation = false,
82198557 },
8220 .owner_decl = key.owner_decl,
8558 .owner_nav = key.owner_nav,
82218559 .ty = func_ty,
82228560 .zir_body_inst = key.zir_body_inst,
82238561 .lbrace_line = key.lbrace_line,
......@@ -8401,7 +8739,7 @@ pub fn getFuncInstance(
84018739
84028740 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
84038741 .analysis = .{
8404 .state = if (arg.cc == .Inline) .inline_only else .none,
8742 .state = .unreferenced,
84058743 .is_cold = false,
84068744 .is_noinline = arg.is_noinline,
84078745 .calls_or_awaits_errorable_fn = false,
......@@ -8409,9 +8747,9 @@ pub fn getFuncInstance(
84098747 .inferred_error_set = false,
84108748 .disable_instrumentation = false,
84118749 },
8412 // This is populated after we create the Decl below. It is not read
8750 // This is populated after we create the Nav below. It is not read
84138751 // by equality or hashing functions.
8414 .owner_decl = undefined,
8752 .owner_nav = undefined,
84158753 .ty = func_ty,
84168754 .branch_quota = 0,
84178755 .generic_owner = generic_owner,
......@@ -8501,7 +8839,7 @@ pub fn getFuncInstanceIes(
85018839
85028840 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
85038841 .analysis = .{
8504 .state = if (arg.cc == .Inline) .inline_only else .none,
8842 .state = .unreferenced,
85058843 .is_cold = false,
85068844 .is_noinline = arg.is_noinline,
85078845 .calls_or_awaits_errorable_fn = false,
......@@ -8509,9 +8847,9 @@ pub fn getFuncInstanceIes(
85098847 .inferred_error_set = true,
85108848 .disable_instrumentation = false,
85118849 },
8512 // This is populated after we create the Decl below. It is not read
8850 // This is populated after we create the Nav below. It is not read
85138851 // by equality or hashing functions.
8514 .owner_decl = undefined,
8852 .owner_nav = undefined,
85158853 .ty = func_ty,
85168854 .branch_quota = 0,
85178855 .generic_owner = generic_owner,
......@@ -8617,41 +8955,29 @@ fn finishFuncInstance(
86178955 alignment: Alignment,
86188956 section: OptionalNullTerminatedString,
86198957) 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),
8958 const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav);
8959 const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace;
8960
8961 // TODO: improve this name
8962 const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
8963 fn_owner_nav.name.fmt(ip), @intFromEnum(func_index),
8964 }, .no_embedded_nulls);
8965 const nav_index = try ip.createNav(gpa, tid, .{
8966 .name = nav_name,
8967 .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name),
8968 .val = func_index,
86288969 .alignment = alignment,
86298970 .@"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,
8971 .@"addrspace" = fn_owner_nav.status.resolved.@"addrspace",
86368972 });
8637 errdefer ip.destroyDecl(tid, decl_index);
86388973
8639 // Populate the owner_decl field which was left undefined until now.
8974 // Populate the owner_nav field which was left undefined until now.
86408975 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);
8976 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?
8977 ] = @intFromEnum(nav_index);
86518978}
86528979
86538980pub const EnumTypeInit = struct {
8654 has_namespace: bool,
86558981 has_values: bool,
86568982 tag_mode: LoadedEnumType.TagMode,
86578983 fields_len: u32,
......@@ -8671,27 +8997,35 @@ pub const WipEnumType = struct {
86718997 tid: Zcu.PerThread.Id,
86728998 index: Index,
86738999 tag_ty_index: u32,
8674 decl_index: u32,
8675 namespace_index: ?u32,
9000 type_name_extra_index: u32,
9001 cau_extra_index: u32,
9002 namespace_extra_index: u32,
86769003 names_map: MapIndex,
86779004 names_start: u32,
86789005 values_map: OptionalMapIndex,
86799006 values_start: u32,
86809007
9008 pub fn setName(
9009 wip: WipEnumType,
9010 ip: *InternPool,
9011 type_name: NullTerminatedString,
9012 ) void {
9013 const extra = ip.getLocalShared(wip.tid).extra.acquire();
9014 const extra_items = extra.view().items(.@"0");
9015 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
9016 }
9017
86819018 pub fn prepare(
86829019 wip: WipEnumType,
86839020 ip: *InternPool,
8684 decl: DeclIndex,
8685 namespace: OptionalNamespaceIndex,
9021 analysis_owner: Cau.Index,
9022 namespace: NamespaceIndex,
86869023 ) void {
86879024 const extra = ip.getLocalShared(wip.tid).extra.acquire();
86889025 const extra_items = extra.view().items(.@"0");
8689 extra_items[wip.decl_index] = @intFromEnum(decl);
8690 if (wip.namespace_index) |i| {
8691 extra_items[i] = @intFromEnum(namespace.unwrap().?);
8692 } else {
8693 assert(namespace == .none);
8694 }
9026
9027 extra_items[wip.cau_extra_index] = @intFromEnum(analysis_owner);
9028 extra_items[wip.namespace_extra_index] = @intFromEnum(namespace);
86959029 }
86969030
86979031 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {
......@@ -8780,15 +9114,16 @@ pub fn getEnumType(
87809114 .reified => 2, // type_hash: PackedU64
87819115 } +
87829116 // zig fmt: on
9117 1 + // cau
87839118 ini.fields_len); // field types
87849119
87859120 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
8786 .decl = undefined, // set by `prepare`
9121 .name = undefined, // set by `prepare`
87879122 .captures_len = switch (ini.key) {
87889123 .declared => |d| @intCast(d.captures.len),
87899124 .reified => std.math.maxInt(u32),
87909125 },
8791 .namespace = .none,
9126 .namespace = undefined, // set by `prepare`
87929127 .int_tag_type = .none, // set by `prepare`
87939128 .fields_len = ini.fields_len,
87949129 .names_map = names_map,
......@@ -8800,6 +9135,8 @@ pub fn getEnumType(
88009135 .tag = .type_enum_auto,
88019136 .data = extra_index,
88029137 });
9138 const cau_extra_index = extra.view().len;
9139 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
88039140 switch (ini.key) {
88049141 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
88059142 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
......@@ -8810,8 +9147,9 @@ pub fn getEnumType(
88109147 .tid = tid,
88119148 .index = gop.put(),
88129149 .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,
9150 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?,
9151 .cau_extra_index = @intCast(cau_extra_index),
9152 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "namespace").?,
88159153 .names_map = names_map,
88169154 .names_start = @intCast(names_start),
88179155 .values_map = .none,
......@@ -8835,16 +9173,17 @@ pub fn getEnumType(
88359173 .reified => 2, // type_hash: PackedU64
88369174 } +
88379175 // zig fmt: on
9176 1 + // cau
88389177 ini.fields_len + // field types
88399178 ini.fields_len * @intFromBool(ini.has_values)); // field values
88409179
88419180 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
8842 .decl = undefined, // set by `prepare`
9181 .name = undefined, // set by `prepare`
88439182 .captures_len = switch (ini.key) {
88449183 .declared => |d| @intCast(d.captures.len),
88459184 .reified => std.math.maxInt(u32),
88469185 },
8847 .namespace = .none,
9186 .namespace = undefined, // set by `prepare`
88489187 .int_tag_type = .none, // set by `prepare`
88499188 .fields_len = ini.fields_len,
88509189 .names_map = names_map,
......@@ -8861,6 +9200,8 @@ pub fn getEnumType(
88619200 },
88629201 .data = extra_index,
88639202 });
9203 const cau_extra_index = extra.view().len;
9204 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
88649205 switch (ini.key) {
88659206 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
88669207 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
......@@ -8874,9 +9215,10 @@ pub fn getEnumType(
88749215 return .{ .wip = .{
88759216 .tid = tid,
88769217 .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,
9218 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,
9219 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?,
9220 .cau_extra_index = @intCast(cau_extra_index),
9221 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").?,
88809222 .names_map = names_map,
88819223 .names_start = @intCast(names_start),
88829224 .values_map = values_map,
......@@ -8887,12 +9229,13 @@ pub fn getEnumType(
88879229}
88889230
88899231const GeneratedTagEnumTypeInit = struct {
8890 decl: DeclIndex,
9232 name: NullTerminatedString,
88919233 owner_union_ty: Index,
88929234 tag_ty: Index,
88939235 names: []const NullTerminatedString,
88949236 values: []const Index,
88959237 tag_mode: LoadedEnumType.TagMode,
9238 parent_namespace: NamespaceIndex,
88969239};
88979240
88989241/// Creates an enum type which was automatically-generated as the tag type of a
......@@ -8919,6 +9262,18 @@ pub fn getGeneratedTagEnumType(
89199262
89209263 const fields_len: u32 = @intCast(ini.names.len);
89219264
9265 // Predict the index the enum will live at so we can construct the namespace before releasing the shard's mutex.
9266 const enum_index = Index.Unwrapped.wrap(.{
9267 .tid = tid,
9268 .index = items.mutate.len,
9269 }, ip);
9270 const namespace = try ip.createNamespace(gpa, tid, .{
9271 .parent = ini.parent_namespace.toOptional(),
9272 .owner_type = enum_index,
9273 .file_scope = ip.namespacePtr(ini.parent_namespace).file_scope,
9274 });
9275 errdefer ip.destroyNamespace(tid, namespace);
9276
89229277 const prev_extra_len = extra.mutate.len;
89239278 switch (ini.tag_mode) {
89249279 .auto => {
......@@ -8928,9 +9283,9 @@ pub fn getGeneratedTagEnumType(
89289283 items.appendAssumeCapacity(.{
89299284 .tag = .type_enum_auto,
89309285 .data = addExtraAssumeCapacity(extra, EnumAuto{
8931 .decl = ini.decl,
9286 .name = ini.name,
89329287 .captures_len = 0,
8933 .namespace = .none,
9288 .namespace = namespace,
89349289 .int_tag_type = ini.tag_ty,
89359290 .fields_len = fields_len,
89369291 .names_map = names_map,
......@@ -8961,9 +9316,9 @@ pub fn getGeneratedTagEnumType(
89619316 .auto => unreachable,
89629317 },
89639318 .data = addExtraAssumeCapacity(extra, EnumExplicit{
8964 .decl = ini.decl,
9319 .name = ini.name,
89659320 .captures_len = 0,
8966 .namespace = .none,
9321 .namespace = namespace,
89679322 .int_tag_type = ini.tag_ty,
89689323 .fields_len = fields_len,
89699324 .names_map = names_map,
......@@ -8988,11 +9343,11 @@ pub fn getGeneratedTagEnumType(
89889343 .generated_tag = .{ .union_type = ini.owner_union_ty },
89899344 } });
89909345 defer gop.deinit();
8991 return gop.put();
9346 assert(gop.put() == enum_index);
9347 return enum_index;
89929348}
89939349
89949350pub const OpaqueTypeInit = struct {
8995 has_namespace: bool,
89969351 key: union(enum) {
89979352 declared: struct {
89989353 zir_index: TrackedInst.Index,
......@@ -9034,8 +9389,8 @@ pub fn getOpaqueType(
90349389 .reified => 0,
90359390 });
90369391 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
9037 .decl = undefined, // set by `finish`
9038 .namespace = .none,
9392 .name = undefined, // set by `finish`
9393 .namespace = undefined, // set by `finish`
90399394 .zir_index = switch (ini.key) {
90409395 inline else => |x| x.zir_index,
90419396 },
......@@ -9052,15 +9407,15 @@ pub fn getOpaqueType(
90529407 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
90539408 .reified => {},
90549409 }
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 } };
9410 return .{
9411 .wip = .{
9412 .tid = tid,
9413 .index = gop.put(),
9414 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
9415 .cau_extra_index = null, // opaques do not undergo type resolution
9416 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?,
9417 },
9418 };
90649419}
90659420
90669421pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
......@@ -9181,7 +9536,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
91819536 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
91829537 extra.appendAssumeCapacity(.{switch (field.type) {
91839538 Index,
9184 DeclIndex,
9539 Cau.Index,
9540 Nav.Index,
91859541 NamespaceIndex,
91869542 OptionalNamespaceIndex,
91879543 MapIndex,
......@@ -9244,7 +9600,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
92449600 const extra_item = extra_items[extra_index];
92459601 @field(result, field.name) = switch (field.type) {
92469602 Index,
9247 DeclIndex,
9603 Cau.Index,
9604 Nav.Index,
92489605 NamespaceIndex,
92499606 OptionalNamespaceIndex,
92509607 MapIndex,
......@@ -9436,12 +9793,6 @@ pub fn getCoerced(
94369793
94379794 switch (ip.indexToKey(val)) {
94389795 .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 }),
94459796 .func => unreachable,
94469797
94479798 .int => |int| switch (ip.indexToKey(new_ty)) {
......@@ -9858,27 +10209,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
985810209 var items_len: usize = 0;
985910210 var extra_len: usize = 0;
986010211 var limbs_len: usize = 0;
9861 var decls_len: usize = 0;
986210212 for (ip.locals) |*local| {
986310213 items_len += local.mutate.items.len;
986410214 extra_len += local.mutate.extra.len;
986510215 limbs_len += local.mutate.limbs.len;
9866 decls_len += local.mutate.decls.buckets_list.len;
986710216 }
986810217 const items_size = (1 + 4) * items_len;
986910218 const extra_size = 4 * extra_len;
987010219 const limbs_size = 8 * limbs_len;
9871 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
987210220
987310221 // TODO: map overhead size is not taken into account
9874 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;
10222 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size;
987510223
987610224 std.debug.print(
987710225 \\InternPool size: {d} bytes
987810226 \\ {d} items: {d} bytes
987910227 \\ {d} extra: {d} bytes
988010228 \\ {d} limbs: {d} bytes
9881 \\ {d} decls: {d} bytes
988210229 \\
988310230 , .{
988410231 total_size,
......@@ -9888,8 +10235,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
988810235 extra_size,
988910236 limbs_len,
989010237 limbs_size,
9891 decls_len,
9892 decls_size,
989310238 });
989410239
989510240 const TagStats = struct {
......@@ -9967,7 +10312,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
996710312 }
996810313 if (info.flags.any_default_inits)
996910314 ints += info.fields_len; // inits
9970 ints += @intFromBool(info.flags.has_namespace); // namespace
997110315 if (info.flags.any_aligned_fields)
997210316 ints += (info.fields_len + 3) / 4; // aligns
997310317 if (info.flags.any_comptime_fields)
......@@ -10034,10 +10378,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1003410378 .undef => 0,
1003510379 .simple_type => 0,
1003610380 .simple_value => 0,
10037 .ptr_decl => @sizeOf(PtrDecl),
10381 .ptr_nav => @sizeOf(PtrNav),
1003810382 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
10039 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
10040 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
10383 .ptr_uav => @sizeOf(PtrUav),
10384 .ptr_uav_aligned => @sizeOf(PtrUavAligned),
1004110385 .ptr_comptime_field => @sizeOf(PtrComptimeField),
1004210386 .ptr_int => @sizeOf(PtrInt),
1004310387 .ptr_eu_payload => @sizeOf(PtrBase),
......@@ -10092,7 +10436,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1009210436 .float_c_longdouble_f128 => @sizeOf(Float128),
1009310437 .float_comptime_float => @sizeOf(Float128),
1009410438 .variable => @sizeOf(Tag.Variable),
10095 .extern_func => @sizeOf(Tag.ExternFunc),
10439 .@"extern" => @sizeOf(Tag.Extern),
1009610440 .func_decl => @sizeOf(Tag.FuncDecl),
1009710441 .func_instance => b: {
1009810442 const info = extraData(extra_list, Tag.FuncInstance, data);
......@@ -10171,10 +10515,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1017110515 .type_union,
1017210516 .type_function,
1017310517 .undef,
10174 .ptr_decl,
10518 .ptr_nav,
1017510519 .ptr_comptime_alloc,
10176 .ptr_anon_decl,
10177 .ptr_anon_decl_aligned,
10520 .ptr_uav,
10521 .ptr_uav_aligned,
1017810522 .ptr_comptime_field,
1017910523 .ptr_int,
1018010524 .ptr_eu_payload,
......@@ -10212,7 +10556,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1021210556 .float_c_longdouble_f128,
1021310557 .float_comptime_float,
1021410558 .variable,
10215 .extern_func,
10559 .@"extern",
1021610560 .func_decl,
1021710561 .func_instance,
1021810562 .func_coerced,
......@@ -10275,13 +10619,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1027510619 instances.sort(SortContext{ .values = instances.values() });
1027610620 var it = instances.iterator();
1027710621 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 });
10622 const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);
10623 try w.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
1028010624 for (entry.value_ptr.items) |index| {
1028110625 const unwrapped_index = index.unwrap(ip);
1028210626 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)});
10627 const owner_nav = ip.getNav(func.owner_nav);
10628 try w.print(" {}: (", .{owner_nav.name.fmt(ip)});
1028510629 for (func.comptime_args.get(ip)) |arg| {
1028610630 if (arg != .none) {
1028710631 const key = ip.indexToKey(arg);
......@@ -10295,66 +10639,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1029510639 try bw.flush();
1029610640}
1029710641
10298pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {
10299 return @constCast(ip.declPtrConst(decl_index));
10642pub fn getCau(ip: *const InternPool, index: Cau.Index) Cau {
10643 const unwrapped = index.unwrap(ip);
10644 const caus = ip.getLocalShared(unwrapped.tid).caus.acquire();
10645 return caus.view().items(.@"0")[unwrapped.index];
1030010646}
1030110647
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];
10648pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav {
10649 const unwrapped = index.unwrap(ip);
10650 const navs = ip.getLocalShared(unwrapped.tid).navs.acquire();
10651 return navs.view().get(unwrapped.index).unpack();
10652}
10653
10654pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
10655 const unwrapped_namespace_index = namespace_index.unwrap(ip);
10656 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
10657 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
10658 return &namespaces_bucket[unwrapped_namespace_index.index];
1030710659}
1030810660
10309pub fn createDecl(
10661/// Create a `Cau` associated with the type at the given `InternPool.Index`.
10662pub fn createTypeCau(
1031010663 ip: *InternPool,
1031110664 gpa: Allocator,
1031210665 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 = .{
10666 zir_index: TrackedInst.Index,
10667 namespace: NamespaceIndex,
10668 owner_type: InternPool.Index,
10669) Allocator.Error!Cau.Index {
10670 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10671 const index_unwrapped: Cau.Index.Unwrapped = .{
1033410672 .tid = tid,
10335 .bucket_index = decls.mutate.len - 1,
10336 .index = local.mutate.decls.last_bucket_len,
10673 .index = caus.mutate.len,
1033710674 };
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;
10675 try caus.append(.{.{
10676 .zir_index = zir_index,
10677 .namespace = namespace,
10678 .owner = Cau.Owner.wrap(.{ .type = owner_type }),
10679 }});
10680 return index_unwrapped.wrap(ip);
1034310681}
1034410682
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);
10683/// Create a `Cau` for a `comptime` declaration.
10684pub fn createComptimeCau(
10685 ip: *InternPool,
10686 gpa: Allocator,
10687 tid: Zcu.PerThread.Id,
10688 zir_index: TrackedInst.Index,
10689 namespace: NamespaceIndex,
10690) Allocator.Error!Cau.Index {
10691 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10692 const index_unwrapped: Cau.Index.Unwrapped = .{
10693 .tid = tid,
10694 .index = caus.mutate.len,
10695 };
10696 try caus.append(.{.{
10697 .zir_index = zir_index,
10698 .namespace = namespace,
10699 .owner = Cau.Owner.wrap(.none),
10700 }});
10701 return index_unwrapped.wrap(ip);
1035110702}
1035210703
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];
10704/// Create a `Nav` not associated with any `Cau`.
10705/// Since there is no analysis owner, the `Nav`'s value must be known at creation time.
10706pub fn createNav(
10707 ip: *InternPool,
10708 gpa: Allocator,
10709 tid: Zcu.PerThread.Id,
10710 opts: struct {
10711 name: NullTerminatedString,
10712 fqn: NullTerminatedString,
10713 val: InternPool.Index,
10714 alignment: Alignment,
10715 @"linksection": OptionalNullTerminatedString,
10716 @"addrspace": std.builtin.AddressSpace,
10717 },
10718) Allocator.Error!Nav.Index {
10719 const navs = ip.getLocal(tid).getMutableNavs(gpa);
10720 const index_unwrapped: Nav.Index.Unwrapped = .{
10721 .tid = tid,
10722 .index = navs.mutate.len,
10723 };
10724 try navs.append(Nav.pack(.{
10725 .name = opts.name,
10726 .fqn = opts.fqn,
10727 .analysis_owner = .none,
10728 .status = .{ .resolved = .{
10729 .val = opts.val,
10730 .alignment = opts.alignment,
10731 .@"linksection" = opts.@"linksection",
10732 .@"addrspace" = opts.@"addrspace",
10733 } },
10734 .is_usingnamespace = false,
10735 }));
10736 return index_unwrapped.wrap(ip);
10737}
10738
10739/// Create a `Cau` and `Nav` which are paired. The value of the `Nav` is
10740/// determined by semantic analysis of the `Cau`. The value of the `Nav`
10741/// is initially unresolved.
10742pub fn createPairedCauNav(
10743 ip: *InternPool,
10744 gpa: Allocator,
10745 tid: Zcu.PerThread.Id,
10746 name: NullTerminatedString,
10747 fqn: NullTerminatedString,
10748 zir_index: TrackedInst.Index,
10749 namespace: NamespaceIndex,
10750 /// TODO: this is hacky! See `Nav.is_usingnamespace`.
10751 is_usingnamespace: bool,
10752) Allocator.Error!struct { Cau.Index, Nav.Index } {
10753 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10754 const navs = ip.getLocal(tid).getMutableNavs(gpa);
10755
10756 try caus.ensureUnusedCapacity(1);
10757 try navs.ensureUnusedCapacity(1);
10758
10759 const cau = Cau.Index.Unwrapped.wrap(.{
10760 .tid = tid,
10761 .index = caus.mutate.len,
10762 }, ip);
10763 const nav = Nav.Index.Unwrapped.wrap(.{
10764 .tid = tid,
10765 .index = navs.mutate.len,
10766 }, ip);
10767
10768 caus.appendAssumeCapacity(.{.{
10769 .zir_index = zir_index,
10770 .namespace = namespace,
10771 .owner = Cau.Owner.wrap(.{ .nav = nav }),
10772 }});
10773 navs.appendAssumeCapacity(Nav.pack(.{
10774 .name = name,
10775 .fqn = fqn,
10776 .analysis_owner = cau.toOptional(),
10777 .status = .unresolved,
10778 .is_usingnamespace = is_usingnamespace,
10779 }));
10780
10781 return .{ cau, nav };
10782}
10783
10784/// Resolve the value of a `Nav` with an analysis owner.
10785/// If its status is already `resolved`, the old value is discarded.
10786pub fn resolveNavValue(
10787 ip: *InternPool,
10788 nav: Nav.Index,
10789 resolved: struct {
10790 val: InternPool.Index,
10791 alignment: Alignment,
10792 @"linksection": OptionalNullTerminatedString,
10793 @"addrspace": std.builtin.AddressSpace,
10794 },
10795) void {
10796 const unwrapped = nav.unwrap(ip);
10797
10798 const local = ip.getLocal(unwrapped.tid);
10799 local.mutate.extra.mutex.lock();
10800 defer local.mutate.extra.mutex.unlock();
10801
10802 const navs = local.shared.navs.view();
10803
10804 const nav_analysis_owners = navs.items(.analysis_owner);
10805 const nav_vals = navs.items(.val);
10806 const nav_linksections = navs.items(.@"linksection");
10807 const nav_bits = navs.items(.bits);
10808
10809 assert(nav_analysis_owners[unwrapped.index] != .none);
10810
10811 @atomicStore(InternPool.Index, &nav_vals[unwrapped.index], resolved.val, .release);
10812 @atomicStore(OptionalNullTerminatedString, &nav_linksections[unwrapped.index], resolved.@"linksection", .release);
10813
10814 var bits = nav_bits[unwrapped.index];
10815 bits.status = .resolved;
10816 bits.alignment = resolved.alignment;
10817 bits.@"addrspace" = resolved.@"addrspace";
10818 @atomicStore(Nav.Repr.Bits, &nav_bits[unwrapped.index], bits, .release);
1035810819}
1035910820
1036010821pub fn createNamespace(
......@@ -10404,7 +10865,7 @@ pub fn destroyNamespace(
1040410865 namespace.* = .{
1040510866 .parent = undefined,
1040610867 .file_scope = undefined,
10407 .decl_index = undefined,
10868 .owner_type = undefined,
1040810869 };
1040910870 @field(namespace, Local.namespace_next_free_field) =
1041010871 @enumFromInt(local.mutate.namespaces.free_list);
......@@ -10750,10 +11211,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1075011211
1075111212 .simple_type, .simple_value => unreachable, // handled via Index above
1075211213
10753 inline .ptr_decl,
11214 inline .ptr_nav,
1075411215 .ptr_comptime_alloc,
10755 .ptr_anon_decl,
10756 .ptr_anon_decl_aligned,
11216 .ptr_uav,
11217 .ptr_uav_aligned,
1075711218 .ptr_comptime_field,
1075811219 .ptr_int,
1075911220 .ptr_eu_payload,
......@@ -10770,7 +11231,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1077011231 .error_union_error,
1077111232 .enum_tag,
1077211233 .variable,
10773 .extern_func,
11234 .@"extern",
1077411235 .func_decl,
1077511236 .func_instance,
1077611237 .func_coerced,
......@@ -10892,14 +11353,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool {
1089211353 return val.unwrap(ip).getTag(ip) == .variable;
1089311354}
1089411355
10895pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
11356pub fn getBackingNav(ip: *const InternPool, val: Index) Nav.Index.Optional {
1089611357 var base = val;
1089711358 while (true) {
1089811359 const unwrapped_base = base.unwrap(ip);
1089911360 const base_item = unwrapped_base.getItem(ip);
1090011361 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").?
11362 .ptr_nav => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
11363 base_item.data + std.meta.fieldIndex(PtrNav, "nav").?
1090311364 ]),
1090411365 inline .ptr_eu_payload,
1090511366 .ptr_opt_payload,
......@@ -10922,11 +11383,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
1092211383 const unwrapped_base = base.unwrap(ip);
1092311384 const base_item = unwrapped_base.getItem(ip);
1092411385 switch (base_item.tag) {
10925 .ptr_decl => return .decl,
11386 .ptr_nav => return .nav,
1092611387 .ptr_comptime_alloc => return .comptime_alloc,
10927 .ptr_anon_decl,
10928 .ptr_anon_decl_aligned,
10929 => return .anon_decl,
11388 .ptr_uav,
11389 .ptr_uav_aligned,
11390 => return .uav,
1093011391 .ptr_comptime_field => return .comptime_field,
1093111392 .ptr_int => return .int,
1093211393 inline .ptr_eu_payload,
......@@ -11098,10 +11559,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1109811559 // values, not types
1109911560 .undef,
1110011561 .simple_value,
11101 .ptr_decl,
11562 .ptr_nav,
1110211563 .ptr_comptime_alloc,
11103 .ptr_anon_decl,
11104 .ptr_anon_decl_aligned,
11564 .ptr_uav,
11565 .ptr_uav_aligned,
1110511566 .ptr_comptime_field,
1110611567 .ptr_int,
1110711568 .ptr_eu_payload,
......@@ -11137,7 +11598,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1113711598 .float_c_longdouble_f128,
1113811599 .float_comptime_float,
1113911600 .variable,
11140 .extern_func,
11601 .@"extern",
1114111602 .func_decl,
1114211603 .func_instance,
1114311604 .func_coerced,
......@@ -11190,18 +11651,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
1119011651 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
1119111652}
1119211653
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
1120511654pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
1120611655 const unwrapped_func = func.unwrap(ip);
1120711656 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
......@@ -11349,10 +11798,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
1134911798 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
1135011799}
1135111800
11352pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
11353 return funcDeclInfo(ip, index).owner_decl;
11354}
11355
1135611801pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
1135711802 const unwrapped_index = index.unwrap(ip);
1135811803 const extra_list = unwrapped_index.getExtra(ip);
......@@ -11409,14 +11854,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {
1140911854 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);
1141011855}
1141111856
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
1142011857/// Returns the already-existing field with the same name, if any.
1142111858pub fn addFieldName(
1142211859 ip: *InternPool,
......@@ -11436,8 +11873,8 @@ pub fn addFieldName(
1143611873 return null;
1143711874}
1143811875
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.
11876/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_uav`
11877/// encoding instead of `Tag.ptr_uav_aligned` when possible.
1144111878fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
1144211879 if (a_ty == b_ty) return true;
1144311880 const b_info = ip.indexToKey(b_ty).ptr_type;
......@@ -11607,3 +12044,7 @@ pub fn getErrorValue(
1160712044pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
1160812045 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
1160912046}
12047
12048pub fn isRemoved(ip: *const InternPool, ty: Index) bool {
12049 return ty.unwrap(ip).getTag(ip) == .removed;
12050}
src/Sema.zig+1054-1088
......@@ -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
......@@ -2816,7 +2802,6 @@ fn zirStructDecl(
28162802 .any_default_inits = small.any_default_inits,
28172803 .inits_resolved = false,
28182804 .any_aligned_fields = small.any_aligned_fields,
2819 .has_namespace = true or decls_len > 0, // TODO: see below
28202805 .key = .{ .declared = .{
28212806 .zir_index = tracked_inst,
28222807 .captures = captures,
......@@ -2831,73 +2816,65 @@ fn zirStructDecl(
28312816 });
28322817 errdefer wip_ty.cancel(ip, pt.tid);
28332818
2834 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2819 wip_ty.setName(ip, try sema.createTypeName(
28352820 block,
2836 Value.fromInterned(wip_ty.index),
28372821 small.name_strategy,
28382822 "struct",
28392823 inst,
2840 );
2841 mod.declPtr(new_decl_index).owns_tv = true;
2842 errdefer pt.abortAnonDecl(new_decl_index);
2824 wip_ty.index,
2825 ));
2826
2827 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
2828 .parent = block.namespace.toOptional(),
2829 .owner_type = wip_ty.index,
2830 .file_scope = block.getFileScopeIndex(mod),
2831 });
2832 errdefer pt.destroyNamespace(new_namespace_index);
2833
2834 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index);
28432835
28442836 if (pt.zcu.comp.incremental) {
28452837 try ip.addDependency(
28462838 sema.gpa,
2847 AnalUnit.wrap(.{ .decl = new_decl_index }),
2848 .{ .src_hash = try block.trackZir(inst) },
2839 AnalUnit.wrap(.{ .cau = new_cau_index }),
2840 .{ .src_hash = tracked_inst },
28492841 );
28502842 }
28512843
2852 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
2853 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
2854 .parent = block.namespace.toOptional(),
2855 .decl_index = new_decl_index,
2856 .file_scope = block.getFileScopeIndex(mod),
2857 })).toOptional() else .none;
2858 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
2859
2860 if (new_namespace_index.unwrap()) |ns| {
2861 const decls = sema.code.bodySlice(extra_index, decls_len);
2862 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
2863 }
2844 const decls = sema.code.bodySlice(extra_index, decls_len);
2845 try pt.scanNamespace(new_namespace_index, decls);
28642846
2865 try pt.finalizeAnonDecl(new_decl_index);
28662847 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));
2848 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
2849 try sema.declareDependency(.{ .interned = wip_ty.index });
2850 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
28692851}
28702852
2871fn createAnonymousDeclTypeNamed(
2853fn createTypeName(
28722854 sema: *Sema,
28732855 block: *Block,
2874 val: Value,
28752856 name_strategy: Zir.Inst.NameStrategy,
28762857 anon_prefix: []const u8,
28772858 inst: ?Zir.Inst.Index,
2878) !InternPool.DeclIndex {
2859 /// This is used purely to give the type a unique name in the `anon` case.
2860 type_index: InternPool.Index,
2861) !InternPool.NullTerminatedString {
28792862 const pt = sema.pt;
28802863 const zcu = pt.zcu;
2864 const gpa = zcu.gpa;
28812865 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);
28862866
28872867 switch (name_strategy) {
28882868 .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 },
2869 .parent => return block.type_name_ctx,
28932870 .func => func_strat: {
28942871 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));
28952872 const zir_tags = sema.code.instructions.items(.tag);
28962873
2897 var buf = std.ArrayList(u8).init(gpa);
2898 defer buf.deinit();
2874 var buf: std.ArrayListUnmanaged(u8) = .{};
2875 defer buf.deinit(gpa);
28992876
2900 const writer = buf.writer();
2877 const writer = buf.writer(gpa);
29012878 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});
29022879
29032880 var arg_i: usize = 0;
......@@ -2931,23 +2908,18 @@ fn createAnonymousDeclTypeNamed(
29312908 };
29322909
29332910 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;
2911 return ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
29372912 },
29382913 .dbg_var => {
2914 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
29392915 const ref = inst.?.toRef();
29402916 const zir_tags = sema.code.instructions.items(.tag);
29412917 const zir_data = sema.code.instructions.items(.data);
29422918 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}", .{
2919 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
2920 return ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
29472921 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
29482922 }, .no_embedded_nulls);
2949 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2950 return new_decl_index;
29512923 },
29522924 else => {},
29532925 };
......@@ -2955,20 +2927,19 @@ fn createAnonymousDeclTypeNamed(
29552927 },
29562928 }
29572929
2958 // anon strat handling.
2930 // anon strat handling
29592931
29602932 // It would be neat to have "struct:line:column" but this name has
29612933 // to survive incremental updates, where it may have been shifted down
29622934 // or up to a different line, but unchanged, and thus not unnecessarily
29632935 // semantically analyzed.
2964 // This name is also used as the key in the parent namespace so it cannot be
2965 // renamed.
2936 // TODO: that would be possible, by detecting line number changes and renaming
2937 // types appropriately. However, `@typeName` becomes a problem then. If we remove
2938 // that builtin from the language, we can consider this.
29662939
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;
2940 return ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2941 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
2942 }, .no_embedded_nulls);
29722943}
29732944
29742945fn zirEnumDecl(
......@@ -3040,7 +3011,6 @@ fn zirEnumDecl(
30403011 } else false;
30413012
30423013 const enum_init: InternPool.EnumTypeInit = .{
3043 .has_namespace = true or decls_len > 0, // TODO: see below
30443014 .has_values = any_values,
30453015 .tag_mode = if (small.nonexhaustive)
30463016 .nonexhaustive
......@@ -3068,60 +3038,50 @@ fn zirEnumDecl(
30683038
30693039 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
30703040
3071 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3041 const type_name = try sema.createTypeName(
30723042 block,
3073 Value.fromInterned(wip_ty.index),
30743043 small.name_strategy,
30753044 "enum",
30763045 inst,
3046 wip_ty.index,
30773047 );
3078 const new_decl = mod.declPtr(new_decl_index);
3079 new_decl.owns_tv = true;
3080 errdefer if (!done) pt.abortAnonDecl(new_decl_index);
3048 wip_ty.setName(ip, type_name);
3049
3050 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3051 .parent = block.namespace.toOptional(),
3052 .owner_type = wip_ty.index,
3053 .file_scope = block.getFileScopeIndex(mod),
3054 });
3055 errdefer if (!done) pt.destroyNamespace(new_namespace_index);
3056
3057 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index);
30813058
30823059 if (pt.zcu.comp.incremental) {
30833060 try mod.intern_pool.addDependency(
30843061 gpa,
3085 AnalUnit.wrap(.{ .decl = new_decl_index }),
3062 AnalUnit.wrap(.{ .cau = new_cau_index }),
30863063 .{ .src_hash = try block.trackZir(inst) },
30873064 );
30883065 }
30893066
3090 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
3091 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
3092 .parent = block.namespace.toOptional(),
3093 .decl_index = new_decl_index,
3094 .file_scope = block.getFileScopeIndex(mod),
3095 })).toOptional() else .none;
3096 errdefer if (!done) if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
3067 try pt.scanNamespace(new_namespace_index, decls);
30973068
3098 if (new_namespace_index.unwrap()) |ns| {
3099 try pt.scanNamespace(ns, decls, new_decl);
3100 }
3069 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3070 try sema.declareDependency(.{ .interned = wip_ty.index });
31013071
31023072 // 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);
3073 // Set the Cau and namespace appropriately, and don't destroy anything on failure.
3074 wip_ty.prepare(ip, new_cau_index, new_namespace_index);
31053075 done = true;
31063076
31073077 const int_tag_ty = ty: {
31083078 // We create a block for the field type instructions because they
31093079 // 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.
3080 // Within the field type, default value, and alignment expressions, the owner should be the enum's `Cau`.
31123081
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;
3082 const prev_owner = sema.owner;
3083 sema.owner = AnalUnit.wrap(.{ .cau = new_cau_index });
3084 defer sema.owner = prev_owner;
31253085
31263086 const prev_func_index = sema.func_index;
31273087 sema.func_index = .none;
......@@ -3130,12 +3090,12 @@ fn zirEnumDecl(
31303090 var enum_block: Block = .{
31313091 .parent = null,
31323092 .sema = sema,
3133 .namespace = new_namespace_index.unwrap() orelse block.namespace,
3093 .namespace = new_namespace_index,
31343094 .instructions = .{},
31353095 .inlining = null,
31363096 .is_comptime = true,
31373097 .src_base_inst = tracked_inst,
3138 .type_name_ctx = new_decl.name,
3098 .type_name_ctx = type_name,
31393099 };
31403100 defer enum_block.instructions.deinit(sema.gpa);
31413101
......@@ -3253,7 +3213,6 @@ fn zirEnumDecl(
32533213 }
32543214 }
32553215
3256 try pt.finalizeAnonDecl(new_decl_index);
32573216 return Air.internedToRef(wip_ty.index);
32583217}
32593218
......@@ -3317,7 +3276,6 @@ fn zirUnionDecl(
33173276 .assumed_pointer_aligned = false,
33183277 .alignment = .none,
33193278 },
3320 .has_namespace = true or decls_len != 0, // TODO: see below
33213279 .fields_len = fields_len,
33223280 .enum_tag_ty = .none, // set later
33233281 .field_types = &.{}, // set later
......@@ -3336,41 +3294,38 @@ fn zirUnionDecl(
33363294 });
33373295 errdefer wip_ty.cancel(ip, pt.tid);
33383296
3339 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3297 wip_ty.setName(ip, try sema.createTypeName(
33403298 block,
3341 Value.fromInterned(wip_ty.index),
33423299 small.name_strategy,
33433300 "union",
33443301 inst,
3345 );
3346 mod.declPtr(new_decl_index).owns_tv = true;
3347 errdefer pt.abortAnonDecl(new_decl_index);
3302 wip_ty.index,
3303 ));
3304
3305 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3306 .parent = block.namespace.toOptional(),
3307 .owner_type = wip_ty.index,
3308 .file_scope = block.getFileScopeIndex(mod),
3309 });
3310 errdefer pt.destroyNamespace(new_namespace_index);
3311
3312 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index);
33483313
33493314 if (pt.zcu.comp.incremental) {
33503315 try mod.intern_pool.addDependency(
33513316 gpa,
3352 AnalUnit.wrap(.{ .decl = new_decl_index }),
3317 AnalUnit.wrap(.{ .cau = new_cau_index }),
33533318 .{ .src_hash = try block.trackZir(inst) },
33543319 );
33553320 }
33563321
3357 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
3358 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
3359 .parent = block.namespace.toOptional(),
3360 .decl_index = new_decl_index,
3361 .file_scope = block.getFileScopeIndex(mod),
3362 })).toOptional() else .none;
3363 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
3364
3365 if (new_namespace_index.unwrap()) |ns| {
3366 const decls = sema.code.bodySlice(extra_index, decls_len);
3367 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3368 }
3322 const decls = sema.code.bodySlice(extra_index, decls_len);
3323 try pt.scanNamespace(new_namespace_index, decls);
33693324
3370 try pt.finalizeAnonDecl(new_decl_index);
33713325 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));
3326 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3327 try sema.declareDependency(.{ .interned = wip_ty.index });
3328 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
33743329}
33753330
33763331fn zirOpaqueDecl(
......@@ -3410,7 +3365,6 @@ fn zirOpaqueDecl(
34103365 extra_index += captures_len;
34113366
34123367 const opaque_init: InternPool.OpaqueTypeInit = .{
3413 .has_namespace = decls_len != 0,
34143368 .key = .{ .declared = .{
34153369 .zir_index = tracked_inst,
34163370 .captures = captures,
......@@ -3418,47 +3372,31 @@ fn zirOpaqueDecl(
34183372 };
34193373 // No `wrapWipTy` needed as no std.builtin types are opaque.
34203374 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 },
3375 // No `maybeRemoveOutdatedType` as opaque types are never outdated.
3376 .existing => |ty| return Air.internedToRef(ty),
34253377 .wip => |wip| wip,
34263378 };
34273379 errdefer wip_ty.cancel(ip, pt.tid);
34283380
3429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3381 wip_ty.setName(ip, try sema.createTypeName(
34303382 block,
3431 Value.fromInterned(wip_ty.index),
34323383 small.name_strategy,
34333384 "opaque",
34343385 inst,
3435 );
3436 mod.declPtr(new_decl_index).owns_tv = true;
3437 errdefer pt.abortAnonDecl(new_decl_index);
3386 wip_ty.index,
3387 ));
34383388
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 }
3446
3447 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try pt.createNamespace(.{
3389 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
34483390 .parent = block.namespace.toOptional(),
3449 .decl_index = new_decl_index,
3391 .owner_type = wip_ty.index,
34503392 .file_scope = block.getFileScopeIndex(mod),
3451 })).toOptional() else .none;
3452 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
3453
3454 if (new_namespace_index.unwrap()) |ns| {
3455 const decls = sema.code.bodySlice(extra_index, decls_len);
3456 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));
3457 }
3393 });
3394 errdefer pt.destroyNamespace(new_namespace_index);
34583395
3459 try pt.finalizeAnonDecl(new_decl_index);
3396 const decls = sema.code.bodySlice(extra_index, decls_len);
3397 try pt.scanNamespace(new_namespace_index, decls);
34603398
3461 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3399 return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index));
34623400}
34633401
34643402fn zirErrorSetDecl(
......@@ -3774,7 +3712,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
37743712 // might have already done our job and created an anon decl ref.
37753713 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
37763714 .ptr => |ptr| switch (ptr.base_addr) {
3777 .anon_decl => {
3715 .uav => {
37783716 // The comptime-ification was already done for us.
37793717 // Just make sure the pointer is const.
37803718 return sema.makePtrConst(block, alloc);
......@@ -3799,7 +3737,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
37993737 // Promote the constant to an anon decl.
38003738 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{
38013739 .ty = alloc_ty.toIntern(),
3802 .base_addr = .{ .anon_decl = .{
3740 .base_addr = .{ .uav = .{
38033741 .val = interned.toIntern(),
38043742 .orig_ty = alloc_ty.toIntern(),
38053743 } },
......@@ -4097,7 +4035,7 @@ fn finishResolveComptimeKnownAllocPtr(
40974035 } else {
40984036 return try pt.intern(.{ .ptr = .{
40994037 .ty = alloc_ty.toIntern(),
4100 .base_addr = .{ .anon_decl = .{
4038 .base_addr = .{ .uav = .{
41014039 .orig_ty = alloc_ty.toIntern(),
41024040 .val = result_val,
41034041 } },
......@@ -4250,7 +4188,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
42504188 }
42514189
42524190 const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) {
4253 .anon_decl => |a| a.val,
4191 .uav => |a| a.val,
42544192 .comptime_alloc => |i| val: {
42554193 const alloc = sema.getComptimeAlloc(i);
42564194 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();
......@@ -5505,22 +5443,23 @@ fn failWithBadMemberAccess(
55055443 field_name: InternPool.NullTerminatedString,
55065444) CompileError {
55075445 const pt = sema.pt;
5508 const mod = pt.zcu;
5509 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
5446 const zcu = pt.zcu;
5447 const ip = &zcu.intern_pool;
5448 const kw_name = switch (agg_ty.zigTypeTag(zcu)) {
55105449 .Union => "union",
55115450 .Struct => "struct",
55125451 .Opaque => "opaque",
55135452 .Enum => "enum",
55145453 else => unreachable,
55155454 };
5516 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
5455 if (agg_ty.typeDeclInst(zcu)) |inst| if (inst.resolve(ip) == .main_struct_inst) {
55175456 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),
5457 agg_ty.fmt(pt), field_name.fmt(ip),
55195458 });
55205459 };
55215460
55225461 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5523 kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),
5462 kw_name, agg_ty.fmt(pt), field_name.fmt(ip),
55245463 });
55255464}
55265465
......@@ -5535,13 +5474,12 @@ fn failWithBadStructFieldAccess(
55355474 const pt = sema.pt;
55365475 const zcu = pt.zcu;
55375476 const ip = &zcu.intern_pool;
5538 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
55395477
55405478 const msg = msg: {
55415479 const msg = try sema.errMsg(
55425480 field_src,
55435481 "no field named '{}' in struct '{}'",
5544 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
5482 .{ field_name.fmt(ip), struct_type.name.fmt(ip) },
55455483 );
55465484 errdefer msg.destroy(sema.gpa);
55475485 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
......@@ -5562,13 +5500,12 @@ fn failWithBadUnionFieldAccess(
55625500 const zcu = pt.zcu;
55635501 const ip = &zcu.intern_pool;
55645502 const gpa = sema.gpa;
5565 const decl = zcu.declPtr(union_obj.decl);
55665503
55675504 const msg = msg: {
55685505 const msg = try sema.errMsg(
55695506 field_src,
55705507 "no field named '{}' in union '{}'",
5571 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
5508 .{ field_name.fmt(ip), union_obj.name.fmt(ip) },
55725509 );
55735510 errdefer msg.destroy(gpa);
55745511 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
......@@ -5659,7 +5596,7 @@ fn storeToInferredAllocComptime(
56595596 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
56605597 iac.ptr = try pt.intern(.{ .ptr = .{
56615598 .ty = alloc_ty.toIntern(),
5662 .base_addr = .{ .anon_decl = .{
5599 .base_addr = .{ .uav = .{
56635600 .val = operand_val.toIntern(),
56645601 .orig_ty = alloc_ty.toIntern(),
56655602 } },
......@@ -5748,11 +5685,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.
57485685 .ty = array_ty.toIntern(),
57495686 .storage = .{ .bytes = string },
57505687 } });
5751 return anonDeclRef(sema, val);
5688 return sema.uavRef(val);
57525689}
57535690
5754fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5755 return Air.internedToRef(try refValue(sema, val));
5691fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5692 return Air.internedToRef(try sema.refValue(val));
57565693}
57575694
57585695fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
......@@ -5767,7 +5704,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
57675704 })).toIntern();
57685705 return pt.intern(.{ .ptr = .{
57695706 .ty = ptr_ty,
5770 .base_addr = .{ .anon_decl = .{
5707 .base_addr = .{ .uav = .{
57715708 .val = val,
57725709 .orig_ty = ptr_ty,
57735710 } },
......@@ -5866,7 +5803,7 @@ fn zirCompileLog(
58665803 }
58675804 try writer.print("\n", .{});
58685805
5869 const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.ownerUnit());
5806 const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.owner);
58705807 if (!gop.found_existing) gop.value_ptr.* = .{
58715808 .base_node_inst = block.src_base_inst,
58725809 .node_offset = src_node,
......@@ -6021,7 +5958,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60215958 if (!comp.config.link_libc)
60225959 try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});
60235960
6024 const gop = try zcu.cimport_errors.getOrPut(gpa, sema.ownerUnit());
5961 const gop = try zcu.cimport_errors.getOrPut(gpa, sema.owner);
60255962 if (!gop.found_existing) {
60265963 gop.value_ptr.* = c_import_res.errors;
60275964 c_import_res.errors = std.zig.ErrorBundle.empty;
......@@ -6069,13 +6006,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60696006 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60706007
60716008 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|
6009 const old_root_type = zcu.fileRootType(result.file_index);
6010 pt.astGenFile(result.file, path_digest, old_root_type) catch |err|
60746011 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60756012
6013 // TODO: register some kind of dependency on the file.
6014 // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to
6015 // trigger re-analysis later.
60766016 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);
6017 return Air.internedToRef(zcu.fileRootType(result.file_index));
60796018}
60806019
60816020fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -6423,36 +6362,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
64236362 defer tracy.end();
64246363
64256364 const pt = sema.pt;
6426 const mod = pt.zcu;
6365 const zcu = pt.zcu;
6366 const ip = &zcu.intern_pool;
64276367 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
64286368 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
64296369 const src = block.nodeOffset(inst_data.src_node);
64306370 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
64316371 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
6432 const decl_name = try mod.intern_pool.getOrPutString(
6433 mod.gpa,
6372 const decl_name = try ip.getOrPutString(
6373 zcu.gpa,
64346374 pt.tid,
64356375 sema.code.nullTerminatedString(extra.decl_name),
64366376 .no_embedded_nulls,
64376377 );
6438 const decl_index = if (extra.namespace != .none) index_blk: {
6378 const nav_index = if (extra.namespace != .none) index_blk: {
64396379 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);
6440 const container_namespace = container_ty.getNamespaceIndex(mod);
6380 const container_namespace = container_ty.getNamespaceIndex(zcu);
64416381
6442 const maybe_index = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false);
6443 break :index_blk maybe_index orelse
6382 const lookup = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false) orelse
64446383 return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name);
6384
6385 break :index_blk lookup.nav;
64456386 } else try sema.lookupIdentifier(block, operand_src, decl_name);
64466387 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);
6388
6389 try sema.ensureNavResolved(src, nav_index);
6390
6391 // Make sure to export the owner Nav if applicable.
6392 const exported_nav = switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) {
6393 .variable => |v| v.owner_nav,
6394 .@"extern" => |e| e.owner_nav,
6395 .func => |f| f.owner_nav,
6396 else => nav_index,
6397 };
6398 try sema.analyzeExport(block, src, options, exported_nav);
64566399}
64576400
64586401fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -6460,7 +6403,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
64606403 defer tracy.end();
64616404
64626405 const pt = sema.pt;
6463 const mod = pt.zcu;
6406 const zcu = pt.zcu;
6407 const ip = &zcu.intern_pool;
64646408 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
64656409 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
64666410 const src = block.nodeOffset(inst_data.src_node);
......@@ -6472,17 +6416,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
64726416 const options = try sema.resolveExportOptions(block, options_src, extra.options);
64736417 if (options.linkage == .internal)
64746418 return;
6475 if (operand.getFunction(mod)) |function| {
6476 const decl_index = function.owner_decl;
6477 return sema.analyzeExport(block, src, options, decl_index);
6478 }
64796419
6480 try sema.exports.append(mod.gpa, .{
6481 .opts = options,
6482 .src = src,
6483 .exported = .{ .value = operand.toIntern() },
6484 .status = .in_progress,
6485 });
6420 // If the value has an owner Nav, export that instead.
6421 const maybe_owner_nav = switch (ip.indexToKey(operand.toIntern())) {
6422 .variable => |v| v.owner_nav,
6423 .@"extern" => |e| e.owner_nav,
6424 .func => |f| f.owner_nav,
6425 else => null,
6426 };
6427 if (maybe_owner_nav) |owner_nav| {
6428 return sema.analyzeExport(block, src, options, owner_nav);
6429 } else {
6430 try sema.exports.append(zcu.gpa, .{
6431 .opts = options,
6432 .src = src,
6433 .exported = .{ .uav = operand.toIntern() },
6434 .status = .in_progress,
6435 });
6436 }
64866437}
64876438
64886439pub fn analyzeExport(
......@@ -6490,22 +6441,22 @@ pub fn analyzeExport(
64906441 block: *Block,
64916442 src: LazySrcLoc,
64926443 options: Module.Export.Options,
6493 exported_decl_index: InternPool.DeclIndex,
6444 exported_nav_index: InternPool.Nav.Index,
64946445) !void {
64956446 const gpa = sema.gpa;
64966447 const pt = sema.pt;
6497 const mod = pt.zcu;
6448 const zcu = pt.zcu;
6449 const ip = &zcu.intern_pool;
64986450
64996451 if (options.linkage == .internal)
65006452 return;
65016453
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);
6454 try sema.ensureNavResolved(src, exported_nav_index);
6455 const exported_nav = ip.getNav(exported_nav_index);
6456 const export_ty = Type.fromInterned(exported_nav.typeOf(ip));
65066457
65076458 if (!try sema.validateExternType(export_ty, .other)) {
6508 const msg = msg: {
6459 return sema.failWithOwnedErrorMsg(block, msg: {
65096460 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
65106461 errdefer msg.destroy(gpa);
65116462
......@@ -6513,59 +6464,50 @@ pub fn analyzeExport(
65136464
65146465 try sema.addDeclaredHereNote(msg, export_ty);
65156466 break :msg msg;
6516 };
6517 return sema.failWithOwnedErrorMsg(block, msg);
6467 });
65186468 }
65196469
65206470 // TODO: some backends might support re-exporting extern decls
6521 if (exported_decl.isExtern(mod)) {
6471 if (exported_nav.isExtern(ip)) {
65226472 return sema.fail(block, src, "export target cannot be extern", .{});
65236473 }
65246474
6525 try sema.maybeQueueFuncBodyAnalysis(src, exported_decl_index);
6475 try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index);
65266476
65276477 try sema.exports.append(gpa, .{
65286478 .opts = options,
65296479 .src = src,
6530 .exported = .{ .decl_index = exported_decl_index },
6480 .exported = .{ .nav = exported_nav_index },
65316481 .status = .in_progress,
65326482 });
65336483}
65346484
65356485fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
65366486 const pt = sema.pt;
6537 const mod = pt.zcu;
6487 const zcu = pt.zcu;
65386488 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
65396489 const operand_src = block.builtinCallArgSrc(extra.node, 0);
65406490 const src = block.nodeOffset(extra.node);
65416491 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
6492
6493 const func = switch (sema.owner.unwrap()) {
6494 .func => |func| func,
6495 .cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}),
6496 };
6497
65426498 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
65436499 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
65446500 alignment.toByteUnits().?,
65456501 });
65466502 }
65476503
6548 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
6549 switch (fn_owner_decl.typeOf(mod).fnCallingConvention(mod)) {
6504 switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) {
65506505 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
65516506 .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);
6507 else => {},
65656508 }
6566 sema.prev_stack_alignment_src = src;
65676509
6568 mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
6510 zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
65696511}
65706512
65716513fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
......@@ -6577,16 +6519,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
65776519 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{
65786520 .needed_comptime_reason = "operand to @setCold must be comptime-known",
65796521 });
6580 if (sema.func_index == .none) return; // does nothing outside a function
6581 ip.funcSetCold(sema.func_index, is_cold);
6522 // TODO: should `@setCold` apply to the parent in an inline call?
6523 // See also #20642 and friends.
6524 const func = switch (sema.owner.unwrap()) {
6525 .func => |func| func,
6526 .cau => return, // does nothing outside a function
6527 };
6528 ip.funcSetCold(func, is_cold);
65826529}
65836530
65846531fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
65856532 const pt = sema.pt;
65866533 const mod = pt.zcu;
65876534 const ip = &mod.intern_pool;
6588 if (sema.func_index == .none) return; // does nothing outside a function
6589 ip.funcSetDisableInstrumentation(sema.func_index);
6535 const func = switch (sema.owner.unwrap()) {
6536 .func => |func| func,
6537 .cau => return, // does nothing outside a function
6538 };
6539 ip.funcSetDisableInstrumentation(func);
65906540}
65916541
65926542fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
......@@ -6760,8 +6710,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
67606710 inst_data.get(sema.code),
67616711 .no_embedded_nulls,
67626712 );
6763 const decl_index = try sema.lookupIdentifier(block, src, decl_name);
6764 return sema.analyzeDeclRef(src, decl_index);
6713 const nav_index = try sema.lookupIdentifier(block, src, decl_name);
6714 return sema.analyzeNavRef(src, nav_index);
67656715}
67666716
67676717fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -6775,17 +6725,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
67756725 inst_data.get(sema.code),
67766726 .no_embedded_nulls,
67776727 );
6778 const decl = try sema.lookupIdentifier(block, src, decl_name);
6779 return sema.analyzeDeclVal(block, src, decl);
6728 const nav = try sema.lookupIdentifier(block, src, decl_name);
6729 return sema.analyzeNavVal(block, src, nav);
67806730}
67816731
6782fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {
6732fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.Nav.Index {
67836733 const pt = sema.pt;
67846734 const mod = pt.zcu;
67856735 var namespace = block.namespace;
67866736 while (true) {
6787 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {
6788 return decl_index;
6737 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |lookup| {
6738 assert(lookup.accessible);
6739 return lookup.nav;
67896740 }
67906741 namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break;
67916742 }
......@@ -6798,69 +6749,74 @@ fn lookupInNamespace(
67986749 sema: *Sema,
67996750 block: *Block,
68006751 src: LazySrcLoc,
6801 opt_namespace_index: InternPool.OptionalNamespaceIndex,
6752 namespace_index: InternPool.NamespaceIndex,
68026753 ident_name: InternPool.NullTerminatedString,
68036754 observe_usingnamespace: bool,
6804) CompileError!?InternPool.DeclIndex {
6755) CompileError!?struct {
6756 nav: InternPool.Nav.Index,
6757 /// If `false`, the declaration is in a different file and is not `pub`.
6758 /// We still return the declaration for better error reporting.
6759 accessible: bool,
6760} {
68056761 const pt = sema.pt;
6806 const mod = pt.zcu;
6762 const zcu = pt.zcu;
6763 const ip = &zcu.intern_pool;
68076764
6808 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 }
6765 const namespace = zcu.namespacePtr(namespace_index);
68146766
6815 if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) {
6816 const src_file = mod.namespacePtr(block.namespace).file_scope;
6767 const adapter: Zcu.Namespace.NameAdapter = .{ .zcu = zcu };
68176768
6769 const src_file = zcu.namespacePtr(block.namespace).file_scope;
6770
6771 if (observe_usingnamespace and (namespace.pub_usingnamespace.items.len != 0 or namespace.priv_usingnamespace.items.len != 0)) {
68186772 const gpa = sema.gpa;
6819 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{};
6773 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{};
68206774 defer checked_namespaces.deinit(gpa);
68216775
68226776 // Keep track of name conflicts for error notes.
6823 var candidates: std.ArrayListUnmanaged(InternPool.DeclIndex) = .{};
6777 var candidates: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{};
68246778 defer candidates.deinit(gpa);
68256779
6826 try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file);
6780 try checked_namespaces.put(gpa, namespace, {});
68276781 var check_i: usize = 0;
68286782
68296783 while (check_i < checked_namespaces.count()) : (check_i += 1) {
68306784 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.
6785 const Pass = enum { @"pub", priv };
6786 for ([2]Pass{ .@"pub", .priv }) |pass| {
6787 if (pass == .priv and src_file != check_ns.file_scope) {
68516788 continue;
68526789 }
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));
6790
6791 const decls, const usingnamespaces = switch (pass) {
6792 .@"pub" => .{ &check_ns.pub_decls, &check_ns.pub_usingnamespace },
6793 .priv => .{ &check_ns.priv_decls, &check_ns.priv_usingnamespace },
6794 };
6795
6796 if (decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6797 try candidates.append(gpa, nav_index);
6798 }
6799
6800 for (usingnamespaces.items) |sub_ns_nav| {
6801 try sema.ensureNavResolved(src, sub_ns_nav);
6802 const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.resolved.val);
6803 const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu));
6804 try checked_namespaces.put(gpa, sub_ns, {});
6805 }
68576806 }
68586807 }
68596808
6860 {
6809 ignore_self: {
6810 const skip_nav = switch (sema.owner.unwrap()) {
6811 .func => break :ignore_self,
6812 .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
6813 .none, .type => break :ignore_self,
6814 .nav => |nav| nav,
6815 },
6816 };
68616817 var i: usize = 0;
68626818 while (i < candidates.items.len) {
6863 if (candidates.items[i] == sema.owner_decl_index) {
6819 if (candidates.items[i] == skip_nav) {
68646820 _ = candidates.orderedRemove(i);
68656821 } else {
68666822 i += 1;
......@@ -6870,48 +6826,50 @@ fn lookupInNamespace(
68706826
68716827 switch (candidates.items.len) {
68726828 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);
6829 1 => return .{
6830 .nav = candidates.items[0],
6831 .accessible = true,
68916832 },
6833 else => return sema.failWithOwnedErrorMsg(block, msg: {
6834 const msg = try sema.errMsg(src, "ambiguous reference", .{});
6835 errdefer msg.destroy(gpa);
6836 for (candidates.items) |candidate| {
6837 try sema.errNote(zcu.navSrcLoc(candidate), msg, "declared here", .{});
6838 }
6839 break :msg msg;
6840 }),
68926841 }
6893 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {
6894 return decl_index;
6842 } else if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6843 return .{
6844 .nav = nav_index,
6845 .accessible = true,
6846 };
6847 } else if (namespace.priv_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6848 return .{
6849 .nav = nav_index,
6850 .accessible = src_file == namespace.file_scope,
6851 };
68956852 }
68966853
68976854 return null;
68986855}
68996856
6900fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6857fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedInst.Index {
69016858 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,
6859 const zcu = pt.zcu;
6860 const ip = &zcu.intern_pool;
6861 const func_val = try sema.resolveValue(func_inst) orelse return null;
6862 if (func_val.isUndef(zcu)) return null;
6863 const nav = switch (ip.indexToKey(func_val.toIntern())) {
6864 .@"extern" => |e| e.owner_nav,
6865 .func => |f| f.owner_nav,
69086866 .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,
6867 .nav => |nav| if (ptr.byte_offset == 0) nav else return null,
69106868 else => return null,
69116869 },
69126870 else => return null,
69136871 };
6914 return mod.declPtr(owner_decl_index);
6872 return ip.getNav(nav).srcInst(ip);
69156873}
69166874
69176875pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
......@@ -7100,11 +7058,12 @@ fn zirCall(
71007058 const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1);
71017059 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
71027060
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;
7061 switch (sema.owner.unwrap()) {
7062 .cau => input_is_error = false,
7063 .func => |owner_func| if (!mod.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) {
7064 // No errorable fn actually called; we have no error return trace
7065 input_is_error = false;
7066 },
71087067 }
71097068
71107069 if (block.ownerModule().error_tracing and
......@@ -7199,7 +7158,7 @@ fn checkCallArgumentCount(
71997158 return func_ty;
72007159 }
72017160
7202 const maybe_decl = try sema.funcDeclSrc(func);
7161 const maybe_func_inst = try sema.funcDeclSrcInst(func);
72037162 const member_str = if (member_fn) "member function " else "";
72047163 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
72057164 const msg = msg: {
......@@ -7215,9 +7174,9 @@ fn checkCallArgumentCount(
72157174 );
72167175 errdefer msg.destroy(sema.gpa);
72177176
7218 if (maybe_decl) |fn_decl| {
7177 if (maybe_func_inst) |func_inst| {
72197178 try sema.errNote(.{
7220 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
7179 .base_node_inst = func_inst,
72217180 .offset = LazySrcLoc.Offset.nodeOffset(0),
72227181 }, msg, "function declared here", .{});
72237182 }
......@@ -7544,7 +7503,7 @@ fn analyzeCall(
75447503 if (func_val.isUndef(mod))
75457504 return sema.failWithUseOfUndef(block, call_src);
75467505 if (cc == .Naked) {
7547 const maybe_decl = try sema.funcDeclSrc(func);
7506 const maybe_func_inst = try sema.funcDeclSrcInst(func);
75487507 const msg = msg: {
75497508 const msg = try sema.errMsg(
75507509 func_src,
......@@ -7553,8 +7512,8 @@ fn analyzeCall(
75537512 );
75547513 errdefer msg.destroy(sema.gpa);
75557514
7556 if (maybe_decl) |fn_decl| try sema.errNote(.{
7557 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
7515 if (maybe_func_inst) |func_inst| try sema.errNote(.{
7516 .base_node_inst = func_inst,
75587517 .offset = LazySrcLoc.Offset.nodeOffset(0),
75597518 }, msg, "function declared here", .{});
75607519 break :msg msg;
......@@ -7654,33 +7613,32 @@ fn analyzeCall(
76547613 .block_comptime_reason = comptime_reason,
76557614 });
76567615 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", .{
7616 .@"extern" => return sema.fail(block, call_src, "{s} call of extern function", .{
76587617 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
76597618 }),
76607619 .func => func_val.toIntern(),
76617620 .ptr => |ptr| blk: {
76627621 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))
7622 .nav => |nav_index| if (ptr.byte_offset == 0) {
7623 const nav = ip.getNav(nav_index);
7624 if (nav.isExtern(ip))
76677625 return sema.fail(block, call_src, "{s} call of extern function pointer", .{
7668 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7626 if (is_comptime_call) "comptime" else "inline",
76697627 });
7670 break :blk func_val_ptr;
7628 break :blk nav.status.resolved.val;
76717629 },
76727630 else => {},
76737631 }
76747632 assert(callee_ty.isPtrAtRuntime(mod));
76757633 return sema.fail(block, call_src, "{s} call of function pointer", .{
7676 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7634 if (is_comptime_call) "comptime" else "inline",
76777635 });
76787636 },
76797637 else => unreachable,
76807638 };
76817639 if (func_ty_info.is_var_args) {
76827640 return sema.fail(block, call_src, "{s} call of variadic function", .{
7683 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7641 if (is_comptime_call) "comptime" else "inline",
76847642 });
76857643 }
76867644
......@@ -7712,7 +7670,12 @@ fn analyzeCall(
77127670 };
77137671
77147672 const module_fn = mod.funcInfo(module_fn_index);
7715 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);
7673
7674 // This is not a function instance, so the function's `Nav` has a
7675 // `Cau` -- we don't need to check `generic_owner`.
7676 const fn_nav = ip.getNav(module_fn.owner_nav);
7677 const fn_cau_index = fn_nav.analysis_owner.unwrap().?;
7678 const fn_cau = ip.getCau(fn_cau_index);
77167679
77177680 // We effectively want a child Sema here, but can't literally do that, because we need AIR
77187681 // to be shared. InlineCallSema is a wrapper which handles this for us. While `ics` is in
......@@ -7720,7 +7683,7 @@ fn analyzeCall(
77207683 // whenever performing an operation where the difference matters.
77217684 var ics = InlineCallSema.init(
77227685 sema,
7723 fn_owner_decl.getFileScope(mod).zir,
7686 mod.cauFileScope(fn_cau_index).zir,
77247687 module_fn_index,
77257688 block.error_return_trace_index,
77267689 );
......@@ -7729,7 +7692,8 @@ fn analyzeCall(
77297692 var child_block: Block = .{
77307693 .parent = null,
77317694 .sema = sema,
7732 .namespace = fn_owner_decl.src_namespace,
7695 // The function body exists in the same namespace as the corresponding function declaration.
7696 .namespace = fn_cau.namespace,
77337697 .instructions = .{},
77347698 .label = null,
77357699 .inlining = &inlining,
......@@ -7740,8 +7704,8 @@ fn analyzeCall(
77407704 .runtime_cond = block.runtime_cond,
77417705 .runtime_loop = block.runtime_loop,
77427706 .runtime_index = block.runtime_index,
7743 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,
7744 .type_name_ctx = fn_owner_decl.name,
7707 .src_base_inst = fn_cau.zir_index,
7708 .type_name_ctx = fn_nav.fqn,
77457709 };
77467710
77477711 const merges = &child_block.inlining.?.merges;
......@@ -7759,7 +7723,7 @@ fn analyzeCall(
77597723 // comptime memory is mutated.
77607724 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
77617725
7762 const owner_info = mod.typeToFunc(fn_owner_decl.typeOf(mod)).?;
7726 const owner_info = mod.typeToFunc(Type.fromInterned(module_fn.ty)).?;
77637727 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);
77647728 var new_fn_info: InternPool.GetFuncTypeKey = .{
77657729 .param_types = new_param_types,
......@@ -7809,9 +7773,6 @@ fn analyzeCall(
78097773 _ = ics.callee();
78107774
78117775 if (!inlining.has_comptime_args) {
7812 if (module_fn.analysisUnordered(ip).state == .sema_failure)
7813 return error.AnalysisFail;
7814
78157776 var block_it = block;
78167777 while (block_it.inlining) |parent_inlining| {
78177778 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {
......@@ -7957,8 +7918,11 @@ fn analyzeCall(
79577918
79587919 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
79597920
7960 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7961 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);
7921 switch (sema.owner.unwrap()) {
7922 .cau => {},
7923 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7924 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
7925 },
79627926 }
79637927
79647928 if (try sema.resolveValue(func)) |func_val| {
......@@ -7994,7 +7958,7 @@ fn analyzeCall(
79947958 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
79957959 .func => break :skip_safety,
79967960 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
7997 .decl => |decl| if (!mod.declPtr(decl).isExtern(mod)) break :skip_safety,
7961 .nav => |nav| if (!ip.getNav(nav).isExtern(ip)) break :skip_safety,
79987962 else => {},
79997963 },
80007964 else => {},
......@@ -8018,18 +7982,18 @@ fn analyzeCall(
80187982
80197983fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
80207984 const pt = sema.pt;
8021 const mod = pt.zcu;
8022 const target = mod.getTarget();
8023 const backend = mod.comp.getZigBackend();
7985 const zcu = pt.zcu;
7986 const target = zcu.getTarget();
7987 const backend = zcu.comp.getZigBackend();
80247988 if (!target_util.supportsTailCall(target, backend)) {
80257989 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", .{
80267990 @tagName(backend), @tagName(target.cpu.arch),
80277991 });
80287992 }
8029 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);
8030 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {
7993 const owner_func_ty = Type.fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty);
7994 if (owner_func_ty.toIntern() != func_ty.toIntern()) {
80317995 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),
7996 func_ty.fmt(pt), owner_func_ty.fmt(pt),
80337997 });
80347998 }
80357999 _ = try block.addUnOp(.ret, result);
......@@ -8191,7 +8155,7 @@ fn instantiateGenericCall(
81918155 });
81928156 const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {
81938157 .func => func_val.toIntern(),
8194 .ptr => |ptr| zcu.declPtr(ptr.base_addr.decl).val.toIntern(),
8158 .ptr => |ptr| ip.getNav(ptr.base_addr.nav).status.resolved.val,
81958159 else => unreachable,
81968160 };
81978161 const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func;
......@@ -8207,10 +8171,10 @@ fn instantiateGenericCall(
82078171 // The actual monomorphization happens via adding `func_instance` to
82088172 // `InternPool`.
82098173
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;
8174 // Since we are looking at the generic owner here, it has a `Cau`.
8175 const fn_nav = ip.getNav(generic_owner_func.owner_nav);
8176 const fn_cau = ip.getCau(fn_nav.analysis_owner.unwrap().?);
8177 const fn_zir = zcu.namespacePtr(fn_cau.namespace).fileScope(zcu).zir;
82148178 const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip));
82158179
82168180 const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());
......@@ -8232,15 +8196,13 @@ fn instantiateGenericCall(
82328196 // We pass the generic callsite's owner decl here because whatever `Decl`
82338197 // dependencies are chased at this point should be attached to the
82348198 // 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,
8199 .owner = sema.owner,
8200 .func_index = sema.func_index,
82388201 // This may not be known yet, since the calling convention could be generic, but there
82398202 // should be no illegal instructions encountered while creating the function anyway.
82408203 .func_is_naked = false,
82418204 .fn_ret_ty = Type.void,
82428205 .fn_ret_ty_ies = null,
8243 .owner_func_index = .none,
82448206 .comptime_args = comptime_args,
82458207 .generic_owner = generic_owner,
82468208 .generic_call_src = call_src,
......@@ -8253,12 +8215,12 @@ fn instantiateGenericCall(
82538215 var child_block: Block = .{
82548216 .parent = null,
82558217 .sema = &child_sema,
8256 .namespace = namespace_index,
8218 .namespace = fn_cau.namespace,
82578219 .instructions = .{},
82588220 .inlining = null,
82598221 .is_comptime = true,
8260 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,
8261 .type_name_ctx = fn_owner_decl.name,
8222 .src_base_inst = fn_cau.zir_index,
8223 .type_name_ctx = fn_nav.fqn,
82628224 };
82638225 defer child_block.instructions.deinit(gpa);
82648226
......@@ -8421,10 +8383,11 @@ fn instantiateGenericCall(
84218383
84228384 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
84238385
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);
8386 switch (sema.owner.unwrap()) {
8387 .cau => {},
8388 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
8389 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
8390 },
84288391 }
84298392
84308393 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));
......@@ -9366,10 +9329,11 @@ fn zirFunc(
93669329 inferred_error_set: bool,
93679330) CompileError!Air.Inst.Ref {
93689331 const pt = sema.pt;
9369 const mod = pt.zcu;
9332 const zcu = pt.zcu;
9333 const ip = &zcu.intern_pool;
93709334 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
93719335 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9372 const target = mod.getTarget();
9336 const target = zcu.getTarget();
93739337 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
93749338
93759339 var extra_index = extra.end;
......@@ -9410,11 +9374,17 @@ fn zirFunc(
94109374 // the callconv based on whether it is exported. Otherwise, the callconv defaults
94119375 // to `.Unspecified`.
94129376 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;
9377 const func_decl_cau = if (sema.generic_owner != .none) cau: {
9378 const generic_owner_fn = zcu.funcInfo(sema.generic_owner);
9379 // The generic owner definitely has a `Cau` for the corresponding function declaration.
9380 const generic_owner_nav = ip.getNav(generic_owner_fn.owner_nav);
9381 break :cau generic_owner_nav.analysis_owner.unwrap().?;
9382 } else sema.owner.unwrap().cau;
9383 const fn_is_exported = exported: {
9384 const decl_inst = ip.getCau(func_decl_cau).zir_index.resolve(ip);
9385 const zir_decl = sema.code.getDeclaration(decl_inst)[0];
9386 break :exported zir_decl.flags.is_export;
9387 };
94189388 break :cc if (fn_is_exported) .C else .Unspecified;
94199389 } else .Unspecified;
94209390
......@@ -9613,10 +9583,10 @@ fn funcCommon(
96139583 is_noinline: bool,
96149584) CompileError!Air.Inst.Ref {
96159585 const pt = sema.pt;
9616 const mod = pt.zcu;
9586 const zcu = pt.zcu;
96179587 const gpa = sema.gpa;
9618 const target = mod.getTarget();
9619 const ip = &mod.intern_pool;
9588 const target = zcu.getTarget();
9589 const ip = &zcu.intern_pool;
96209590 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
96219591 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
96229592 const func_src = block.nodeOffset(src_node_offset);
......@@ -9664,8 +9634,8 @@ fn funcCommon(
96649634 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) {
96659635 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});
96669636 }
9667 if (!param_ty.isValidParamType(mod)) {
9668 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
9637 if (!param_ty.isValidParamType(zcu)) {
9638 const opaque_str = if (param_ty.zigTypeTag(zcu) == .Opaque) "opaque " else "";
96699639 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
96709640 opaque_str, param_ty.fmt(pt),
96719641 });
......@@ -9699,7 +9669,7 @@ fn funcCommon(
96999669 return sema.failWithOwnedErrorMsg(block, msg);
97009670 }
97019671 if (is_source_decl and !this_generic and is_noalias and
9702 !(param_ty.zigTypeTag(mod) == .Pointer or param_ty.isPtrLikeOptional(mod)))
9672 !(param_ty.zigTypeTag(zcu) == .Pointer or param_ty.isPtrLikeOptional(zcu)))
97039673 {
97049674 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
97059675 }
......@@ -9707,7 +9677,7 @@ fn funcCommon(
97079677 .Interrupt => if (target.cpu.arch.isX86()) {
97089678 const err_code_size = target.ptrBitWidth();
97099679 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", .{}),
9680 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", .{}),
97119681 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}),
97129682 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),
97139683 }
......@@ -9769,14 +9739,11 @@ fn funcCommon(
97699739 );
97709740 }
97719741
9772 // extern_func and func_decl functions take ownership of `sema.owner_decl`.
9773 sema.owner_decl.@"linksection" = switch (section) {
9742 const section_name: InternPool.OptionalNullTerminatedString = switch (section) {
97749743 .generic => .none,
97759744 .default => .none,
9776 .explicit => |section_name| section_name.toOptional(),
9745 .explicit => |name| name.toOptional(),
97779746 };
9778 sema.owner_decl.alignment = alignment orelse .none;
9779 sema.owner_decl.@"addrspace" = address_space orelse .generic;
97809747
97819748 if (inferred_error_set) {
97829749 assert(!is_extern);
......@@ -9784,7 +9751,7 @@ fn funcCommon(
97849751 if (!ret_poison)
97859752 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
97869753 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9787 .owner_decl = sema.owner_decl_index,
9754 .owner_nav = sema.getOwnerCauNav(),
97889755
97899756 .param_types = param_types,
97909757 .noalias_bits = noalias_bits,
......@@ -9804,6 +9771,13 @@ fn funcCommon(
98049771 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
98059772 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
98069773 });
9774 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
9775 ip.resolveNavValue(sema.getOwnerCauNav(), .{
9776 .val = func_index,
9777 .alignment = alignment orelse .none,
9778 .@"linksection" = section_name,
9779 .@"addrspace" = address_space orelse .generic,
9780 });
98079781 return finishFunc(
98089782 sema,
98099783 block,
......@@ -9846,11 +9820,20 @@ fn funcCommon(
98469820 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
98479821 .node_offset_lib_name = src_node_offset,
98489822 }), lib_name);
9849 const func_index = try ip.getExternFunc(gpa, pt.tid, .{
9823 const func_index = try pt.getExtern(.{
9824 .name = sema.getOwnerCauNavName(),
98509825 .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),
9826 .lib_name = try ip.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
9827 .is_const = true,
9828 .is_threadlocal = false,
9829 .is_weak_linkage = false,
9830 .alignment = alignment orelse .none,
9831 .@"addrspace" = address_space orelse .generic,
9832 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
9833 .owner_nav = undefined, // ignored by `getExtern`
98539834 });
9835 // Note that unlike function declaration, extern functions don't touch the
9836 // Sema's owner Cau's owner Nav. The alignment etc were passed above.
98549837 return finishFunc(
98559838 sema,
98569839 block,
......@@ -9872,7 +9855,7 @@ fn funcCommon(
98729855
98739856 if (has_body) {
98749857 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9875 .owner_decl = sema.owner_decl_index,
9858 .owner_nav = sema.getOwnerCauNav(),
98769859 .ty = func_ty,
98779860 .cc = cc,
98789861 .is_noinline = is_noinline,
......@@ -9882,6 +9865,13 @@ fn funcCommon(
98829865 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
98839866 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
98849867 });
9868 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
9869 ip.resolveNavValue(sema.getOwnerCauNav(), .{
9870 .val = func_index,
9871 .alignment = alignment orelse .none,
9872 .@"linksection" = section_name,
9873 .@"addrspace" = address_space orelse .generic,
9874 });
98859875 return finishFunc(
98869876 sema,
98879877 block,
......@@ -11179,7 +11169,7 @@ const SwitchProngAnalysis = struct {
1117911169 return block.addStructFieldVal(spa.operand, field_index, field_ty);
1118011170 }
1118111171 } else if (capture_byref) {
11182 return anonDeclRef(sema, item_val.toIntern());
11172 return sema.uavRef(item_val.toIntern());
1118311173 } else {
1118411174 return inline_case_capture;
1118511175 }
......@@ -13946,10 +13936,9 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1394613936 } });
1394713937 }
1394813938
13949 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)) {
13939 const namespace = container_type.getNamespace(mod).unwrap() orelse return .bool_false;
13940 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
13941 if (lookup.accessible) {
1395313942 return .bool_true;
1395413943 }
1395513944 }
......@@ -13981,9 +13970,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1398113970 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
1398213971 },
1398313972 };
13973 // TODO: register some kind of dependency on the file.
13974 // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to
13975 // trigger re-analysis later.
1398413976 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);
13977 return Air.internedToRef(zcu.fileRootType(result.file_index));
1398713978}
1398813979
1398913980fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -16970,7 +16961,7 @@ fn analyzeArithmetic(
1697016961 if (block.wantSafety() and want_safety and scalar_tag == .Int) {
1697116962 if (mod.backendSupportsFeature(.safety_checked_instructions)) {
1697216963 if (air_tag != air_tag_safe) {
16973 _ = try sema.preparePanicId(block, .integer_overflow);
16964 _ = try sema.preparePanicId(block, src, .integer_overflow);
1697416965 }
1697516966 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
1697616967 } else {
......@@ -17158,13 +17149,11 @@ fn zirAsm(
1715817149 if (is_volatile) {
1715917150 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});
1716017151 }
17161 try mod.addGlobalAssembly(sema.owner_decl_index, asm_source);
17152 try mod.addGlobalAssembly(sema.owner.unwrap().cau, asm_source);
1716217153 return .void_value;
1716317154 }
1716417155
17165 if (block.is_comptime) {
17166 try sema.requireRuntimeBlock(block, src, null);
17167 }
17156 try sema.requireRuntimeBlock(block, src, null);
1716817157
1716917158 var extra_i = extra.end;
1717017159 var output_type_bits = extra.data.output_type_bits;
......@@ -17646,18 +17635,17 @@ fn zirThis(
1764617635 block: *Block,
1764717636 extended: Zir.Inst.Extended.InstData,
1764817637) CompileError!Air.Inst.Ref {
17638 _ = extended;
1764917639 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);
17640 const namespace = pt.zcu.namespacePtr(block.namespace);
17641 return Air.internedToRef(namespace.owner_type);
1765417642}
1765517643
1765617644fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
1765717645 const pt = sema.pt;
1765817646 const mod = pt.zcu;
1765917647 const ip = &mod.intern_pool;
17660 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);
17648 const captures = Type.fromInterned(mod.namespacePtr(block.namespace).owner_type).getCaptures(mod);
1766117649
1766217650 const src_node: i32 = @bitCast(extended.operand);
1766317651 const src = block.nodeOffset(src_node);
......@@ -17665,8 +17653,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
1766517653 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {
1766617654 .@"comptime" => |index| return Air.internedToRef(index),
1766717655 .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),
17656 .nav_val => |nav| return sema.analyzeNavVal(block, src, nav),
17657 .nav_ref => |nav| return sema.analyzeNavRef(src, nav),
1767017658 };
1767117659
1767217660 // The comptime case is handled already above. Runtime case below.
......@@ -17764,20 +17752,19 @@ fn zirBuiltinSrc(
1776417752 block: *Block,
1776517753 extended: Zir.Inst.Extended.InstData,
1776617754) CompileError!Air.Inst.Ref {
17767 _ = block;
1776817755 const tracy = trace(@src());
1776917756 defer tracy.end();
1777017757
1777117758 const pt = sema.pt;
1777217759 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);
1777517760 const ip = &zcu.intern_pool;
17761 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
17762 const fn_name = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).name;
1777617763 const gpa = sema.gpa;
17777 const file_scope = fn_owner_decl.getFileScope(zcu);
17764 const file_scope = block.getFileScope(zcu);
1777817765
1777917766 const func_name_val = v: {
17780 const func_name_len = fn_owner_decl.name.length(ip);
17767 const func_name_len = fn_name.length(ip);
1778117768 const array_ty = try pt.intern(.{ .array_type = .{
1778217769 .len = func_name_len,
1778317770 .sentinel = .zero_u8,
......@@ -17787,11 +17774,11 @@ fn zirBuiltinSrc(
1778717774 .ty = .slice_const_u8_sentinel_0_type,
1778817775 .ptr = try pt.intern(.{ .ptr = .{
1778917776 .ty = .manyptr_const_u8_sentinel_0_type,
17790 .base_addr = .{ .anon_decl = .{
17777 .base_addr = .{ .uav = .{
1779117778 .orig_ty = .slice_const_u8_sentinel_0_type,
1779217779 .val = try pt.intern(.{ .aggregate = .{
1779317780 .ty = array_ty,
17794 .storage = .{ .bytes = fn_owner_decl.name.toString() },
17781 .storage = .{ .bytes = fn_name.toString() },
1779517782 } }),
1779617783 } },
1779717784 .byte_offset = 0,
......@@ -17811,7 +17798,7 @@ fn zirBuiltinSrc(
1781117798 .ty = .slice_const_u8_sentinel_0_type,
1781217799 .ptr = try pt.intern(.{ .ptr = .{
1781317800 .ty = .manyptr_const_u8_sentinel_0_type,
17814 .base_addr = .{ .anon_decl = .{
17801 .base_addr = .{ .uav = .{
1781517802 .orig_ty = .slice_const_u8_sentinel_0_type,
1781617803 .val = try pt.intern(.{ .aggregate = .{
1781717804 .ty = array_ty,
......@@ -17837,7 +17824,7 @@ fn zirBuiltinSrc(
1783717824 .ty = .slice_const_u8_sentinel_0_type,
1783817825 .ptr = try pt.intern(.{ .ptr = .{
1783917826 .ty = .manyptr_const_u8_sentinel_0_type,
17840 .base_addr = .{ .anon_decl = .{
17827 .base_addr = .{ .uav = .{
1784117828 .orig_ty = .slice_const_u8_sentinel_0_type,
1784217829 .val = try pt.intern(.{ .aggregate = .{
1784317830 .ty = array_ty,
......@@ -17902,25 +17889,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1790217889 .val = .void_value,
1790317890 } }))),
1790417891 .Fn => {
17905 const fn_info_decl_index = (try sema.namespaceLookup(
17892 const fn_info_nav = try sema.namespaceLookup(
1790617893 block,
1790717894 src,
1790817895 type_info_ty.getNamespaceIndex(mod),
1790917896 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();
17897 ) orelse @panic("std.builtin.Type is corrupt");
17898 try sema.ensureNavResolved(src, fn_info_nav);
17899 const fn_info_ty = Type.fromInterned(ip.getNav(fn_info_nav).status.resolved.val);
1791417900
17915 const param_info_decl_index = (try sema.namespaceLookup(
17901 const param_info_nav = try sema.namespaceLookup(
1791617902 block,
1791717903 src,
1791817904 fn_info_ty.getNamespaceIndex(mod),
1791917905 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();
17906 ) orelse @panic("std.builtin.Type is corrupt");
17907 try sema.ensureNavResolved(src, param_info_nav);
17908 const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val);
1792417909
1792517910 const func_ty_info = mod.typeToFunc(ty).?;
1792617911 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
......@@ -17972,7 +17957,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1797217957 .ty = slice_ty,
1797317958 .ptr = try pt.intern(.{ .ptr = .{
1797417959 .ty = manyptr_ty,
17975 .base_addr = .{ .anon_decl = .{
17960 .base_addr = .{ .uav = .{
1797617961 .orig_ty = manyptr_ty,
1797717962 .val = new_decl_val,
1797817963 } },
......@@ -18014,15 +17999,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1801417999 } })));
1801518000 },
1801618001 .Int => {
18017 const int_info_decl_index = (try sema.namespaceLookup(
18002 const int_info_nav = try sema.namespaceLookup(
1801818003 block,
1801918004 src,
1802018005 type_info_ty.getNamespaceIndex(mod),
1802118006 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();
18007 ) orelse @panic("std.builtin.Type is corrupt");
18008 try sema.ensureNavResolved(src, int_info_nav);
18009 const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val);
1802618010
1802718011 const signedness_ty = try pt.getBuiltinType("Signedness");
1802818012 const info = ty.intInfo(mod);
......@@ -18042,15 +18026,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1804218026 } })));
1804318027 },
1804418028 .Float => {
18045 const float_info_decl_index = (try sema.namespaceLookup(
18029 const float_info_nav = try sema.namespaceLookup(
1804618030 block,
1804718031 src,
1804818032 type_info_ty.getNamespaceIndex(mod),
1804918033 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();
18034 ) orelse @panic("std.builtin.Type is corrupt");
18035 try sema.ensureNavResolved(src, float_info_nav);
18036 const float_info_ty = Type.fromInterned(ip.getNav(float_info_nav).status.resolved.val);
1805418037
1805518038 const field_vals = .{
1805618039 // bits: u16,
......@@ -18074,26 +18057,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1807418057
1807518058 const addrspace_ty = try pt.getBuiltinType("AddressSpace");
1807618059 const pointer_ty = t: {
18077 const decl_index = (try sema.namespaceLookup(
18060 const nav = try sema.namespaceLookup(
1807818061 block,
1807918062 src,
1808018063 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
1808118064 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();
18065 ) orelse @panic("std.builtin.Type is corrupt");
18066 try sema.ensureNavResolved(src, nav);
18067 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1808618068 };
1808718069 const ptr_size_ty = t: {
18088 const decl_index = (try sema.namespaceLookup(
18070 const nav = try sema.namespaceLookup(
1808918071 block,
1809018072 src,
1809118073 pointer_ty.getNamespaceIndex(mod),
1809218074 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();
18075 ) orelse @panic("std.builtin.Type is corrupt");
18076 try sema.ensureNavResolved(src, nav);
18077 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1809718078 };
1809818079
1809918080 const field_values = .{
......@@ -18128,15 +18109,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1812818109 },
1812918110 .Array => {
1813018111 const array_field_ty = t: {
18131 const array_field_ty_decl_index = (try sema.namespaceLookup(
18112 const nav = try sema.namespaceLookup(
1813218113 block,
1813318114 src,
1813418115 type_info_ty.getNamespaceIndex(mod),
1813518116 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();
18117 ) orelse @panic("std.builtin.Type is corrupt");
18118 try sema.ensureNavResolved(src, nav);
18119 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1814018120 };
1814118121
1814218122 const info = ty.arrayInfo(mod);
......@@ -18159,15 +18139,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1815918139 },
1816018140 .Vector => {
1816118141 const vector_field_ty = t: {
18162 const vector_field_ty_decl_index = (try sema.namespaceLookup(
18142 const nav = try sema.namespaceLookup(
1816318143 block,
1816418144 src,
1816518145 type_info_ty.getNamespaceIndex(mod),
1816618146 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();
18147 ) orelse @panic("std.builtin.Type is corrupt");
18148 try sema.ensureNavResolved(src, nav);
18149 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1817118150 };
1817218151
1817318152 const info = ty.arrayInfo(mod);
......@@ -18188,15 +18167,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1818818167 },
1818918168 .Optional => {
1819018169 const optional_field_ty = t: {
18191 const optional_field_ty_decl_index = (try sema.namespaceLookup(
18170 const nav = try sema.namespaceLookup(
1819218171 block,
1819318172 src,
1819418173 type_info_ty.getNamespaceIndex(mod),
1819518174 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();
18175 ) orelse @panic("std.builtin.Type is corrupt");
18176 try sema.ensureNavResolved(src, nav);
18177 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1820018178 };
1820118179
1820218180 const field_values = .{
......@@ -18215,15 +18193,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1821518193 .ErrorSet => {
1821618194 // Get the Error type
1821718195 const error_field_ty = t: {
18218 const set_field_ty_decl_index = (try sema.namespaceLookup(
18196 const nav = try sema.namespaceLookup(
1821918197 block,
1822018198 src,
1822118199 type_info_ty.getNamespaceIndex(mod),
1822218200 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();
18201 ) orelse @panic("std.builtin.Type is corrupt");
18202 try sema.ensureNavResolved(src, nav);
18203 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1822718204 };
1822818205
1822918206 // Build our list of Error values
......@@ -18251,7 +18228,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1825118228 .ty = .slice_const_u8_sentinel_0_type,
1825218229 .ptr = try pt.intern(.{ .ptr = .{
1825318230 .ty = .manyptr_const_u8_sentinel_0_type,
18254 .base_addr = .{ .anon_decl = .{
18231 .base_addr = .{ .uav = .{
1825518232 .val = new_decl_val,
1825618233 .orig_ty = .slice_const_u8_sentinel_0_type,
1825718234 } },
......@@ -18298,7 +18275,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1829818275 .ty = slice_errors_ty.toIntern(),
1829918276 .ptr = try pt.intern(.{ .ptr = .{
1830018277 .ty = manyptr_errors_ty,
18301 .base_addr = .{ .anon_decl = .{
18278 .base_addr = .{ .uav = .{
1830218279 .orig_ty = manyptr_errors_ty,
1830318280 .val = new_decl_val,
1830418281 } },
......@@ -18321,15 +18298,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1832118298 },
1832218299 .ErrorUnion => {
1832318300 const error_union_field_ty = t: {
18324 const error_union_field_ty_decl_index = (try sema.namespaceLookup(
18301 const nav = try sema.namespaceLookup(
1832518302 block,
1832618303 src,
1832718304 type_info_ty.getNamespaceIndex(mod),
1832818305 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();
18306 ) orelse @panic("std.builtin.Type is corrupt");
18307 try sema.ensureNavResolved(src, nav);
18308 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1833318309 };
1833418310
1833518311 const field_values = .{
......@@ -18351,15 +18327,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1835118327 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1835218328
1835318329 const enum_field_ty = t: {
18354 const enum_field_ty_decl_index = (try sema.namespaceLookup(
18330 const nav = try sema.namespaceLookup(
1835518331 block,
1835618332 src,
1835718333 type_info_ty.getNamespaceIndex(mod),
1835818334 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();
18335 ) orelse @panic("std.builtin.Type is corrupt");
18336 try sema.ensureNavResolved(src, nav);
18337 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1836318338 };
1836418339
1836518340 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
......@@ -18392,7 +18367,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1839218367 .ty = .slice_const_u8_sentinel_0_type,
1839318368 .ptr = try pt.intern(.{ .ptr = .{
1839418369 .ty = .manyptr_const_u8_sentinel_0_type,
18395 .base_addr = .{ .anon_decl = .{
18370 .base_addr = .{ .uav = .{
1839618371 .val = new_decl_val,
1839718372 .orig_ty = .slice_const_u8_sentinel_0_type,
1839818373 } },
......@@ -18435,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1843518410 .ty = slice_ty,
1843618411 .ptr = try pt.intern(.{ .ptr = .{
1843718412 .ty = manyptr_ty,
18438 .base_addr = .{ .anon_decl = .{
18413 .base_addr = .{ .uav = .{
1843918414 .val = new_decl_val,
1844018415 .orig_ty = manyptr_ty,
1844118416 } },
......@@ -18445,18 +18420,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1844518420 } });
1844618421 };
1844718422
18448 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace);
18423 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
1844918424
1845018425 const type_enum_ty = t: {
18451 const type_enum_ty_decl_index = (try sema.namespaceLookup(
18426 const nav = try sema.namespaceLookup(
1845218427 block,
1845318428 src,
1845418429 type_info_ty.getNamespaceIndex(mod),
1845518430 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();
18431 ) orelse @panic("std.builtin.Type is corrupt");
18432 try sema.ensureNavResolved(src, nav);
18433 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1846018434 };
1846118435
1846218436 const field_values = .{
......@@ -18480,27 +18454,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1848018454 },
1848118455 .Union => {
1848218456 const type_union_ty = t: {
18483 const type_union_ty_decl_index = (try sema.namespaceLookup(
18457 const nav = try sema.namespaceLookup(
1848418458 block,
1848518459 src,
1848618460 type_info_ty.getNamespaceIndex(mod),
1848718461 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();
18462 ) orelse @panic("std.builtin.Type is corrupt");
18463 try sema.ensureNavResolved(src, nav);
18464 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1849218465 };
1849318466
1849418467 const union_field_ty = t: {
18495 const union_field_ty_decl_index = (try sema.namespaceLookup(
18468 const nav = try sema.namespaceLookup(
1849618469 block,
1849718470 src,
1849818471 type_info_ty.getNamespaceIndex(mod),
1849918472 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();
18473 ) orelse @panic("std.builtin.Type is corrupt");
18474 try sema.ensureNavResolved(src, nav);
18475 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1850418476 };
1850518477
1850618478 try ty.resolveLayout(pt); // Getting alignment requires type layout
......@@ -18528,7 +18500,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1852818500 .ty = .slice_const_u8_sentinel_0_type,
1852918501 .ptr = try pt.intern(.{ .ptr = .{
1853018502 .ty = .manyptr_const_u8_sentinel_0_type,
18531 .base_addr = .{ .anon_decl = .{
18503 .base_addr = .{ .uav = .{
1853218504 .val = new_decl_val,
1853318505 .orig_ty = .slice_const_u8_sentinel_0_type,
1853418506 } },
......@@ -18579,7 +18551,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1857918551 .ty = slice_ty,
1858018552 .ptr = try pt.intern(.{ .ptr = .{
1858118553 .ty = manyptr_ty,
18582 .base_addr = .{ .anon_decl = .{
18554 .base_addr = .{ .uav = .{
1858318555 .orig_ty = manyptr_ty,
1858418556 .val = new_decl_val,
1858518557 } },
......@@ -18589,7 +18561,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1858918561 } });
1859018562 };
1859118563
18592 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
18564 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod).toOptional());
1859318565
1859418566 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
1859518567 .ty = (try pt.optionalType(.type_type)).toIntern(),
......@@ -18597,15 +18569,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1859718569 } });
1859818570
1859918571 const container_layout_ty = t: {
18600 const decl_index = (try sema.namespaceLookup(
18572 const nav = try sema.namespaceLookup(
1860118573 block,
1860218574 src,
1860318575 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
1860418576 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();
18577 ) orelse @panic("std.builtin.Type is corrupt");
18578 try sema.ensureNavResolved(src, nav);
18579 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1860918580 };
1861018581
1861118582 const field_values = .{
......@@ -18630,27 +18601,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1863018601 },
1863118602 .Struct => {
1863218603 const type_struct_ty = t: {
18633 const type_struct_ty_decl_index = (try sema.namespaceLookup(
18604 const nav = try sema.namespaceLookup(
1863418605 block,
1863518606 src,
1863618607 type_info_ty.getNamespaceIndex(mod),
1863718608 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();
18609 ) orelse @panic("std.builtin.Type is corrupt");
18610 try sema.ensureNavResolved(src, nav);
18611 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1864218612 };
1864318613
1864418614 const struct_field_ty = t: {
18645 const struct_field_ty_decl_index = (try sema.namespaceLookup(
18615 const nav = try sema.namespaceLookup(
1864618616 block,
1864718617 src,
1864818618 type_info_ty.getNamespaceIndex(mod),
1864918619 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();
18620 ) orelse @panic("std.builtin.Type is corrupt");
18621 try sema.ensureNavResolved(src, nav);
18622 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1865418623 };
1865518624
1865618625 try ty.resolveLayout(pt); // Getting alignment requires type layout
......@@ -18683,7 +18652,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1868318652 .ty = .slice_const_u8_sentinel_0_type,
1868418653 .ptr = try pt.intern(.{ .ptr = .{
1868518654 .ty = .manyptr_const_u8_sentinel_0_type,
18686 .base_addr = .{ .anon_decl = .{
18655 .base_addr = .{ .uav = .{
1868718656 .val = new_decl_val,
1868818657 .orig_ty = .slice_const_u8_sentinel_0_type,
1868918658 } },
......@@ -18747,7 +18716,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1874718716 .ty = .slice_const_u8_sentinel_0_type,
1874818717 .ptr = try pt.intern(.{ .ptr = .{
1874918718 .ty = .manyptr_const_u8_sentinel_0_type,
18750 .base_addr = .{ .anon_decl = .{
18719 .base_addr = .{ .uav = .{
1875118720 .val = new_decl_val,
1875218721 .orig_ty = .slice_const_u8_sentinel_0_type,
1875318722 } },
......@@ -18809,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1880918778 .ty = slice_ty,
1881018779 .ptr = try pt.intern(.{ .ptr = .{
1881118780 .ty = manyptr_ty,
18812 .base_addr = .{ .anon_decl = .{
18781 .base_addr = .{ .uav = .{
1881318782 .orig_ty = manyptr_ty,
1881418783 .val = new_decl_val,
1881518784 } },
......@@ -18819,7 +18788,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1881918788 } });
1882018789 };
1882118790
18822 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
18791 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(mod));
1882318792
1882418793 const backing_integer_val = try pt.intern(.{ .opt = .{
1882518794 .ty = (try pt.optionalType(.type_type)).toIntern(),
......@@ -18830,15 +18799,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1883018799 } });
1883118800
1883218801 const container_layout_ty = t: {
18833 const decl_index = (try sema.namespaceLookup(
18802 const nav = try sema.namespaceLookup(
1883418803 block,
1883518804 src,
1883618805 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
1883718806 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();
18807 ) orelse @panic("std.builtin.Type is corrupt");
18808 try sema.ensureNavResolved(src, nav);
18809 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1884218810 };
1884318811
1884418812 const layout = ty.containerLayout(mod);
......@@ -18866,19 +18834,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1886618834 },
1886718835 .Opaque => {
1886818836 const type_opaque_ty = t: {
18869 const type_opaque_ty_decl_index = (try sema.namespaceLookup(
18837 const nav = try sema.namespaceLookup(
1887018838 block,
1887118839 src,
1887218840 type_info_ty.getNamespaceIndex(mod),
1887318841 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();
18842 ) orelse @panic("std.builtin.Type is corrupt");
18843 try sema.ensureNavResolved(src, nav);
18844 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1887818845 };
1887918846
1888018847 try ty.resolveFields(pt);
18881 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
18848 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(mod));
1888218849
1888318850 const field_values = .{
1888418851 // decls: []const Declaration,
......@@ -18906,19 +18873,19 @@ fn typeInfoDecls(
1890618873 opt_namespace: InternPool.OptionalNamespaceIndex,
1890718874) CompileError!InternPool.Index {
1890818875 const pt = sema.pt;
18909 const mod = pt.zcu;
18876 const zcu = pt.zcu;
18877 const ip = &zcu.intern_pool;
1891018878 const gpa = sema.gpa;
1891118879
1891218880 const declaration_ty = t: {
18913 const declaration_ty_decl_index = (try sema.namespaceLookup(
18881 const nav = try sema.namespaceLookup(
1891418882 block,
1891518883 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();
18884 type_info_ty.getNamespaceIndex(zcu),
18885 try ip.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
18886 ) orelse @panic("std.builtin.Type is corrupt");
18887 try sema.ensureNavResolved(src, nav);
18888 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
1892218889 };
1892318890
1892418891 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
......@@ -18927,7 +18894,7 @@ fn typeInfoDecls(
1892718894 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
1892818895 defer seen_namespaces.deinit();
1892918896
18930 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
18897 try sema.typeInfoNamespaceDecls(block, src, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
1893118898
1893218899 const array_decl_ty = try pt.arrayType(.{
1893318900 .len = decl_vals.items.len,
......@@ -18944,12 +18911,12 @@ fn typeInfoDecls(
1894418911 .is_const = true,
1894518912 },
1894618913 })).toIntern();
18947 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();
18914 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern();
1894818915 return try pt.intern(.{ .slice = .{
1894918916 .ty = slice_ty,
1895018917 .ptr = try pt.intern(.{ .ptr = .{
1895118918 .ty = manyptr_ty,
18952 .base_addr = .{ .anon_decl = .{
18919 .base_addr = .{ .uav = .{
1895318920 .orig_ty = manyptr_ty,
1895418921 .val = new_decl_val,
1895518922 } },
......@@ -18962,59 +18929,54 @@ fn typeInfoDecls(
1896218929fn typeInfoNamespaceDecls(
1896318930 sema: *Sema,
1896418931 block: *Block,
18932 src: LazySrcLoc,
1896518933 opt_namespace_index: InternPool.OptionalNamespaceIndex,
1896618934 declaration_ty: Type,
1896718935 decl_vals: *std.ArrayList(InternPool.Index),
1896818936 seen_namespaces: *std.AutoHashMap(*Namespace, void),
1896918937) !void {
1897018938 const pt = sema.pt;
18971 const mod = pt.zcu;
18972 const ip = &mod.intern_pool;
18939 const zcu = pt.zcu;
18940 const ip = &zcu.intern_pool;
1897318941
1897418942 const namespace_index = opt_namespace_index.unwrap() orelse return;
18975 const namespace = mod.namespacePtr(namespace_index);
18943 const namespace = zcu.namespacePtr(namespace_index);
1897618944
1897718945 const gop = try seen_namespaces.getOrPut(namespace);
1897818946 if (gop.found_existing) return;
1897918947
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,
18948 for (namespace.pub_decls.keys()) |nav| {
18949 const name = ip.getNav(nav).name;
18950 const name_val = name_val: {
18951 const name_len = name.length(ip);
18952 const array_ty = try pt.arrayType(.{
18953 .len = name_len,
1899518954 .sentinel = .zero_u8,
1899618955 .child = .u8_type,
1899718956 });
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(),
18957 const array_val = try pt.intern(.{ .aggregate = .{
18958 .ty = array_ty.toIntern(),
18959 .storage = .{ .bytes = name.toString() },
1901318960 } });
18961 break :name_val try pt.intern(.{
18962 .slice = .{
18963 .ty = .slice_const_u8_sentinel_0_type, // [:0]const u8
18964 .ptr = try pt.intern(.{
18965 .ptr = .{
18966 .ty = .manyptr_const_u8_sentinel_0_type, // [*:0]const u8
18967 .base_addr = .{ .uav = .{
18968 .orig_ty = .slice_const_u8_sentinel_0_type,
18969 .val = array_val,
18970 } },
18971 .byte_offset = 0,
18972 },
18973 }),
18974 .len = (try pt.intValue(Type.usize, name_len)).toIntern(),
18975 },
18976 });
1901418977 };
19015
19016 const fields = .{
19017 //name: [:0]const u8,
18978 const fields = [_]InternPool.Index{
18979 // name: [:0]const u8,
1901818980 name_val,
1901918981 };
1902018982 try decl_vals.append(try pt.intern(.{ .aggregate = .{
......@@ -19022,6 +18984,17 @@ fn typeInfoNamespaceDecls(
1902218984 .storage = .{ .elems = &fields },
1902318985 } }));
1902418986 }
18987
18988 for (namespace.pub_usingnamespace.items) |nav| {
18989 if (ip.getNav(nav).analysis_owner.unwrap()) |cau| {
18990 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .cau = cau }))) {
18991 continue;
18992 }
18993 }
18994 try sema.ensureNavResolved(src, nav);
18995 const namespace_ty = Type.fromInterned(ip.getNav(nav).status.resolved.val);
18996 try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces);
18997 }
1902518998}
1902618999
1902719000fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -19906,7 +19879,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
1990619879 return;
1990719880 }
1990819881
19909 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
19882 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return;
1991019883 if (!start_block.ownerModule().error_tracing) return;
1991119884
1991219885 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
......@@ -19928,7 +19901,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
1992819901 },
1992919902 else => if (ip.isInferredErrorSetType(err_set_ty)) {
1993019903 const ies = sema.fn_ret_ty_ies.?;
19931 assert(ies.func == sema.func_index);
19904 assert(ies.func == sema.owner.unwrap().func);
1993219905 try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand));
1993319906 },
1993419907 }
......@@ -20232,7 +20205,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
2023220205
2023320206 if (is_byref) {
2023420207 const init_val = (try sema.resolveValue(init_ref)).?;
20235 return anonDeclRef(sema, init_val.toIntern());
20208 return sema.uavRef(init_val.toIntern());
2023620209 } else {
2023720210 return init_ref;
2023820211 }
......@@ -21056,7 +21029,7 @@ fn arrayInitAnon(
2105621029}
2105721030
2105821031fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
21059 return if (is_ref) anonDeclRef(sema, val) else Air.internedToRef(val);
21032 return if (is_ref) sema.uavRef(val) else Air.internedToRef(val);
2106021033}
2106121034
2106221035fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -21163,16 +21136,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2116321136 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2116421137 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2116521138
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);
21139 switch (sema.owner.unwrap()) {
21140 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
21141 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21142 },
21143 .cau => {},
2117121144 }
21172 return Air.internedToRef((try pt.intern(.{ .opt = .{
21145 return Air.internedToRef(try pt.intern(.{ .opt = .{
2117321146 .ty = opt_ptr_stack_trace_ty.toIntern(),
2117421147 .val = .none,
21175 } })));
21148 } }));
2117621149}
2117721150
2117821151fn zirFrame(
......@@ -21369,24 +21342,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2136921342 const operand = try sema.resolveInst(inst_data.operand);
2137021343 const operand_ty = sema.typeOf(operand);
2137121344 const pt = sema.pt;
21372 const mod = pt.zcu;
21373 const ip = &mod.intern_pool;
21345 const zcu = pt.zcu;
21346 const ip = &zcu.intern_pool;
2137421347
2137521348 try operand_ty.resolveLayout(pt);
21376 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
21349 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
2137721350 .EnumLiteral => {
2137821351 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
2137921352 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
2138021353 return sema.addNullTerminatedStrLit(tag_name);
2138121354 },
2138221355 .Enum => operand_ty,
21383 .Union => operand_ty.unionTagType(mod) orelse
21356 .Union => operand_ty.unionTagType(zcu) orelse
2138421357 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),
2138521358 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
2138621359 operand_ty.fmt(pt),
2138721360 }),
2138821361 };
21389 if (enum_ty.enumFieldCount(mod) == 0) {
21362 if (enum_ty.enumFieldCount(zcu) == 0) {
2139021363 // TODO I don't think this is the correct way to handle this but
2139121364 // it prevents a crash.
2139221365 // https://github.com/ziglang/zig/issues/15909
......@@ -21394,26 +21367,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2139421367 enum_ty.fmt(pt),
2139521368 });
2139621369 }
21397 const enum_decl_index = enum_ty.getOwnerDecl(mod);
2139821370 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
2139921371 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
21400 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
21372 const field_index = enum_ty.enumTagFieldIndex(val, zcu) orelse {
2140121373 const msg = msg: {
2140221374 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),
21375 val.fmtValueSema(pt, sema), enum_ty.fmt(pt),
2140421376 });
2140521377 errdefer msg.destroy(sema.gpa);
21406 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});
21378 try sema.errNote(enum_ty.srcLoc(zcu), msg, "declared here", .{});
2140721379 break :msg msg;
2140821380 };
2140921381 return sema.failWithOwnedErrorMsg(block, msg);
2141021382 };
2141121383 // TODO: write something like getCoercedInts to avoid needing to dupe
21412 const field_name = enum_ty.enumFieldName(field_index, mod);
21384 const field_name = enum_ty.enumFieldName(field_index, zcu);
2141321385 return sema.addNullTerminatedStrLit(field_name);
2141421386 }
2141521387 try sema.requireRuntimeBlock(block, src, operand_src);
21416 if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) {
21388 if (block.wantSafety() and zcu.backendSupportsFeature(.is_named_enum_value)) {
2141721389 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
2141821390 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
2141921391 }
......@@ -21810,7 +21782,6 @@ fn zirReify(
2181021782 }
2181121783
2181221784 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{
21813 .has_namespace = false,
2181421785 .key = .{ .reified = .{
2181521786 .zir_index = try block.trackZir(inst),
2181621787 } },
......@@ -21820,19 +21791,21 @@ fn zirReify(
2182021791 };
2182121792 errdefer wip_ty.cancel(ip, pt.tid);
2182221793
21823 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21794 wip_ty.setName(ip, try sema.createTypeName(
2182421795 block,
21825 Value.fromInterned(wip_ty.index),
2182621796 name_strategy,
2182721797 "opaque",
2182821798 inst,
21829 );
21830 mod.declPtr(new_decl_index).owns_tv = true;
21831 errdefer pt.abortAnonDecl(new_decl_index);
21799 wip_ty.index,
21800 ));
2183221801
21833 try pt.finalizeAnonDecl(new_decl_index);
21802 const new_namespace_index = try pt.createNamespace(.{
21803 .parent = block.namespace.toOptional(),
21804 .owner_type = wip_ty.index,
21805 .file_scope = block.getFileScopeIndex(mod),
21806 });
2183421807
21835 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
21808 return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index));
2183621809 },
2183721810 .Union => {
2183821811 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
......@@ -22001,13 +21974,14 @@ fn reifyEnum(
2200121974 });
2200221975 }
2200321976
21977 const tracked_inst = try block.trackZir(inst);
21978
2200421979 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
22005 .has_namespace = false,
2200621980 .has_values = true,
2200721981 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
2200821982 .fields_len = fields_len,
2200921983 .key = .{ .reified = .{
22010 .zir_index = try block.trackZir(inst),
21984 .zir_index = tracked_inst,
2201121985 .type_hash = hasher.final(),
2201221986 } },
2201321987 })) {
......@@ -22020,17 +21994,23 @@ fn reifyEnum(
2202021994 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
2202121995 }
2202221996
22023 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21997 wip_ty.setName(ip, try sema.createTypeName(
2202421998 block,
22025 Value.fromInterned(wip_ty.index),
2202621999 name_strategy,
2202722000 "enum",
2202822001 inst,
22029 );
22030 mod.declPtr(new_decl_index).owns_tv = true;
22031 errdefer pt.abortAnonDecl(new_decl_index);
22002 wip_ty.index,
22003 ));
2203222004
22033 wip_ty.prepare(ip, new_decl_index, .none);
22005 const new_namespace_index = try pt.createNamespace(.{
22006 .parent = block.namespace.toOptional(),
22007 .owner_type = wip_ty.index,
22008 .file_scope = block.getFileScopeIndex(mod),
22009 });
22010
22011 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index);
22012
22013 wip_ty.prepare(ip, new_cau_index, new_namespace_index);
2203422014 wip_ty.setTagTy(ip, tag_ty.toIntern());
2203522015
2203622016 for (0..fields_len) |field_idx| {
......@@ -22076,7 +22056,6 @@ fn reifyEnum(
2207622056 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
2207722057 }
2207822058
22079 try pt.finalizeAnonDecl(new_decl_index);
2208022059 return Air.internedToRef(wip_ty.index);
2208122060}
2208222061
......@@ -22134,6 +22113,8 @@ fn reifyUnion(
2213422113 }
2213522114 }
2213622115
22116 const tracked_inst = try block.trackZir(inst);
22117
2213722118 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
2213822119 .flags = .{
2213922120 .layout = layout,
......@@ -22152,13 +22133,12 @@ fn reifyUnion(
2215222133 .assumed_pointer_aligned = false,
2215322134 .alignment = .none,
2215422135 },
22155 .has_namespace = false,
2215622136 .fields_len = fields_len,
2215722137 .enum_tag_ty = .none, // set later because not yet validated
2215822138 .field_types = &.{}, // set later
2215922139 .field_aligns = &.{}, // set later
2216022140 .key = .{ .reified = .{
22161 .zir_index = try block.trackZir(inst),
22141 .zir_index = tracked_inst,
2216222142 .type_hash = hasher.final(),
2216322143 } },
2216422144 })) {
......@@ -22167,15 +22147,14 @@ fn reifyUnion(
2216722147 };
2216822148 errdefer wip_ty.cancel(ip, pt.tid);
2216922149
22170 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22150 const type_name = try sema.createTypeName(
2217122151 block,
22172 Value.fromInterned(wip_ty.index),
2217322152 name_strategy,
2217422153 "union",
2217522154 inst,
22155 wip_ty.index,
2217622156 );
22177 mod.declPtr(new_decl_index).owns_tv = true;
22178 errdefer pt.abortAnonDecl(new_decl_index);
22157 wip_ty.setName(ip, type_name);
2217922158
2218022159 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
2218122160 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
......@@ -22268,7 +22247,7 @@ fn reifyUnion(
2226822247 }
2226922248 }
2227022249
22271 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));
22250 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), wip_ty.index, type_name);
2227222251 break :tag_ty .{ enum_tag_ty, false };
2227322252 };
2227422253 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
......@@ -22315,10 +22294,17 @@ fn reifyUnion(
2231522294 loaded_union.setTagType(ip, enum_tag_ty);
2231622295 loaded_union.setStatus(ip, .have_field_types);
2231722296
22318 try pt.finalizeAnonDecl(new_decl_index);
22297 const new_namespace_index = try pt.createNamespace(.{
22298 .parent = block.namespace.toOptional(),
22299 .owner_type = wip_ty.index,
22300 .file_scope = block.getFileScopeIndex(mod),
22301 });
22302
22303 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index);
22304
2231922305 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));
22306 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22307 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
2232222308}
2232322309
2232422310fn reifyStruct(
......@@ -22399,6 +22385,8 @@ fn reifyStruct(
2239922385 }
2240022386 }
2240122387
22388 const tracked_inst = try block.trackZir(inst);
22389
2240222390 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
2240322391 .layout = layout,
2240422392 .fields_len = fields_len,
......@@ -22409,9 +22397,8 @@ fn reifyStruct(
2240922397 .any_default_inits = any_default_inits,
2241022398 .any_aligned_fields = any_aligned_fields,
2241122399 .inits_resolved = true,
22412 .has_namespace = false,
2241322400 .key = .{ .reified = .{
22414 .zir_index = try block.trackZir(inst),
22401 .zir_index = tracked_inst,
2241522402 .type_hash = hasher.final(),
2241622403 } },
2241722404 })) {
......@@ -22426,15 +22413,13 @@ fn reifyStruct(
2242622413 .auto => {},
2242722414 };
2242822415
22429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22416 wip_ty.setName(ip, try sema.createTypeName(
2243022417 block,
22431 Value.fromInterned(wip_ty.index),
2243222418 name_strategy,
2243322419 "struct",
2243422420 inst,
22435 );
22436 mod.declPtr(new_decl_index).owns_tv = true;
22437 errdefer pt.abortAnonDecl(new_decl_index);
22421 wip_ty.index,
22422 ));
2243822423
2243922424 const struct_type = ip.loadStructType(wip_ty.index);
2244022425
......@@ -22582,10 +22567,17 @@ fn reifyStruct(
2258222567 }
2258322568 }
2258422569
22585 try pt.finalizeAnonDecl(new_decl_index);
22570 const new_namespace_index = try pt.createNamespace(.{
22571 .parent = block.namespace.toOptional(),
22572 .owner_type = wip_ty.index,
22573 .file_scope = block.getFileScopeIndex(mod),
22574 });
22575
22576 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index);
22577
2258622578 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));
22579 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22580 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
2258922581}
2259022582
2259122583fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
......@@ -26028,7 +26020,8 @@ fn zirVarExtended(
2602826020 extended: Zir.Inst.Extended.InstData,
2602926021) CompileError!Air.Inst.Ref {
2603026022 const pt = sema.pt;
26031 const mod = pt.zcu;
26023 const zcu = pt.zcu;
26024 const ip = &zcu.intern_pool;
2603226025 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
2603326026 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
2603426027 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
......@@ -26075,16 +26068,62 @@ fn zirVarExtended(
2607526068
2607626069 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
2607726070
26078 return Air.internedToRef((try pt.intern(.{ .variable = .{
26071 if (small.is_extern) {
26072 // We need to resolve the alignment and addrspace early.
26073 // Keep in sync with logic in `Zcu.PerThread.semaCau`.
26074 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
26075 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
26076
26077 const decl_inst, const decl_bodies = decl: {
26078 const decl_inst = sema.getOwnerCauDeclInst().resolve(ip);
26079 const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst);
26080 break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) };
26081 };
26082
26083 const alignment: InternPool.Alignment = a: {
26084 const align_body = decl_bodies.align_body orelse break :a .none;
26085 const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst);
26086 break :a try sema.analyzeAsAlign(block, align_src, align_ref);
26087 };
26088
26089 const @"addrspace": std.builtin.AddressSpace = as: {
26090 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(var_ty.toIntern())) {
26091 .func_type => .function,
26092 else => .variable,
26093 };
26094 const target = zcu.getTarget();
26095 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
26096 .function => target_util.defaultAddressSpace(target, .function),
26097 .variable => target_util.defaultAddressSpace(target, .global_mutable),
26098 .constant => target_util.defaultAddressSpace(target, .global_constant),
26099 else => unreachable,
26100 };
26101 const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst);
26102 break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx);
26103 };
26104
26105 return Air.internedToRef(try pt.getExtern(.{
26106 .name = sema.getOwnerCauNavName(),
26107 .ty = var_ty.toIntern(),
26108 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
26109 .is_const = small.is_const,
26110 .is_threadlocal = small.is_threadlocal,
26111 .is_weak_linkage = false,
26112 .alignment = alignment,
26113 .@"addrspace" = @"addrspace",
26114 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
26115 .owner_nav = undefined, // ignored by `getExtern`
26116 }));
26117 }
26118 assert(!small.is_const); // non-const non-extern variable is not legal
26119 return Air.internedToRef(try pt.intern(.{ .variable = .{
2607926120 .ty = var_ty.toIntern(),
2608026121 .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,
26122 .owner_nav = sema.getOwnerCauNav(),
26123 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
2608526124 .is_threadlocal = small.is_threadlocal,
2608626125 .is_weak_linkage = false,
26087 } })));
26126 } }));
2608826127}
2608926128
2609026129fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -26255,10 +26294,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2625526294 else => |e| return e,
2625626295 };
2625726296 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;
26297 } else cc: {
26298 if (has_body) {
26299 const decl_inst = if (sema.generic_owner != .none) decl_inst: {
26300 // Generic instance -- use the original function declaration to
26301 // look for the `export` syntax.
26302 const nav = mod.intern_pool.getNav(mod.funcInfo(sema.generic_owner).owner_nav);
26303 const cau = mod.intern_pool.getCau(nav.analysis_owner.unwrap().?);
26304 break :decl_inst cau.zir_index;
26305 } else sema.getOwnerCauDeclInst(); // not an instantiation so we're analyzing a function declaration Cau
26306
26307 const zir_decl = sema.code.getDeclaration(decl_inst.resolve(&mod.intern_pool))[0];
26308 if (zir_decl.flags.is_export) {
26309 break :cc .C;
26310 }
26311 }
26312 break :cc .Unspecified;
26313 };
2626226314
2626326315 const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: {
2626426316 const body_len = sema.code.extra[extra_index];
......@@ -26600,42 +26652,32 @@ fn zirBuiltinExtern(
2660026652
2660126653 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
2660226654
26655 // TODO: error for threadlocal functions, non-const functions, etc
26656
2660326657 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
2660426658 ty = try pt.optionalType(ty.toIntern());
2660526659 }
2660626660 const ptr_info = ty.ptrInfo(mod);
2660726661
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);
26662 const extern_val = try pt.getExtern(.{
26663 .name = options.name,
26664 .ty = ptr_info.child,
26665 .lib_name = options.library_name,
26666 .is_const = ptr_info.flags.is_const,
26667 .is_threadlocal = options.is_thread_local,
26668 .is_weak_linkage = options.linkage == .weak,
26669 .alignment = ptr_info.flags.alignment,
26670 .@"addrspace" = ptr_info.flags.address_space,
26671 // This instruction is just for source locations.
26672 // `builtin_extern` doesn't provide enough information, and isn't currently tracked.
26673 // So, for now, just use our containing `declaration`.
26674 .zir_index = switch (sema.owner.unwrap()) {
26675 .cau => sema.getOwnerCauDeclInst(),
26676 .func => sema.getOwnerFuncDeclInst(),
26677 },
26678 .owner_nav = undefined, // ignored by `getExtern`
26679 });
26680 const extern_nav = ip.indexToKey(extern_val).@"extern".owner_nav;
2663926681
2664026682 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{
2664126683 .ty = switch (ip.indexToKey(ty.toIntern())) {
......@@ -26643,7 +26685,7 @@ fn zirBuiltinExtern(
2664326685 .opt_type => |child_type| child_type,
2664426686 else => unreachable,
2664526687 },
26646 .base_addr = .{ .decl = new_decl_index },
26688 .base_addr = .{ .nav = extern_nav },
2664726689 .byte_offset = 0,
2664826690 } })), ty)).toIntern());
2664926691}
......@@ -27129,17 +27171,15 @@ fn explainWhyTypeIsNotPacked(
2712927171 }
2713027172}
2713127173
27132fn prepareSimplePanic(sema: *Sema) !void {
27174fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
2713327175 const pt = sema.pt;
2713427176 const mod = pt.zcu;
2713527177
2713627178 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 });
27179 const fn_ref = try sema.analyzeNavVal(block, src, try pt.getBuiltinNav("panic"));
27180 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{
27181 .needed_comptime_reason = "panic handler must be comptime-known",
27182 });
2714327183 assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn);
2714427184 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));
2714527185 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());
......@@ -27167,16 +27207,16 @@ fn prepareSimplePanic(sema: *Sema) !void {
2716727207/// Backends depend on panic decls being available when lowering safety-checked
2716827208/// instructions. This function ensures the panic function will be available to
2716927209/// be called during that time.
27170fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {
27210fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) !InternPool.Nav.Index {
2717127211 const pt = sema.pt;
2717227212 const mod = pt.zcu;
2717327213 const gpa = sema.gpa;
2717427214 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2717527215
27176 try sema.prepareSimplePanic();
27216 try sema.prepareSimplePanic(block, src);
2717727217
2717827218 const panic_messages_ty = try pt.getBuiltinType("panic_messages");
27179 const msg_decl_index = (sema.namespaceLookup(
27219 const msg_nav_index = (sema.namespaceLookup(
2718027220 block,
2718127221 LazySrcLoc.unneeded,
2718227222 panic_messages_ty.getNamespaceIndex(mod),
......@@ -27186,9 +27226,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
2718627226 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
2718727227 error.OutOfMemory => |e| return e,
2718827228 }).?;
27189 try sema.ensureDeclAnalyzed(msg_decl_index);
27190 mod.panic_messages[@intFromEnum(panic_id)] = msg_decl_index.toOptional();
27191 return msg_decl_index;
27229 try sema.ensureNavResolved(src, msg_nav_index);
27230 mod.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27231 return msg_nav_index;
2719227232}
2719327233
2719427234fn addSafetyCheck(
......@@ -27282,10 +27322,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
2728227322 return;
2728327323 }
2728427324
27285 try sema.prepareSimplePanic();
27325 try sema.prepareSimplePanic(block, src);
2728627326
2728727327 const panic_func = mod.funcInfo(mod.panic_func_index);
27288 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);
27328 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
2728927329 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);
2729027330
2729127331 const opt_usize_ty = try pt.optionalType(.usize_type);
......@@ -27455,8 +27495,8 @@ fn safetyCheckFormatted(
2745527495}
2745627496
2745727497fn 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);
27498 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);
27499 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);
2746027500 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
2746127501}
2746227502
......@@ -27628,21 +27668,21 @@ fn fieldVal(
2762827668 return Air.internedToRef(enum_val.toIntern());
2762927669 },
2763027670 .Struct, .Opaque => {
27631 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27632 return inst;
27671 switch (child_type.toIntern()) {
27672 .empty_struct_type, .anyopaque_type => {}, // no namespace
27673 else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27674 return inst;
27675 },
2763327676 }
2763427677 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
2763527678 },
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 },
27679 else => return sema.failWithOwnedErrorMsg(block, msg: {
27680 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27681 errdefer msg.destroy(sema.gpa);
27682 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
27683 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});
27684 break :msg msg;
27685 }),
2764627686 }
2764727687 },
2764827688 .Struct => if (is_pointer_to) {
......@@ -27700,7 +27740,7 @@ fn fieldPtr(
2770027740 .Array => {
2770127741 if (field_name.eqlSlice("len", ip)) {
2770227742 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));
27703 return anonDeclRef(sema, int_val.toIntern());
27743 return uavRef(sema, int_val.toIntern());
2770427744 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2770527745 const ptr_info = object_ty.ptrInfo(mod);
2770627746 const new_ptr_ty = try pt.ptrTypeSema(.{
......@@ -27839,7 +27879,7 @@ fn fieldPtr(
2783927879 child_type
2784027880 else
2784127881 try pt.singleErrorSetType(field_name);
27842 return anonDeclRef(sema, try pt.intern(.{ .err = .{
27882 return uavRef(sema, try pt.intern(.{ .err = .{
2784327883 .ty = error_set_type.toIntern(),
2784427884 .name = field_name,
2784527885 } }));
......@@ -27853,7 +27893,7 @@ fn fieldPtr(
2785327893 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
2785427894 const field_index_u32: u32 = @intCast(field_index);
2785527895 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
27856 return anonDeclRef(sema, idx_val.toIntern());
27896 return uavRef(sema, idx_val.toIntern());
2785727897 }
2785827898 }
2785927899 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
......@@ -27867,7 +27907,7 @@ fn fieldPtr(
2786727907 };
2786827908 const field_index_u32: u32 = @intCast(field_index);
2786927909 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
27870 return anonDeclRef(sema, idx_val.toIntern());
27910 return uavRef(sema, idx_val.toIntern());
2787127911 },
2787227912 .Struct, .Opaque => {
2787327913 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
......@@ -27923,18 +27963,18 @@ fn fieldCallBind(
2792327963 // in `fieldVal`. This function takes a pointer and returns a pointer.
2792427964
2792527965 const pt = sema.pt;
27926 const mod = pt.zcu;
27927 const ip = &mod.intern_pool;
27966 const zcu = pt.zcu;
27967 const ip = &zcu.intern_pool;
2792827968 const raw_ptr_src = src; // TODO better source location
2792927969 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)
27970 const inner_ty = if (raw_ptr_ty.zigTypeTag(zcu) == .Pointer and (raw_ptr_ty.ptrSize(zcu) == .One or raw_ptr_ty.ptrSize(zcu) == .C))
27971 raw_ptr_ty.childType(zcu)
2793227972 else
2793327973 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
2793427974
2793527975 // 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;
27976 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .Pointer and inner_ty.ptrSize(zcu) == .One;
27977 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;
2793827978 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
2793927979 const object_ptr = if (is_double_ptr)
2794027980 try sema.analyzeLoad(block, src, raw_ptr, src)
......@@ -27942,36 +27982,36 @@ fn fieldCallBind(
2794227982 raw_ptr;
2794327983
2794427984 find_field: {
27945 switch (concrete_ty.zigTypeTag(mod)) {
27985 switch (concrete_ty.zigTypeTag(zcu)) {
2794627986 .Struct => {
2794727987 try concrete_ty.resolveFields(pt);
27948 if (mod.typeToStruct(concrete_ty)) |struct_type| {
27988 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
2794927989 const field_index = struct_type.nameIndex(ip, field_name) orelse
2795027990 break :find_field;
2795127991 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2795227992
2795327993 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
27954 } else if (concrete_ty.isTuple(mod)) {
27994 } else if (concrete_ty.isTuple(zcu)) {
2795527995 if (field_name.eqlSlice("len", ip)) {
27956 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };
27996 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(zcu)) };
2795727997 }
2795827998 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);
27999 if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field;
28000 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, zcu), field_index, object_ptr);
2796128001 }
2796228002 } else {
27963 const max = concrete_ty.structFieldCount(mod);
28003 const max = concrete_ty.structFieldCount(zcu);
2796428004 for (0..max) |i_usize| {
2796528005 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);
28006 if (field_name == concrete_ty.structFieldName(i, zcu).unwrap().?) {
28007 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, zcu), i, object_ptr);
2796828008 }
2796928009 }
2797028010 }
2797128011 },
2797228012 .Union => {
2797328013 try concrete_ty.resolveFields(pt);
27974 const union_obj = mod.typeToUnion(concrete_ty).?;
28014 const union_obj = zcu.typeToUnion(concrete_ty).?;
2797528015 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
2797628016 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
2797728017 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };
......@@ -27985,23 +28025,23 @@ fn fieldCallBind(
2798528025 }
2798628026
2798728027 // 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;
28028 const found_nav = found_nav: {
28029 const namespace = concrete_ty.getNamespace(zcu).unwrap() orelse
28030 break :found_nav null;
28031 const nav_index = try sema.namespaceLookup(block, src, namespace, field_name) orelse
28032 break :found_nav null;
2799328033
27994 const decl_val = try sema.analyzeDeclVal(block, src, decl_idx);
28034 const decl_val = try sema.analyzeNavVal(block, src, nav_index);
2799528035 const decl_type = sema.typeOf(decl_val);
27996 if (mod.typeToFunc(decl_type)) |func_type| f: {
28036 if (zcu.typeToFunc(decl_type)) |func_type| f: {
2799728037 if (func_type.param_types.len == 0) break :f;
2799828038
2799928039 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);
2800028040 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)))
28041 (first_param_type.zigTypeTag(zcu) == .Pointer and
28042 (first_param_type.ptrSize(zcu) == .One or
28043 first_param_type.ptrSize(zcu) == .C) and
28044 first_param_type.childType(zcu).eql(concrete_ty, zcu)))
2800528045 {
2800628046 // Note that if the param type is generic poison, we know that it must
2800728047 // specifically be `anytype` since it's the first parameter, meaning we
......@@ -28012,31 +28052,31 @@ fn fieldCallBind(
2801228052 .func_inst = decl_val,
2801328053 .arg0_inst = object_ptr,
2801428054 } };
28015 } else if (first_param_type.eql(concrete_ty, mod)) {
28055 } else if (first_param_type.eql(concrete_ty, zcu)) {
2801628056 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2801728057 return .{ .method = .{
2801828058 .func_inst = decl_val,
2801928059 .arg0_inst = deref,
2802028060 } };
28021 } else if (first_param_type.zigTypeTag(mod) == .Optional) {
28022 const child = first_param_type.optionalChild(mod);
28023 if (child.eql(concrete_ty, mod)) {
28061 } else if (first_param_type.zigTypeTag(zcu) == .Optional) {
28062 const child = first_param_type.optionalChild(zcu);
28063 if (child.eql(concrete_ty, zcu)) {
2802428064 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2802528065 return .{ .method = .{
2802628066 .func_inst = decl_val,
2802728067 .arg0_inst = deref,
2802828068 } };
28029 } else if (child.zigTypeTag(mod) == .Pointer and
28030 child.ptrSize(mod) == .One and
28031 child.childType(mod).eql(concrete_ty, mod))
28069 } else if (child.zigTypeTag(zcu) == .Pointer and
28070 child.ptrSize(zcu) == .One and
28071 child.childType(zcu).eql(concrete_ty, zcu))
2803228072 {
2803328073 return .{ .method = .{
2803428074 .func_inst = decl_val,
2803528075 .arg0_inst = object_ptr,
2803628076 } };
2803728077 }
28038 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and
28039 first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod))
28078 } else if (first_param_type.zigTypeTag(zcu) == .ErrorUnion and
28079 first_param_type.errorUnionPayload(zcu).eql(concrete_ty, zcu))
2804028080 {
2804128081 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
2804228082 return .{ .method = .{
......@@ -28045,7 +28085,7 @@ fn fieldCallBind(
2804528085 } };
2804628086 }
2804728087 }
28048 break :found_decl decl_idx;
28088 break :found_nav nav_index;
2804928089 };
2805028090
2805128091 const msg = msg: {
......@@ -28055,14 +28095,15 @@ fn fieldCallBind(
2805528095 });
2805628096 errdefer msg.destroy(sema.gpa);
2805728097 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)});
28098 if (found_nav) |nav_index| {
28099 try sema.errNote(
28100 zcu.navSrcLoc(nav_index),
28101 msg,
28102 "'{}' is not a member function",
28103 .{field_name.fmt(ip)},
28104 );
2806428105 }
28065 if (concrete_ty.zigTypeTag(mod) == .ErrorUnion) {
28106 if (concrete_ty.zigTypeTag(zcu) == .ErrorUnion) {
2806628107 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
2806728108 }
2806828109 if (is_double_ptr) {
......@@ -28117,29 +28158,24 @@ fn namespaceLookup(
2811728158 sema: *Sema,
2811828159 block: *Block,
2811928160 src: LazySrcLoc,
28120 opt_namespace: InternPool.OptionalNamespaceIndex,
28161 namespace: InternPool.NamespaceIndex,
2812128162 decl_name: InternPool.NullTerminatedString,
28122) CompileError!?InternPool.DeclIndex {
28163) CompileError!?InternPool.Nav.Index {
2812328164 const pt = sema.pt;
28124 const mod = pt.zcu;
28165 const zcu = pt.zcu;
2812528166 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: {
28167 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
28168 if (!lookup.accessible) {
28169 return sema.failWithOwnedErrorMsg(block, msg: {
2813028170 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
28131 decl_name.fmt(&mod.intern_pool),
28171 decl_name.fmt(&zcu.intern_pool),
2813228172 });
2813328173 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", .{});
28174 try sema.errNote(zcu.navSrcLoc(lookup.nav), msg, "declared here", .{});
2813828175 break :msg msg;
28139 };
28140 return sema.failWithOwnedErrorMsg(block, msg);
28176 });
2814128177 }
28142 return decl_index;
28178 return lookup.nav;
2814328179 }
2814428180 return null;
2814528181}
......@@ -28148,22 +28184,22 @@ fn namespaceLookupRef(
2814828184 sema: *Sema,
2814928185 block: *Block,
2815028186 src: LazySrcLoc,
28151 opt_namespace: InternPool.OptionalNamespaceIndex,
28187 namespace: InternPool.NamespaceIndex,
2815228188 decl_name: InternPool.NullTerminatedString,
2815328189) 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);
28190 const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null;
28191 return try sema.analyzeNavRef(src, nav);
2815628192}
2815728193
2815828194fn namespaceLookupVal(
2815928195 sema: *Sema,
2816028196 block: *Block,
2816128197 src: LazySrcLoc,
28162 opt_namespace: InternPool.OptionalNamespaceIndex,
28198 namespace: InternPool.NamespaceIndex,
2816328199 decl_name: InternPool.NullTerminatedString,
2816428200) 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);
28201 const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null;
28202 return try sema.analyzeNavVal(block, src, nav);
2816728203}
2816828204
2816928205fn structFieldPtr(
......@@ -29200,9 +29236,9 @@ const CoerceOpts = struct {
2920029236
2920129237 fn get(info: @This(), sema: *Sema) !?LazySrcLoc {
2920229238 if (info.func_inst == .none) return null;
29203 const fn_decl = try sema.funcDeclSrc(info.func_inst) orelse return null;
29239 const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null;
2920429240 return .{
29205 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
29241 .base_node_inst = func_inst,
2920629242 .offset = .{ .fn_proto_param_type = .{
2920729243 .fn_proto_node_offset = 0,
2920829244 .param_index = info.param_i,
......@@ -29303,8 +29339,12 @@ fn coerceExtra(
2930329339 // Function body to function pointer.
2930429340 if (inst_ty.zigTypeTag(zcu) == .Fn) {
2930529341 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);
29342 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
29343 .func => |f| f.owner_nav,
29344 .@"extern" => |e| e.owner_nav,
29345 else => unreachable,
29346 };
29347 const inst_as_ptr = try sema.analyzeNavRef(inst_src, fn_nav);
2930829348 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
2930929349 }
2931029350
......@@ -29846,7 +29886,7 @@ fn coerceExtra(
2984629886 errdefer msg.destroy(sema.gpa);
2984729887
2984829888 const ret_ty_src: LazySrcLoc = .{
29849 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,
29889 .base_node_inst = sema.getOwnerFuncDeclInst(),
2985029890 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
2985129891 };
2985229892 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
......@@ -29879,10 +29919,10 @@ fn coerceExtra(
2987929919
2988029920 // Add notes about function return type
2988129921 if (opts.is_ret and
29882 zcu.test_functions.get(zcu.funcOwnerDeclIndex(sema.func_index)) == null)
29922 !zcu.test_functions.contains(zcu.funcInfo(sema.owner.unwrap().func).owner_nav))
2988329923 {
2988429924 const ret_ty_src: LazySrcLoc = .{
29885 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,
29925 .base_node_inst = sema.getOwnerFuncDeclInst(),
2988629926 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
2988729927 };
2988829928 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
......@@ -30885,9 +30925,9 @@ fn coerceVarArgParam(
3088530925 if (block.is_typeof) return inst;
3088630926
3088730927 const pt = sema.pt;
30888 const mod = pt.zcu;
30928 const zcu = pt.zcu;
3088930929 const uncasted_ty = sema.typeOf(inst);
30890 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {
30930 const coerced = switch (uncasted_ty.zigTypeTag(zcu)) {
3089130931 // TODO consider casting to c_int/f64 if they fit
3089230932 .ComptimeInt, .ComptimeFloat => return sema.fail(
3089330933 block,
......@@ -30897,12 +30937,12 @@ fn coerceVarArgParam(
3089730937 ),
3089830938 .Fn => fn_ptr: {
3089930939 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);
30940 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
30941 break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav);
3090230942 },
3090330943 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
3090430944 .Float => float: {
30905 const target = mod.getTarget();
30945 const target = zcu.getTarget();
3090630946 const double_bits = target.c_type_bit_size(.double);
3090730947 const inst_bits = uncasted_ty.floatBits(target);
3090830948 if (inst_bits >= double_bits) break :float inst;
......@@ -30912,10 +30952,10 @@ fn coerceVarArgParam(
3091230952 else => unreachable,
3091330953 }
3091430954 },
30915 else => if (uncasted_ty.isAbiInt(mod)) int: {
30955 else => if (uncasted_ty.isAbiInt(zcu)) int: {
3091630956 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
30917 const target = mod.getTarget();
30918 const uncasted_info = uncasted_ty.intInfo(mod);
30957 const target = zcu.getTarget();
30958 const uncasted_info = uncasted_ty.intInfo(zcu);
3091930959 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {
3092030960 .signed => .int,
3092130961 .unsigned => .uint,
......@@ -32117,23 +32157,14 @@ fn coerceTupleToTuple(
3211732157 } })));
3211832158}
3211932159
32120fn analyzeDeclVal(
32160fn analyzeNavVal(
3212132161 sema: *Sema,
3212232162 block: *Block,
3212332163 src: LazySrcLoc,
32124 decl_index: InternPool.DeclIndex,
32164 nav_index: InternPool.Nav.Index,
3212532165) 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;
32166 const ref = try sema.analyzeNavRefInner(src, nav_index, false);
32167 return sema.analyzeLoad(block, src, ref, src);
3213732168}
3213832169
3213932170fn addReferenceEntry(
......@@ -32148,44 +32179,37 @@ fn addReferenceEntry(
3214832179 // TODO: we need to figure out how to model inline calls here.
3214932180 // They aren't references in the analysis sense, but ought to show up in the reference trace!
3215032181 // Would representing inline calls in the reference table cause excessive memory usage?
32151 try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src);
32182 try zcu.addUnitReference(sema.owner, referenced_unit, src);
3215232183}
3215332184
32154pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {
32185pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!void {
3215532186 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 }
32187 const zcu = pt.zcu;
32188 const ip = &zcu.intern_pool;
3216632189
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}
32190 const nav = ip.getNav(nav_index);
3217632191
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;
32192 const cau_index = nav.analysis_owner.unwrap() orelse {
32193 assert(nav.status == .resolved);
32194 return;
3218832195 };
32196
32197 // Note that even if `nav.status == .resolved`, we must still trigger `ensureCauAnalyzed`
32198 // to make sure the value is up-to-date on incremental updates.
32199
32200 assert(ip.getCau(cau_index).owner.unwrap().nav == nav_index);
32201
32202 const anal_unit = AnalUnit.wrap(.{ .cau = cau_index });
32203 try sema.addReferenceEntry(src, anal_unit);
32204
32205 if (zcu.analysis_in_progress.contains(anal_unit)) {
32206 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{
32207 .base_node_inst = ip.getCau(cau_index).zir_index,
32208 .offset = LazySrcLoc.Offset.nodeOffset(0),
32209 }, "dependency loop detected", .{}));
32210 }
32211
32212 return pt.ensureCauAnalyzed(cau_index);
3218932213}
3219032214
3219132215fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
......@@ -32200,55 +32224,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
3220032224 } }));
3220132225}
3220232226
32203fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {
32204 return sema.analyzeDeclRefInner(src, decl_index, true);
32227fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref {
32228 return sema.analyzeNavRefInner(src, nav_index, true);
3220532229}
3220632230
32207/// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but
32231/// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed, but
3220832232/// 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
32233/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeNavRef` wraps
3221032234/// 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 {
32235fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
3221232236 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);
32237 const zcu = pt.zcu;
32238 const ip = &zcu.intern_pool;
3221632239
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 });
32240 // TODO: if this is a `decl_ref` of a non-variable Nav, only depend on Nav type
32241 try sema.declareDependency(.{ .nav_val = orig_nav_index });
32242 try sema.ensureNavResolved(src, orig_nav_index);
32243
32244 const nav_val = zcu.navValue(orig_nav_index);
32245 const nav_index, const is_const = switch (ip.indexToKey(nav_val.toIntern())) {
32246 .variable => |v| .{ v.owner_nav, false },
32247 .func => |f| .{ f.owner_nav, true },
32248 .@"extern" => |e| .{ e.owner_nav, e.is_const },
32249 else => .{ orig_nav_index, true },
32250 };
32251 const nav_info = ip.getNav(nav_index).status.resolved;
3222632252 const ptr_ty = try pt.ptrTypeSema(.{
32227 .child = decl_val.typeOf(mod).toIntern(),
32253 .child = nav_val.typeOf(zcu).toIntern(),
3222832254 .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",
32255 .alignment = nav_info.alignment,
32256 .is_const = is_const,
32257 .address_space = nav_info.@"addrspace",
3223232258 },
3223332259 });
3223432260 if (analyze_fn_body) {
32235 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);
32261 try sema.maybeQueueFuncBodyAnalysis(src, nav_index);
3223632262 }
3223732263 return Air.internedToRef((try pt.intern(.{ .ptr = .{
3223832264 .ty = ptr_ty.toIntern(),
32239 .base_addr = .{ .decl = decl_index },
32265 .base_addr = .{ .nav = nav_index },
3224032266 .byte_offset = 0,
3224132267 } })));
3224232268}
3224332269
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());
32270fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void {
32271 const zcu = sema.pt.zcu;
32272 const ip = &zcu.intern_pool;
32273 const nav_val = zcu.navValue(nav_index);
32274 if (!ip.isFuncBody(nav_val.toIntern())) return;
32275 if (!try sema.fnHasRuntimeBits(nav_val.typeOf(zcu))) return;
32276 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() }));
32277 try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
3225232278}
3225332279
3225432280fn analyzeRef(
......@@ -32263,9 +32289,9 @@ fn analyzeRef(
3226332289
3226432290 if (try sema.resolveValue(operand)) |val| {
3226532291 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()),
32292 .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav),
32293 .func => |f| return sema.analyzeNavRef(src, f.owner_nav),
32294 else => return uavRef(sema, val.toIntern()),
3226932295 }
3227032296 }
3227132297
......@@ -35198,7 +35224,7 @@ pub fn resolveStructAlignment(
3519835224 const ip = &mod.intern_pool;
3519935225 const target = mod.getTarget();
3520035226
35201 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35227 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3520235228
3520335229 assert(struct_type.layout != .@"packed");
3520435230 assert(struct_type.flagsUnordered(ip).alignment == .none);
......@@ -35242,7 +35268,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3524235268 const ip = &zcu.intern_pool;
3524335269 const struct_type = zcu.typeToStruct(ty) orelse return;
3524435270
35245 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35271 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3524635272
3524735273 if (struct_type.haveLayout(ip))
3524835274 return;
......@@ -35384,8 +35410,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
3538435410 const gpa = zcu.gpa;
3538535411 const ip = &zcu.intern_pool;
3538635412
35387 const decl_index = struct_type.decl.unwrap().?;
35388 const decl = zcu.declPtr(decl_index);
35413 const cau_index = struct_type.cau.unwrap().?;
3538935414
3539035415 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;
3539135416
......@@ -35400,13 +35425,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
3540035425 .gpa = gpa,
3540135426 .arena = analysis_arena.allocator(),
3540235427 .code = zir,
35403 .owner_decl = decl,
35404 .owner_decl_index = decl_index,
35428 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3540535429 .func_index = .none,
3540635430 .func_is_naked = false,
3540735431 .fn_ret_ty = Type.void,
3540835432 .fn_ret_ty_ies = null,
35409 .owner_func_index = .none,
3541035433 .comptime_err_ret_trace = &comptime_err_ret_trace,
3541135434 };
3541235435 defer sema.deinit();
......@@ -35414,12 +35437,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
3541435437 var block: Block = .{
3541535438 .parent = null,
3541635439 .sema = &sema,
35417 .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,
35440 .namespace = ip.getCau(cau_index).namespace,
3541835441 .instructions = .{},
3541935442 .inlining = null,
3542035443 .is_comptime = true,
3542135444 .src_base_inst = struct_type.zir_index.unwrap().?,
35422 .type_name_ctx = decl.name,
35445 .type_name_ctx = struct_type.name,
3542335446 };
3542435447 defer assert(block.instructions.items.len == 0);
3542535448
......@@ -35544,7 +35567,7 @@ pub fn resolveUnionAlignment(
3554435567 const ip = &zcu.intern_pool;
3554535568 const target = zcu.getTarget();
3554635569
35547 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35570 assert(sema.owner.unwrap().cau == union_type.cau);
3554835571
3554935572 assert(!union_type.haveLayout(ip));
3555035573
......@@ -35584,7 +35607,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
3558435607 // Load again, since the tag type might have changed due to resolution.
3558535608 const union_type = ip.loadUnionType(ty.ip_index);
3558635609
35587 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35610 assert(sema.owner.unwrap().cau == union_type.cau);
3558835611
3558935612 const old_flags = union_type.flagsUnordered(ip);
3559035613 switch (old_flags.status) {
......@@ -35697,7 +35720,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3569735720 const ip = &mod.intern_pool;
3569835721 const struct_type = mod.typeToStruct(ty).?;
3569935722
35700 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35723 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3570135724
3570235725 if (struct_type.setFullyResolved(ip)) return;
3570335726 errdefer struct_type.clearFullyResolved(ip);
......@@ -35720,7 +35743,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
3572035743 const ip = &mod.intern_pool;
3572135744 const union_obj = mod.typeToUnion(ty).?;
3572235745
35723 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);
35746 assert(sema.owner.unwrap().cau == union_obj.cau);
3572435747
3572535748 switch (union_obj.flagsUnordered(ip).status) {
3572635749 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
......@@ -35754,21 +35777,8 @@ pub fn resolveTypeFieldsStruct(
3575435777 const pt = sema.pt;
3575535778 const zcu = pt.zcu;
3575635779 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;
3575935780
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 }
35781 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3577235782
3577335783 if (struct_type.haveFieldTypes(ip)) return;
3577435784
......@@ -35783,13 +35793,7 @@ pub fn resolveTypeFieldsStruct(
3578335793 defer struct_type.clearFieldTypesWip(ip);
3578435794
3578535795 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,
35796 error.AnalysisFail, error.OutOfMemory => |e| return e,
3579335797 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3579435798 };
3579535799}
......@@ -35799,9 +35803,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3579935803 const zcu = pt.zcu;
3580035804 const ip = &zcu.intern_pool;
3580135805 const struct_type = zcu.typeToStruct(ty) orelse return;
35802 const owner_decl = struct_type.decl.unwrap() orelse return;
3580335806
35804 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35807 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3580535808
3580635809 // Inits can start as resolved
3580735810 if (struct_type.haveFieldInits(ip)) return;
......@@ -35819,13 +35822,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3581935822 defer struct_type.clearInitsWip(ip);
3582035823
3582135824 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,
35825 error.AnalysisFail, error.OutOfMemory => |e| return e,
3582935826 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3583035827 };
3583135828 struct_type.setHaveFieldInits(ip);
......@@ -35835,20 +35832,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3583535832 const pt = sema.pt;
3583635833 const zcu = pt.zcu;
3583735834 const ip = &zcu.intern_pool;
35838 const owner_decl = zcu.declPtr(union_type.decl);
3583935835
35840 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35836 assert(sema.owner.unwrap().cau == union_type.cau);
3584135837
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 }
3585235838 switch (union_type.flagsUnordered(ip).status) {
3585335839 .none => {},
3585435840 .field_types_wip => {
......@@ -35869,14 +35855,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3586935855
3587035856 union_type.setStatus(ip, .field_types_wip);
3587135857 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,
35858 semaUnionFields(pt, sema.arena, ty.toIntern(), union_type) catch |err| switch (err) {
35859 error.AnalysisFail, error.OutOfMemory => |e| return e,
3588035860 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3588135861 };
3588235862 union_type.setStatus(ip, .have_field_types);
......@@ -35891,28 +35871,28 @@ fn resolveInferredErrorSet(
3589135871 ies_index: InternPool.Index,
3589235872) CompileError!InternPool.Index {
3589335873 const pt = sema.pt;
35894 const mod = pt.zcu;
35895 const ip = &mod.intern_pool;
35874 const zcu = pt.zcu;
35875 const ip = &zcu.intern_pool;
3589635876 const func_index = ip.iesFuncIndex(ies_index);
35897 const func = mod.funcInfo(func_index);
35877 const func = zcu.funcInfo(func_index);
3589835878
35899 try sema.declareDependency(.{ .func_ies = func_index });
35879 try sema.declareDependency(.{ .interned = func_index }); // resolved IES
3590035880
3590135881 // TODO: during an incremental update this might not be `.none`, but the
3590235882 // function might be out-of-date!
3590335883 const resolved_ty = func.resolvedErrorSetUnordered(ip);
3590435884 if (resolved_ty != .none) return resolved_ty;
3590535885
35906 if (func.analysisUnordered(ip).state == .in_progress)
35886 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .func = func_index }))) {
3590735887 return sema.fail(block, src, "unable to resolve inferred error set", .{});
35888 }
3590835889
3590935890 // In order to ensure that all dependencies are properly added to the set,
3591035891 // we need to ensure the function body is analyzed of the inferred error
3591135892 // set. However, in the case of comptime/inline function calls with
3591235893 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
3591335894 // 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)).?;
35895 const ies_func_info = zcu.typeToFunc(Type.fromInterned(func.ty)).?;
3591635896 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
3591735897 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
3591835898 // so here we can simply skip this case.
......@@ -35920,22 +35900,17 @@ fn resolveInferredErrorSet(
3592035900 assert(ies_func_info.cc == .Inline);
3592135901 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {
3592235902 if (ies_func_info.is_generic) {
35923 const msg = msg: {
35903 return sema.failWithOwnedErrorMsg(block, msg: {
3592435904 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});
3592535905 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", .{});
35906 try sema.errNote(zcu.navSrcLoc(func.owner_nav), msg, "generic function declared here", .{});
3593135907 break :msg msg;
35932 };
35933 return sema.failWithOwnedErrorMsg(block, msg);
35908 });
3593435909 }
3593535910 // In this case we are dealing with the actual InferredErrorSet object that
3593635911 // corresponds to the function, not one created to track an inline/comptime call.
3593735912 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));
35938 try sema.ensureFuncBodyAnalyzed(func_index);
35913 try pt.ensureFuncBodyAnalyzed(func_index);
3593935914 }
3594035915
3594135916 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`
......@@ -36092,9 +36067,8 @@ fn semaStructFields(
3609236067 const zcu = pt.zcu;
3609336068 const gpa = zcu.gpa;
3609436069 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;
36070 const cau_index = struct_type.cau.unwrap().?;
36071 const namespace_index = ip.getCau(cau_index).namespace;
3609836072 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
3609936073 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
3610036074
......@@ -36119,13 +36093,11 @@ fn semaStructFields(
3611936093 .gpa = gpa,
3612036094 .arena = arena,
3612136095 .code = zir,
36122 .owner_decl = decl,
36123 .owner_decl_index = decl_index,
36096 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3612436097 .func_index = .none,
3612536098 .func_is_naked = false,
3612636099 .fn_ret_ty = Type.void,
3612736100 .fn_ret_ty_ies = null,
36128 .owner_func_index = .none,
3612936101 .comptime_err_ret_trace = &comptime_err_ret_trace,
3613036102 };
3613136103 defer sema.deinit();
......@@ -36138,7 +36110,7 @@ fn semaStructFields(
3613836110 .inlining = null,
3613936111 .is_comptime = true,
3614036112 .src_base_inst = struct_type.zir_index.unwrap().?,
36141 .type_name_ctx = decl.name,
36113 .type_name_ctx = struct_type.name,
3614236114 };
3614336115 defer assert(block_scope.instructions.items.len == 0);
3614436116
......@@ -36318,9 +36290,8 @@ fn semaStructFieldInits(
3631836290
3631936291 assert(!struct_type.haveFieldInits(ip));
3632036292
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;
36293 const cau_index = struct_type.cau.unwrap().?;
36294 const namespace_index = ip.getCau(cau_index).namespace;
3632436295 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
3632536296 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
3632636297 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
......@@ -36333,13 +36304,11 @@ fn semaStructFieldInits(
3633336304 .gpa = gpa,
3633436305 .arena = arena,
3633536306 .code = zir,
36336 .owner_decl = decl,
36337 .owner_decl_index = decl_index,
36307 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3633836308 .func_index = .none,
3633936309 .func_is_naked = false,
3634036310 .fn_ret_ty = Type.void,
3634136311 .fn_ret_ty_ies = null,
36342 .owner_func_index = .none,
3634336312 .comptime_err_ret_trace = &comptime_err_ret_trace,
3634436313 };
3634536314 defer sema.deinit();
......@@ -36352,7 +36321,7 @@ fn semaStructFieldInits(
3635236321 .inlining = null,
3635336322 .is_comptime = true,
3635436323 .src_base_inst = struct_type.zir_index.unwrap().?,
36355 .type_name_ctx = decl.name,
36324 .type_name_ctx = struct_type.name,
3635636325 };
3635736326 defer assert(block_scope.instructions.items.len == 0);
3635836327
......@@ -36449,15 +36418,15 @@ fn semaStructFieldInits(
3644936418 try sema.flushExports();
3645036419}
3645136420
36452fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {
36421fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_ty: InternPool.Index, union_type: InternPool.LoadedUnionType) CompileError!void {
3645336422 const tracy = trace(@src());
3645436423 defer tracy.end();
3645536424
3645636425 const zcu = pt.zcu;
3645736426 const gpa = zcu.gpa;
3645836427 const ip = &zcu.intern_pool;
36459 const decl_index = union_type.decl;
36460 const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir;
36428 const cau_index = union_type.cau;
36429 const zir = zcu.namespacePtr(union_type.namespace).fileScope(zcu).zir;
3646136430 const zir_index = union_type.zir_index.resolve(ip);
3646236431 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
3646336432 assert(extended.opcode == .union_decl);
......@@ -36501,8 +36470,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3650136470 const body = zir.bodySlice(extra_index, body_len);
3650236471 extra_index += body.len;
3650336472
36504 const decl = zcu.declPtr(decl_index);
36505
3650636473 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
3650736474 defer comptime_err_ret_trace.deinit();
3650836475
......@@ -36511,13 +36478,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3651136478 .gpa = gpa,
3651236479 .arena = arena,
3651336480 .code = zir,
36514 .owner_decl = decl,
36515 .owner_decl_index = decl_index,
36481 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
3651636482 .func_index = .none,
3651736483 .func_is_naked = false,
3651836484 .fn_ret_ty = Type.void,
3651936485 .fn_ret_ty_ies = null,
36520 .owner_func_index = .none,
3652136486 .comptime_err_ret_trace = &comptime_err_ret_trace,
3652236487 };
3652336488 defer sema.deinit();
......@@ -36525,12 +36490,12 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3652536490 var block_scope: Block = .{
3652636491 .parent = null,
3652736492 .sema = &sema,
36528 .namespace = union_type.namespace.unwrap().?,
36493 .namespace = union_type.namespace,
3652936494 .instructions = .{},
3653036495 .inlining = null,
3653136496 .is_comptime = true,
3653236497 .src_base_inst = union_type.zir_index,
36533 .type_name_ctx = decl.name,
36498 .type_name_ctx = union_type.name,
3653436499 };
3653536500 defer assert(block_scope.instructions.items.len == 0);
3653636501
......@@ -36817,10 +36782,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
3681736782 return sema.failWithOwnedErrorMsg(&block_scope, msg);
3681836783 }
3681936784 } 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));
36785 const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), union_ty, union_type.name);
3682136786 union_type.setTagType(ip, enum_ty);
3682236787 } else {
36823 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl));
36788 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, union_ty, union_type.name);
3682436789 union_type.setTagType(ip, enum_ty);
3682536790 }
3682636791
......@@ -36839,36 +36804,25 @@ fn generateUnionTagTypeNumbered(
3683936804 block: *Block,
3684036805 enum_field_names: []const InternPool.NullTerminatedString,
3684136806 enum_field_vals: []const InternPool.Index,
36842 union_owner_decl: *Module.Decl,
36807 union_type: InternPool.Index,
36808 union_name: InternPool.NullTerminatedString,
3684336809) !InternPool.Index {
3684436810 const pt = sema.pt;
3684536811 const mod = pt.zcu;
3684636812 const gpa = sema.gpa;
3684736813 const ip = &mod.intern_pool;
3684836814
36849 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36850 errdefer pt.destroyDecl(new_decl_index);
3685136815 const name = try ip.getOrPutStringFmt(
3685236816 gpa,
3685336817 pt.tid,
3685436818 "@typeInfo({}).Union.tag_type.?",
36855 .{union_owner_decl.fqn.fmt(ip)},
36819 .{union_name.fmt(ip)},
3685636820 .no_embedded_nulls,
3685736821 );
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;
3686836822
3686936823 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36870 .decl = new_decl_index,
36871 .owner_union_ty = union_owner_decl.val.toIntern(),
36824 .name = name,
36825 .owner_union_ty = union_type,
3687236826 .tag_ty = if (enum_field_vals.len == 0)
3687336827 (try pt.intType(.unsigned, 0)).toIntern()
3687436828 else
......@@ -36876,11 +36830,9 @@ fn generateUnionTagTypeNumbered(
3687636830 .names = enum_field_names,
3687736831 .values = enum_field_vals,
3687836832 .tag_mode = .explicit,
36833 .parent_namespace = block.namespace,
3687936834 });
3688036835
36881 new_decl.val = Value.fromInterned(enum_ty);
36882
36883 try pt.finalizeAnonDecl(new_decl_index);
3688436836 return enum_ty;
3688536837}
3688636838
......@@ -36888,36 +36840,25 @@ fn generateUnionTagTypeSimple(
3688836840 sema: *Sema,
3688936841 block: *Block,
3689036842 enum_field_names: []const InternPool.NullTerminatedString,
36891 union_owner_decl: *Module.Decl,
36843 union_type: InternPool.Index,
36844 union_name: InternPool.NullTerminatedString,
3689236845) !InternPool.Index {
3689336846 const pt = sema.pt;
3689436847 const mod = pt.zcu;
3689536848 const ip = &mod.intern_pool;
3689636849 const gpa = sema.gpa;
3689736850
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);
36851 const name = try ip.getOrPutStringFmt(
36852 gpa,
36853 pt.tid,
36854 "@typeInfo({}).Union.tag_type.?",
36855 .{union_name.fmt(ip)},
36856 .no_embedded_nulls,
36857 );
3691736858
3691836859 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36919 .decl = new_decl_index,
36920 .owner_union_ty = union_owner_decl.val.toIntern(),
36860 .name = name,
36861 .owner_union_ty = union_type,
3692136862 .tag_ty = if (enum_field_names.len == 0)
3692236863 (try pt.intType(.unsigned, 0)).toIntern()
3692336864 else
......@@ -36925,13 +36866,9 @@ fn generateUnionTagTypeSimple(
3692536866 .names = enum_field_names,
3692636867 .values = &.{},
3692736868 .tag_mode = .auto,
36869 .parent_namespace = block.namespace,
3692836870 });
3692936871
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);
3693536872 return enum_ty;
3693636873}
3693736874
......@@ -37057,9 +36994,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3705736994 // values, not types
3705836995 .undef,
3705936996 .simple_value,
37060 .ptr_decl,
37061 .ptr_anon_decl,
37062 .ptr_anon_decl_aligned,
36997 .ptr_nav,
36998 .ptr_uav,
36999 .ptr_uav_aligned,
3706337000 .ptr_comptime_alloc,
3706437001 .ptr_comptime_field,
3706537002 .ptr_int,
......@@ -37096,7 +37033,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3709637033 .float_c_longdouble_f128,
3709737034 .float_comptime_float,
3709837035 .variable,
37099 .extern_func,
37036 .@"extern",
3710037037 .func_decl,
3710137038 .func_instance,
3710237039 .func_coerced,
......@@ -37965,7 +37902,7 @@ fn intFitsInType(
3796537902 .zero_usize, .zero_u8 => return true,
3796637903 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
3796737904 .undef => return true,
37968 .variable, .extern_func, .func, .ptr => {
37905 .variable, .@"extern", .func, .ptr => {
3796937906 const target = mod.getTarget();
3797037907 const ptr_bits = target.ptrBitWidth();
3797137908 return switch (info.signedness) {
......@@ -38240,24 +38177,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
3824038177 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
3824138178 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
3824238179 // the loop.
38243 if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) {
38244 return;
38180 switch (sema.owner.unwrap()) {
38181 .cau => |cau| switch (dependee) {
38182 .nav_val => |nav| if (zcu.intern_pool.getNav(nav).analysis_owner == cau.toOptional()) {
38183 return;
38184 },
38185 else => {},
38186 },
38187 .func => {},
3824538188 }
3824638189
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);
38190 try zcu.intern_pool.addDependency(sema.gpa, sema.owner, dependee);
3825438191}
3825538192
3825638193fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
3825738194 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
3825838195 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),
3825938196 .ptr => |ptr| switch (ptr.base_addr) {
38260 .anon_decl, .decl, .int => false,
38197 .uav, .nav, .int => false,
3826138198 .comptime_field => true,
3826238199 .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const,
3826338200 .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)),
......@@ -38388,19 +38325,17 @@ pub fn flushExports(sema: *Sema) !void {
3838838325 const zcu = sema.pt.zcu;
3838938326 const gpa = zcu.gpa;
3839038327
38391 const unit = sema.ownerUnit();
38392
3839338328 // There may be existing exports. For instance, a struct may export
3839438329 // things during both field type resolution and field default resolution.
3839538330 //
3839638331 // So, pick up and delete any existing exports. This strategy performs
3839738332 // redundant work, but that's okay, because this case is exceedingly rare.
38398 if (zcu.single_exports.get(unit)) |export_idx| {
38333 if (zcu.single_exports.get(sema.owner)) |export_idx| {
3839938334 try sema.exports.append(gpa, zcu.all_exports.items[export_idx]);
38400 } else if (zcu.multi_exports.get(unit)) |info| {
38335 } else if (zcu.multi_exports.get(sema.owner)) |info| {
3840138336 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
3840238337 }
38403 zcu.deleteUnitExports(unit);
38338 zcu.deleteUnitExports(sema.owner);
3840438339
3840538340 // `sema.exports` is completed; store the data into the `Zcu`.
3840638341 if (sema.exports.items.len == 1) {
......@@ -38410,24 +38345,55 @@ pub fn flushExports(sema: *Sema) !void {
3841038345 break :idx zcu.all_exports.items.len - 1;
3841138346 };
3841238347 zcu.all_exports.items[export_idx] = sema.exports.items[0];
38413 zcu.single_exports.putAssumeCapacityNoClobber(unit, @intCast(export_idx));
38348 zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, @intCast(export_idx));
3841438349 } else {
3841538350 try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);
3841638351 const exports_base = zcu.all_exports.items.len;
3841738352 try zcu.all_exports.appendSlice(gpa, sema.exports.items);
38418 zcu.multi_exports.putAssumeCapacityNoClobber(unit, .{
38353 zcu.multi_exports.putAssumeCapacityNoClobber(sema.owner, .{
3841938354 .index = @intCast(exports_base),
3842038355 .len = @intCast(sema.exports.items.len),
3842138356 });
3842238357 }
3842338358}
3842438359
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 }
38360/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38361/// the corresponding `Nav`.
38362fn getOwnerCauNav(sema: *Sema) InternPool.Nav.Index {
38363 const cau = sema.owner.unwrap().cau;
38364 return sema.pt.zcu.intern_pool.getCau(cau).owner.unwrap().nav;
38365}
38366
38367/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38368/// the declaration name from its corresponding `Nav`.
38369fn getOwnerCauNavName(sema: *Sema) InternPool.NullTerminatedString {
38370 const nav = sema.getOwnerCauNav();
38371 return sema.pt.zcu.intern_pool.getNav(nav).name;
38372}
38373
38374/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38375/// the `TrackedInst` corresponding to this `declaration` instruction.
38376fn getOwnerCauDeclInst(sema: *Sema) InternPool.TrackedInst.Index {
38377 const ip = &sema.pt.zcu.intern_pool;
38378 const cau = ip.getCau(sema.owner.unwrap().cau);
38379 assert(cau.owner.unwrap() == .nav);
38380 return cau.zir_index;
38381}
38382
38383/// Given that this `Sema` is owned by a runtime function, fetches the
38384/// `TrackedInst` corresponding to its `declaration` instruction.
38385fn getOwnerFuncDeclInst(sema: *Sema) InternPool.TrackedInst.Index {
38386 const zcu = sema.pt.zcu;
38387 const ip = &zcu.intern_pool;
38388 const func = sema.owner.unwrap().func;
38389 const func_info = zcu.funcInfo(func);
38390 const cau = if (func_info.generic_owner == .none) cau: {
38391 break :cau ip.getNav(func_info.owner_nav).analysis_owner.unwrap().?;
38392 } else cau: {
38393 const generic_owner = zcu.funcInfo(func_info.generic_owner);
38394 break :cau ip.getNav(generic_owner.owner_nav).analysis_owner.unwrap().?;
38395 };
38396 return ip.getCau(cau).zir_index;
3843138397}
3843238398
3843338399pub 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+102-90
......@@ -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,
......@@ -2972,41 +2968,27 @@ pub fn indexableHasLen(ty: Type, mod: *Module) bool {
29722968}
29732969
29742970/// Asserts that the type can have a namespace.
2975pub fn getNamespaceIndex(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex {
2976 return ty.getNamespace(zcu).?;
2971pub fn getNamespaceIndex(ty: Type, zcu: *Zcu) InternPool.NamespaceIndex {
2972 return ty.getNamespace(zcu).unwrap().?;
29772973}
29782974
29792975/// Returns null if the type has no namespace.
2980pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {
2976pub fn getNamespace(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex {
29812977 const ip = &zcu.intern_pool;
29822978 return switch (ip.indexToKey(ty.toIntern())) {
2983 .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace,
2979 .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(),
29842980 .struct_type => ip.loadStructType(ty.toIntern()).namespace,
2985 .union_type => ip.loadUnionType(ty.toIntern()).namespace,
2986 .enum_type => ip.loadEnumType(ty.toIntern()).namespace,
2987
2988 .anon_struct_type => .none,
2989 .simple_type => |s| switch (s) {
2990 .anyopaque,
2991 .atomic_order,
2992 .atomic_rmw_op,
2993 .calling_convention,
2994 .address_space,
2995 .float_mode,
2996 .reduce_op,
2997 .call_modifier,
2998 .prefetch_options,
2999 .export_options,
3000 .extern_options,
3001 .type_info,
3002 => .none,
3003 else => null,
3004 },
3005
3006 else => null,
2981 .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(),
2982 .enum_type => ip.loadEnumType(ty.toIntern()).namespace.toOptional(),
2983 else => .none,
30072984 };
30082985}
30092986
2987// TODO: new dwarf structure will also need the enclosing code block for types created in imperative scopes
2988pub fn getParentNamespace(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex {
2989 return zcu.namespacePtr(ty.getNamespace(zcu).unwrap() orelse return .none).parent;
2990}
2991
30102992// Works for vectors and vectors of integers.
30112993pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
30122994 const mod = pt.zcu;
......@@ -3321,21 +3303,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {
33213303 }
33223304}
33233305
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
33393306pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {
33403307 const ip = &zcu.intern_pool;
33413308 return .{
......@@ -3366,7 +3333,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {
33663333 .struct_type => {
33673334 const struct_type = ip.loadStructType(ty.toIntern());
33683335 if (struct_type.layout == .@"packed") return false;
3369 if (struct_type.decl == .none) return false;
3336 if (struct_type.cau == .none) return false;
33703337 return struct_type.flagsUnordered(ip).is_tuple;
33713338 },
33723339 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,
......@@ -3388,7 +3355,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {
33883355 .struct_type => {
33893356 const struct_type = ip.loadStructType(ty.toIntern());
33903357 if (struct_type.layout == .@"packed") return false;
3391 if (struct_type.decl == .none) return false;
3358 if (struct_type.cau == .none) return false;
33923359 return struct_type.flagsUnordered(ip).is_tuple;
33933360 },
33943361 .anon_struct_type => true,
......@@ -3444,6 +3411,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
34443411 };
34453412}
34463413
3414pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3415 const ip = &zcu.intern_pool;
3416 return switch (ip.indexToKey(ty.toIntern())) {
3417 .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(),
3418 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3419 .enum_type => |e| switch (e) {
3420 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3421 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3422 .empty_struct => unreachable,
3423 },
3424 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
3425 else => null,
3426 };
3427}
3428
34473429pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
34483430 const ip = &zcu.intern_pool;
34493431 const tracked = switch (ip.indexToKey(ty.toIntern())) {
......@@ -3471,7 +3453,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
34713453 };
34723454}
34733455
3474/// Given a namespace type, returns its list of caotured values.
3456/// Given a namespace type, returns its list of captured values.
34753457pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
34763458 const ip = &zcu.intern_pool;
34773459 return switch (ip.indexToKey(ty.toIntern())) {
......@@ -3773,7 +3755,11 @@ fn resolveStructInner(
37733755 const gpa = zcu.gpa;
37743756
37753757 const struct_obj = zcu.typeToStruct(ty).?;
3776 const owner_decl_index = struct_obj.decl.unwrap() orelse return;
3758 const owner = InternPool.AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap() orelse return });
3759
3760 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3761 return error.AnalysisFail;
3762 }
37773763
37783764 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
37793765 defer analysis_arena.deinit();
......@@ -3786,24 +3772,30 @@ fn resolveStructInner(
37863772 .gpa = gpa,
37873773 .arena = analysis_arena.allocator(),
37883774 .code = undefined, // This ZIR will not be used.
3789 .owner_decl = zcu.declPtr(owner_decl_index),
3790 .owner_decl_index = owner_decl_index,
3775 .owner = owner,
37913776 .func_index = .none,
37923777 .func_is_naked = false,
37933778 .fn_ret_ty = Type.void,
37943779 .fn_ret_ty_ies = null,
3795 .owner_func_index = .none,
37963780 .comptime_err_ret_trace = &comptime_err_ret_trace,
37973781 };
37983782 defer sema.deinit();
37993783
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 }
3784 (switch (resolution) {
3785 .fields => sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),
3786 .inits => sema.resolveStructFieldInits(ty),
3787 .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3788 .layout => sema.resolveStructLayout(ty),
3789 .full => sema.resolveStructFully(ty),
3790 }) catch |err| switch (err) {
3791 error.AnalysisFail => {
3792 if (!zcu.failed_analysis.contains(owner)) {
3793 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3794 }
3795 return error.AnalysisFail;
3796 },
3797 error.OutOfMemory => |e| return e,
3798 };
38073799}
38083800
38093801/// `ty` must be a union.
......@@ -3816,7 +3808,11 @@ fn resolveUnionInner(
38163808 const gpa = zcu.gpa;
38173809
38183810 const union_obj = zcu.typeToUnion(ty).?;
3819 const owner_decl_index = union_obj.decl;
3811 const owner = InternPool.AnalUnit.wrap(.{ .cau = union_obj.cau });
3812
3813 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3814 return error.AnalysisFail;
3815 }
38203816
38213817 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
38223818 defer analysis_arena.deinit();
......@@ -3829,23 +3825,29 @@ fn resolveUnionInner(
38293825 .gpa = gpa,
38303826 .arena = analysis_arena.allocator(),
38313827 .code = undefined, // This ZIR will not be used.
3832 .owner_decl = zcu.declPtr(owner_decl_index),
3833 .owner_decl_index = owner_decl_index,
3828 .owner = owner,
38343829 .func_index = .none,
38353830 .func_is_naked = false,
38363831 .fn_ret_ty = Type.void,
38373832 .fn_ret_ty_ies = null,
3838 .owner_func_index = .none,
38393833 .comptime_err_ret_trace = &comptime_err_ret_trace,
38403834 };
38413835 defer sema.deinit();
38423836
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 }
3837 (switch (resolution) {
3838 .fields => sema.resolveTypeFieldsUnion(ty, union_obj),
3839 .alignment => sema.resolveUnionAlignment(ty, union_obj),
3840 .layout => sema.resolveUnionLayout(ty),
3841 .full => sema.resolveUnionFully(ty),
3842 }) catch |err| switch (err) {
3843 error.AnalysisFail => {
3844 if (!zcu.failed_analysis.contains(owner)) {
3845 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3846 }
3847 return error.AnalysisFail;
3848 },
3849 error.OutOfMemory => |e| return e,
3850 };
38493851}
38503852
38513853/// Fully resolves a simple type. This is usually a nop, but for builtin types with
......@@ -3945,6 +3947,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {
39453947 });
39463948}
39473949
3950pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
3951 return switch (ip.indexToKey(ty.toIntern())) {
3952 .struct_type => ip.loadStructType(ty.toIntern()).name,
3953 .union_type => ip.loadUnionType(ty.toIntern()).name,
3954 .enum_type => ip.loadEnumType(ty.toIntern()).name,
3955 .opaque_type => ip.loadOpaqueType(ty.toIntern()).name,
3956 else => unreachable,
3957 };
3958}
3959
39483960pub const @"u1": Type = .{ .ip_index = .u1_type };
39493961pub const @"u8": Type = .{ .ip_index = .u8_type };
39503962pub 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+834-844
......@@ -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;
......@@ -901,7 +887,6 @@ fn getFileRootStruct(
901887 .any_default_inits = small.any_default_inits,
902888 .inits_resolved = false,
903889 .any_aligned_fields = small.any_aligned_fields,
904 .has_namespace = true,
905890 .key = .{ .declared = .{
906891 .zir_index = tracked_inst,
907892 .captures = &.{},
......@@ -912,34 +897,37 @@ fn getFileRootStruct(
912897 };
913898 errdefer wip_ty.cancel(ip, pt.tid);
914899
900 wip_ty.setName(ip, try file.internFullyQualifiedName(pt));
901 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;
902 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, namespace_index, wip_ty.index);
903
915904 if (zcu.comp.incremental) {
916905 try ip.addDependency(
917906 gpa,
918 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
907 InternPool.AnalUnit.wrap(.{ .cau = new_cau_index }),
919908 .{ .src_hash = tracked_inst },
920909 );
921910 }
922911
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);
912 try pt.scanNamespace(namespace_index, decls);
930913 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
931 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
914 zcu.setFileRootType(file_index, wip_ty.index);
915 return wip_ty.finish(ip, new_cau_index.toOptional(), namespace_index);
932916}
933917
934/// Re-analyze the root Decl of a file on an incremental update.
918/// Re-analyze the root type of a file on an incremental update.
935919/// If `type_outdated`, the struct type itself is considered outdated and is
936920/// reconstructed at a new InternPool index. Otherwise, the namespace is just
937921/// re-analyzed. Returns whether the decl's tyval was invalidated.
922/// Returns `error.AnalysisFail` if the file has an error.
938923fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {
939924 const zcu = pt.zcu;
940925 const ip = &zcu.intern_pool;
941926 const file = zcu.fileByIndex(file_index);
942 const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?);
927 const file_root_type = zcu.fileRootType(file_index);
928 const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu);
929
930 assert(file_root_type != .none);
943931
944932 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
945933 file.mod.fully_qualified_name,
......@@ -948,33 +936,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
948936 });
949937
950938 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;
939 return error.AnalysisFail;
964940 }
965941
966 assert(decl.has_tv);
967 assert(decl.owns_tv);
968
969942 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);
943 // Invalidate the existing type, reusing its namespace.
944 const file_root_type_cau = ip.loadStructType(file_root_type).cau.unwrap().?;
945 ip.removeDependenciesForDepender(
946 zcu.gpa,
947 InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }),
948 );
949 ip.remove(pt.tid, file_root_type);
950 _ = try pt.createFileRootStruct(file_index, namespace_index);
978951 return true;
979952 }
980953
......@@ -994,7 +967,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
994967 const decls = file.zir.bodySlice(extra_index, decls_len);
995968
996969 if (!type_outdated) {
997 try pt.scanNamespace(decl.src_namespace, decls, decl);
970 try pt.scanNamespace(namespace_index, decls);
998971 }
999972
1000973 return false;
......@@ -1009,43 +982,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1009982 const zcu = pt.zcu;
1010983 const gpa = zcu.gpa;
1011984 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;
985 assert(zcu.fileRootType(file_index) == .none);
1041986
1042987 if (file.status != .success_zir) {
1043 new_decl.analysis = .file_failure;
1044 return;
988 return error.AnalysisFail;
1045989 }
1046990 assert(file.zir_loaded);
1047991
1048 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
992 const new_namespace_index = try pt.createNamespace(.{
993 .parent = .none,
994 .owner_type = undefined, // set in `createFileRootStruct`
995 .file_scope = file_index,
996 });
997 const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index);
1049998 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
1050999
10511000 switch (zcu.comp.cache_use) {
......@@ -1067,98 +1016,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10671016
10681017 whole.cache_manifest_mutex.lock();
10691018 defer whole.cache_manifest_mutex.unlock();
1070 try man.addFilePostContents(resolved_path, source.bytes, source.stat);
1019 man.addFilePostContents(resolved_path, source.bytes, source.stat) catch |err| switch (err) {
1020 error.OutOfMemory => |e| return e,
1021 else => {
1022 try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)});
1023 return error.AnalysisFail;
1024 },
1025 };
10711026 },
10721027 .incremental => {},
10731028 }
10741029}
10751030
1076fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1077 const tracy = trace(@src());
1078 defer tracy.end();
1031const SemaCauResult = packed struct {
1032 /// Whether the value of a `decl_val` of the corresponding Nav changed.
1033 invalidate_decl_val: bool,
1034 /// Whether the type of a `decl_ref` of the corresponding Nav changed.
1035 invalidate_decl_ref: bool,
1036};
10791037
1038/// Performs semantic analysis on the given `Cau`, storing results to its owner `Nav` if needed.
1039/// If analysis fails, returns `error.AnalysisFail`, storing an error in `zcu.failed_analysis` unless
1040/// the error is transitive.
1041/// On success, returns information about whether the `Nav` value changed.
1042fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
10801043 const zcu = pt.zcu;
1081 const decl = zcu.declPtr(decl_index);
1044 const gpa = zcu.gpa;
10821045 const ip = &zcu.intern_pool;
10831046
1084 if (decl.getFileScope(zcu).status != .success_zir) {
1085 return error.AnalysisFail;
1086 }
1047 const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index });
10871048
1088 assert(!zcu.declIsRoot(decl_index));
1049 const cau = ip.getCau(cau_index);
1050 const inst_info = cau.zir_index.resolveFull(ip);
1051 const file = zcu.fileByIndex(inst_info.file);
1052 const zir = file.zir;
10891053
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);
1054 if (file.status != .success_zir) {
1055 return error.AnalysisFail;
10931056 }
10941057
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)});
1058 // We are about to re-analyze this `Cau`; drop its depenndencies.
1059 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
10981060
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);
1061 const builtin_type_target_index: InternPool.Index = switch (cau.owner.unwrap()) {
1062 .none => ip_index: {
1063 // `comptime` decl -- we will re-analyze its body.
1064 // This declaration has no value so is definitely not a std.builtin type.
1065 break :ip_index .none;
1066 },
1067 .type => |ty| {
1068 // This is an incremental update, and this type is being re-analyzed because it is outdated.
1069 // The type must be recreated at a new `InternPool.Index`.
1070 // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed.
1071 ip.remove(pt.tid, ty);
1072 return .{
1073 .invalidate_decl_val = true,
1074 .invalidate_decl_ref = true,
1075 };
1076 },
1077 .nav => |nav| ip_index: {
1078 // Other decl -- we will re-analyze its value.
1079 // This might be a type in `builtin.zig` -- check.
1080 if (file.mod != zcu.std_mod) break :ip_index .none;
1081 // We're in the std module.
1082 const nav_name = ip.getNav(nav).name;
1083 const std_file_imported = try pt.importPkg(zcu.std_mod);
1084 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
1085 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
1086 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
1087 const builtin_nav = ip.getNav(std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse break :ip_index .none);
1088 const builtin_namespace = switch (builtin_nav.status) {
1089 .unresolved => break :ip_index .none,
1090 .resolved => |r| Type.fromInterned(r.val).getNamespace(zcu).unwrap().?,
1091 };
1092 if (cau.namespace != builtin_namespace) break :ip_index .none;
1093 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
1094 for ([_][]const u8{
1095 "AtomicOrder",
1096 "AtomicRmwOp",
1097 "CallingConvention",
1098 "AddressSpace",
1099 "FloatMode",
1100 "ReduceOp",
1101 "CallModifier",
1102 "PrefetchOptions",
1103 "ExportOptions",
1104 "ExternOptions",
1105 "Type",
1106 }, [_]InternPool.Index{
1107 .atomic_order_type,
1108 .atomic_rmw_op_type,
1109 .calling_convention_type,
1110 .address_space_type,
1111 .float_mode_type,
1112 .reduce_op_type,
1113 .call_modifier_type,
1114 .prefetch_options_type,
1115 .export_options_type,
1116 .extern_options_type,
1117 .type_info_type,
1118 }) |type_name, type_ip| {
1119 if (nav_name.eqlSlice(type_name, ip)) break :ip_index type_ip;
1120 }
1121 break :ip_index .none;
1122 },
1123 };
11121124
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;
1125 const is_usingnamespace = switch (cau.owner.unwrap()) {
1126 .nav => |nav| ip.getNav(nav).is_usingnamespace,
1127 .none, .type => false,
11571128 };
11581129
1159 zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1130 log.debug("semaCau '{d}'", .{@intFromEnum(cau_index)});
11601131
1161 decl.analysis = .in_progress;
1132 try zcu.analysis_in_progress.put(gpa, anal_unit, {});
1133 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
11621134
11631135 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
11641136 defer analysis_arena.deinit();
......@@ -1171,224 +1143,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
11711143 .gpa = gpa,
11721144 .arena = analysis_arena.allocator(),
11731145 .code = zir,
1174 .owner_decl = decl,
1175 .owner_decl_index = decl_index,
1146 .owner = anal_unit,
11761147 .func_index = .none,
11771148 .func_is_naked = false,
11781149 .fn_ret_ty = Type.void,
11791150 .fn_ret_ty_ies = null,
1180 .owner_func_index = .none,
11811151 .comptime_err_ret_trace = &comptime_err_ret_trace,
11821152 .builtin_type_target_index = builtin_type_target_index,
11831153 };
11841154 defer sema.deinit();
11851155
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 }) });
1156 // Every `Cau` has a dependency on the source of its own ZIR instruction.
1157 try sema.declareDependency(.{ .src_hash = cau.zir_index });
11911158
1192 var block_scope: Sema.Block = .{
1159 var block: Sema.Block = .{
11931160 .parent = null,
11941161 .sema = &sema,
1195 .namespace = decl.src_namespace,
1162 .namespace = cau.namespace,
11961163 .instructions = .{},
11971164 .inlining = null,
11981165 .is_comptime = true,
1199 .src_base_inst = decl.zir_decl_index.unwrap().?,
1200 .type_name_ctx = decl.name,
1166 .src_base_inst = cau.zir_index,
1167 .type_name_ctx = switch (cau.owner.unwrap()) {
1168 .nav => |nav| ip.getNav(nav).fqn,
1169 .type => |ty| Type.fromInterned(ty).containerTypeName(ip),
1170 .none => try ip.getOrPutStringFmt(gpa, pt.tid, "{}.comptime", .{
1171 Type.fromInterned(zcu.namespacePtr(cau.namespace).owner_type).containerTypeName(ip).fmt(ip),
1172 }, .no_embedded_nulls),
1173 },
1174 };
1175 defer block.instructions.deinit(gpa);
1176
1177 const zir_decl: Zir.Inst.Declaration, const decl_bodies: Zir.Inst.Declaration.Bodies = decl: {
1178 const decl, const extra_end = zir.getDeclaration(inst_info.inst);
1179 break :decl .{ decl, decl.getBodies(extra_end, zir) };
1180 };
1181
1182 // We have to fetch this state before resolving the body because of the `nav_already_populated`
1183 // case below. We might change the language in future so that align/linksection/etc for functions
1184 // work in a way more in line with other declarations, in which case that logic will go away.
1185 const old_nav_info = switch (cau.owner.unwrap()) {
1186 .none, .type => undefined, // we'll never use `old_nav_info`
1187 .nav => |nav| ip.getNav(nav),
12011188 };
1202 defer block_scope.instructions.deinit(gpa);
12031189
1204 const decl_bodies = decl.zirBodies(zcu);
1190 const result_ref = try sema.resolveInlineBody(&block, decl_bodies.value_body, inst_info.inst);
12051191
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.
1192 const nav_index = switch (cau.owner.unwrap()) {
1193 .none => {
1194 // This is a `comptime` decl, so we are done -- the side effects are all we care about.
1195 // Just make sure to `flushExports`.
1196 try sema.flushExports();
1197 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1198 return .{
1199 .invalidate_decl_val = false,
1200 .invalidate_decl_ref = false,
1201 };
1202 },
1203 .nav => |nav| nav, // We will resolve this `Nav` below.
1204 .type => unreachable, // Handled at top of function.
1205 };
1206
1207 // We'll do more work with the Sema. Clear the target type index just in case we analyze any type.
12091208 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);
1209
1210 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
1211 const section_src = block.src(.{ .node_offset_var_decl_section = 0 });
1212 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
1213 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
1214 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
1215
1216 const decl_val = try sema.resolveFinalDeclValue(&block, init_src, result_ref);
12161217 const decl_ty = decl_val.typeOf(zcu);
12171218
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.
1219 switch (decl_val.toIntern()) {
1220 .generic_poison => unreachable, // assertion failure
1221 .unreachable_value => unreachable, // assertion failure
1222 else => {},
1223 }
1224
1225 // This resolves the type of the resolved value, not that value itself. If `decl_val` is a struct type,
1226 // this resolves the type `type` (which needs no resolution), not the struct itself.
12211227 try decl_ty.resolveLayout(pt);
12221228
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)});
1229 // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`.
1230 if (is_usingnamespace) {
1231 if (decl_ty.toIntern() != .type_type) {
1232 return sema.fail(&block, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
12261233 }
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)});
1234 if (decl_val.toType().getNamespace(zcu) == .none) {
1235 return sema.fail(&block, ty_src, "type {} has no namespace", .{decl_val.toType().fmt(pt)});
12301236 }
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
1237 ip.resolveNavValue(nav_index, .{
1238 .val = decl_val.toIntern(),
1239 .alignment = .none,
1240 .@"linksection" = .none,
1241 .@"addrspace" = .generic,
1242 });
1243 // TODO: usingnamespace cannot participate in incremental compilation
1244 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
12401245 return .{
12411246 .invalidate_decl_val = true,
12421247 .invalidate_decl_ref = true,
12431248 };
12441249 }
12451250
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 }
1251 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
1252 .func => |f| .{ f.owner_nav == nav_index, false },
1253 .variable => |v| .{ false, v.owner_nav == nav_index },
1254 .@"extern" => .{ false, false },
1255 else => .{ false, true },
1256 };
12741257
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);
1258 if (nav_already_populated) {
1259 // This is a function declaration.
1260 // Logic in `Sema.funcCommon` has already populated the `Nav` for us.
1261 assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern());
1262 } else {
1263 // Keep in sync with logic in `Sema.zirVarExtended`.
1264 const alignment: InternPool.Alignment = a: {
1265 const align_body = decl_bodies.align_body orelse break :a .none;
1266 const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst);
1267 break :a try sema.analyzeAsAlign(&block, align_src, align_ref);
12821268 };
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, .{
1269
1270 const @"linksection": InternPool.OptionalNullTerminatedString = ls: {
1271 const linksection_body = decl_bodies.linksection_body orelse break :ls .none;
1272 const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst);
1273 const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{
12871274 .needed_comptime_reason = "linksection must be comptime-known",
12881275 });
12891276 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {
1290 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
1277 return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{});
12911278 } else if (bytes.len == 0) {
1292 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
1279 return sema.fail(&block, section_src, "linksection cannot be empty", .{});
12931280 }
1294 break :blk try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
1281 break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
12951282 };
1296 decl.@"addrspace" = blk: {
1283
1284 const @"addrspace": std.builtin.AddressSpace = as: {
12971285 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
1286 .func => .function,
12981287 .variable => .variable,
1299 .extern_func, .func => .function,
1288 .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type)
1289 .function
1290 else
1291 .variable,
13001292 else => .constant,
13011293 };
1302
13031294 const target = zcu.getTarget();
1304
1305 const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) {
1295 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
13061296 .function => target_util.defaultAddressSpace(target, .function),
13071297 .variable => target_util.defaultAddressSpace(target, .global_mutable),
13081298 .constant => target_util.defaultAddressSpace(target, .global_constant),
13091299 else => unreachable,
13101300 };
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);
1301 const addrspace_ref = try sema.resolveInlineBody(&block, addrspace_body, inst_info.inst);
1302 break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx);
13131303 };
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 });
13391304
1340 if (result.invalidate_decl_ref and zcu.emit_h != null) {
1341 try zcu.comp.queueJob(.{ .emit_h_decl = decl_index });
1342 }
1305 ip.resolveNavValue(nav_index, .{
1306 .val = decl_val.toIntern(),
1307 .alignment = alignment,
1308 .@"linksection" = @"linksection",
1309 .@"addrspace" = @"addrspace",
1310 });
13431311 }
13441312
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);
1313 // Mark the `Cau` as completed before evaluating the export!
1314 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1315
1316 if (zir_decl.flags.is_export) {
1317 const export_src = block.src(.{ .token_offset = @intFromBool(zir_decl.flags.is_pub) });
1318 const name_slice = zir.nullTerminatedString(zir_decl.name.toString(zir).?);
1319 const name_ip = try ip.getOrPutString(gpa, pt.tid, name_slice, .no_embedded_nulls);
1320 try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_index);
13501321 }
13511322
13521323 try sema.flushExports();
13531324
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);
1325 queue_codegen: {
1326 if (!queue_linker_work) break :queue_codegen;
13601327
1361 assert(decl.has_tv);
1362 assert(decl.owns_tv);
1328 // Needed for codegen_nav which will call updateDecl and then the
1329 // codegen backend wants full access to the Decl Type.
1330 // We also need this for the `isFnOrHasRuntimeBits` check below.
1331 // TODO: we could make the language more lenient by deferring this work
1332 // to the `codegen_nav` job.
1333 try decl_ty.resolveFully(pt);
13631334
1364 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
1335 if (!decl_ty.isFnOrHasRuntimeBits(pt)) break :queue_codegen;
13651336
1366 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
1367 .Fn => @panic("TODO: update fn instance"),
1368 .Type => {},
1369 else => unreachable,
1337 try zcu.comp.queueJob(.{ .codegen_nav = nav_index });
13701338 }
13711339
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 };
1340 switch (old_nav_info.status) {
1341 .unresolved => return .{
1342 .invalidate_decl_val = true,
1343 .invalidate_decl_ref = true,
1344 },
1345 .resolved => |old| {
1346 const new = ip.getNav(nav_index).status.resolved;
1347 return .{
1348 .invalidate_decl_val = new.val != old.val,
1349 .invalidate_decl_ref = ip.typeOf(new.val) != ip.typeOf(old.val) or
1350 new.alignment != old.alignment or
1351 new.@"linksection" != old.@"linksection" or
1352 new.@"addrspace" != old.@"addrspace",
1353 };
1354 },
1355 }
13921356}
13931357
13941358pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
......@@ -1426,7 +1390,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
14261390 const file_index = try ip.createFile(gpa, pt.tid, .{
14271391 .bin_digest = path_digest,
14281392 .file = builtin_file,
1429 .root_decl = .none,
1393 .root_type = .none,
14301394 });
14311395 keep_resolved_path = true; // It's now owned by import_table.
14321396 gop.value_ptr.* = file_index;
......@@ -1453,7 +1417,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
14531417 const new_file_index = try ip.createFile(gpa, pt.tid, .{
14541418 .bin_digest = path_digest,
14551419 .file = new_file,
1456 .root_decl = .none,
1420 .root_type = .none,
14571421 });
14581422 keep_resolved_path = true; // It's now owned by import_table.
14591423 gop.value_ptr.* = new_file_index;
......@@ -1563,7 +1527,7 @@ pub fn importFile(
15631527 const new_file_index = try ip.createFile(gpa, pt.tid, .{
15641528 .bin_digest = path_digest,
15651529 .file = new_file,
1566 .root_decl = .none,
1530 .root_type = .none,
15671531 });
15681532 keep_resolved_path = true; // It's now owned by import_table.
15691533 gop.value_ptr.* = new_file_index;
......@@ -1726,7 +1690,7 @@ fn newEmbedFile(
17261690 })).toIntern();
17271691 const ptr_val = try pt.intern(.{ .ptr = .{
17281692 .ty = ptr_ty,
1729 .base_addr = .{ .anon_decl = .{
1693 .base_addr = .{ .uav = .{
17301694 .val = array_val,
17311695 .orig_ty = ptr_ty,
17321696 } },
......@@ -1748,39 +1712,70 @@ pub fn scanNamespace(
17481712 pt: Zcu.PerThread,
17491713 namespace_index: Zcu.Namespace.Index,
17501714 decls: []const Zir.Inst.Index,
1751 parent_decl: *Zcu.Decl,
17521715) Allocator.Error!void {
17531716 const tracy = trace(@src());
17541717 defer tracy.end();
17551718
17561719 const zcu = pt.zcu;
1720 const ip = &zcu.intern_pool;
17571721 const gpa = zcu.gpa;
17581722 const namespace = zcu.namespacePtr(namespace_index);
17591723
17601724 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
17611725 // 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) = .{};
1726 // We map to the `Cau`, since not every declaration has a `Nav`.
1727 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index) = .{};
17631728 defer existing_by_inst.deinit(gpa);
17641729
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);
1730 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(
1731 namespace.pub_decls.count() + namespace.priv_decls.count() +
1732 namespace.pub_usingnamespace.items.len + namespace.priv_usingnamespace.items.len +
1733 namespace.other_decls.items.len,
1734 ));
1735
1736 for (namespace.pub_decls.keys()) |nav| {
1737 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1738 const zir_index = ip.getCau(cau_index).zir_index;
1739 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1740 }
1741 for (namespace.priv_decls.keys()) |nav| {
1742 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1743 const zir_index = ip.getCau(cau_index).zir_index;
1744 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1745 }
1746 for (namespace.pub_usingnamespace.items) |nav| {
1747 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1748 const zir_index = ip.getCau(cau_index).zir_index;
1749 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1750 }
1751 for (namespace.priv_usingnamespace.items) |nav| {
1752 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1753 const zir_index = ip.getCau(cau_index).zir_index;
1754 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1755 }
1756 for (namespace.other_decls.items) |cau_index| {
1757 const cau = ip.getCau(cau_index);
1758 existing_by_inst.putAssumeCapacityNoClobber(cau.zir_index, cau_index);
1759 // If this is a test, it'll be re-added to `test_functions` later on
1760 // if still alive. Remove it for now.
1761 switch (cau.owner.unwrap()) {
1762 .none, .type => {},
1763 .nav => |nav| _ = zcu.test_functions.swapRemove(nav),
1764 }
17701765 }
17711766
17721767 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
17731768 defer seen_decls.deinit(gpa);
17741769
1775 namespace.decls.clearRetainingCapacity();
1776 try namespace.decls.ensureTotalCapacity(gpa, decls.len);
1777
1778 namespace.usingnamespace_set.clearRetainingCapacity();
1770 namespace.pub_decls.clearRetainingCapacity();
1771 namespace.priv_decls.clearRetainingCapacity();
1772 namespace.pub_usingnamespace.clearRetainingCapacity();
1773 namespace.priv_usingnamespace.clearRetainingCapacity();
1774 namespace.other_decls.clearRetainingCapacity();
17791775
17801776 var scan_decl_iter: ScanDeclIter = .{
17811777 .pt = pt,
17821778 .namespace_index = namespace_index,
1783 .parent_decl = parent_decl,
17841779 .seen_decls = &seen_decls,
17851780 .existing_by_inst = &existing_by_inst,
17861781 .pass = .named,
......@@ -1792,34 +1787,17 @@ pub fn scanNamespace(
17921787 for (decls) |decl_inst| {
17931788 try scan_decl_iter.scanDecl(decl_inst);
17941789 }
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 }
18101790}
18111791
18121792const ScanDeclIter = struct {
18131793 pt: Zcu.PerThread,
18141794 namespace_index: Zcu.Namespace.Index,
1815 parent_decl: *Zcu.Decl,
18161795 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
1817 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index),
1796 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index),
18181797 /// Decl scanning is run in two passes, so that we can detect when a generated
18191798 /// name would clash with an explicit name and use a different one.
18201799 pass: enum { named, unnamed },
18211800 usingnamespace_index: usize = 0,
1822 comptime_index: usize = 0,
18231801 unnamed_test_index: usize = 0,
18241802
18251803 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
......@@ -1843,37 +1821,35 @@ const ScanDeclIter = struct {
18431821
18441822 const pt = iter.pt;
18451823 const zcu = pt.zcu;
1824 const comp = zcu.comp;
18461825 const namespace_index = iter.namespace_index;
18471826 const namespace = zcu.namespacePtr(namespace_index);
18481827 const gpa = zcu.gpa;
1849 const zir = namespace.fileScope(zcu).zir;
1828 const file = namespace.fileScope(zcu);
1829 const zir = file.zir;
18501830 const ip = &zcu.intern_pool;
18511831
18521832 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
18531833 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
18541834 const declaration = extra.data;
18551835
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) {
1836 const Kind = enum { @"comptime", @"usingnamespace", @"test", named };
1837
1838 const maybe_name: InternPool.OptionalNullTerminatedString, const kind: Kind, const is_named_test: bool = switch (declaration.name) {
18581839 .@"comptime" => info: {
18591840 if (iter.pass != .unnamed) return;
1860 const i = iter.comptime_index;
1861 iter.comptime_index += 1;
18621841 break :info .{
1863 try iter.avoidNameConflict("comptime_{d}", .{i}),
1842 .none,
18641843 .@"comptime",
18651844 false,
18661845 };
18671846 },
18681847 .@"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;
1848 if (iter.pass != .unnamed) return;
18731849 const i = iter.usingnamespace_index;
18741850 iter.usingnamespace_index += 1;
18751851 break :info .{
1876 try iter.avoidNameConflict("usingnamespace_{d}", .{i}),
1852 (try iter.avoidNameConflict("usingnamespace_{d}", .{i})).toOptional(),
18771853 .@"usingnamespace",
18781854 false,
18791855 };
......@@ -1883,7 +1859,7 @@ const ScanDeclIter = struct {
18831859 const i = iter.unnamed_test_index;
18841860 iter.unnamed_test_index += 1;
18851861 break :info .{
1886 try iter.avoidNameConflict("test_{d}", .{i}),
1862 (try iter.avoidNameConflict("test_{d}", .{i})).toOptional(),
18871863 .@"test",
18881864 false,
18891865 };
......@@ -1894,7 +1870,7 @@ const ScanDeclIter = struct {
18941870 assert(declaration.flags.has_doc_comment);
18951871 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
18961872 break :info .{
1897 try iter.avoidNameConflict("decltest.{s}", .{name}),
1873 (try iter.avoidNameConflict("decltest.{s}", .{name})).toOptional(),
18981874 .@"test",
18991875 true,
19001876 };
......@@ -1903,7 +1879,7 @@ const ScanDeclIter = struct {
19031879 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
19041880 if (iter.pass != .unnamed) return;
19051881 break :info .{
1906 try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),
1882 (try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)})).toOptional(),
19071883 .@"test",
19081884 true,
19091885 };
......@@ -1917,132 +1893,144 @@ const ScanDeclIter = struct {
19171893 );
19181894 try iter.seen_decls.putNoClobber(gpa, name, {});
19191895 break :info .{
1920 name,
1896 name.toOptional(),
19211897 .named,
19221898 false,
19231899 };
19241900 },
19251901 };
19261902
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);
19341903 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
1935 .file = parent_file_scope_index,
1904 .file = namespace.file_scope,
19361905 .inst = decl_inst,
19371906 });
19381907
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 });
1908 const existing_cau = iter.existing_by_inst.get(tracked_inst);
1909
1910 const cau, const want_analysis = switch (kind) {
1911 .@"comptime" => cau: {
1912 const cau = existing_cau orelse try ip.createComptimeCau(gpa, pt.tid, tracked_inst, namespace_index);
1913
1914 // For a `comptime` declaration, whether to re-analyze is based solely on whether the
1915 // `Cau` is outdated. So, add this one to `outdated` and `outdated_ready` if not already.
1916 const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
1917 if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| {
1918 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1919 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1920 zcu.outdated.putAssumeCapacityNoClobber(unit, kv.value);
1921 if (kv.value == 0) { // no PO deps
1922 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1923 }
1924 } else if (!zcu.outdated.contains(unit)) {
1925 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1926 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1927 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
1928 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1929 }
19671930
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;
1931 break :cau .{ cau, true };
19761932 },
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;
1933 else => cau: {
1934 const name = maybe_name.unwrap().?;
1935 const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name);
1936 const cau, const nav = if (existing_cau) |cau_index| cau_nav: {
1937 const nav_index = ip.getCau(cau_index).owner.unwrap().nav;
1938 const nav = ip.getNav(nav_index);
1939 assert(nav.name == name);
1940 assert(nav.fqn == fqn);
1941 break :cau_nav .{ cau_index, nav_index };
1942 } else try ip.createPairedCauNav(gpa, pt.tid, name, fqn, tracked_inst, namespace_index, kind == .@"usingnamespace");
1943 const want_analysis = switch (kind) {
1944 .@"comptime" => unreachable,
1945 .@"usingnamespace" => a: {
1946 if (declaration.flags.is_pub) {
1947 try namespace.pub_usingnamespace.append(gpa, nav);
1948 } else {
1949 try namespace.priv_usingnamespace.append(gpa, nav);
1950 }
1951 break :a true;
1952 },
1953 .@"test" => a: {
1954 try namespace.other_decls.append(gpa, cau);
1955 // TODO: incremental compilation!
1956 // * remove from `test_functions` if no longer matching filter
1957 // * add to `test_functions` if newly passing filter
1958 // This logic is unaware of incremental: we'll end up with duplicates.
1959 // Perhaps we should add all test indiscriminately and filter at the end of the update.
1960 if (!comp.config.is_test) break :a false;
1961 if (file.mod != zcu.main_mod) break :a false;
1962 if (is_named_test and comp.test_filters.len > 0) {
1963 const fqn_slice = fqn.toSlice(ip);
1964 for (comp.test_filters) |test_filter| {
1965 if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break;
1966 } else break :a false;
1967 }
1968 try zcu.test_functions.put(gpa, nav, {});
1969 break :a true;
1970 },
1971 .named => a: {
1972 if (declaration.flags.is_pub) {
1973 try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
1974 } else {
1975 try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
1976 }
1977 break :a false;
1978 },
1979 };
1980 break :cau .{ cau, want_analysis };
19891981 },
19901982 };
19911983
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 }
1984 if (want_analysis or declaration.flags.is_export) {
1985 log.debug(
1986 "scanDecl queue analyze_cau file='{s}' cau_index={d}",
1987 .{ namespace.fileScope(zcu).sub_file_path, cau },
1988 );
1989 try comp.queueJob(.{ .analyze_cau = cau });
20021990 }
20031991
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 }
1992 // TODO: we used to do line number updates here, but this is an inappropriate place for this logic to live.
20111993 }
20121994};
20131995
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 {
1996fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!Air {
20291997 const tracy = trace(@src());
20301998 defer tracy.end();
20311999
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);
2000 const zcu = pt.zcu;
2001 const gpa = zcu.gpa;
2002 const ip = &zcu.intern_pool;
2003
2004 const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index });
2005 const func = zcu.funcInfo(func_index);
2006 const inst_info = func.zir_body_inst.resolveFull(ip);
2007 const file = zcu.fileByIndex(inst_info.file);
2008 const zir = file.zir;
2009
2010 try zcu.analysis_in_progress.put(gpa, anal_unit, {});
2011 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
2012
2013 func.setAnalysisState(ip, .analyzed);
2014
2015 // This is the `Cau` corresponding to the `declaration` instruction which the function or its generic owner originates from.
2016 const decl_cau = ip.getCau(cau: {
2017 const orig_nav = if (func.generic_owner == .none)
2018 func.owner_nav
2019 else
2020 zcu.funcInfo(func.generic_owner).owner_nav;
2021
2022 break :cau ip.getNav(orig_nav).analysis_owner.unwrap().?;
2023 });
20382024
2039 log.debug("func name '{}'", .{decl.fqn.fmt(ip)});
2040 defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
2025 const func_nav = ip.getNav(func.owner_nav);
20412026
2042 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
2027 const decl_prog_node = zcu.sema_prog_node.start(func_nav.fqn.toSlice(ip), 0);
20432028 defer decl_prog_node.end();
20442029
2045 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
2030 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
2031
2032 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
2033 defer analysis_arena.deinit();
20462034
20472035 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
20482036 defer comptime_err_ret_trace.deinit();
......@@ -2052,21 +2040,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20522040 // the runtime-known parameters only, not to be confused with the
20532041 // generic_owner function type, which potentially has more parameters,
20542042 // including comptime parameters.
2055 const fn_ty = decl.typeOf(mod);
2056 const fn_ty_info = mod.typeToFunc(fn_ty).?;
2043 const fn_ty = Type.fromInterned(func.ty);
2044 const fn_ty_info = zcu.typeToFunc(fn_ty).?;
20572045
20582046 var sema: Sema = .{
20592047 .pt = pt,
20602048 .gpa = gpa,
2061 .arena = arena,
2062 .code = decl.getFileScope(mod).zir,
2063 .owner_decl = decl,
2064 .owner_decl_index = decl_index,
2049 .arena = analysis_arena.allocator(),
2050 .code = zir,
2051 .owner = anal_unit,
20652052 .func_index = func_index,
20662053 .func_is_naked = fn_ty_info.cc == .Naked,
20672054 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
20682055 .fn_ret_ty_ies = null,
2069 .owner_func_index = func_index,
20702056 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),
20712057 .comptime_err_ret_trace = &comptime_err_ret_trace,
20722058 };
......@@ -2074,11 +2060,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20742060
20752061 // Every runtime function has a dependency on the source of the Decl it originates from.
20762062 // 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 });
2063 try sema.declareDependency(.{ .src_hash = decl_cau.zir_index });
2064 try sema.declareDependency(.{ .nav_val = func.owner_nav });
20792065
20802066 if (func.analysisUnordered(ip).inferred_error_set) {
2081 const ies = try arena.create(Sema.InferredErrorSet);
2067 const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet);
20822068 ies.* = .{ .func = func_index };
20832069 sema.fn_ret_ty_ies = ies;
20842070 }
......@@ -2094,19 +2080,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20942080 var inner_block: Sema.Block = .{
20952081 .parent = null,
20962082 .sema = &sema,
2097 .namespace = decl.src_namespace,
2083 .namespace = decl_cau.namespace,
20982084 .instructions = .{},
20992085 .inlining = null,
21002086 .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,
2087 .src_base_inst = decl_cau.zir_index,
2088 .type_name_ctx = func_nav.fqn,
21102089 };
21112090 defer inner_block.instructions.deinit(gpa);
21122091
......@@ -2144,10 +2123,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
21442123 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
21452124 if (gop.found_existing) continue; // provided above by comptime arg
21462125
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,
2126 const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
2127 const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
2128 .param_anytype => param_inst_info.data.str_tok.start,
2129 .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
21512130 else => unreachable,
21522131 };
21532132
......@@ -2179,8 +2158,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
21792158 });
21802159 }
21812160
2182 func.setAnalysisState(ip, .in_progress);
2183
21842161 const last_arg_index = inner_block.instructions.items.len;
21852162
21862163 // Save the error trace as our first action in the function.
......@@ -2190,9 +2167,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
21902167 inner_block.error_return_trace_index = error_return_trace_index;
21912168
21922169 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"),
2170 error.GenericPoison => unreachable,
2171 error.ComptimeReturn => unreachable,
21962172 else => |e| return e,
21972173 };
21982174
......@@ -2207,14 +2183,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
22072183
22082184 // If we don't get an error return trace from a caller, create our own.
22092185 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))
2186 zcu.comp.config.any_error_tracing and
2187 !sema.fn_ret_ty.isError(zcu))
22122188 {
22132189 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"),
2190 error.GenericPoison => unreachable,
2191 error.ComptimeReturn => unreachable,
2192 error.ComptimeBreak => unreachable,
22182193 else => |e| return e,
22192194 };
22202195 }
......@@ -2239,35 +2214,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
22392214 error.GenericPoison => unreachable,
22402215 error.ComptimeReturn => unreachable,
22412216 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 },
22482217 else => |e| return e,
22492218 };
22502219 assert(ies.resolved != .none);
22512220 ip.funcSetIesResolved(func_index, ies.resolved);
22522221 }
22532222
2254 func.setAnalysisState(ip, .success);
2223 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
22552224
22562225 // Finally we must resolve the return type and parameter types so that backends
22572226 // have full access to type information.
22582227 // Crucially, this happens *after* we set the function state to success above,
22592228 // so that dependencies on the function body will now be satisfied rather than
22602229 // result in circular dependency errors.
2230 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
2231 // The codegen timing guarantees that the parameter types will be populated.
22612232 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
22622233 error.GenericPoison => unreachable,
22632234 error.ComptimeReturn => unreachable,
22642235 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 },
22712236 else => |e| return e,
22722237 };
22732238
......@@ -2287,36 +2252,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index)
22872252 return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index);
22882253}
22892254
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
23202255pub fn getErrorValue(
23212256 pt: Zcu.PerThread,
23222257 name: InternPool.NullTerminatedString,
......@@ -2328,25 +2263,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err
23282263 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
23292264}
23302265
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
23502266fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
23512267 switch (file.status) {
23522268 .success_zir, .retryable_failure => {},
......@@ -2367,35 +2283,35 @@ pub fn processExports(pt: Zcu.PerThread) !void {
23672283 const zcu = pt.zcu;
23682284 const gpa = zcu.gpa;
23692285
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)) = .{};
2286 // First, construct a mapping of every exported value and Nav to the indices of all its different exports.
2287 var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .{};
2288 var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
23732289 defer {
2374 for (decl_exports.values()) |*exports| {
2290 for (nav_exports.values()) |*exports| {
23752291 exports.deinit(gpa);
23762292 }
2377 decl_exports.deinit(gpa);
2378 for (value_exports.values()) |*exports| {
2293 nav_exports.deinit(gpa);
2294 for (uav_exports.values()) |*exports| {
23792295 exports.deinit(gpa);
23802296 }
2381 value_exports.deinit(gpa);
2297 uav_exports.deinit(gpa);
23822298 }
23832299
23842300 // We note as a heuristic:
23852301 // * It is rare to export a value.
2386 // * It is rare for one Decl to be exported multiple times.
2302 // * It is rare for one Nav to be exported multiple times.
23872303 // 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());
2304 try nav_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
23892305
23902306 for (zcu.single_exports.values()) |export_idx| {
23912307 const exp = zcu.all_exports.items[export_idx];
23922308 const value_ptr, const found_existing = switch (exp.exported) {
2393 .decl_index => |i| gop: {
2394 const gop = try decl_exports.getOrPut(gpa, i);
2309 .nav => |nav| gop: {
2310 const gop = try nav_exports.getOrPut(gpa, nav);
23952311 break :gop .{ gop.value_ptr, gop.found_existing };
23962312 },
2397 .value => |i| gop: {
2398 const gop = try value_exports.getOrPut(gpa, i);
2313 .uav => |uav| gop: {
2314 const gop = try uav_exports.getOrPut(gpa, uav);
23992315 break :gop .{ gop.value_ptr, gop.found_existing };
24002316 },
24012317 };
......@@ -2406,12 +2322,12 @@ pub fn processExports(pt: Zcu.PerThread) !void {
24062322 for (zcu.multi_exports.values()) |info| {
24072323 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {
24082324 const value_ptr, const found_existing = switch (exp.exported) {
2409 .decl_index => |i| gop: {
2410 const gop = try decl_exports.getOrPut(gpa, i);
2325 .nav => |nav| gop: {
2326 const gop = try nav_exports.getOrPut(gpa, nav);
24112327 break :gop .{ gop.value_ptr, gop.found_existing };
24122328 },
2413 .value => |i| gop: {
2414 const gop = try value_exports.getOrPut(gpa, i);
2329 .uav => |uav| gop: {
2330 const gop = try uav_exports.getOrPut(gpa, uav);
24152331 break :gop .{ gop.value_ptr, gop.found_existing };
24162332 },
24172333 };
......@@ -2424,13 +2340,13 @@ pub fn processExports(pt: Zcu.PerThread) !void {
24242340 var symbol_exports: SymbolExports = .{};
24252341 defer symbol_exports.deinit(gpa);
24262342
2427 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {
2428 const exported: Zcu.Exported = .{ .decl_index = exported_decl };
2343 for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| {
2344 const exported: Zcu.Exported = .{ .nav = exported_nav };
24292345 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
24302346 }
24312347
2432 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {
2433 const exported: Zcu.Exported = .{ .value = exported_value };
2348 for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| {
2349 const exported: Zcu.Exported = .{ .uav = exported_uav };
24342350 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
24352351 }
24362352}
......@@ -2467,20 +2383,31 @@ fn processExportsInner(
24672383 }
24682384
24692385 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;
2386 .nav => |nav_index| if (failed: {
2387 const nav = ip.getNav(nav_index);
2388 if (zcu.failed_codegen.contains(nav_index)) break :failed true;
2389 if (nav.analysis_owner.unwrap()) |cau| {
2390 const cau_unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
2391 if (zcu.failed_analysis.contains(cau_unit)) break :failed true;
2392 if (zcu.transitive_failed_analysis.contains(cau_unit)) break :failed true;
2393 }
2394 const val = switch (nav.status) {
2395 .unresolved => break :failed true,
2396 .resolved => |r| Value.fromInterned(r.val),
2397 };
2398 // If the value is a function, we also need to check if that function succeeded analysis.
2399 if (val.typeOf(zcu).zigTypeTag(zcu) == .Fn) {
2400 const func_unit = InternPool.AnalUnit.wrap(.{ .func = val.toIntern() });
2401 if (zcu.failed_analysis.contains(func_unit)) break :failed true;
2402 if (zcu.transitive_failed_analysis.contains(func_unit)) break :failed true;
2403 }
2404 break :failed false;
24782405 }) {
24792406 // This `Decl` is failed, so was never sent to codegen.
24802407 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?
24812408 return;
24822409 },
2483 .value => {},
2410 .uav => {},
24842411 }
24852412
24862413 if (zcu.comp.bin_file) |lf| {
......@@ -2499,46 +2426,49 @@ pub fn populateTestFunctions(
24992426 const ip = &zcu.intern_pool;
25002427 const builtin_mod = zcu.root_mod.getBuiltinDependency();
25012428 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 },
2429 pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) {
2430 error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt
2431 error.OutOfMemory => |e| return e,
2432 };
2433 const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index));
2434 const builtin_namespace = builtin_root_type.getNamespace(zcu).unwrap().?;
2435 const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted(
2436 try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls),
2437 Zcu.Namespace.NameAdapter{ .zcu = zcu },
25092438 ).?;
25102439 {
2511 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
2440 // We have to call `ensureCauAnalyzed` here in case `builtin.test_functions`
25122441 // was not referenced by start code.
25132442 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
25142443 defer {
25152444 zcu.sema_prog_node.end();
25162445 zcu.sema_prog_node = std.Progress.Node.none;
25172446 }
2518 try pt.ensureDeclAnalyzed(decl_index);
2447 const cau_index = ip.getNav(nav_index).analysis_owner.unwrap().?;
2448 try pt.ensureCauAnalyzed(cau_index);
25192449 }
25202450
2521 const decl = zcu.declPtr(decl_index);
2522 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
2451 const test_fns_val = zcu.navValue(nav_index);
2452 const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
25232453
2524 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: {
2454 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = array: {
25252455 // Add zcu.test_functions to an array decl then make the test_functions
25262456 // decl reference it as a slice.
25272457 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
25282458 defer gpa.free(test_fn_vals);
25292459
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: {
2460 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_nav_index| {
2461 const test_nav = ip.getNav(test_nav_index);
2462 const test_nav_name = test_nav.fqn;
2463 const test_nav_name_len = test_nav_name.length(ip);
2464 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = n: {
25352465 const test_name_ty = try pt.arrayType(.{
2536 .len = test_decl_name_len,
2466 .len = test_nav_name_len,
25372467 .child = .u8_type,
25382468 });
25392469 const test_name_val = try pt.intern(.{ .aggregate = .{
25402470 .ty = test_name_ty.toIntern(),
2541 .storage = .{ .bytes = test_decl_name.toString() },
2471 .storage = .{ .bytes = test_nav_name.toString() },
25422472 } });
25432473 break :n .{
25442474 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),
......@@ -2552,23 +2482,18 @@ pub fn populateTestFunctions(
25522482 .ty = .slice_const_u8_type,
25532483 .ptr = try pt.intern(.{ .ptr = .{
25542484 .ty = .manyptr_const_u8_type,
2555 .base_addr = .{ .anon_decl = test_name_anon_decl },
2485 .base_addr = .{ .uav = test_name_anon_decl },
25562486 .byte_offset = 0,
25572487 } }),
25582488 .len = try pt.intern(.{ .int = .{
25592489 .ty = .usize_type,
2560 .storage = .{ .u64 = test_decl_name_len },
2490 .storage = .{ .u64 = test_nav_name_len },
25612491 } }),
25622492 } }),
25632493 // func
25642494 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 },
2495 .ty = (try pt.navPtrType(test_nav_index)).toIntern(),
2496 .base_addr = .{ .nav = test_nav_index },
25722497 .byte_offset = 0,
25732498 } }),
25742499 };
......@@ -2601,22 +2526,16 @@ pub fn populateTestFunctions(
26012526 .size = .Slice,
26022527 },
26032528 });
2604 const new_val = decl.val;
26052529 const new_init = try pt.intern(.{ .slice = .{
26062530 .ty = new_ty.toIntern(),
26072531 .ptr = try pt.intern(.{ .ptr = .{
26082532 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
2609 .base_addr = .{ .anon_decl = array_anon_decl },
2533 .base_addr = .{ .uav = array_anon_decl },
26102534 .byte_offset = 0,
26112535 } }),
26122536 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
26132537 } });
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;
2538 ip.mutateVarInit(test_fns_val.toIntern(), new_init);
26202539 }
26212540 {
26222541 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
......@@ -2625,40 +2544,45 @@ pub fn populateTestFunctions(
26252544 zcu.codegen_prog_node = std.Progress.Node.none;
26262545 }
26272546
2628 try pt.linkerUpdateDecl(decl_index);
2547 try pt.linkerUpdateNav(nav_index);
26292548 }
26302549}
26312550
2632pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
2551pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
26332552 const zcu = pt.zcu;
26342553 const comp = zcu.comp;
26352554
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);
2555 const nav = zcu.intern_pool.getNav(nav_index);
2556 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0);
26392557 defer codegen_prog_node.end();
26402558
26412559 if (comp.bin_file) |lf| {
2642 lf.updateDecl(pt, decl_index) catch |err| switch (err) {
2560 lf.updateNav(pt, nav_index) catch |err| switch (err) {
26432561 error.OutOfMemory => return error.OutOfMemory,
26442562 error.AnalysisFail => {
2645 decl.analysis = .codegen_failure;
2563 assert(zcu.failed_codegen.contains(nav_index));
26462564 },
26472565 else => {
26482566 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(
2567 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
2568 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, try Zcu.ErrorMsg.create(
26512569 gpa,
2652 decl.navSrcLoc(zcu),
2570 zcu.navSrcLoc(nav_index),
26532571 "unable to codegen: {s}",
26542572 .{@errorName(err)},
26552573 ));
2656 decl.analysis = .codegen_failure;
2657 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
2574 if (nav.analysis_owner.unwrap()) |cau| {
2575 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .cau = cau }));
2576 } else {
2577 // TODO: we don't have a way to indicate that this failure is retryable!
2578 // Since these are really rare, we could as a cop-out retry the whole build next update.
2579 // But perhaps we can do better...
2580 @panic("TODO: retryable failure codegenning non-declaration Nav");
2581 }
26582582 },
26592583 };
26602584 } else if (zcu.llvm_object) |llvm_object| {
2661 llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) {
2585 llvm_object.updateNav(pt, nav_index) catch |err| switch (err) {
26622586 error.OutOfMemory => return error.OutOfMemory,
26632587 };
26642588 }
......@@ -2750,9 +2674,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool
27502674 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
27512675}
27522676
2753/// Shortcut for calling `intern_pool.getCoerced`.
2677/// Essentially a shortcut for calling `intern_pool.getCoerced`.
2678/// However, this function also allows coercing `extern`s. The `InternPool` function can't do
2679/// this because it requires potentially pushing to the job queue.
27542680pub 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()));
2681 const ip = &pt.zcu.intern_pool;
2682 switch (ip.indexToKey(val.toIntern())) {
2683 .@"extern" => |e| {
2684 const coerced = try pt.getExtern(.{
2685 .name = e.name,
2686 .ty = new_ty.toIntern(),
2687 .lib_name = e.lib_name,
2688 .is_const = e.is_const,
2689 .is_threadlocal = e.is_threadlocal,
2690 .is_weak_linkage = e.is_weak_linkage,
2691 .alignment = e.alignment,
2692 .@"addrspace" = e.@"addrspace",
2693 .zir_index = e.zir_index,
2694 .owner_nav = undefined, // ignored by `getExtern`.
2695 });
2696 return Value.fromInterned(coerced);
2697 },
2698 else => {},
2699 }
2700 return Value.fromInterned(try ip.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));
27562701}
27572702
27582703pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
......@@ -3237,24 +3182,28 @@ pub fn structPackedFieldBitOffset(
32373182}
32383183
32393184pub 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());
3185 const zcu = pt.zcu;
3186 const ip = &zcu.intern_pool;
3187 const nav = try pt.getBuiltinNav(name);
3188 pt.ensureCauAnalyzed(ip.getNav(nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3189 return Air.internedToRef(ip.getNav(nav).status.resolved.val);
32433190}
32443191
3245pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex {
3192pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
32463193 const zcu = pt.zcu;
32473194 const gpa = zcu.gpa;
32483195 const ip = &zcu.intern_pool;
32493196 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).?;
3197 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3198 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
32523199 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");
3200 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3201 @panic("lib/std.zig is corrupt and missing 'builtin'");
3202 pt.ensureCauAnalyzed(ip.getNav(builtin_nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3203 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.resolved.val);
3204 const builtin_namespace = zcu.namespacePtr(builtin_type.getNamespace(zcu).unwrap() orelse @panic("std.builtin is corrupt"));
32563205 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");
3206 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
32583207}
32593208
32603209pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {
......@@ -3264,6 +3213,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type
32643213 return ty;
32653214}
32663215
3216pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator.Error!Type {
3217 const zcu = pt.zcu;
3218 const ip = &zcu.intern_pool;
3219 const r = ip.getNav(nav_index).status.resolved;
3220 const ty = Value.fromInterned(r.val).typeOf(zcu);
3221 return pt.ptrType(.{
3222 .child = ty.toIntern(),
3223 .flags = .{
3224 .alignment = if (r.alignment == ty.abiAlignment(pt))
3225 .none
3226 else
3227 r.alignment,
3228 .address_space = r.@"addrspace",
3229 .is_const = switch (ip.indexToKey(r.val)) {
3230 .variable => false,
3231 .@"extern" => |e| e.is_const,
3232 else => true,
3233 },
3234 },
3235 });
3236}
3237
3238/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
3239/// If necessary, the new `Nav` is queued for codegen.
3240/// `key.owner_nav` is ignored and may be `undefined`.
3241pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!InternPool.Index {
3242 const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key);
3243 if (result.new_nav.unwrap()) |nav| {
3244 try pt.zcu.comp.queueJob(.{ .codegen_nav = nav });
3245 }
3246 return result.index;
3247}
3248
3249// TODO: this shouldn't need a `PerThread`! Fix the signature of `Type.abiAlignment`.
3250pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPool.Alignment {
3251 const zcu = pt.zcu;
3252 const r = zcu.intern_pool.getNav(nav_index).status.resolved;
3253 if (r.alignment != .none) return r.alignment;
3254 return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(pt);
3255}
3256
32673257const Air = @import("../Air.zig");
32683258const Allocator = std.mem.Allocator;
32693259const 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+410-440
......@@ -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));
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();
2806 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);
2805 const builtin_ty = zcu.navValue(builtin_nav).toType();
2806 const builtin_namespace = zcu.namespacePtr(builtin_ty.getNamespaceIndex(zcu));
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