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 {...@@ -354,28 +354,25 @@ pub const RcIncludes = enum {
354354
355const Job = union(enum) {355const Job = union(enum) {
356 /// Write the constant value for a Decl to the output file.356 /// Write the constant value for a Decl to the output file.
357 codegen_decl: InternPool.DeclIndex,357 codegen_nav: InternPool.Nav.Index,
358 /// Write the machine code for a function to the output file.358 /// 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`.
360 codegen_func: struct {359 codegen_func: struct {
360 /// This will either be a non-generic `func_decl` or a `func_instance`.
361 func: InternPool.Index,361 func: InternPool.Index,
362 /// This `Air` is owned by the `Job` and allocated with `gpa`.362 /// This `Air` is owned by the `Job` and allocated with `gpa`.
363 /// It must be deinited when the job is processed.363 /// It must be deinited when the job is processed.
364 air: Air,364 air: Air,
365 },365 },
366 /// Render the .h file snippet for the Decl.366 /// The `Cau` must be semantically analyzed (and possibly export itself).
367 emit_h_decl: InternPool.DeclIndex,367 /// This may be its first time being analyzed, or it may be outdated.
368 /// The Decl needs to be analyzed and possibly export itself.368 analyze_cau: InternPool.Cau.Index,
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,
372 /// Analyze the body of a runtime function.369 /// Analyze the body of a runtime function.
373 /// After analysis, a `codegen_func` job will be queued.370 /// After analysis, a `codegen_func` job will be queued.
374 /// These must be separate jobs to ensure any needed type resolution occurs *before* codegen.371 /// These must be separate jobs to ensure any needed type resolution occurs *before* codegen.
375 analyze_func: InternPool.Index,372 analyze_func: InternPool.Index,
376 /// The source file containing the Decl has been updated, and so the373 /// The source file containing the Decl has been updated, and so the
377 /// Decl may need its line number information updated in the debug info.374 /// Decl may need its line number information updated in the debug info.
378 update_line_number: InternPool.DeclIndex,375 update_line_number: void, // TODO
379 /// The main source file for the module needs to be analyzed.376 /// The main source file for the module needs to be analyzed.
380 analyze_mod: *Package.Module,377 analyze_mod: *Package.Module,
381 /// Fully resolve the given `struct` or `union` type.378 /// Fully resolve the given `struct` or `union` type.
...@@ -419,7 +416,7 @@ const Job = union(enum) {...@@ -419,7 +416,7 @@ const Job = union(enum) {
419};416};
420417
421const CodegenJob = union(enum) {418const CodegenJob = union(enum) {
422 decl: InternPool.DeclIndex,419 nav: InternPool.Nav.Index,
423 func: struct {420 func: struct {
424 func: InternPool.Index,421 func: InternPool.Index,
425 /// This `Air` is owned by the `Job` and allocated with `gpa`.422 /// 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...@@ -1445,12 +1442,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1445 .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}),1442 .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}),
1446 };1443 };
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
1454 const std_mod = options.std_mod orelse try Package.Module.create(arena, .{1445 const std_mod = options.std_mod orelse try Package.Module.create(arena, .{
1455 .global_cache_directory = options.global_cache_directory,1446 .global_cache_directory = options.global_cache_directory,
1456 .paths = .{1447 .paths = .{
...@@ -1478,7 +1469,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1478,7 +1469,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1478 .std_mod = std_mod,1469 .std_mod = std_mod,
1479 .global_zir_cache = global_zir_cache,1470 .global_zir_cache = global_zir_cache,
1480 .local_zir_cache = local_zir_cache,1471 .local_zir_cache = local_zir_cache,
1481 .emit_h = emit_h,
1482 .error_limit = error_limit,1472 .error_limit = error_limit,
1483 .llvm_object = null,1473 .llvm_object = null,
1484 };1474 };
...@@ -2581,7 +2571,7 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -2581,7 +2571,7 @@ fn addNonIncrementalStuffToCacheManifest(
2581 man.hash.addOptionalBytes(comp.test_name_prefix);2571 man.hash.addOptionalBytes(comp.test_name_prefix);
2582 man.hash.add(comp.skip_linker_dependencies);2572 man.hash.add(comp.skip_linker_dependencies);
2583 man.hash.add(comp.formatted_panics);2573 man.hash.add(comp.formatted_panics);
2584 man.hash.add(mod.emit_h != null);2574 //man.hash.add(mod.emit_h != null);
2585 man.hash.add(mod.error_limit);2575 man.hash.add(mod.error_limit);
2586 } else {2576 } else {
2587 cache_helpers.addModule(&man.hash, comp.root_mod);2577 cache_helpers.addModule(&man.hash, comp.root_mod);
...@@ -2930,7 +2920,7 @@ const Header = extern struct {...@@ -2930,7 +2920,7 @@ const Header = extern struct {
2930 intern_pool: extern struct {2920 intern_pool: extern struct {
2931 thread_count: u32,2921 thread_count: u32,
2932 src_hash_deps_len: u32,2922 src_hash_deps_len: u32,
2933 decl_val_deps_len: u32,2923 nav_val_deps_len: u32,
2934 namespace_deps_len: u32,2924 namespace_deps_len: u32,
2935 namespace_name_deps_len: u32,2925 namespace_name_deps_len: u32,
2936 first_dependency_len: u32,2926 first_dependency_len: u32,
...@@ -2972,7 +2962,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2972,7 +2962,7 @@ pub fn saveState(comp: *Compilation) !void {
2972 .intern_pool = .{2962 .intern_pool = .{
2973 .thread_count = @intCast(ip.locals.len),2963 .thread_count = @intCast(ip.locals.len),
2974 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),2964 .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()),
2976 .namespace_deps_len = @intCast(ip.namespace_deps.count()),2966 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
2977 .namespace_name_deps_len = @intCast(ip.namespace_name_deps.count()),2967 .namespace_name_deps_len = @intCast(ip.namespace_name_deps.count()),
2978 .first_dependency_len = @intCast(ip.first_dependency.count()),2968 .first_dependency_len = @intCast(ip.first_dependency.count()),
...@@ -2999,8 +2989,8 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2999,8 +2989,8 @@ pub fn saveState(comp: *Compilation) !void {
29992989
3000 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.keys()));2990 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.keys()));
3001 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.values()));2991 addBuf(&bufs, mem.sliceAsBytes(ip.src_hash_deps.values()));
3002 addBuf(&bufs, mem.sliceAsBytes(ip.decl_val_deps.keys()));2992 addBuf(&bufs, mem.sliceAsBytes(ip.nav_val_deps.keys()));
3003 addBuf(&bufs, mem.sliceAsBytes(ip.decl_val_deps.values()));2993 addBuf(&bufs, mem.sliceAsBytes(ip.nav_val_deps.values()));
3004 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.keys()));2994 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.keys()));
3005 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.values()));2995 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_deps.values()));
3006 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_name_deps.keys()));2996 addBuf(&bufs, mem.sliceAsBytes(ip.namespace_name_deps.keys()));
...@@ -3019,7 +3009,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -3019,7 +3009,7 @@ pub fn saveState(comp: *Compilation) !void {
3019 addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]);3009 addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]);
3020 addBuf(&bufs, mem.sliceAsBytes(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len]));3010 addBuf(&bufs, mem.sliceAsBytes(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len]));
3021 addBuf(&bufs, mem.sliceAsBytes(local.shared.files.view().items(.bin_digest)[0..pt_header.intern_pool.files_len]));3011 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]));
3023 }3013 }
30243014
3025 //// TODO: compilation errors3015 //// TODO: compilation errors
...@@ -3065,6 +3055,8 @@ pub fn totalErrorCount(comp: *Compilation) u32 {...@@ -3065,6 +3055,8 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
3065 }3055 }
30663056
3067 if (comp.module) |zcu| {3057 if (comp.module) |zcu| {
3058 const ip = &zcu.intern_pool;
3059
3068 total += zcu.failed_exports.count();3060 total += zcu.failed_exports.count();
3069 total += zcu.failed_embed_files.count();3061 total += zcu.failed_embed_files.count();
30703062
...@@ -3084,25 +3076,18 @@ pub fn totalErrorCount(comp: *Compilation) u32 {...@@ -3084,25 +3076,18 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
3084 // When a parse error is introduced, we keep all the semantic analysis for3076 // When a parse error is introduced, we keep all the semantic analysis for
3085 // the previous parse success, including compile errors, but we cannot3077 // the previous parse success, including compile errors, but we cannot
3086 // emit them until the file succeeds parsing.3078 // emit them until the file succeeds parsing.
3087 for (zcu.failed_analysis.keys()) |key| {3079 for (zcu.failed_analysis.keys()) |anal_unit| {
3088 const decl_index = switch (key.unwrap()) {3080 const file_index = switch (anal_unit.unwrap()) {
3089 .decl => |d| d,3081 .cau => |cau| zcu.namespacePtr(ip.getCau(cau).namespace).file_scope,
3090 .func => |ip_index| zcu.funcInfo(ip_index).owner_decl,3082 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFull(ip).file,
3091 };3083 };
3092 if (zcu.declFileScope(decl_index).okToReportErrors()) {3084 if (zcu.fileByIndex(file_index).okToReportErrors()) {
3093 total += 1;3085 total += 1;
3094 if (zcu.cimport_errors.get(key)) |errors| {3086 if (zcu.cimport_errors.get(anal_unit)) |errors| {
3095 total += errors.errorMessageCount();3087 total += errors.errorMessageCount();
3096 }3088 }
3097 }3089 }
3098 }3090 }
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
3107 if (zcu.intern_pool.global_error_set.getNamesFromMainThread().len > zcu.error_limit) {3092 if (zcu.intern_pool.global_error_set.getNamesFromMainThread().len > zcu.error_limit) {
3108 total += 1;3093 total += 1;
...@@ -3169,6 +3154,8 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3169,6 +3154,8 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3169 });3154 });
3170 }3155 }
3171 if (comp.module) |zcu| {3156 if (comp.module) |zcu| {
3157 const ip = &zcu.intern_pool;
3158
3172 var all_references = try zcu.resolveReferences();3159 var all_references = try zcu.resolveReferences();
3173 defer all_references.deinit(gpa);3160 defer all_references.deinit(gpa);
31743161
...@@ -3219,14 +3206,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3219,14 +3206,14 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3219 if (err) |e| return e;3206 if (err) |e| return e;
3220 }3207 }
3221 for (zcu.failed_analysis.keys(), zcu.failed_analysis.values()) |anal_unit, error_msg| {3208 for (zcu.failed_analysis.keys(), zcu.failed_analysis.values()) |anal_unit, error_msg| {
3222 const decl_index = switch (anal_unit.unwrap()) {3209 const file_index = switch (anal_unit.unwrap()) {
3223 .decl => |d| d,3210 .cau => |cau| zcu.namespacePtr(ip.getCau(cau).namespace).file_scope,
3224 .func => |ip_index| zcu.funcInfo(ip_index).owner_decl,3211 .func => |ip_index| zcu.funcInfo(ip_index).zir_body_inst.resolveFull(ip).file,
3225 };3212 };
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.
3228 // We'll try again once parsing succeeds.3215 // We'll try again once parsing succeeds.
3229 if (!zcu.declFileScope(decl_index).okToReportErrors()) continue;3216 if (!zcu.fileByIndex(file_index).okToReportErrors()) continue;
32303217
3231 try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);3218 try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);
3232 if (zcu.cimport_errors.get(anal_unit)) |errors| {3219 if (zcu.cimport_errors.get(anal_unit)) |errors| {
...@@ -3250,15 +3237,6 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3250,15 +3237,6 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3250 }3237 }
3251 }3238 }
3252 }3239 }
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 }
3262 for (zcu.failed_exports.values()) |value| {3240 for (zcu.failed_exports.values()) |value| {
3263 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);3241 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
3264 }3242 }
...@@ -3437,11 +3415,15 @@ pub fn addModuleErrorMsg(...@@ -3437,11 +3415,15 @@ pub fn addModuleErrorMsg(
3437 const loc = std.zig.findLineColumn(source.bytes, span.main);3415 const loc = std.zig.findLineColumn(source.bytes, span.main);
3438 const rt_file_path = try src.file_scope.fullPath(gpa);3416 const rt_file_path = try src.file_scope.fullPath(gpa);
3439 const name = switch (ref.referencer.unwrap()) {3417 const name = switch (ref.referencer.unwrap()) {
3440 .decl => |d| mod.declPtr(d).name,3418 .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
3441 .func => |f| mod.funcOwnerDeclPtr(f).name,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),
3442 };3424 };
3443 try ref_traces.append(gpa, .{3425 try ref_traces.append(gpa, .{
3444 .decl_name = try eb.addString(name.toSlice(ip)),3426 .decl_name = try eb.addString(name),
3445 .src_loc = try eb.addSourceLocation(.{3427 .src_loc = try eb.addSourceLocation(.{
3446 .src_path = try eb.addString(rt_file_path),3428 .src_path = try eb.addString(rt_file_path),
3447 .span_start = span.start,3429 .span_start = span.start,
...@@ -3617,10 +3599,10 @@ fn performAllTheWorkInner(...@@ -3617,10 +3599,10 @@ fn performAllTheWorkInner(
3617 // Pre-load these things from our single-threaded context since they3599 // Pre-load these things from our single-threaded context since they
3618 // will be needed by the worker threads.3600 // will be needed by the worker threads.
3619 const path_digest = zcu.filePathDigest(file_index);3601 const path_digest = zcu.filePathDigest(file_index);
3620 const root_decl = zcu.fileRootDecl(file_index);3602 const old_root_type = zcu.fileRootType(file_index);
3621 const file = zcu.fileByIndex(file_index);3603 const file = zcu.fileByIndex(file_index);
3622 comp.thread_pool.spawnWgId(&astgen_wait_group, workerAstGenFile, .{3604 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,
3624 });3606 });
3625 }3607 }
3626 }3608 }
...@@ -3682,7 +3664,7 @@ fn performAllTheWorkInner(...@@ -3682,7 +3664,7 @@ fn performAllTheWorkInner(
3682 // which we need to work on, and queue it if so.3664 // which we need to work on, and queue it if so.
3683 if (try zcu.findOutdatedToAnalyze()) |outdated| {3665 if (try zcu.findOutdatedToAnalyze()) |outdated| {
3684 switch (outdated.unwrap()) {3666 switch (outdated.unwrap()) {
3685 .decl => |decl| try comp.queueJob(.{ .analyze_decl = decl }),3667 .cau => |cau| try comp.queueJob(.{ .analyze_cau = cau }),
3686 .func => |func| try comp.queueJob(.{ .analyze_func = func }),3668 .func => |func| try comp.queueJob(.{ .analyze_func = func }),
3687 }3669 }
3688 continue;3670 continue;
...@@ -3704,24 +3686,17 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {...@@ -3704,24 +3686,17 @@ pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
37043686
3705fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {3687fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void {
3706 switch (job) {3688 switch (job) {
3707 .codegen_decl => |decl_index| {3689 .codegen_nav => |nav_index| {
3708 const decl = comp.module.?.declPtr(decl_index);3690 const zcu = comp.module.?;
37093691 const nav = zcu.intern_pool.getNav(nav_index);
3710 switch (decl.analysis) {3692 if (nav.analysis_owner.unwrap()) |cau| {
3711 .unreferenced => unreachable,3693 const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
3712 .in_progress => unreachable,3694 if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) {
37133695 return;
3714 .file_failure,3696 }
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 },
3724 }3697 }
3698 assert(nav.status == .resolved);
3699 try comp.queueCodegenJob(tid, .{ .nav = nav_index });
3725 },3700 },
3726 .codegen_func => |func| {3701 .codegen_func => |func| {
3727 // This call takes ownership of `func.air`.3702 // This call takes ownership of `func.air`.
...@@ -3740,82 +3715,30 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre...@@ -3740,82 +3715,30 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
3740 error.AnalysisFail => return,3715 error.AnalysisFail => return,
3741 };3716 };
3742 },3717 },
3743 .emit_h_decl => |decl_index| {3718 .analyze_cau => |cau_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
3747 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };3719 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3748 const decl = pt.zcu.declPtr(decl_index);3720 pt.ensureCauAnalyzed(cau_index) catch |err| switch (err) {
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) {
3810 error.OutOfMemory => return error.OutOfMemory,3721 error.OutOfMemory => return error.OutOfMemory,
3811 error.AnalysisFail => return,3722 error.AnalysisFail => return,
3812 };3723 };
3813 const decl = pt.zcu.declPtr(decl_index);3724 queue_test_analysis: {
3814 if (decl.kind == .@"test" and comp.config.is_test) {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
3815 // Tests are always emitted in test binaries. The decl_refs are created by3738 // Tests are always emitted in test binaries. The decl_refs are created by
3816 // Zcu.populateTestFunctions, but this will not queue body analysis, so do3739 // Zcu.populateTestFunctions, but this will not queue body analysis, so do
3817 // that now.3740 // that now.
3818 try pt.zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern());3741 try pt.zcu.ensureFuncBodyAnalysisQueued(ip.getNav(nav_index).status.resolved.val);
3819 }3742 }
3820 },3743 },
3821 .resolve_type_fully => |ty| {3744 .resolve_type_fully => |ty| {
...@@ -3832,6 +3755,8 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre...@@ -3832,6 +3755,8 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
3832 const named_frame = tracy.namedFrame("update_line_number");3755 const named_frame = tracy.namedFrame("update_line_number");
3833 defer named_frame.end();3756 defer named_frame.end();
38343757
3758 if (true) @panic("TODO: update_line_number");
3759
3835 const gpa = comp.gpa;3760 const gpa = comp.gpa;
3836 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };3761 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
3837 const decl = pt.zcu.declPtr(decl_index);3762 const decl = pt.zcu.declPtr(decl_index);
...@@ -4054,12 +3979,12 @@ fn codegenThread(tid: usize, comp: *Compilation) void {...@@ -4054,12 +3979,12 @@ fn codegenThread(tid: usize, comp: *Compilation) void {
40543979
4055fn processOneCodegenJob(tid: usize, comp: *Compilation, codegen_job: CodegenJob) JobError!void {3980fn processOneCodegenJob(tid: usize, comp: *Compilation, codegen_job: CodegenJob) JobError!void {
4056 switch (codegen_job) {3981 switch (codegen_job) {
4057 .decl => |decl_index| {3982 .nav => |nav_index| {
4058 const named_frame = tracy.namedFrame("codegen_decl");3983 const named_frame = tracy.namedFrame("codegen_nav");
4059 defer named_frame.end();3984 defer named_frame.end();
40603985
4061 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };3986 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };
4062 try pt.linkerUpdateDecl(decl_index);3987 try pt.linkerUpdateNav(nav_index);
4063 },3988 },
4064 .func => |func| {3989 .func => |func| {
4065 const named_frame = tracy.namedFrame("codegen_func");3990 const named_frame = tracy.namedFrame("codegen_func");
...@@ -4366,7 +4291,7 @@ fn workerAstGenFile(...@@ -4366,7 +4291,7 @@ fn workerAstGenFile(
4366 file: *Zcu.File,4291 file: *Zcu.File,
4367 file_index: Zcu.File.Index,4292 file_index: Zcu.File.Index,
4368 path_digest: Cache.BinDigest,4293 path_digest: Cache.BinDigest,
4369 root_decl: Zcu.Decl.OptionalIndex,4294 old_root_type: InternPool.Index,
4370 prog_node: std.Progress.Node,4295 prog_node: std.Progress.Node,
4371 wg: *WaitGroup,4296 wg: *WaitGroup,
4372 src: Zcu.AstGenSrc,4297 src: Zcu.AstGenSrc,
...@@ -4375,7 +4300,7 @@ fn workerAstGenFile(...@@ -4375,7 +4300,7 @@ fn workerAstGenFile(
4375 defer child_prog_node.end();4300 defer child_prog_node.end();
43764301
4377 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = @enumFromInt(tid) };4302 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) {
4379 error.AnalysisFail => return,4304 error.AnalysisFail => return,
4380 else => {4305 else => {
4381 file.status = .retryable_failure;4306 file.status = .retryable_failure;
...@@ -4406,7 +4331,7 @@ fn workerAstGenFile(...@@ -4406,7 +4331,7 @@ fn workerAstGenFile(
4406 // `@import("builtin")` is handled specially.4331 // `@import("builtin")` is handled specially.
4407 if (mem.eql(u8, import_path, "builtin")) continue;4332 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: {
4410 comp.mutex.lock();4335 comp.mutex.lock();
4411 defer comp.mutex.unlock();4336 defer comp.mutex.unlock();
44124337
...@@ -4421,8 +4346,8 @@ fn workerAstGenFile(...@@ -4421,8 +4346,8 @@ fn workerAstGenFile(
4421 comp.appendFileSystemInput(fsi, res.file.mod.root, res.file.sub_file_path) catch continue;4346 comp.appendFileSystemInput(fsi, res.file.mod.root, res.file.sub_file_path) catch continue;
4422 };4347 };
4423 const imported_path_digest = pt.zcu.filePathDigest(res.file_index);4348 const imported_path_digest = pt.zcu.filePathDigest(res.file_index);
4424 const imported_root_decl = pt.zcu.fileRootDecl(res.file_index);4349 const imported_root_type = pt.zcu.fileRootType(res.file_index);
4425 break :blk .{ res, imported_path_digest, imported_root_decl };4350 break :blk .{ res, imported_path_digest, imported_root_type };
4426 };4351 };
4427 if (import_result.is_new) {4352 if (import_result.is_new) {
4428 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{4353 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
...@@ -4433,7 +4358,7 @@ fn workerAstGenFile(...@@ -4433,7 +4358,7 @@ fn workerAstGenFile(
4433 .import_tok = item.data.token,4358 .import_tok = item.data.token,
4434 } };4359 } };
4435 comp.thread_pool.spawnWgId(wg, workerAstGenFile, .{4360 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,
4437 });4362 });
4438 }4363 }
4439 }4364 }
src/InternPool.zig+964-523
...@@ -24,12 +24,14 @@ tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th...@@ -24,12 +24,14 @@ tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th
24/// These are also invalidated if tracking fails for this instruction.24/// These are also invalidated if tracking fails for this instruction.
25/// Value is index into `dep_entries` of the first dependency on this hash.25/// Value is index into `dep_entries` of the first dependency on this hash.
26src_hash_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index) = .{},26src_hash_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index) = .{},
27/// Dependencies on the value of a Decl.27/// Dependencies on the value of a Nav.
28/// Value is index into `dep_entries` of the first dependency on this Decl value.28/// Value is index into `dep_entries` of the first dependency on this Nav value.
29decl_val_deps: std.AutoArrayHashMapUnmanaged(DeclIndex, DepEntry.Index) = .{},29nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index) = .{},
30/// Dependencies on the IES of a runtime function.30/// Dependencies on an interned value, either:
31/// Value is index into `dep_entries` of the first dependency on this Decl value.31/// * a runtime function (invalidated when its IES changes)
32func_ies_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index) = .{},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) = .{},
33/// Dependencies on the full set of names in a ZIR namespace.35/// Dependencies on the full set of names in a ZIR namespace.
34/// Key refers to a `struct_decl`, `union_decl`, etc.36/// Key refers to a `struct_decl`, `union_decl`, etc.
35/// Value is index into `dep_entries` of the first dependency on this namespace.37/// Value is index into `dep_entries` of the first dependency on this namespace.
...@@ -210,25 +212,25 @@ pub fn trackZir(...@@ -210,25 +212,25 @@ pub fn trackZir(
210}212}
211213
212/// Analysis Unit. Represents a single entity which undergoes semantic analysis.214/// 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.
214/// The LSB is used as a tag bit.216/// The LSB is used as a tag bit.
215/// This is the "source" of an incremental dependency edge.217/// This is the "source" of an incremental dependency edge.
216pub const AnalUnit = packed struct(u32) {218pub const AnalUnit = packed struct(u32) {
217 kind: enum(u1) { decl, func },219 kind: enum(u1) { cau, func },
218 index: u31,220 index: u31,
219 pub const Unwrapped = union(enum) {221 pub const Unwrapped = union(enum) {
220 decl: DeclIndex,222 cau: Cau.Index,
221 func: InternPool.Index,223 func: InternPool.Index,
222 };224 };
223 pub fn unwrap(as: AnalUnit) Unwrapped {225 pub fn unwrap(as: AnalUnit) Unwrapped {
224 return switch (as.kind) {226 return switch (as.kind) {
225 .decl => .{ .decl = @enumFromInt(as.index) },227 .cau => .{ .cau = @enumFromInt(as.index) },
226 .func => .{ .func = @enumFromInt(as.index) },228 .func => .{ .func = @enumFromInt(as.index) },
227 };229 };
228 }230 }
229 pub fn wrap(raw: Unwrapped) AnalUnit {231 pub fn wrap(raw: Unwrapped) AnalUnit {
230 return switch (raw) {232 return switch (raw) {
231 .decl => |decl| .{ .kind = .decl, .index = @intCast(@intFromEnum(decl)) },233 .cau => |cau| .{ .kind = .cau, .index = @intCast(@intFromEnum(cau)) },
232 .func => |func| .{ .kind = .func, .index = @intCast(@intFromEnum(func)) },234 .func => |func| .{ .kind = .func, .index = @intCast(@intFromEnum(func)) },
233 };235 };
234 }236 }
...@@ -247,10 +249,275 @@ pub const AnalUnit = packed struct(u32) {...@@ -247,10 +249,275 @@ pub const AnalUnit = packed struct(u32) {
247 };249 };
248};250};
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
250pub const Dependee = union(enum) {517pub const Dependee = union(enum) {
251 src_hash: TrackedInst.Index,518 src_hash: TrackedInst.Index,
252 decl_val: DeclIndex,519 nav_val: Nav.Index,
253 func_ies: Index,520 interned: Index,
254 namespace: TrackedInst.Index,521 namespace: TrackedInst.Index,
255 namespace_name: NamespaceNameKey,522 namespace_name: NamespaceNameKey,
256};523};
...@@ -297,8 +564,8 @@ pub const DependencyIterator = struct {...@@ -297,8 +564,8 @@ pub const DependencyIterator = struct {
297pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyIterator {564pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyIterator {
298 const first_entry = switch (dependee) {565 const first_entry = switch (dependee) {
299 .src_hash => |x| ip.src_hash_deps.get(x),566 .src_hash => |x| ip.src_hash_deps.get(x),
300 .decl_val => |x| ip.decl_val_deps.get(x),567 .nav_val => |x| ip.nav_val_deps.get(x),
301 .func_ies => |x| ip.func_ies_deps.get(x),568 .interned => |x| ip.interned_deps.get(x),
302 .namespace => |x| ip.namespace_deps.get(x),569 .namespace => |x| ip.namespace_deps.get(x),
303 .namespace_name => |x| ip.namespace_name_deps.get(x),570 .namespace_name => |x| ip.namespace_name_deps.get(x),
304 } orelse return .{571 } orelse return .{
...@@ -337,8 +604,8 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend...@@ -337,8 +604,8 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
337 inline else => |dependee_payload, tag| new_index: {604 inline else => |dependee_payload, tag| new_index: {
338 const gop = try switch (tag) {605 const gop = try switch (tag) {
339 .src_hash => ip.src_hash_deps,606 .src_hash => ip.src_hash_deps,
340 .decl_val => ip.decl_val_deps,607 .nav_val => ip.nav_val_deps,
341 .func_ies => ip.func_ies_deps,608 .interned => ip.interned_deps,
342 .namespace => ip.namespace_deps,609 .namespace => ip.namespace_deps,
343 .namespace_name => ip.namespace_name_deps,610 .namespace_name => ip.namespace_name_deps,
344 }.getOrPut(gpa, dependee_payload);611 }.getOrPut(gpa, dependee_payload);
...@@ -426,8 +693,9 @@ const Local = struct {...@@ -426,8 +693,9 @@ const Local = struct {
426 tracked_insts: ListMutate,693 tracked_insts: ListMutate,
427 files: ListMutate,694 files: ListMutate,
428 maps: ListMutate,695 maps: ListMutate,
696 caus: ListMutate,
697 navs: ListMutate,
429698
430 decls: BucketListMutate,
431 namespaces: BucketListMutate,699 namespaces: BucketListMutate,
432 } align(std.atomic.cache_line),700 } align(std.atomic.cache_line),
433701
...@@ -439,8 +707,9 @@ const Local = struct {...@@ -439,8 +707,9 @@ const Local = struct {
439 tracked_insts: TrackedInsts,707 tracked_insts: TrackedInsts,
440 files: List(File),708 files: List(File),
441 maps: Maps,709 maps: Maps,
710 caus: Caus,
711 navs: Navs,
442712
443 decls: Decls,
444 namespaces: Namespaces,713 namespaces: Namespaces,
445714
446 pub fn getLimbs(shared: *const Local.Shared) Limbs {715 pub fn getLimbs(shared: *const Local.Shared) Limbs {
...@@ -461,15 +730,12 @@ const Local = struct {...@@ -461,15 +730,12 @@ const Local = struct {
461 const Strings = List(struct { u8 });730 const Strings = List(struct { u8 });
462 const TrackedInsts = List(struct { TrackedInst });731 const TrackedInsts = List(struct { TrackedInst });
463 const Maps = List(struct { FieldMap });732 const Maps = List(struct { FieldMap });
464733 const Caus = List(struct { Cau });
465 const decls_bucket_width = 8;734 const Navs = List(Nav.Repr);
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 });
469735
470 const namespaces_bucket_width = 8;736 const namespaces_bucket_width = 8;
471 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;737 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";
473 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });739 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });
474740
475 const ListMutate = struct {741 const ListMutate = struct {
...@@ -810,8 +1076,6 @@ const Local = struct {...@@ -810,8 +1076,6 @@ const Local = struct {
810 ///1076 ///
811 /// Key is the hash of the path to this file, used to store1077 /// Key is the hash of the path to this file, used to store
812 /// `InternPool.TrackedInst`.1078 /// `InternPool.TrackedInst`.
813 ///
814 /// Value is the `Decl` of the struct that represents this `File`.
815 pub fn getMutableFiles(local: *Local, gpa: Allocator) List(File).Mutable {1079 pub fn getMutableFiles(local: *Local, gpa: Allocator) List(File).Mutable {
816 return .{1080 return .{
817 .gpa = gpa,1081 .gpa = gpa,
...@@ -835,26 +1099,34 @@ const Local = struct {...@@ -835,26 +1099,34 @@ const Local = struct {
835 };1099 };
836 }1100 }
8371101
838 /// Rather than allocating Decl objects with an Allocator, we instead allocate1102 pub fn getMutableCaus(local: *Local, gpa: Allocator) Caus.Mutable {
839 /// them with this BucketList. This provides four advantages:1103 return .{
840 /// * Stable memory so that one thread can access a Decl object while another1104 .gpa = gpa,
841 /// thread allocates additional Decl objects from this list.1105 .arena = &local.mutate.arena,
842 /// * It allows us to use u32 indexes to reference Decl objects rather than1106 .mutate = &local.mutate.caus,
843 /// pointers, saving memory in Type, Value, and dependency sets.1107 .list = &local.shared.caus,
844 /// * Using integers to reference Decl objects rather than pointers makes1108 };
845 /// serialization trivial.1109 }
846 /// * It provides a unique integer to be used for anonymous symbol names, avoiding1110
847 /// multi-threaded contention on an atomic counter.1111 pub fn getMutableNavs(local: *Local, gpa: Allocator) Navs.Mutable {
848 pub fn getMutableDecls(local: *Local, gpa: Allocator) Decls.Mutable {
849 return .{1112 return .{
850 .gpa = gpa,1113 .gpa = gpa,
851 .arena = &local.mutate.arena,1114 .arena = &local.mutate.arena,
852 .mutate = &local.mutate.decls.buckets_list,1115 .mutate = &local.mutate.navs,
853 .list = &local.shared.decls,1116 .list = &local.shared.navs,
854 };1117 };
855 }1118 }
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.
858 pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable {1130 pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable {
859 return .{1131 return .{
860 .gpa = gpa,1132 .gpa = gpa,
...@@ -1038,51 +1310,6 @@ pub const RuntimeIndex = enum(u32) {...@@ -1038,51 +1310,6 @@ pub const RuntimeIndex = enum(u32) {
10381310
1039pub const ComptimeAllocIndex = enum(u32) { _ };1311pub 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
1086pub const NamespaceIndex = enum(u32) {1313pub const NamespaceIndex = enum(u32) {
1087 _,1314 _,
10881315
...@@ -1153,7 +1380,8 @@ pub const FileIndex = enum(u32) {...@@ -1153,7 +1380,8 @@ pub const FileIndex = enum(u32) {
1153const File = struct {1380const File = struct {
1154 bin_digest: Cache.BinDigest,1381 bin_digest: Cache.BinDigest,
1155 file: *Zcu.File,1382 file: *Zcu.File,
1156 root_decl: OptionalDeclIndex,1383 /// `.none` means no type has been created yet.
1384 root_type: InternPool.Index,
1157};1385};
11581386
1159/// An index into `strings`.1387/// An index into `strings`.
...@@ -1332,26 +1560,26 @@ pub const OptionalNullTerminatedString = enum(u32) {...@@ -1332,26 +1560,26 @@ pub const OptionalNullTerminatedString = enum(u32) {
1332/// `Index` because we must differentiate between the following cases:1560/// `Index` because we must differentiate between the following cases:
1333/// * runtime-known value (where we store the type)1561/// * runtime-known value (where we store the type)
1334/// * comptime-known value (where we store the value)1562/// * comptime-known value (where we store the value)
1335/// * decl val (so that we can analyze the value lazily)1563/// * `Nav` val (so that we can analyze the value lazily)
1336/// * decl ref (so that we can analyze the reference lazily)1564/// * `Nav` ref (so that we can analyze the reference lazily)
1337pub const CaptureValue = packed struct(u32) {1565pub 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 },
1339 idx: u30,1567 idx: u30,
13401568
1341 pub fn wrap(val: Unwrapped) CaptureValue {1569 pub fn wrap(val: Unwrapped) CaptureValue {
1342 return switch (val) {1570 return switch (val) {
1343 .@"comptime" => |i| .{ .tag = .@"comptime", .idx = @intCast(@intFromEnum(i)) },1571 .@"comptime" => |i| .{ .tag = .@"comptime", .idx = @intCast(@intFromEnum(i)) },
1344 .runtime => |i| .{ .tag = .runtime, .idx = @intCast(@intFromEnum(i)) },1572 .runtime => |i| .{ .tag = .runtime, .idx = @intCast(@intFromEnum(i)) },
1345 .decl_val => |i| .{ .tag = .decl_val, .idx = @intCast(@intFromEnum(i)) },1573 .nav_val => |i| .{ .tag = .nav_val, .idx = @intCast(@intFromEnum(i)) },
1346 .decl_ref => |i| .{ .tag = .decl_ref, .idx = @intCast(@intFromEnum(i)) },1574 .nav_ref => |i| .{ .tag = .nav_ref, .idx = @intCast(@intFromEnum(i)) },
1347 };1575 };
1348 }1576 }
1349 pub fn unwrap(val: CaptureValue) Unwrapped {1577 pub fn unwrap(val: CaptureValue) Unwrapped {
1350 return switch (val.tag) {1578 return switch (val.tag) {
1351 .@"comptime" => .{ .@"comptime" = @enumFromInt(val.idx) },1579 .@"comptime" => .{ .@"comptime" = @enumFromInt(val.idx) },
1352 .runtime => .{ .runtime = @enumFromInt(val.idx) },1580 .runtime => .{ .runtime = @enumFromInt(val.idx) },
1353 .decl_val => .{ .decl_val = @enumFromInt(val.idx) },1581 .nav_val => .{ .nav_val = @enumFromInt(val.idx) },
1354 .decl_ref => .{ .decl_ref = @enumFromInt(val.idx) },1582 .nav_ref => .{ .nav_ref = @enumFromInt(val.idx) },
1355 };1583 };
1356 }1584 }
13571585
...@@ -1360,8 +1588,8 @@ pub const CaptureValue = packed struct(u32) {...@@ -1360,8 +1588,8 @@ pub const CaptureValue = packed struct(u32) {
1360 @"comptime": Index,1588 @"comptime": Index,
1361 /// Index refers to the type.1589 /// Index refers to the type.
1362 runtime: Index,1590 runtime: Index,
1363 decl_val: DeclIndex,1591 nav_val: Nav.Index,
1364 decl_ref: DeclIndex,1592 nav_ref: Nav.Index,
1365 };1593 };
13661594
1367 pub const Slice = struct {1595 pub const Slice = struct {
...@@ -1410,7 +1638,7 @@ pub const Key = union(enum) {...@@ -1410,7 +1638,7 @@ pub const Key = union(enum) {
1410 undef: Index,1638 undef: Index,
1411 simple_value: SimpleValue,1639 simple_value: SimpleValue,
1412 variable: Variable,1640 variable: Variable,
1413 extern_func: ExternFunc,1641 @"extern": Extern,
1414 func: Func,1642 func: Func,
1415 int: Key.Int,1643 int: Key.Int,
1416 err: Error,1644 err: Error,
...@@ -1637,25 +1865,37 @@ pub const Key = union(enum) {...@@ -1637,25 +1865,37 @@ pub const Key = union(enum) {
1637 }1865 }
1638 };1866 };
16391867
1868 /// A runtime variable defined in this `Zcu`.
1640 pub const Variable = struct {1869 pub const Variable = struct {
1641 ty: Index,1870 ty: Index,
1642 init: Index,1871 init: Index,
1643 decl: DeclIndex,1872 owner_nav: Nav.Index,
1644 lib_name: OptionalNullTerminatedString,1873 lib_name: OptionalNullTerminatedString,
1645 is_extern: bool,
1646 is_const: bool,
1647 is_threadlocal: bool,1874 is_threadlocal: bool,
1648 is_weak_linkage: bool,1875 is_weak_linkage: bool,
1649 };1876 };
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.
1652 ty: Index,1883 ty: Index,
1653 /// The Decl that corresponds to the function itself.
1654 decl: DeclIndex,
1655 /// Library name if specified.1884 /// Library name if specified.
1656 /// For example `extern "c" fn write(...) usize` would have 'c' as library name.1885 /// For example `extern "c" fn write(...) usize` would have 'c' as library name.
1657 /// Index into the string table bytes.1886 /// Index into the string table bytes.
1658 lib_name: OptionalNullTerminatedString,1887 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,
1659 };1899 };
16601900
1661 pub const Func = struct {1901 pub const Func = struct {
...@@ -1687,8 +1927,7 @@ pub const Key = union(enum) {...@@ -1687,8 +1927,7 @@ pub const Key = union(enum) {
1687 /// so that it can be mutated.1927 /// so that it can be mutated.
1688 /// This will be 0 when the function is not a generic function instantiation.1928 /// This will be 0 when the function is not a generic function instantiation.
1689 branch_quota_extra_index: u32,1929 branch_quota_extra_index: u32,
1690 /// The Decl that corresponds to the function itself.1930 owner_nav: Nav.Index,
1691 owner_decl: DeclIndex,
1692 /// The ZIR instruction that is a function instruction. Use this to find1931 /// The ZIR instruction that is a function instruction. Use this to find
1693 /// the body. We store this rather than the body directly so that when ZIR1932 /// the body. We store this rather than the body directly so that when ZIR
1694 /// is regenerated on update(), we can map this to the new corresponding1933 /// is regenerated on update(), we can map this to the new corresponding
...@@ -1861,14 +2100,14 @@ pub const Key = union(enum) {...@@ -1861,14 +2100,14 @@ pub const Key = union(enum) {
1861 pub const BaseAddr = union(enum) {2100 pub const BaseAddr = union(enum) {
1862 const Tag = @typeInfo(BaseAddr).Union.tag_type.?;2101 const Tag = @typeInfo(BaseAddr).Union.tag_type.?;
18632102
1864 /// Points to the value of a single `Decl`, which may be constant or a `variable`.2103 /// Points to the value of a single `Nav`, which may be constant or a `variable`.
1865 decl: DeclIndex,2104 nav: Nav.Index,
18662105
1867 /// Points to the value of a single comptime alloc stored in `Sema`.2106 /// Points to the value of a single comptime alloc stored in `Sema`.
1868 comptime_alloc: ComptimeAllocIndex,2107 comptime_alloc: ComptimeAllocIndex,
18692108
1870 /// Points to a single unnamed constant value.2109 /// Points to a single unnamed constant value.
1871 anon_decl: AnonDecl,2110 uav: Uav,
18722111
1873 /// Points to a comptime field of a struct. Index is the field's value.2112 /// Points to a comptime field of a struct. Index is the field's value.
1874 ///2113 ///
...@@ -1923,15 +2162,11 @@ pub const Key = union(enum) {...@@ -1923,15 +2162,11 @@ pub const Key = union(enum) {
1923 /// the aggregate pointer.2162 /// the aggregate pointer.
1924 arr_elem: BaseIndex,2163 arr_elem: BaseIndex,
19252164
1926 pub const MutDecl = struct {
1927 decl: DeclIndex,
1928 runtime_index: RuntimeIndex,
1929 };
1930 pub const BaseIndex = struct {2165 pub const BaseIndex = struct {
1931 base: Index,2166 base: Index,
1932 index: u64,2167 index: u64,
1933 };2168 };
1934 pub const AnonDecl = extern struct {2169 pub const Uav = extern struct {
1935 val: Index,2170 val: Index,
1936 /// Contains the canonical pointer type of the anonymous2171 /// Contains the canonical pointer type of the anonymous
1937 /// declaration. This may equal `ty` of the `Ptr` or it may be2172 /// declaration. This may equal `ty` of the `Ptr` or it may be
...@@ -1944,10 +2179,10 @@ pub const Key = union(enum) {...@@ -1944,10 +2179,10 @@ pub const Key = union(enum) {
1944 if (@as(Key.Ptr.BaseAddr.Tag, a) != @as(Key.Ptr.BaseAddr.Tag, b)) return false;2179 if (@as(Key.Ptr.BaseAddr.Tag, a) != @as(Key.Ptr.BaseAddr.Tag, b)) return false;
19452180
1946 return switch (a) {2181 return switch (a) {
1947 .decl => |a_decl| a_decl == b.decl,2182 .nav => |a_nav| a_nav == b.nav,
1948 .comptime_alloc => |a_alloc| a_alloc == b.comptime_alloc,2183 .comptime_alloc => |a_alloc| a_alloc == b.comptime_alloc,
1949 .anon_decl => |ad| ad.val == b.anon_decl.val and2184 .uav => |ad| ad.val == b.uav.val and
1950 ad.orig_ty == b.anon_decl.orig_ty,2185 ad.orig_ty == b.uav.orig_ty,
1951 .int => true,2186 .int => true,
1952 .eu_payload => |a_eu_payload| a_eu_payload == b.eu_payload,2187 .eu_payload => |a_eu_payload| a_eu_payload == b.eu_payload,
1953 .opt_payload => |a_opt_payload| a_opt_payload == b.opt_payload,2188 .opt_payload => |a_opt_payload| a_opt_payload == b.opt_payload,
...@@ -2048,7 +2283,7 @@ pub const Key = union(enum) {...@@ -2048,7 +2283,7 @@ pub const Key = union(enum) {
2048 .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)),2283 .payload => |y| Hash.hash(seed + 1, asBytes(&x.ty) ++ asBytes(&y)),
2049 },2284 },
20502285
2051 .variable => |variable| Hash.hash(seed, asBytes(&variable.decl)),2286 .variable => |variable| Hash.hash(seed, asBytes(&variable.owner_nav)),
20522287
2053 .opaque_type,2288 .opaque_type,
2054 .enum_type,2289 .enum_type,
...@@ -2125,9 +2360,9 @@ pub const Key = union(enum) {...@@ -2125,9 +2360,9 @@ pub const Key = union(enum) {
2125 const big_offset: i128 = ptr.byte_offset;2360 const big_offset: i128 = ptr.byte_offset;
2126 const common = asBytes(&ptr.ty) ++ asBytes(&big_offset);2361 const common = asBytes(&ptr.ty) ++ asBytes(&big_offset);
2127 return switch (ptr.base_addr) {2362 return switch (ptr.base_addr) {
2128 inline .decl,2363 inline .nav,
2129 .comptime_alloc,2364 .comptime_alloc,
2130 .anon_decl,2365 .uav,
2131 .int,2366 .int,
2132 .eu_payload,2367 .eu_payload,
2133 .opt_payload,2368 .opt_payload,
...@@ -2231,7 +2466,7 @@ pub const Key = union(enum) {...@@ -2231,7 +2466,7 @@ pub const Key = union(enum) {
2231 // function instances which have inferred error sets.2466 // function instances which have inferred error sets.
22322467
2233 if (func.generic_owner == .none and func.resolved_error_set_extra_index == 0) {2468 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) ++
2235 [1]u8{@intFromBool(func.uncoerced_ty == func.ty)};2470 [1]u8{@intFromBool(func.uncoerced_ty == func.ty)};
2236 return Hash.hash(seed, bytes);2471 return Hash.hash(seed, bytes);
2237 }2472 }
...@@ -2250,7 +2485,11 @@ pub const Key = union(enum) {...@@ -2250,7 +2485,11 @@ pub const Key = union(enum) {
2250 return hasher.final();2485 return hasher.final();
2251 },2486 },
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)),
2254 };2493 };
2255 }2494 }
22562495
...@@ -2331,11 +2570,19 @@ pub const Key = union(enum) {...@@ -2331,11 +2570,19 @@ pub const Key = union(enum) {
23312570
2332 .variable => |a_info| {2571 .variable => |a_info| {
2333 const b_info = b.variable;2572 const b_info = b.variable;
2334 return a_info.decl == b_info.decl;2573 return a_info.owner_nav == b_info.owner_nav;
2335 },2574 },
2336 .extern_func => |a_info| {2575 .@"extern" => |a_info| {
2337 const b_info = b.extern_func;2576 const b_info = b.@"extern";
2338 return a_info.ty == b_info.ty and a_info.decl == b_info.decl;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;
2339 },2586 },
2340 .func => |a_info| {2587 .func => |a_info| {
2341 const b_info = b.func;2588 const b_info = b.func;
...@@ -2344,7 +2591,7 @@ pub const Key = union(enum) {...@@ -2344,7 +2591,7 @@ pub const Key = union(enum) {
2344 return false;2591 return false;
23452592
2346 if (a_info.generic_owner == .none) {2593 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)
2348 return false;2595 return false;
2349 } else {2596 } else {
2350 if (!std.mem.eql(2597 if (!std.mem.eql(
...@@ -2594,7 +2841,7 @@ pub const Key = union(enum) {...@@ -2594,7 +2841,7 @@ pub const Key = union(enum) {
2594 .float,2841 .float,
2595 .opt,2842 .opt,
2596 .variable,2843 .variable,
2597 .extern_func,2844 .@"extern",
2598 .func,2845 .func,
2599 .err,2846 .err,
2600 .error_union,2847 .error_union,
...@@ -2632,10 +2879,13 @@ pub const LoadedUnionType = struct {...@@ -2632,10 +2879,13 @@ pub const LoadedUnionType = struct {
2632 tid: Zcu.PerThread.Id,2879 tid: Zcu.PerThread.Id,
2633 /// The index of the `Tag.TypeUnion` payload.2880 /// The index of the `Tag.TypeUnion` payload.
2634 extra_index: u32,2881 extra_index: u32,
2635 /// The Decl that corresponds to the union itself.2882 // TODO: the non-fqn will be needed by the new dwarf structure
2636 decl: DeclIndex,2883 /// The name of this union type.
2884 name: NullTerminatedString,
2885 /// The `Cau` within which type resolution occurs.
2886 cau: Cau.Index,
2637 /// Represents the declarations inside this union.2887 /// Represents the declarations inside this union.
2638 namespace: OptionalNamespaceIndex,2888 namespace: NamespaceIndex,
2639 /// The enum tag type.2889 /// The enum tag type.
2640 enum_tag_ty: Index,2890 enum_tag_ty: Index,
2641 /// List of field types in declaration order.2891 /// List of field types in declaration order.
...@@ -2949,7 +3199,8 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -2949,7 +3199,8 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2949 return .{3199 return .{
2950 .tid = unwrapped_index.tid,3200 .tid = unwrapped_index.tid,
2951 .extra_index = data,3201 .extra_index = data,
2952 .decl = type_union.data.decl,3202 .name = type_union.data.name,
3203 .cau = type_union.data.cau,
2953 .namespace = type_union.data.namespace,3204 .namespace = type_union.data.namespace,
2954 .enum_tag_ty = type_union.data.tag_ty,3205 .enum_tag_ty = type_union.data.tag_ty,
2955 .field_types = field_types,3206 .field_types = field_types,
...@@ -2963,9 +3214,12 @@ pub const LoadedStructType = struct {...@@ -2963,9 +3214,12 @@ pub const LoadedStructType = struct {
2963 tid: Zcu.PerThread.Id,3214 tid: Zcu.PerThread.Id,
2964 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.3215 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.
2965 extra_index: u32,3216 extra_index: u32,
2966 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.3217 // TODO: the non-fqn will be needed by the new dwarf structure
2967 decl: OptionalDeclIndex,3218 /// The name of this struct type.
2968 /// `none` when the struct has no declarations.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(.{})`.
2969 namespace: OptionalNamespaceIndex,3223 namespace: OptionalNamespaceIndex,
2970 /// Index of the `struct_decl` or `reify` ZIR instruction.3224 /// Index of the `struct_decl` or `reify` ZIR instruction.
2971 /// Only `none` when the struct is `@TypeOf(.{})`.3225 /// Only `none` when the struct is `@TypeOf(.{})`.
...@@ -3563,7 +3817,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3563,7 +3817,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3563 if (item.data == 0) return .{3817 if (item.data == 0) return .{
3564 .tid = .main,3818 .tid = .main,
3565 .extra_index = 0,3819 .extra_index = 0,
3566 .decl = .none,3820 .name = .empty,
3821 .cau = .none,
3567 .namespace = .none,3822 .namespace = .none,
3568 .zir_index = .none,3823 .zir_index = .none,
3569 .layout = .auto,3824 .layout = .auto,
...@@ -3577,7 +3832,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3577,7 +3832,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3577 .names_map = .none,3832 .names_map = .none,
3578 .captures = CaptureValue.Slice.empty,3833 .captures = CaptureValue.Slice.empty,
3579 };3834 };
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").?]);
3581 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);3838 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
3582 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];3839 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
3583 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));3840 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 {...@@ -3622,11 +3879,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3622 extra_index += fields_len;3879 extra_index += fields_len;
3623 break :i inits;3880 break :i inits;
3624 } else Index.Slice.empty;3881 } 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;
3630 const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: {3882 const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: {
3631 const a: Alignment.Slice = .{3883 const a: Alignment.Slice = .{
3632 .tid = unwrapped_index.tid,3884 .tid = unwrapped_index.tid,
...@@ -3667,8 +3919,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3667,8 +3919,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3667 return .{3919 return .{
3668 .tid = unwrapped_index.tid,3920 .tid = unwrapped_index.tid,
3669 .extra_index = item.data,3921 .extra_index = item.data,
3670 .decl = decl.toOptional(),3922 .name = name,
3671 .namespace = namespace,3923 .cau = cau.toOptional(),
3924 .namespace = namespace.toOptional(),
3672 .zir_index = zir_index.toOptional(),3925 .zir_index = zir_index.toOptional(),
3673 .layout = if (flags.is_extern) .@"extern" else .auto,3926 .layout = if (flags.is_extern) .@"extern" else .auto,
3674 .field_names = names,3927 .field_names = names,
...@@ -3683,10 +3936,11 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3683,10 +3936,11 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3683 };3936 };
3684 },3937 },
3685 .type_struct_packed, .type_struct_packed_inits => {3938 .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").?]);
3687 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);3941 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
3688 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];3942 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").?]);
3690 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);3944 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);
3691 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));3945 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));
3692 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);3946 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 {...@@ -3729,8 +3983,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3729 return .{3983 return .{
3730 .tid = unwrapped_index.tid,3984 .tid = unwrapped_index.tid,
3731 .extra_index = item.data,3985 .extra_index = item.data,
3732 .decl = decl.toOptional(),3986 .name = name,
3733 .namespace = namespace,3987 .cau = cau.toOptional(),
3988 .namespace = namespace.toOptional(),
3734 .zir_index = zir_index.toOptional(),3989 .zir_index = zir_index.toOptional(),
3735 .layout = .@"packed",3990 .layout = .@"packed",
3736 .field_names = field_names,3991 .field_names = field_names,
...@@ -3749,10 +4004,14 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3749,10 +4004,14 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3749}4004}
37504005
3751const LoadedEnumType = struct {4006const LoadedEnumType = struct {
3752 /// The Decl that corresponds to the enum itself.4007 // TODO: the non-fqn will be needed by the new dwarf structure
3753 decl: DeclIndex,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,
3754 /// Represents the declarations inside this enum.4013 /// Represents the declarations inside this enum.
3755 namespace: OptionalNamespaceIndex,4014 namespace: NamespaceIndex,
3756 /// An integer type which is used for the numerical value of the enum.4015 /// An integer type which is used for the numerical value of the enum.
3757 /// This field is present regardless of whether the enum has an4016 /// This field is present regardless of whether the enum has an
3758 /// explicitly provided tag type or auto-numbered.4017 /// explicitly provided tag type or auto-numbered.
...@@ -3827,15 +4086,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3827,15 +4086,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3827 .type_enum_auto => {4086 .type_enum_auto => {
3828 const extra = extraDataTrail(extra_list, EnumAuto, item.data);4087 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
3829 var extra_index: u32 = @intCast(extra.end);4088 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: {
3831 extra_index += 1; // owner_union4090 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 };
3833 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {4097 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
3834 extra_index += 2; // type_hash: PackedU644098 extra_index += 2; // type_hash: PackedU64
3835 break :c 0;4099 break :c 0;
3836 } else extra.data.captures_len;4100 } else extra.data.captures_len;
3837 return .{4101 return .{
3838 .decl = extra.data.decl,4102 .name = extra.data.name,
4103 .cau = cau,
3839 .namespace = extra.data.namespace,4104 .namespace = extra.data.namespace,
3840 .tag_ty = extra.data.int_tag_type,4105 .tag_ty = extra.data.int_tag_type,
3841 .names = .{4106 .names = .{
...@@ -3861,15 +4126,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3861,15 +4126,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3861 };4126 };
3862 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);4127 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
3863 var extra_index: u32 = @intCast(extra.end);4128 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: {
3865 extra_index += 1; // owner_union4130 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 };
3867 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {4137 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
3868 extra_index += 2; // type_hash: PackedU644138 extra_index += 2; // type_hash: PackedU64
3869 break :c 0;4139 break :c 0;
3870 } else extra.data.captures_len;4140 } else extra.data.captures_len;
3871 return .{4141 return .{
3872 .decl = extra.data.decl,4142 .name = extra.data.name,
4143 .cau = cau,
3873 .namespace = extra.data.namespace,4144 .namespace = extra.data.namespace,
3874 .tag_ty = extra.data.int_tag_type,4145 .tag_ty = extra.data.int_tag_type,
3875 .names = .{4146 .names = .{
...@@ -3896,10 +4167,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3896,10 +4167,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38964167
3897/// Note that this type doubles as the payload for `Tag.type_opaque`.4168/// Note that this type doubles as the payload for `Tag.type_opaque`.
3898pub const LoadedOpaqueType = struct {4169pub const LoadedOpaqueType = struct {
3899 /// The opaque's owner Decl.
3900 decl: DeclIndex,
3901 /// Contains the declarations inside this opaque.4170 /// 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,
3903 /// Index of the `opaque_decl` or `reify` instruction.4175 /// Index of the `opaque_decl` or `reify` instruction.
3904 zir_index: TrackedInst.Index,4176 zir_index: TrackedInst.Index,
3905 captures: CaptureValue.Slice,4177 captures: CaptureValue.Slice,
...@@ -3915,7 +4187,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {...@@ -3915,7 +4187,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
3915 else4187 else
3916 extra.data.captures_len;4188 extra.data.captures_len;
3917 return .{4189 return .{
3918 .decl = extra.data.decl,4190 .name = extra.data.name,
3919 .namespace = extra.data.namespace,4191 .namespace = extra.data.namespace,
3920 .zir_index = extra.data.zir_index,4192 .zir_index = extra.data.zir_index,
3921 .captures = .{4193 .captures = .{
...@@ -4216,10 +4488,10 @@ pub const Index = enum(u32) {...@@ -4216,10 +4488,10 @@ pub const Index = enum(u32) {
42164488
4217 undef: DataIsIndex,4489 undef: DataIsIndex,
4218 simple_value: void,4490 simple_value: void,
4219 ptr_decl: struct { data: *PtrDecl },4491 ptr_nav: struct { data: *PtrNav },
4220 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },4492 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },
4221 ptr_anon_decl: struct { data: *PtrAnonDecl },4493 ptr_uav: struct { data: *PtrUav },
4222 ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned },4494 ptr_uav_aligned: struct { data: *PtrUavAligned },
4223 ptr_comptime_field: struct { data: *PtrComptimeField },4495 ptr_comptime_field: struct { data: *PtrComptimeField },
4224 ptr_int: struct { data: *PtrInt },4496 ptr_int: struct { data: *PtrInt },
4225 ptr_eu_payload: struct { data: *PtrBase },4497 ptr_eu_payload: struct { data: *PtrBase },
...@@ -4255,7 +4527,7 @@ pub const Index = enum(u32) {...@@ -4255,7 +4527,7 @@ pub const Index = enum(u32) {
4255 float_c_longdouble_f128: struct { data: *Float128 },4527 float_c_longdouble_f128: struct { data: *Float128 },
4256 float_comptime_float: struct { data: *Float128 },4528 float_comptime_float: struct { data: *Float128 },
4257 variable: struct { data: *Tag.Variable },4529 variable: struct { data: *Tag.Variable },
4258 extern_func: struct { data: *Key.ExternFunc },4530 @"extern": struct { data: *Tag.Extern },
4259 func_decl: struct {4531 func_decl: struct {
4260 const @"data.analysis.inferred_error_set" = opaque {};4532 const @"data.analysis.inferred_error_set" = opaque {};
4261 data: *Tag.FuncDecl,4533 data: *Tag.FuncDecl,
...@@ -4669,23 +4941,23 @@ pub const Tag = enum(u8) {...@@ -4669,23 +4941,23 @@ pub const Tag = enum(u8) {
4669 /// A value that can be represented with only an enum tag.4941 /// A value that can be represented with only an enum tag.
4670 /// data is SimpleValue enum value.4942 /// data is SimpleValue enum value.
4671 simple_value,4943 simple_value,
4672 /// A pointer to a decl.4944 /// A pointer to a `Nav`.
4673 /// data is extra index of `PtrDecl`, which contains the type and address.4945 /// data is extra index of `PtrNav`, which contains the type and address.
4674 ptr_decl,4946 ptr_nav,
4675 /// A pointer to a decl that can be mutated at comptime.4947 /// A pointer to a decl that can be mutated at comptime.
4676 /// data is extra index of `PtrComptimeAlloc`, which contains the type and address.4948 /// data is extra index of `PtrComptimeAlloc`, which contains the type and address.
4677 ptr_comptime_alloc,4949 ptr_comptime_alloc,
4678 /// A pointer to an anonymous decl.4950 /// A pointer to an anonymous addressable value.
4679 /// data is extra index of `PtrAnonDecl`, which contains the pointer type and decl value.4951 /// data is extra index of `PtrUav`, which contains the pointer type and decl value.
4680 /// The alignment of the anonymous decl is communicated via the pointer type.4952 /// The alignment of the uav is communicated via the pointer type.
4681 ptr_anon_decl,4953 ptr_uav,
4682 /// A pointer to an anonymous decl.4954 /// A pointer to an unnamed addressable value.
4683 /// data is extra index of `PtrAnonDeclAligned`, which contains the pointer4955 /// data is extra index of `PtrUavAligned`, which contains the pointer
4684 /// type and decl value.4956 /// type and decl value.
4685 /// The original pointer type is also provided, which will be different than `ty`.4957 /// 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 is4958 /// This encoding is only used when a pointer to a Uav is
4687 /// coerced to a different pointer type with a different alignment.4959 /// coerced to a different pointer type with a different alignment.
4688 ptr_anon_decl_aligned,4960 ptr_uav_aligned,
4689 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.4961 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.
4690 ptr_comptime_field,4962 ptr_comptime_field,
4691 /// A pointer with an integer value.4963 /// A pointer with an integer value.
...@@ -4800,9 +5072,10 @@ pub const Tag = enum(u8) {...@@ -4800,9 +5072,10 @@ pub const Tag = enum(u8) {
4800 /// A global variable.5072 /// A global variable.
4801 /// data is extra index to Variable.5073 /// data is extra index to Variable.
4802 variable,5074 variable,
4803 /// An extern function.5075 /// An extern function or variable.
4804 /// data is extra index to ExternFunc.5076 /// data is extra index to Extern.
4805 extern_func,5077 /// Some parts of the key are stored in `owner_nav`.
5078 @"extern",
4806 /// A non-extern function corresponding directly to the AST node from whence it originated.5079 /// A non-extern function corresponding directly to the AST node from whence it originated.
4807 /// data is extra index to `FuncDecl`.5080 /// data is extra index to `FuncDecl`.
4808 /// Only the owner Decl is used for hashing and equality because the other5081 /// Only the owner Decl is used for hashing and equality because the other
...@@ -4843,7 +5116,6 @@ pub const Tag = enum(u8) {...@@ -4843,7 +5116,6 @@ pub const Tag = enum(u8) {
4843 const TypeValue = Key.TypeValue;5116 const TypeValue = Key.TypeValue;
4844 const Error = Key.Error;5117 const Error = Key.Error;
4845 const EnumTag = Key.EnumTag;5118 const EnumTag = Key.EnumTag;
4846 const ExternFunc = Key.ExternFunc;
4847 const Union = Key.Union;5119 const Union = Key.Union;
4848 const TypePointer = Key.PtrType;5120 const TypePointer = Key.PtrType;
48495121
...@@ -4877,10 +5149,10 @@ pub const Tag = enum(u8) {...@@ -4877,10 +5149,10 @@ pub const Tag = enum(u8) {
48775149
4878 .undef => unreachable,5150 .undef => unreachable,
4879 .simple_value => unreachable,5151 .simple_value => unreachable,
4880 .ptr_decl => PtrDecl,5152 .ptr_nav => PtrNav,
4881 .ptr_comptime_alloc => PtrComptimeAlloc,5153 .ptr_comptime_alloc => PtrComptimeAlloc,
4882 .ptr_anon_decl => PtrAnonDecl,5154 .ptr_uav => PtrUav,
4883 .ptr_anon_decl_aligned => PtrAnonDeclAligned,5155 .ptr_uav_aligned => PtrUavAligned,
4884 .ptr_comptime_field => PtrComptimeField,5156 .ptr_comptime_field => PtrComptimeField,
4885 .ptr_int => PtrInt,5157 .ptr_int => PtrInt,
4886 .ptr_eu_payload => PtrBase,5158 .ptr_eu_payload => PtrBase,
...@@ -4916,7 +5188,7 @@ pub const Tag = enum(u8) {...@@ -4916,7 +5188,7 @@ pub const Tag = enum(u8) {
4916 .float_c_longdouble_f128 => unreachable,5188 .float_c_longdouble_f128 => unreachable,
4917 .float_comptime_float => unreachable,5189 .float_comptime_float => unreachable,
4918 .variable => Variable,5190 .variable => Variable,
4919 .extern_func => ExternFunc,5191 .@"extern" => Extern,
4920 .func_decl => FuncDecl,5192 .func_decl => FuncDecl,
4921 .func_instance => FuncInstance,5193 .func_instance => FuncInstance,
4922 .func_coerced => FuncCoerced,5194 .func_coerced => FuncCoerced,
...@@ -4933,21 +5205,29 @@ pub const Tag = enum(u8) {...@@ -4933,21 +5205,29 @@ pub const Tag = enum(u8) {
4933 ty: Index,5205 ty: Index,
4934 /// May be `none`.5206 /// May be `none`.
4935 init: Index,5207 init: Index,
4936 decl: DeclIndex,5208 owner_nav: Nav.Index,
4937 /// Library name if specified.5209 /// Library name if specified.
4938 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.5210 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.
4939 lib_name: OptionalNullTerminatedString,5211 lib_name: OptionalNullTerminatedString,
4940 flags: Flags,5212 flags: Flags,
49415213
4942 pub const Flags = packed struct(u32) {5214 pub const Flags = packed struct(u32) {
4943 is_extern: bool,
4944 is_const: bool,5215 is_const: bool,
4945 is_threadlocal: bool,5216 is_threadlocal: bool,
4946 is_weak_linkage: bool,5217 is_weak_linkage: bool,
4947 _: u28 = 0,5218 _: u29 = 0,
4948 };5219 };
4949 };5220 };
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
4951 /// Trailing:5231 /// Trailing:
4952 /// 0. element: Index for each len5232 /// 0. element: Index for each len
4953 /// len is determined by the aggregate type.5233 /// len is determined by the aggregate type.
...@@ -4962,7 +5242,7 @@ pub const Tag = enum(u8) {...@@ -4962,7 +5242,7 @@ pub const Tag = enum(u8) {
4962 /// A `none` value marks that the inferred error set is not resolved yet.5242 /// A `none` value marks that the inferred error set is not resolved yet.
4963 pub const FuncDecl = struct {5243 pub const FuncDecl = struct {
4964 analysis: FuncAnalysis,5244 analysis: FuncAnalysis,
4965 owner_decl: DeclIndex,5245 owner_nav: Nav.Index,
4966 ty: Index,5246 ty: Index,
4967 zir_body_inst: TrackedInst.Index,5247 zir_body_inst: TrackedInst.Index,
4968 lbrace_line: u32,5248 lbrace_line: u32,
...@@ -4979,7 +5259,7 @@ pub const Tag = enum(u8) {...@@ -4979,7 +5259,7 @@ pub const Tag = enum(u8) {
4979 pub const FuncInstance = struct {5259 pub const FuncInstance = struct {
4980 analysis: FuncAnalysis,5260 analysis: FuncAnalysis,
4981 // Needed by the linker for codegen. Not part of hashing or equality.5261 // Needed by the linker for codegen. Not part of hashing or equality.
4982 owner_decl: DeclIndex,5262 owner_nav: Nav.Index,
4983 ty: Index,5263 ty: Index,
4984 branch_quota: u32,5264 branch_quota: u32,
4985 /// Points to a `FuncDecl`.5265 /// Points to a `FuncDecl`.
...@@ -5029,6 +5309,7 @@ pub const Tag = enum(u8) {...@@ -5029,6 +5309,7 @@ pub const Tag = enum(u8) {
5029 /// 3. field type: Index for each field; declaration order5309 /// 3. field type: Index for each field; declaration order
5030 /// 4. field align: Alignment for each field; declaration order5310 /// 4. field align: Alignment for each field; declaration order
5031 pub const TypeUnion = struct {5311 pub const TypeUnion = struct {
5312 name: NullTerminatedString,
5032 flags: Flags,5313 flags: Flags,
5033 /// This could be provided through the tag type, but it is more convenient5314 /// This could be provided through the tag type, but it is more convenient
5034 /// to store it directly. This is also necessary for `dumpStatsFallible` to5315 /// to store it directly. This is also necessary for `dumpStatsFallible` to
...@@ -5038,8 +5319,8 @@ pub const Tag = enum(u8) {...@@ -5038,8 +5319,8 @@ pub const Tag = enum(u8) {
5038 size: u32,5319 size: u32,
5039 /// Only valid after .have_layout5320 /// Only valid after .have_layout
5040 padding: u32,5321 padding: u32,
5041 decl: DeclIndex,5322 cau: Cau.Index,
5042 namespace: OptionalNamespaceIndex,5323 namespace: NamespaceIndex,
5043 /// The enum that provides the list of field names and values.5324 /// The enum that provides the list of field names and values.
5044 tag_ty: Index,5325 tag_ty: Index,
5045 zir_index: TrackedInst.Index,5326 zir_index: TrackedInst.Index,
...@@ -5068,10 +5349,11 @@ pub const Tag = enum(u8) {...@@ -5068,10 +5349,11 @@ pub const Tag = enum(u8) {
5068 /// 4. name: NullTerminatedString for each fields_len5349 /// 4. name: NullTerminatedString for each fields_len
5069 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits5350 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits
5070 pub const TypeStructPacked = struct {5351 pub const TypeStructPacked = struct {
5071 decl: DeclIndex,5352 name: NullTerminatedString,
5353 cau: Cau.Index,
5072 zir_index: TrackedInst.Index,5354 zir_index: TrackedInst.Index,
5073 fields_len: u32,5355 fields_len: u32,
5074 namespace: OptionalNamespaceIndex,5356 namespace: NamespaceIndex,
5075 backing_int_ty: Index,5357 backing_int_ty: Index,
5076 names_map: MapIndex,5358 names_map: MapIndex,
5077 flags: Flags,5359 flags: Flags,
...@@ -5110,18 +5392,18 @@ pub const Tag = enum(u8) {...@@ -5110,18 +5392,18 @@ pub const Tag = enum(u8) {
5110 /// name: NullTerminatedString // for each field in declared order5392 /// name: NullTerminatedString // for each field in declared order
5111 /// 5. if any_default_inits:5393 /// 5. if any_default_inits:
5112 /// init: Index // for each field in declared order5394 /// init: Index // for each field in declared order
5113 /// 6. if has_namespace:5395 /// 6. if any_aligned_fields:
5114 /// namespace: NamespaceIndex
5115 /// 7. if any_aligned_fields:
5116 /// align: Alignment // for each field in declared order5396 /// align: Alignment // for each field in declared order
5117 /// 8. if any_comptime_fields:5397 /// 7. if any_comptime_fields:
5118 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 05398 /// 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:
5120 /// field_index: RuntimeOrder // for each field in runtime order5400 /// field_index: RuntimeOrder // for each field in runtime order
5121 /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved5401 /// 9. field_offset: u32 // for each field in declared order, undef until layout_resolved
5122 pub const TypeStruct = struct {5402 pub const TypeStruct = struct {
5123 decl: DeclIndex,5403 name: NullTerminatedString,
5404 cau: Cau.Index,
5124 zir_index: TrackedInst.Index,5405 zir_index: TrackedInst.Index,
5406 namespace: NamespaceIndex,
5125 fields_len: u32,5407 fields_len: u32,
5126 flags: Flags,5408 flags: Flags,
5127 size: u32,5409 size: u32,
...@@ -5134,7 +5416,6 @@ pub const Tag = enum(u8) {...@@ -5134,7 +5416,6 @@ pub const Tag = enum(u8) {
5134 is_tuple: bool = false,5416 is_tuple: bool = false,
5135 assumed_runtime_bits: bool = false,5417 assumed_runtime_bits: bool = false,
5136 assumed_pointer_aligned: bool = false,5418 assumed_pointer_aligned: bool = false,
5137 has_namespace: bool = false,
5138 any_comptime_fields: bool = false,5419 any_comptime_fields: bool = false,
5139 any_default_inits: bool = false,5420 any_default_inits: bool = false,
5140 any_aligned_fields: bool = false,5421 any_aligned_fields: bool = false,
...@@ -5157,17 +5438,16 @@ pub const Tag = enum(u8) {...@@ -5157,17 +5438,16 @@ pub const Tag = enum(u8) {
5157 // which `layout_resolved` does not ensure.5438 // which `layout_resolved` does not ensure.
5158 fully_resolved: bool = false,5439 fully_resolved: bool = false,
5159 is_reified: bool = false,5440 is_reified: bool = false,
5160 _: u6 = 0,5441 _: u7 = 0,
5161 };5442 };
5162 };5443 };
51635444
5164 /// Trailing:5445 /// Trailing:
5165 /// 0. capture: CaptureValue // for each `captures_len`5446 /// 0. capture: CaptureValue // for each `captures_len`
5166 pub const TypeOpaque = struct {5447 pub const TypeOpaque = struct {
5167 /// The opaque's owner Decl.5448 name: NullTerminatedString,
5168 decl: DeclIndex,
5169 /// Contains the declarations inside this opaque.5449 /// Contains the declarations inside this opaque.
5170 namespace: OptionalNamespaceIndex,5450 namespace: NamespaceIndex,
5171 /// The index of the `opaque_decl` instruction.5451 /// The index of the `opaque_decl` instruction.
5172 zir_index: TrackedInst.Index,5452 zir_index: TrackedInst.Index,
5173 /// `std.math.maxInt(u32)` indicates this type is reified.5453 /// `std.math.maxInt(u32)` indicates this type is reified.
...@@ -5188,29 +5468,19 @@ pub const FuncAnalysis = packed struct(u32) {...@@ -5188,29 +5468,19 @@ pub const FuncAnalysis = packed struct(u32) {
5188 inferred_error_set: bool,5468 inferred_error_set: bool,
5189 disable_instrumentation: bool,5469 disable_instrumentation: bool,
51905470
5191 _: u13 = 0,5471 _: u19 = 0,
51925472
5193 pub const State = enum(u8) {5473 pub const State = enum(u2) {
5194 /// This function has not yet undergone analysis, because we have not5474 /// The runtime function has never been referenced.
5195 /// seen a potential runtime call. It may be analyzed in future.5475 /// As such, it has never been analyzed, nor is it queued for analysis.
5196 none,5476 unreferenced,
5197 /// Analysis for this function has been queued, but not yet completed.5477 /// The runtime function has been referenced, but has not yet been analyzed.
5478 /// Its semantic analysis is queued.
5198 queued,5479 queued,
5199 /// This function intentionally only has ZIR generated because it is marked5480 /// The runtime function has been (or is currently being) semantically analyzed.
5200 /// inline, which means no runtime version of the function will be generated.5481 /// To know if analysis succeeded, consult `zcu.[transitive_]failed_analysis`.
5201 inline_only,5482 /// To know if analysis is up-to-date, consult `zcu.[potentially_]outdated`.
5202 in_progress,5483 analyzed,
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,
5214 };5484 };
5215};5485};
52165486
...@@ -5477,17 +5747,16 @@ pub const Array = struct {...@@ -5477,17 +5747,16 @@ pub const Array = struct {
54775747
5478/// Trailing:5748/// Trailing:
5479/// 0. owner_union: Index // if `zir_index == .none`5749/// 0. owner_union: Index // if `zir_index == .none`
5480/// 1. capture: CaptureValue // for each `captures_len`5750/// 1. cau: Cau.Index // if `zir_index != .none`
5481/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)5751/// 2. capture: CaptureValue // for each `captures_len`
5482/// 3. field name: NullTerminatedString for each fields_len; declaration order5752/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5483/// 4. tag value: Index for each fields_len; declaration order5753/// 4. field name: NullTerminatedString for each fields_len; declaration order
5754/// 5. tag value: Index for each fields_len; declaration order
5484pub const EnumExplicit = struct {5755pub const EnumExplicit = struct {
5485 /// The Decl that corresponds to the enum itself.5756 name: NullTerminatedString,
5486 decl: DeclIndex,
5487 /// `std.math.maxInt(u32)` indicates this type is reified.5757 /// `std.math.maxInt(u32)` indicates this type is reified.
5488 captures_len: u32,5758 captures_len: u32,
5489 /// This may be `none` if there are no declarations.5759 namespace: NamespaceIndex,
5490 namespace: OptionalNamespaceIndex,
5491 /// An integer type which is used for the numerical value of the enum, which5760 /// An integer type which is used for the numerical value of the enum, which
5492 /// has been explicitly provided by the enum declaration.5761 /// has been explicitly provided by the enum declaration.
5493 int_tag_type: Index,5762 int_tag_type: Index,
...@@ -5505,16 +5774,15 @@ pub const EnumExplicit = struct {...@@ -5505,16 +5774,15 @@ pub const EnumExplicit = struct {
55055774
5506/// Trailing:5775/// Trailing:
5507/// 0. owner_union: Index // if `zir_index == .none`5776/// 0. owner_union: Index // if `zir_index == .none`
5508/// 1. capture: CaptureValue // for each `captures_len`5777/// 1. cau: Cau.Index // if `zir_index != .none`
5509/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)5778/// 2. capture: CaptureValue // for each `captures_len`
5510/// 3. field name: NullTerminatedString for each fields_len; declaration order5779/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5780/// 4. field name: NullTerminatedString for each fields_len; declaration order
5511pub const EnumAuto = struct {5781pub const EnumAuto = struct {
5512 /// The Decl that corresponds to the enum itself.5782 name: NullTerminatedString,
5513 decl: DeclIndex,
5514 /// `std.math.maxInt(u32)` indicates this type is reified.5783 /// `std.math.maxInt(u32)` indicates this type is reified.
5515 captures_len: u32,5784 captures_len: u32,
5516 /// This may be `none` if there are no declarations.5785 namespace: NamespaceIndex,
5517 namespace: OptionalNamespaceIndex,
5518 /// An integer type which is used for the numerical value of the enum, which5786 /// An integer type which is used for the numerical value of the enum, which
5519 /// was inferred by Zig based on the number of tags.5787 /// was inferred by Zig based on the number of tags.
5520 int_tag_type: Index,5788 int_tag_type: Index,
...@@ -5539,15 +5807,15 @@ pub const PackedU64 = packed struct(u64) {...@@ -5539,15 +5807,15 @@ pub const PackedU64 = packed struct(u64) {
5539 }5807 }
5540};5808};
55415809
5542pub const PtrDecl = struct {5810pub const PtrNav = struct {
5543 ty: Index,5811 ty: Index,
5544 decl: DeclIndex,5812 nav: Nav.Index,
5545 byte_offset_a: u32,5813 byte_offset_a: u32,
5546 byte_offset_b: u32,5814 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() {
5548 return .{5816 return .{
5549 .ty = ty,5817 .ty = ty,
5550 .decl = decl,5818 .nav = nav,
5551 .byte_offset_a = @intCast(byte_offset >> 32),5819 .byte_offset_a = @intCast(byte_offset >> 32),
5552 .byte_offset_b = @truncate(byte_offset),5820 .byte_offset_b = @truncate(byte_offset),
5553 };5821 };
...@@ -5557,7 +5825,7 @@ pub const PtrDecl = struct {...@@ -5557,7 +5825,7 @@ pub const PtrDecl = struct {
5557 }5825 }
5558};5826};
55595827
5560pub const PtrAnonDecl = struct {5828pub const PtrUav = struct {
5561 ty: Index,5829 ty: Index,
5562 val: Index,5830 val: Index,
5563 byte_offset_a: u32,5831 byte_offset_a: u32,
...@@ -5575,7 +5843,7 @@ pub const PtrAnonDecl = struct {...@@ -5575,7 +5843,7 @@ pub const PtrAnonDecl = struct {
5575 }5843 }
5576};5844};
55775845
5578pub const PtrAnonDeclAligned = struct {5846pub const PtrUavAligned = struct {
5579 ty: Index,5847 ty: Index,
5580 val: Index,5848 val: Index,
5581 /// Must be nonequal to `ty`. Only the alignment from this value is important.5849 /// 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 {...@@ -5805,8 +6073,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5805 .tracked_insts = Local.TrackedInsts.empty,6073 .tracked_insts = Local.TrackedInsts.empty,
5806 .files = Local.List(File).empty,6074 .files = Local.List(File).empty,
5807 .maps = Local.Maps.empty,6075 .maps = Local.Maps.empty,
6076 .caus = Local.Caus.empty,
6077 .navs = Local.Navs.empty,
58086078
5809 .decls = Local.Decls.empty,
5810 .namespaces = Local.Namespaces.empty,6079 .namespaces = Local.Namespaces.empty,
5811 },6080 },
5812 .mutate = .{6081 .mutate = .{
...@@ -5819,8 +6088,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5819,8 +6088,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5819 .tracked_insts = Local.ListMutate.empty,6088 .tracked_insts = Local.ListMutate.empty,
5820 .files = Local.ListMutate.empty,6089 .files = Local.ListMutate.empty,
5821 .maps = Local.ListMutate.empty,6090 .maps = Local.ListMutate.empty,
6091 .caus = Local.ListMutate.empty,
6092 .navs = Local.ListMutate.empty,
58226093
5823 .decls = Local.BucketListMutate.empty,
5824 .namespaces = Local.BucketListMutate.empty,6094 .namespaces = Local.BucketListMutate.empty,
5825 },6095 },
5826 });6096 });
...@@ -5878,8 +6148,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5878,8 +6148,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58786148
5879pub fn deinit(ip: *InternPool, gpa: Allocator) void {6149pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5880 ip.src_hash_deps.deinit(gpa);6150 ip.src_hash_deps.deinit(gpa);
5881 ip.decl_val_deps.deinit(gpa);6151 ip.nav_val_deps.deinit(gpa);
5882 ip.func_ies_deps.deinit(gpa);6152 ip.interned_deps.deinit(gpa);
5883 ip.namespace_deps.deinit(gpa);6153 ip.namespace_deps.deinit(gpa);
5884 ip.namespace_name_deps.deinit(gpa);6154 ip.namespace_name_deps.deinit(gpa);
58856155
...@@ -5900,8 +6170,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -5900,8 +6170,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5900 else6170 else
5901 local.mutate.namespaces.last_bucket_len]) |*namespace|6171 local.mutate.namespaces.last_bucket_len]) |*namespace|
5902 {6172 {
5903 namespace.decls.deinit(gpa);6173 namespace.pub_decls.deinit(gpa);
5904 namespace.usingnamespace_set.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);
5905 }6178 }
5906 };6179 };
5907 const maps = local.getMutableMaps(gpa);6180 const maps = local.getMutableMaps(gpa);
...@@ -6082,14 +6355,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6082,14 +6355,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6082 if (extra.data.captures_len == std.math.maxInt(u32)) {6355 if (extra.data.captures_len == std.math.maxInt(u32)) {
6083 break :ns .{ .reified = .{6356 break :ns .{ .reified = .{
6084 .zir_index = zir_index,6357 .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(),
6086 } };6359 } };
6087 }6360 }
6088 break :ns .{ .declared = .{6361 break :ns .{ .declared = .{
6089 .zir_index = zir_index,6362 .zir_index = zir_index,
6090 .captures = .{ .owned = .{6363 .captures = .{ .owned = .{
6091 .tid = unwrapped_index.tid,6364 .tid = unwrapped_index.tid,
6092 .start = extra.end,6365 .start = extra.end + 1,
6093 .len = extra.data.captures_len,6366 .len = extra.data.captures_len,
6094 } },6367 } },
6095 } };6368 } };
...@@ -6106,14 +6379,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6106,14 +6379,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6106 if (extra.data.captures_len == std.math.maxInt(u32)) {6379 if (extra.data.captures_len == std.math.maxInt(u32)) {
6107 break :ns .{ .reified = .{6380 break :ns .{ .reified = .{
6108 .zir_index = zir_index,6381 .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(),
6110 } };6383 } };
6111 }6384 }
6112 break :ns .{ .declared = .{6385 break :ns .{ .declared = .{
6113 .zir_index = zir_index,6386 .zir_index = zir_index,
6114 .captures = .{ .owned = .{6387 .captures = .{ .owned = .{
6115 .tid = unwrapped_index.tid,6388 .tid = unwrapped_index.tid,
6116 .start = extra.end,6389 .start = extra.end + 1,
6117 .len = extra.data.captures_len,6390 .len = extra.data.captures_len,
6118 } },6391 } },
6119 } };6392 } };
...@@ -6132,24 +6405,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6132,24 +6405,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6132 .val = extra.val,6405 .val = extra.val,
6133 } };6406 } };
6134 },6407 },
6135 .ptr_decl => {6408 .ptr_nav => {
6136 const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data);6409 const info = extraData(unwrapped_index.getExtra(ip), PtrNav, data);
6137 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };6410 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .nav = info.nav }, .byte_offset = info.byteOffset() } };
6138 },6411 },
6139 .ptr_comptime_alloc => {6412 .ptr_comptime_alloc => {
6140 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);6413 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);
6141 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };6414 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
6142 },6415 },
6143 .ptr_anon_decl => {6416 .ptr_uav => {
6144 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);6417 const info = extraData(unwrapped_index.getExtra(ip), PtrUav, data);
6145 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{6418 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
6146 .val = info.val,6419 .val = info.val,
6147 .orig_ty = info.ty,6420 .orig_ty = info.ty,
6148 } }, .byte_offset = info.byteOffset() } };6421 } }, .byte_offset = info.byteOffset() } };
6149 },6422 },
6150 .ptr_anon_decl_aligned => {6423 .ptr_uav_aligned => {
6151 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data);6424 const info = extraData(unwrapped_index.getExtra(ip), PtrUavAligned, data);
6152 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{6425 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
6153 .val = info.val,6426 .val = info.val,
6154 .orig_ty = info.orig_ty,6427 .orig_ty = info.orig_ty,
6155 } }, .byte_offset = info.byteOffset() } };6428 } }, .byte_offset = info.byteOffset() } };
...@@ -6293,15 +6566,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6293,15 +6566,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6293 return .{ .variable = .{6566 return .{ .variable = .{
6294 .ty = extra.ty,6567 .ty = extra.ty,
6295 .init = extra.init,6568 .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,
6297 .lib_name = extra.lib_name,6581 .lib_name = extra.lib_name,
6298 .is_extern = extra.flags.is_extern,
6299 .is_const = extra.flags.is_const,6582 .is_const = extra.flags.is_const,
6300 .is_threadlocal = extra.flags.is_threadlocal,6583 .is_threadlocal = extra.flags.is_threadlocal,
6301 .is_weak_linkage = extra.flags.is_weak_linkage,6584 .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,
6302 } };6589 } };
6303 },6590 },
6304 .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) },
6305 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },6591 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6306 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },6592 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6307 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },6593 .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...@@ -6513,7 +6799,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
6513 .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?,6799 .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?,
6514 .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0,6800 .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0,
6515 .branch_quota_extra_index = 0,6801 .branch_quota_extra_index = 0,
6516 .owner_decl = func_decl.data.owner_decl,6802 .owner_nav = func_decl.data.owner_nav,
6517 .zir_body_inst = func_decl.data.zir_body_inst,6803 .zir_body_inst = func_decl.data.zir_body_inst,
6518 .lbrace_line = func_decl.data.lbrace_line,6804 .lbrace_line = func_decl.data.lbrace_line,
6519 .rbrace_line = func_decl.data.rbrace_line,6805 .rbrace_line = func_decl.data.rbrace_line,
...@@ -6528,7 +6814,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local....@@ -6528,7 +6814,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
6528 const extra_items = extra.view().items(.@"0");6814 const extra_items = extra.view().items(.@"0");
6529 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;6815 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;
6530 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .unordered));6816 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").?]);
6532 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);6818 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);
6533 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);6819 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
6534 const func_decl = ip.funcDeclInfo(generic_owner);6820 const func_decl = ip.funcDeclInfo(generic_owner);
...@@ -6541,7 +6827,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local....@@ -6541,7 +6827,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
6541 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,6827 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,
6542 .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0,6828 .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0,
6543 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,6829 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,
6544 .owner_decl = owner_decl,6830 .owner_nav = owner_nav,
6545 .zir_body_inst = func_decl.zir_body_inst,6831 .zir_body_inst = func_decl.zir_body_inst,
6546 .lbrace_line = func_decl.lbrace_line,6832 .lbrace_line = func_decl.lbrace_line,
6547 .rbrace_line = func_decl.rbrace_line,6833 .rbrace_line = func_decl.rbrace_line,
...@@ -6905,7 +7191,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6905,7 +7191,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69057191
6906 .enum_type => unreachable, // use getEnumType() instead7192 .enum_type => unreachable, // use getEnumType() instead
6907 .func_type => unreachable, // use getFuncType() instead7193 .func_type => unreachable, // use getFuncType() instead
6908 .extern_func => unreachable, // use getExternFunc() instead7194 .@"extern" => unreachable, // use getExtern() instead
6909 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead7195 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead
69107196
6911 .variable => |variable| {7197 .variable => |variable| {
...@@ -6916,11 +7202,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6916,11 +7202,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6916 .data = try addExtra(extra, Tag.Variable{7202 .data = try addExtra(extra, Tag.Variable{
6917 .ty = variable.ty,7203 .ty = variable.ty,
6918 .init = variable.init,7204 .init = variable.init,
6919 .decl = variable.decl,7205 .owner_nav = variable.owner_nav,
6920 .lib_name = variable.lib_name,7206 .lib_name = variable.lib_name,
6921 .flags = .{7207 .flags = .{
6922 .is_extern = variable.is_extern,7208 .is_const = false,
6923 .is_const = variable.is_const,
6924 .is_threadlocal = variable.is_threadlocal,7209 .is_threadlocal = variable.is_threadlocal,
6925 .is_weak_linkage = variable.is_weak_linkage,7210 .is_weak_linkage = variable.is_weak_linkage,
6926 },7211 },
...@@ -6945,29 +7230,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6945,29 +7230,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6945 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;7230 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
6946 assert(ptr_type.flags.size != .Slice);7231 assert(ptr_type.flags.size != .Slice);
6947 items.appendAssumeCapacity(switch (ptr.base_addr) {7232 items.appendAssumeCapacity(switch (ptr.base_addr) {
6948 .decl => |decl| .{7233 .nav => |nav| .{
6949 .tag = .ptr_decl,7234 .tag = .ptr_nav,
6950 .data = try addExtra(extra, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),7235 .data = try addExtra(extra, PtrNav.init(ptr.ty, nav, ptr.byte_offset)),
6951 },7236 },
6952 .comptime_alloc => |alloc_index| .{7237 .comptime_alloc => |alloc_index| .{
6953 .tag = .ptr_comptime_alloc,7238 .tag = .ptr_comptime_alloc,
6954 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),7239 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
6955 },7240 },
6956 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {7241 .uav => |uav| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, uav.orig_ty)) item: {
6957 if (ptr.ty != anon_decl.orig_ty) {7242 if (ptr.ty != uav.orig_ty) {
6958 gop.cancel();7243 gop.cancel();
6959 var new_key = key;7244 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;
6961 gop = try ip.getOrPutKey(gpa, tid, new_key);7246 gop = try ip.getOrPutKey(gpa, tid, new_key);
6962 if (gop == .existing) return gop.existing;7247 if (gop == .existing) return gop.existing;
6963 }7248 }
6964 break :item .{7249 break :item .{
6965 .tag = .ptr_anon_decl,7250 .tag = .ptr_uav,
6966 .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),7251 .data = try addExtra(extra, PtrUav.init(ptr.ty, uav.val, ptr.byte_offset)),
6967 };7252 };
6968 } else .{7253 } else .{
6969 .tag = .ptr_anon_decl_aligned,7254 .tag = .ptr_uav_aligned,
6970 .data = try addExtra(extra, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),7255 .data = try addExtra(extra, PtrUavAligned.init(ptr.ty, uav.val, uav.orig_ty, ptr.byte_offset)),
6971 },7256 },
6972 .comptime_field => |field_val| item: {7257 .comptime_field => |field_val| item: {
6973 assert(field_val != .none);7258 assert(field_val != .none);
...@@ -7561,7 +7846,6 @@ pub const UnionTypeInit = struct {...@@ -7561,7 +7846,6 @@ pub const UnionTypeInit = struct {
7561 assumed_pointer_aligned: bool,7846 assumed_pointer_aligned: bool,
7562 alignment: Alignment,7847 alignment: Alignment,
7563 },7848 },
7564 has_namespace: bool,
7565 fields_len: u32,7849 fields_len: u32,
7566 enum_tag_ty: Index,7850 enum_tag_ty: Index,
7567 /// May have length 0 which leaves the values unset until later.7851 /// May have length 0 which leaves the values unset until later.
...@@ -7635,8 +7919,9 @@ pub fn getUnionType(...@@ -7635,8 +7919,9 @@ pub fn getUnionType(
7635 .fields_len = ini.fields_len,7919 .fields_len = ini.fields_len,
7636 .size = std.math.maxInt(u32),7920 .size = std.math.maxInt(u32),
7637 .padding = std.math.maxInt(u32),7921 .padding = std.math.maxInt(u32),
7638 .decl = undefined, // set by `finish`7922 .name = undefined, // set by `finish`
7639 .namespace = .none, // set by `finish`7923 .cau = undefined, // set by `finish`
7924 .namespace = undefined, // set by `finish`
7640 .tag_ty = ini.enum_tag_ty,7925 .tag_ty = ini.enum_tag_ty,
7641 .zir_index = switch (ini.key) {7926 .zir_index = switch (ini.key) {
7642 inline else => |x| x.zir_index,7927 inline else => |x| x.zir_index,
...@@ -7682,29 +7967,49 @@ pub fn getUnionType(...@@ -7682,29 +7967,49 @@ pub fn getUnionType(
7682 return .{ .wip = .{7967 return .{ .wip = .{
7683 .tid = tid,7968 .tid = tid,
7684 .index = gop.put(),7969 .index = gop.put(),
7685 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,7970 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
7686 .namespace_extra_index = if (ini.has_namespace)7971 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "cau").?,
7687 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?7972 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,
7688 else
7689 null,
7690 } };7973 } };
7691}7974}
76927975
7693pub const WipNamespaceType = struct {7976pub const WipNamespaceType = struct {
7694 tid: Zcu.PerThread.Id,7977 tid: Zcu.PerThread.Id,
7695 index: Index,7978 index: Index,
7696 decl_extra_index: u32,7979 type_name_extra_index: u32,
7697 namespace_extra_index: ?u32,7980 cau_extra_index: ?u32,
7698 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {7981 namespace_extra_index: u32,
7699 const extra_items = ip.getLocalShared(wip.tid).extra.acquire().view().items(.@"0");7982
7700 extra_items[wip.decl_extra_index] = @intFromEnum(decl);7983 pub fn setName(
7701 if (wip.namespace_extra_index) |i| {7984 wip: WipNamespaceType,
7702 extra_items[i] = @intFromEnum(namespace.unwrap().?);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().?);
7703 } else {8004 } else {
7704 assert(namespace == .none);8005 assert(analysis_owner == .none);
7705 }8006 }
8007
8008 extra_items[wip.namespace_extra_index] = @intFromEnum(namespace);
8009
7706 return wip.index;8010 return wip.index;
7707 }8011 }
8012
7708 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {8013 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
7709 ip.remove(tid, wip.index);8014 ip.remove(tid, wip.index);
7710 }8015 }
...@@ -7725,7 +8030,6 @@ pub const StructTypeInit = struct {...@@ -7725,7 +8030,6 @@ pub const StructTypeInit = struct {
7725 any_default_inits: bool,8030 any_default_inits: bool,
7726 inits_resolved: bool,8031 inits_resolved: bool,
7727 any_aligned_fields: bool,8032 any_aligned_fields: bool,
7728 has_namespace: bool,
7729 key: union(enum) {8033 key: union(enum) {
7730 declared: struct {8034 declared: struct {
7731 zir_index: TrackedInst.Index,8035 zir_index: TrackedInst.Index,
...@@ -7784,10 +8088,11 @@ pub fn getStructType(...@@ -7784,10 +8088,11 @@ pub fn getStructType(
7784 ini.fields_len + // names8088 ini.fields_len + // names
7785 ini.fields_len); // inits8089 ini.fields_len); // inits
7786 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{8090 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`
7788 .zir_index = zir_index,8093 .zir_index = zir_index,
7789 .fields_len = ini.fields_len,8094 .fields_len = ini.fields_len,
7790 .namespace = .none,8095 .namespace = undefined, // set by `finish`
7791 .backing_int_ty = .none,8096 .backing_int_ty = .none,
7792 .names_map = names_map,8097 .names_map = names_map,
7793 .flags = .{8098 .flags = .{
...@@ -7818,11 +8123,9 @@ pub fn getStructType(...@@ -7818,11 +8123,9 @@ pub fn getStructType(
7818 return .{ .wip = .{8123 return .{ .wip = .{
7819 .tid = tid,8124 .tid = tid,
7820 .index = gop.put(),8125 .index = gop.put(),
7821 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,8126 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
7822 .namespace_extra_index = if (ini.has_namespace)8127 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?,
7823 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?8128 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,
7824 else
7825 null,
7826 } };8129 } };
7827 },8130 },
7828 };8131 };
...@@ -7841,10 +8144,12 @@ pub fn getStructType(...@@ -7841,10 +8144,12 @@ pub fn getStructType(
7841 // zig fmt: on8144 // zig fmt: on
7842 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets8145 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
7843 align_elements_len + comptime_elements_len +8146 align_elements_len + comptime_elements_len +
7844 2); // names_map + namespace8147 1); // names_map
7845 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{8148 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`
7847 .zir_index = zir_index,8151 .zir_index = zir_index,
8152 .namespace = undefined, // set by `finish`
7848 .fields_len = ini.fields_len,8153 .fields_len = ini.fields_len,
7849 .size = std.math.maxInt(u32),8154 .size = std.math.maxInt(u32),
7850 .flags = .{8155 .flags = .{
...@@ -7855,7 +8160,6 @@ pub fn getStructType(...@@ -7855,7 +8160,6 @@ pub fn getStructType(
7855 .is_tuple = ini.is_tuple,8160 .is_tuple = ini.is_tuple,
7856 .assumed_runtime_bits = false,8161 .assumed_runtime_bits = false,
7857 .assumed_pointer_aligned = false,8162 .assumed_pointer_aligned = false,
7858 .has_namespace = ini.has_namespace,
7859 .any_comptime_fields = ini.any_comptime_fields,8163 .any_comptime_fields = ini.any_comptime_fields,
7860 .any_default_inits = ini.any_default_inits,8164 .any_default_inits = ini.any_default_inits,
7861 .any_aligned_fields = ini.any_aligned_fields,8165 .any_aligned_fields = ini.any_aligned_fields,
...@@ -7891,10 +8195,6 @@ pub fn getStructType(...@@ -7891,10 +8195,6 @@ pub fn getStructType(
7891 if (ini.any_default_inits) {8195 if (ini.any_default_inits) {
7892 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);8196 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
7893 }8197 }
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;
7898 if (ini.any_aligned_fields) {8198 if (ini.any_aligned_fields) {
7899 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);8199 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
7900 }8200 }
...@@ -7908,8 +8208,9 @@ pub fn getStructType(...@@ -7908,8 +8208,9 @@ pub fn getStructType(
7908 return .{ .wip = .{8208 return .{ .wip = .{
7909 .tid = tid,8209 .tid = tid,
7910 .index = gop.put(),8210 .index = gop.put(),
7911 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,8211 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
7912 .namespace_extra_index = namespace_extra_index,8212 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "cau").?,
8213 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,
7913 } };8214 } };
7914}8215}
79158216
...@@ -8047,34 +8348,71 @@ pub fn getFuncType(...@@ -8047,34 +8348,71 @@ pub fn getFuncType(
8047 return gop.put();8348 return gop.put();
8048}8349}
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(
8051 ip: *InternPool,8354 ip: *InternPool,
8052 gpa: Allocator,8355 gpa: Allocator,
8053 tid: Zcu.PerThread.Id,8356 tid: Zcu.PerThread.Id,
8054 key: Key.ExternFunc,8357 /// `key.owner_nav` is ignored.
8055) Allocator.Error!Index {8358 key: Key.Extern,
8056 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });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 });
8057 defer gop.deinit();8365 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
8060 const local = ip.getLocal(tid);8371 const local = ip.getLocal(tid);
8061 const items = local.getMutableItems(gpa);8372 const items = local.getMutableItems(gpa);
8062 try items.ensureUnusedCapacity(1);
8063 const extra = local.getMutableExtra(gpa);8373 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;8378 // Predict the index the `@"extern" will live at, so we can construct the owner `Nav` before releasing the shard's mutex.
8066 const extra_index = try addExtra(extra, @as(Tag.ExternFunc, key));8379 const extern_index = Index.Unwrapped.wrap(.{
8067 errdefer extra.mutate.len = prev_extra_len;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 });
8068 items.appendAssumeCapacity(.{8402 items.appendAssumeCapacity(.{
8069 .tag = .extern_func,8403 .tag = .@"extern",
8070 .data = extra_index,8404 .data = extra_index,
8071 });8405 });
8072 errdefer items.mutate.len -= 1;8406 assert(gop.put() == extern_index);
8073 return gop.put();8407
8408 return .{
8409 .index = extern_index,
8410 .new_nav = owner_nav.toOptional(),
8411 };
8074}8412}
80758413
8076pub const GetFuncDeclKey = struct {8414pub const GetFuncDeclKey = struct {
8077 owner_decl: DeclIndex,8415 owner_nav: Nav.Index,
8078 ty: Index,8416 ty: Index,
8079 zir_body_inst: TrackedInst.Index,8417 zir_body_inst: TrackedInst.Index,
8080 lbrace_line: u32,8418 lbrace_line: u32,
...@@ -8105,7 +8443,7 @@ pub fn getFuncDecl(...@@ -8105,7 +8443,7 @@ pub fn getFuncDecl(
81058443
8106 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{8444 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
8107 .analysis = .{8445 .analysis = .{
8108 .state = if (key.cc == .Inline) .inline_only else .none,8446 .state = .unreferenced,
8109 .is_cold = false,8447 .is_cold = false,
8110 .is_noinline = key.is_noinline,8448 .is_noinline = key.is_noinline,
8111 .calls_or_awaits_errorable_fn = false,8449 .calls_or_awaits_errorable_fn = false,
...@@ -8113,7 +8451,7 @@ pub fn getFuncDecl(...@@ -8113,7 +8451,7 @@ pub fn getFuncDecl(
8113 .inferred_error_set = false,8451 .inferred_error_set = false,
8114 .disable_instrumentation = false,8452 .disable_instrumentation = false,
8115 },8453 },
8116 .owner_decl = key.owner_decl,8454 .owner_nav = key.owner_nav,
8117 .ty = key.ty,8455 .ty = key.ty,
8118 .zir_body_inst = key.zir_body_inst,8456 .zir_body_inst = key.zir_body_inst,
8119 .lbrace_line = key.lbrace_line,8457 .lbrace_line = key.lbrace_line,
...@@ -8140,7 +8478,7 @@ pub fn getFuncDecl(...@@ -8140,7 +8478,7 @@ pub fn getFuncDecl(
8140}8478}
81418479
8142pub const GetFuncDeclIesKey = struct {8480pub const GetFuncDeclIesKey = struct {
8143 owner_decl: DeclIndex,8481 owner_nav: Nav.Index,
8144 param_types: []Index,8482 param_types: []Index,
8145 noalias_bits: u32,8483 noalias_bits: u32,
8146 comptime_bits: u32,8484 comptime_bits: u32,
...@@ -8209,7 +8547,7 @@ pub fn getFuncDeclIes(...@@ -8209,7 +8547,7 @@ pub fn getFuncDeclIes(
82098547
8210 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{8548 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
8211 .analysis = .{8549 .analysis = .{
8212 .state = if (key.cc == .Inline) .inline_only else .none,8550 .state = .unreferenced,
8213 .is_cold = false,8551 .is_cold = false,
8214 .is_noinline = key.is_noinline,8552 .is_noinline = key.is_noinline,
8215 .calls_or_awaits_errorable_fn = false,8553 .calls_or_awaits_errorable_fn = false,
...@@ -8217,7 +8555,7 @@ pub fn getFuncDeclIes(...@@ -8217,7 +8555,7 @@ pub fn getFuncDeclIes(
8217 .inferred_error_set = true,8555 .inferred_error_set = true,
8218 .disable_instrumentation = false,8556 .disable_instrumentation = false,
8219 },8557 },
8220 .owner_decl = key.owner_decl,8558 .owner_nav = key.owner_nav,
8221 .ty = func_ty,8559 .ty = func_ty,
8222 .zir_body_inst = key.zir_body_inst,8560 .zir_body_inst = key.zir_body_inst,
8223 .lbrace_line = key.lbrace_line,8561 .lbrace_line = key.lbrace_line,
...@@ -8401,7 +8739,7 @@ pub fn getFuncInstance(...@@ -8401,7 +8739,7 @@ pub fn getFuncInstance(
84018739
8402 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{8740 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
8403 .analysis = .{8741 .analysis = .{
8404 .state = if (arg.cc == .Inline) .inline_only else .none,8742 .state = .unreferenced,
8405 .is_cold = false,8743 .is_cold = false,
8406 .is_noinline = arg.is_noinline,8744 .is_noinline = arg.is_noinline,
8407 .calls_or_awaits_errorable_fn = false,8745 .calls_or_awaits_errorable_fn = false,
...@@ -8409,9 +8747,9 @@ pub fn getFuncInstance(...@@ -8409,9 +8747,9 @@ pub fn getFuncInstance(
8409 .inferred_error_set = false,8747 .inferred_error_set = false,
8410 .disable_instrumentation = false,8748 .disable_instrumentation = false,
8411 },8749 },
8412 // This is populated after we create the Decl below. It is not read8750 // This is populated after we create the Nav below. It is not read
8413 // by equality or hashing functions.8751 // by equality or hashing functions.
8414 .owner_decl = undefined,8752 .owner_nav = undefined,
8415 .ty = func_ty,8753 .ty = func_ty,
8416 .branch_quota = 0,8754 .branch_quota = 0,
8417 .generic_owner = generic_owner,8755 .generic_owner = generic_owner,
...@@ -8501,7 +8839,7 @@ pub fn getFuncInstanceIes(...@@ -8501,7 +8839,7 @@ pub fn getFuncInstanceIes(
85018839
8502 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{8840 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
8503 .analysis = .{8841 .analysis = .{
8504 .state = if (arg.cc == .Inline) .inline_only else .none,8842 .state = .unreferenced,
8505 .is_cold = false,8843 .is_cold = false,
8506 .is_noinline = arg.is_noinline,8844 .is_noinline = arg.is_noinline,
8507 .calls_or_awaits_errorable_fn = false,8845 .calls_or_awaits_errorable_fn = false,
...@@ -8509,9 +8847,9 @@ pub fn getFuncInstanceIes(...@@ -8509,9 +8847,9 @@ pub fn getFuncInstanceIes(
8509 .inferred_error_set = true,8847 .inferred_error_set = true,
8510 .disable_instrumentation = false,8848 .disable_instrumentation = false,
8511 },8849 },
8512 // This is populated after we create the Decl below. It is not read8850 // This is populated after we create the Nav below. It is not read
8513 // by equality or hashing functions.8851 // by equality or hashing functions.
8514 .owner_decl = undefined,8852 .owner_nav = undefined,
8515 .ty = func_ty,8853 .ty = func_ty,
8516 .branch_quota = 0,8854 .branch_quota = 0,
8517 .generic_owner = generic_owner,8855 .generic_owner = generic_owner,
...@@ -8617,41 +8955,29 @@ fn finishFuncInstance(...@@ -8617,41 +8955,29 @@ fn finishFuncInstance(
8617 alignment: Alignment,8955 alignment: Alignment,
8618 section: OptionalNullTerminatedString,8956 section: OptionalNullTerminatedString,
8619) Allocator.Error!void {8957) Allocator.Error!void {
8620 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));8958 const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav);
8621 const decl_index = try ip.createDecl(gpa, tid, .{8959 const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace;
8622 .name = undefined,8960
8623 .fqn = undefined,8961 // TODO: improve this name
8624 .src_namespace = fn_owner_decl.src_namespace,8962 const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
8625 .has_tv = true,8963 fn_owner_nav.name.fmt(ip), @intFromEnum(func_index),
8626 .owns_tv = true,8964 }, .no_embedded_nulls);
8627 .val = @import("Value.zig").fromInterned(func_index),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,
8628 .alignment = alignment,8969 .alignment = alignment,
8629 .@"linksection" = section,8970 .@"linksection" = section,
8630 .@"addrspace" = fn_owner_decl.@"addrspace",8971 .@"addrspace" = fn_owner_nav.status.resolved.@"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,
8636 });8972 });
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.
8640 extra.view().items(.@"0")[8975 extra.view().items(.@"0")[
8641 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?8976 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?
8642 ] = @intFromEnum(decl_index);8977 ] = @intFromEnum(nav_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);
8651}8978}
86528979
8653pub const EnumTypeInit = struct {8980pub const EnumTypeInit = struct {
8654 has_namespace: bool,
8655 has_values: bool,8981 has_values: bool,
8656 tag_mode: LoadedEnumType.TagMode,8982 tag_mode: LoadedEnumType.TagMode,
8657 fields_len: u32,8983 fields_len: u32,
...@@ -8671,27 +8997,35 @@ pub const WipEnumType = struct {...@@ -8671,27 +8997,35 @@ pub const WipEnumType = struct {
8671 tid: Zcu.PerThread.Id,8997 tid: Zcu.PerThread.Id,
8672 index: Index,8998 index: Index,
8673 tag_ty_index: u32,8999 tag_ty_index: u32,
8674 decl_index: u32,9000 type_name_extra_index: u32,
8675 namespace_index: ?u32,9001 cau_extra_index: u32,
9002 namespace_extra_index: u32,
8676 names_map: MapIndex,9003 names_map: MapIndex,
8677 names_start: u32,9004 names_start: u32,
8678 values_map: OptionalMapIndex,9005 values_map: OptionalMapIndex,
8679 values_start: u32,9006 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
8681 pub fn prepare(9018 pub fn prepare(
8682 wip: WipEnumType,9019 wip: WipEnumType,
8683 ip: *InternPool,9020 ip: *InternPool,
8684 decl: DeclIndex,9021 analysis_owner: Cau.Index,
8685 namespace: OptionalNamespaceIndex,9022 namespace: NamespaceIndex,
8686 ) void {9023 ) void {
8687 const extra = ip.getLocalShared(wip.tid).extra.acquire();9024 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8688 const extra_items = extra.view().items(.@"0");9025 const extra_items = extra.view().items(.@"0");
8689 extra_items[wip.decl_index] = @intFromEnum(decl);9026
8690 if (wip.namespace_index) |i| {9027 extra_items[wip.cau_extra_index] = @intFromEnum(analysis_owner);
8691 extra_items[i] = @intFromEnum(namespace.unwrap().?);9028 extra_items[wip.namespace_extra_index] = @intFromEnum(namespace);
8692 } else {
8693 assert(namespace == .none);
8694 }
8695 }9029 }
86969030
8697 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {9031 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {
...@@ -8780,15 +9114,16 @@ pub fn getEnumType(...@@ -8780,15 +9114,16 @@ pub fn getEnumType(
8780 .reified => 2, // type_hash: PackedU649114 .reified => 2, // type_hash: PackedU64
8781 } +9115 } +
8782 // zig fmt: on9116 // zig fmt: on
9117 1 + // cau
8783 ini.fields_len); // field types9118 ini.fields_len); // field types
87849119
8785 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{9120 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
8786 .decl = undefined, // set by `prepare`9121 .name = undefined, // set by `prepare`
8787 .captures_len = switch (ini.key) {9122 .captures_len = switch (ini.key) {
8788 .declared => |d| @intCast(d.captures.len),9123 .declared => |d| @intCast(d.captures.len),
8789 .reified => std.math.maxInt(u32),9124 .reified => std.math.maxInt(u32),
8790 },9125 },
8791 .namespace = .none,9126 .namespace = undefined, // set by `prepare`
8792 .int_tag_type = .none, // set by `prepare`9127 .int_tag_type = .none, // set by `prepare`
8793 .fields_len = ini.fields_len,9128 .fields_len = ini.fields_len,
8794 .names_map = names_map,9129 .names_map = names_map,
...@@ -8800,6 +9135,8 @@ pub fn getEnumType(...@@ -8800,6 +9135,8 @@ pub fn getEnumType(
8800 .tag = .type_enum_auto,9135 .tag = .type_enum_auto,
8801 .data = extra_index,9136 .data = extra_index,
8802 });9137 });
9138 const cau_extra_index = extra.view().len;
9139 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
8803 switch (ini.key) {9140 switch (ini.key) {
8804 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),9141 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8805 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),9142 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
...@@ -8810,8 +9147,9 @@ pub fn getEnumType(...@@ -8810,8 +9147,9 @@ pub fn getEnumType(
8810 .tid = tid,9147 .tid = tid,
8811 .index = gop.put(),9148 .index = gop.put(),
8812 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,9149 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
8813 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,9150 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?,
8814 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,9151 .cau_extra_index = @intCast(cau_extra_index),
9152 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "namespace").?,
8815 .names_map = names_map,9153 .names_map = names_map,
8816 .names_start = @intCast(names_start),9154 .names_start = @intCast(names_start),
8817 .values_map = .none,9155 .values_map = .none,
...@@ -8835,16 +9173,17 @@ pub fn getEnumType(...@@ -8835,16 +9173,17 @@ pub fn getEnumType(
8835 .reified => 2, // type_hash: PackedU649173 .reified => 2, // type_hash: PackedU64
8836 } +9174 } +
8837 // zig fmt: on9175 // zig fmt: on
9176 1 + // cau
8838 ini.fields_len + // field types9177 ini.fields_len + // field types
8839 ini.fields_len * @intFromBool(ini.has_values)); // field values9178 ini.fields_len * @intFromBool(ini.has_values)); // field values
88409179
8841 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{9180 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
8842 .decl = undefined, // set by `prepare`9181 .name = undefined, // set by `prepare`
8843 .captures_len = switch (ini.key) {9182 .captures_len = switch (ini.key) {
8844 .declared => |d| @intCast(d.captures.len),9183 .declared => |d| @intCast(d.captures.len),
8845 .reified => std.math.maxInt(u32),9184 .reified => std.math.maxInt(u32),
8846 },9185 },
8847 .namespace = .none,9186 .namespace = undefined, // set by `prepare`
8848 .int_tag_type = .none, // set by `prepare`9187 .int_tag_type = .none, // set by `prepare`
8849 .fields_len = ini.fields_len,9188 .fields_len = ini.fields_len,
8850 .names_map = names_map,9189 .names_map = names_map,
...@@ -8861,6 +9200,8 @@ pub fn getEnumType(...@@ -8861,6 +9200,8 @@ pub fn getEnumType(
8861 },9200 },
8862 .data = extra_index,9201 .data = extra_index,
8863 });9202 });
9203 const cau_extra_index = extra.view().len;
9204 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
8864 switch (ini.key) {9205 switch (ini.key) {
8865 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),9206 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8866 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),9207 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
...@@ -8874,9 +9215,10 @@ pub fn getEnumType(...@@ -8874,9 +9215,10 @@ pub fn getEnumType(
8874 return .{ .wip = .{9215 return .{ .wip = .{
8875 .tid = tid,9216 .tid = tid,
8876 .index = gop.put(),9217 .index = gop.put(),
8877 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,9218 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,
8878 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,9219 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?,
8879 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,9220 .cau_extra_index = @intCast(cau_extra_index),
9221 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").?,
8880 .names_map = names_map,9222 .names_map = names_map,
8881 .names_start = @intCast(names_start),9223 .names_start = @intCast(names_start),
8882 .values_map = values_map,9224 .values_map = values_map,
...@@ -8887,12 +9229,13 @@ pub fn getEnumType(...@@ -8887,12 +9229,13 @@ pub fn getEnumType(
8887}9229}
88889230
8889const GeneratedTagEnumTypeInit = struct {9231const GeneratedTagEnumTypeInit = struct {
8890 decl: DeclIndex,9232 name: NullTerminatedString,
8891 owner_union_ty: Index,9233 owner_union_ty: Index,
8892 tag_ty: Index,9234 tag_ty: Index,
8893 names: []const NullTerminatedString,9235 names: []const NullTerminatedString,
8894 values: []const Index,9236 values: []const Index,
8895 tag_mode: LoadedEnumType.TagMode,9237 tag_mode: LoadedEnumType.TagMode,
9238 parent_namespace: NamespaceIndex,
8896};9239};
88979240
8898/// Creates an enum type which was automatically-generated as the tag type of a9241/// Creates an enum type which was automatically-generated as the tag type of a
...@@ -8919,6 +9262,18 @@ pub fn getGeneratedTagEnumType(...@@ -8919,6 +9262,18 @@ pub fn getGeneratedTagEnumType(
89199262
8920 const fields_len: u32 = @intCast(ini.names.len);9263 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
8922 const prev_extra_len = extra.mutate.len;9277 const prev_extra_len = extra.mutate.len;
8923 switch (ini.tag_mode) {9278 switch (ini.tag_mode) {
8924 .auto => {9279 .auto => {
...@@ -8928,9 +9283,9 @@ pub fn getGeneratedTagEnumType(...@@ -8928,9 +9283,9 @@ pub fn getGeneratedTagEnumType(
8928 items.appendAssumeCapacity(.{9283 items.appendAssumeCapacity(.{
8929 .tag = .type_enum_auto,9284 .tag = .type_enum_auto,
8930 .data = addExtraAssumeCapacity(extra, EnumAuto{9285 .data = addExtraAssumeCapacity(extra, EnumAuto{
8931 .decl = ini.decl,9286 .name = ini.name,
8932 .captures_len = 0,9287 .captures_len = 0,
8933 .namespace = .none,9288 .namespace = namespace,
8934 .int_tag_type = ini.tag_ty,9289 .int_tag_type = ini.tag_ty,
8935 .fields_len = fields_len,9290 .fields_len = fields_len,
8936 .names_map = names_map,9291 .names_map = names_map,
...@@ -8961,9 +9316,9 @@ pub fn getGeneratedTagEnumType(...@@ -8961,9 +9316,9 @@ pub fn getGeneratedTagEnumType(
8961 .auto => unreachable,9316 .auto => unreachable,
8962 },9317 },
8963 .data = addExtraAssumeCapacity(extra, EnumExplicit{9318 .data = addExtraAssumeCapacity(extra, EnumExplicit{
8964 .decl = ini.decl,9319 .name = ini.name,
8965 .captures_len = 0,9320 .captures_len = 0,
8966 .namespace = .none,9321 .namespace = namespace,
8967 .int_tag_type = ini.tag_ty,9322 .int_tag_type = ini.tag_ty,
8968 .fields_len = fields_len,9323 .fields_len = fields_len,
8969 .names_map = names_map,9324 .names_map = names_map,
...@@ -8988,11 +9343,11 @@ pub fn getGeneratedTagEnumType(...@@ -8988,11 +9343,11 @@ pub fn getGeneratedTagEnumType(
8988 .generated_tag = .{ .union_type = ini.owner_union_ty },9343 .generated_tag = .{ .union_type = ini.owner_union_ty },
8989 } });9344 } });
8990 defer gop.deinit();9345 defer gop.deinit();
8991 return gop.put();9346 assert(gop.put() == enum_index);
9347 return enum_index;
8992}9348}
89939349
8994pub const OpaqueTypeInit = struct {9350pub const OpaqueTypeInit = struct {
8995 has_namespace: bool,
8996 key: union(enum) {9351 key: union(enum) {
8997 declared: struct {9352 declared: struct {
8998 zir_index: TrackedInst.Index,9353 zir_index: TrackedInst.Index,
...@@ -9034,8 +9389,8 @@ pub fn getOpaqueType(...@@ -9034,8 +9389,8 @@ pub fn getOpaqueType(
9034 .reified => 0,9389 .reified => 0,
9035 });9390 });
9036 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{9391 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
9037 .decl = undefined, // set by `finish`9392 .name = undefined, // set by `finish`
9038 .namespace = .none,9393 .namespace = undefined, // set by `finish`
9039 .zir_index = switch (ini.key) {9394 .zir_index = switch (ini.key) {
9040 inline else => |x| x.zir_index,9395 inline else => |x| x.zir_index,
9041 },9396 },
...@@ -9052,15 +9407,15 @@ pub fn getOpaqueType(...@@ -9052,15 +9407,15 @@ pub fn getOpaqueType(
9052 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),9407 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
9053 .reified => {},9408 .reified => {},
9054 }9409 }
9055 return .{ .wip = .{9410 return .{
9056 .tid = tid,9411 .wip = .{
9057 .index = gop.put(),9412 .tid = tid,
9058 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,9413 .index = gop.put(),
9059 .namespace_extra_index = if (ini.has_namespace)9414 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
9060 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?9415 .cau_extra_index = null, // opaques do not undergo type resolution
9061 else9416 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?,
9062 null,9417 },
9063 } };9418 };
9064}9419}
90659420
9066pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {9421pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
...@@ -9181,7 +9536,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -9181,7 +9536,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
9181 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {9536 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
9182 extra.appendAssumeCapacity(.{switch (field.type) {9537 extra.appendAssumeCapacity(.{switch (field.type) {
9183 Index,9538 Index,
9184 DeclIndex,9539 Cau.Index,
9540 Nav.Index,
9185 NamespaceIndex,9541 NamespaceIndex,
9186 OptionalNamespaceIndex,9542 OptionalNamespaceIndex,
9187 MapIndex,9543 MapIndex,
...@@ -9244,7 +9600,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -9244,7 +9600,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
9244 const extra_item = extra_items[extra_index];9600 const extra_item = extra_items[extra_index];
9245 @field(result, field.name) = switch (field.type) {9601 @field(result, field.name) = switch (field.type) {
9246 Index,9602 Index,
9247 DeclIndex,9603 Cau.Index,
9604 Nav.Index,
9248 NamespaceIndex,9605 NamespaceIndex,
9249 OptionalNamespaceIndex,9606 OptionalNamespaceIndex,
9250 MapIndex,9607 MapIndex,
...@@ -9436,12 +9793,6 @@ pub fn getCoerced(...@@ -9436,12 +9793,6 @@ pub fn getCoerced(
94369793
9437 switch (ip.indexToKey(val)) {9794 switch (ip.indexToKey(val)) {
9438 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),9795 .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 }),
9445 .func => unreachable,9796 .func => unreachable,
94469797
9447 .int => |int| switch (ip.indexToKey(new_ty)) {9798 .int => |int| switch (ip.indexToKey(new_ty)) {
...@@ -9858,27 +10209,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9858,27 +10209,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9858 var items_len: usize = 0;10209 var items_len: usize = 0;
9859 var extra_len: usize = 0;10210 var extra_len: usize = 0;
9860 var limbs_len: usize = 0;10211 var limbs_len: usize = 0;
9861 var decls_len: usize = 0;
9862 for (ip.locals) |*local| {10212 for (ip.locals) |*local| {
9863 items_len += local.mutate.items.len;10213 items_len += local.mutate.items.len;
9864 extra_len += local.mutate.extra.len;10214 extra_len += local.mutate.extra.len;
9865 limbs_len += local.mutate.limbs.len;10215 limbs_len += local.mutate.limbs.len;
9866 decls_len += local.mutate.decls.buckets_list.len;
9867 }10216 }
9868 const items_size = (1 + 4) * items_len;10217 const items_size = (1 + 4) * items_len;
9869 const extra_size = 4 * extra_len;10218 const extra_size = 4 * extra_len;
9870 const limbs_size = 8 * limbs_len;10219 const limbs_size = 8 * limbs_len;
9871 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
987210220
9873 // TODO: map overhead size is not taken into account10221 // 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
9876 std.debug.print(10224 std.debug.print(
9877 \\InternPool size: {d} bytes10225 \\InternPool size: {d} bytes
9878 \\ {d} items: {d} bytes10226 \\ {d} items: {d} bytes
9879 \\ {d} extra: {d} bytes10227 \\ {d} extra: {d} bytes
9880 \\ {d} limbs: {d} bytes10228 \\ {d} limbs: {d} bytes
9881 \\ {d} decls: {d} bytes
9882 \\10229 \\
9883 , .{10230 , .{
9884 total_size,10231 total_size,
...@@ -9888,8 +10235,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9888,8 +10235,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9888 extra_size,10235 extra_size,
9889 limbs_len,10236 limbs_len,
9890 limbs_size,10237 limbs_size,
9891 decls_len,
9892 decls_size,
9893 });10238 });
989410239
9895 const TagStats = struct {10240 const TagStats = struct {
...@@ -9967,7 +10312,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9967,7 +10312,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9967 }10312 }
9968 if (info.flags.any_default_inits)10313 if (info.flags.any_default_inits)
9969 ints += info.fields_len; // inits10314 ints += info.fields_len; // inits
9970 ints += @intFromBool(info.flags.has_namespace); // namespace
9971 if (info.flags.any_aligned_fields)10315 if (info.flags.any_aligned_fields)
9972 ints += (info.fields_len + 3) / 4; // aligns10316 ints += (info.fields_len + 3) / 4; // aligns
9973 if (info.flags.any_comptime_fields)10317 if (info.flags.any_comptime_fields)
...@@ -10034,10 +10378,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10034,10 +10378,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10034 .undef => 0,10378 .undef => 0,
10035 .simple_type => 0,10379 .simple_type => 0,
10036 .simple_value => 0,10380 .simple_value => 0,
10037 .ptr_decl => @sizeOf(PtrDecl),10381 .ptr_nav => @sizeOf(PtrNav),
10038 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),10382 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
10039 .ptr_anon_decl => @sizeOf(PtrAnonDecl),10383 .ptr_uav => @sizeOf(PtrUav),
10040 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),10384 .ptr_uav_aligned => @sizeOf(PtrUavAligned),
10041 .ptr_comptime_field => @sizeOf(PtrComptimeField),10385 .ptr_comptime_field => @sizeOf(PtrComptimeField),
10042 .ptr_int => @sizeOf(PtrInt),10386 .ptr_int => @sizeOf(PtrInt),
10043 .ptr_eu_payload => @sizeOf(PtrBase),10387 .ptr_eu_payload => @sizeOf(PtrBase),
...@@ -10092,7 +10436,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10092,7 +10436,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10092 .float_c_longdouble_f128 => @sizeOf(Float128),10436 .float_c_longdouble_f128 => @sizeOf(Float128),
10093 .float_comptime_float => @sizeOf(Float128),10437 .float_comptime_float => @sizeOf(Float128),
10094 .variable => @sizeOf(Tag.Variable),10438 .variable => @sizeOf(Tag.Variable),
10095 .extern_func => @sizeOf(Tag.ExternFunc),10439 .@"extern" => @sizeOf(Tag.Extern),
10096 .func_decl => @sizeOf(Tag.FuncDecl),10440 .func_decl => @sizeOf(Tag.FuncDecl),
10097 .func_instance => b: {10441 .func_instance => b: {
10098 const info = extraData(extra_list, Tag.FuncInstance, data);10442 const info = extraData(extra_list, Tag.FuncInstance, data);
...@@ -10171,10 +10515,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -10171,10 +10515,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
10171 .type_union,10515 .type_union,
10172 .type_function,10516 .type_function,
10173 .undef,10517 .undef,
10174 .ptr_decl,10518 .ptr_nav,
10175 .ptr_comptime_alloc,10519 .ptr_comptime_alloc,
10176 .ptr_anon_decl,10520 .ptr_uav,
10177 .ptr_anon_decl_aligned,10521 .ptr_uav_aligned,
10178 .ptr_comptime_field,10522 .ptr_comptime_field,
10179 .ptr_int,10523 .ptr_int,
10180 .ptr_eu_payload,10524 .ptr_eu_payload,
...@@ -10212,7 +10556,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -10212,7 +10556,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
10212 .float_c_longdouble_f128,10556 .float_c_longdouble_f128,
10213 .float_comptime_float,10557 .float_comptime_float,
10214 .variable,10558 .variable,
10215 .extern_func,10559 .@"extern",
10216 .func_decl,10560 .func_decl,
10217 .func_instance,10561 .func_instance,
10218 .func_coerced,10562 .func_coerced,
...@@ -10275,13 +10619,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -10275,13 +10619,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
10275 instances.sort(SortContext{ .values = instances.values() });10619 instances.sort(SortContext{ .values = instances.values() });
10276 var it = instances.iterator();10620 var it = instances.iterator();
10277 while (it.next()) |entry| {10621 while (it.next()) |entry| {
10278 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));10622 const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav);
10279 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });10623 try w.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
10280 for (entry.value_ptr.items) |index| {10624 for (entry.value_ptr.items) |index| {
10281 const unwrapped_index = index.unwrap(ip);10625 const unwrapped_index = index.unwrap(ip);
10282 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));10626 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
10283 const owner_decl = ip.declPtrConst(func.owner_decl);10627 const owner_nav = ip.getNav(func.owner_nav);
10284 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});10628 try w.print(" {}: (", .{owner_nav.name.fmt(ip)});
10285 for (func.comptime_args.get(ip)) |arg| {10629 for (func.comptime_args.get(ip)) |arg| {
10286 if (arg != .none) {10630 if (arg != .none) {
10287 const key = ip.indexToKey(arg);10631 const key = ip.indexToKey(arg);
...@@ -10295,66 +10639,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -10295,66 +10639,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
10295 try bw.flush();10639 try bw.flush();
10296}10640}
1029710641
10298pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {10642pub fn getCau(ip: *const InternPool, index: Cau.Index) Cau {
10299 return @constCast(ip.declPtrConst(decl_index));10643 const unwrapped = index.unwrap(ip);
10644 const caus = ip.getLocalShared(unwrapped.tid).caus.acquire();
10645 return caus.view().items(.@"0")[unwrapped.index];
10300}10646}
1030110647
10302pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl {10648pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav {
10303 const unwrapped_decl_index = decl_index.unwrap(ip);10649 const unwrapped = index.unwrap(ip);
10304 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();10650 const navs = ip.getLocalShared(unwrapped.tid).navs.acquire();
10305 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];10651 return navs.view().get(unwrapped.index).unpack();
10306 return &decls_bucket[unwrapped_decl_index.index];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];
10307}10659}
1030810660
10309pub fn createDecl(10661/// Create a `Cau` associated with the type at the given `InternPool.Index`.
10662pub fn createTypeCau(
10310 ip: *InternPool,10663 ip: *InternPool,
10311 gpa: Allocator,10664 gpa: Allocator,
10312 tid: Zcu.PerThread.Id,10665 tid: Zcu.PerThread.Id,
10313 initialization: Zcu.Decl,10666 zir_index: TrackedInst.Index,
10314) Allocator.Error!DeclIndex {10667 namespace: NamespaceIndex,
10315 const local = ip.getLocal(tid);10668 owner_type: InternPool.Index,
10316 const free_list_next = local.mutate.decls.free_list;10669) Allocator.Error!Cau.Index {
10317 if (free_list_next != Local.BucketListMutate.free_list_sentinel) {10670 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10318 const reused_decl_index: DeclIndex = @enumFromInt(free_list_next);10671 const index_unwrapped: Cau.Index.Unwrapped = .{
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 = .{
10334 .tid = tid,10672 .tid = tid,
10335 .bucket_index = decls.mutate.len - 1,10673 .index = caus.mutate.len,
10336 .index = local.mutate.decls.last_bucket_len,
10337 };10674 };
10338 local.mutate.decls.last_bucket_len =10675 try caus.append(.{.{
10339 (unwrapped_decl_index.index + 1) & Local.namespaces_bucket_mask;10676 .zir_index = zir_index,
10340 const decl_index = unwrapped_decl_index.wrap(ip);10677 .namespace = namespace,
10341 ip.declPtr(decl_index).* = initialization;10678 .owner = Cau.Owner.wrap(.{ .type = owner_type }),
10342 return decl_index;10679 }});
10680 return index_unwrapped.wrap(ip);
10343}10681}
1034410682
10345pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex) void {10683/// Create a `Cau` for a `comptime` declaration.
10346 const local = ip.getLocal(tid);10684pub fn createComptimeCau(
10347 const decl = ip.declPtr(decl_index);10685 ip: *InternPool,
10348 decl.* = undefined;10686 gpa: Allocator,
10349 @field(decl, Local.decl_next_free_field) = @enumFromInt(local.mutate.decls.free_list);10687 tid: Zcu.PerThread.Id,
10350 local.mutate.decls.free_list = @intFromEnum(decl_index);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);
10351}10702}
1035210703
10353pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {10704/// Create a `Nav` not associated with any `Cau`.
10354 const unwrapped_namespace_index = namespace_index.unwrap(ip);10705/// Since there is no analysis owner, the `Nav`'s value must be known at creation time.
10355 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();10706pub fn createNav(
10356 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];10707 ip: *InternPool,
10357 return &namespaces_bucket[unwrapped_namespace_index.index];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);
10358}10819}
1035910820
10360pub fn createNamespace(10821pub fn createNamespace(
...@@ -10404,7 +10865,7 @@ pub fn destroyNamespace(...@@ -10404,7 +10865,7 @@ pub fn destroyNamespace(
10404 namespace.* = .{10865 namespace.* = .{
10405 .parent = undefined,10866 .parent = undefined,
10406 .file_scope = undefined,10867 .file_scope = undefined,
10407 .decl_index = undefined,10868 .owner_type = undefined,
10408 };10869 };
10409 @field(namespace, Local.namespace_next_free_field) =10870 @field(namespace, Local.namespace_next_free_field) =
10410 @enumFromInt(local.mutate.namespaces.free_list);10871 @enumFromInt(local.mutate.namespaces.free_list);
...@@ -10750,10 +11211,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -10750,10 +11211,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1075011211
10751 .simple_type, .simple_value => unreachable, // handled via Index above11212 .simple_type, .simple_value => unreachable, // handled via Index above
1075211213
10753 inline .ptr_decl,11214 inline .ptr_nav,
10754 .ptr_comptime_alloc,11215 .ptr_comptime_alloc,
10755 .ptr_anon_decl,11216 .ptr_uav,
10756 .ptr_anon_decl_aligned,11217 .ptr_uav_aligned,
10757 .ptr_comptime_field,11218 .ptr_comptime_field,
10758 .ptr_int,11219 .ptr_int,
10759 .ptr_eu_payload,11220 .ptr_eu_payload,
...@@ -10770,7 +11231,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -10770,7 +11231,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
10770 .error_union_error,11231 .error_union_error,
10771 .enum_tag,11232 .enum_tag,
10772 .variable,11233 .variable,
10773 .extern_func,11234 .@"extern",
10774 .func_decl,11235 .func_decl,
10775 .func_instance,11236 .func_instance,
10776 .func_coerced,11237 .func_coerced,
...@@ -10892,14 +11353,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool {...@@ -10892,14 +11353,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool {
10892 return val.unwrap(ip).getTag(ip) == .variable;11353 return val.unwrap(ip).getTag(ip) == .variable;
10893}11354}
1089411355
10895pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {11356pub fn getBackingNav(ip: *const InternPool, val: Index) Nav.Index.Optional {
10896 var base = val;11357 var base = val;
10897 while (true) {11358 while (true) {
10898 const unwrapped_base = base.unwrap(ip);11359 const unwrapped_base = base.unwrap(ip);
10899 const base_item = unwrapped_base.getItem(ip);11360 const base_item = unwrapped_base.getItem(ip);
10900 switch (base_item.tag) {11361 switch (base_item.tag) {
10901 .ptr_decl => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[11362 .ptr_nav => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
10902 base_item.data + std.meta.fieldIndex(PtrDecl, "decl").?11363 base_item.data + std.meta.fieldIndex(PtrNav, "nav").?
10903 ]),11364 ]),
10904 inline .ptr_eu_payload,11365 inline .ptr_eu_payload,
10905 .ptr_opt_payload,11366 .ptr_opt_payload,
...@@ -10922,11 +11383,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta...@@ -10922,11 +11383,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
10922 const unwrapped_base = base.unwrap(ip);11383 const unwrapped_base = base.unwrap(ip);
10923 const base_item = unwrapped_base.getItem(ip);11384 const base_item = unwrapped_base.getItem(ip);
10924 switch (base_item.tag) {11385 switch (base_item.tag) {
10925 .ptr_decl => return .decl,11386 .ptr_nav => return .nav,
10926 .ptr_comptime_alloc => return .comptime_alloc,11387 .ptr_comptime_alloc => return .comptime_alloc,
10927 .ptr_anon_decl,11388 .ptr_uav,
10928 .ptr_anon_decl_aligned,11389 .ptr_uav_aligned,
10929 => return .anon_decl,11390 => return .uav,
10930 .ptr_comptime_field => return .comptime_field,11391 .ptr_comptime_field => return .comptime_field,
10931 .ptr_int => return .int,11392 .ptr_int => return .int,
10932 inline .ptr_eu_payload,11393 inline .ptr_eu_payload,
...@@ -11098,10 +11559,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11098,10 +11559,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
11098 // values, not types11559 // values, not types
11099 .undef,11560 .undef,
11100 .simple_value,11561 .simple_value,
11101 .ptr_decl,11562 .ptr_nav,
11102 .ptr_comptime_alloc,11563 .ptr_comptime_alloc,
11103 .ptr_anon_decl,11564 .ptr_uav,
11104 .ptr_anon_decl_aligned,11565 .ptr_uav_aligned,
11105 .ptr_comptime_field,11566 .ptr_comptime_field,
11106 .ptr_int,11567 .ptr_int,
11107 .ptr_eu_payload,11568 .ptr_eu_payload,
...@@ -11137,7 +11598,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11137,7 +11598,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
11137 .float_c_longdouble_f128,11598 .float_c_longdouble_f128,
11138 .float_comptime_float,11599 .float_comptime_float,
11139 .variable,11600 .variable,
11140 .extern_func,11601 .@"extern",
11141 .func_decl,11602 .func_decl,
11142 .func_instance,11603 .func_instance,
11143 .func_coerced,11604 .func_coerced,
...@@ -11190,18 +11651,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {...@@ -11190,18 +11651,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
11190 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);11651 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
11191}11652}
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
11205pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {11654pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
11206 const unwrapped_func = func.unwrap(ip);11655 const unwrapped_func = func.unwrap(ip);
11207 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;11656 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 {...@@ -11349,10 +11798,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
11349 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);11798 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
11350}11799}
1135111800
11352pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
11353 return funcDeclInfo(ip, index).owner_decl;
11354}
11355
11356pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {11801pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
11357 const unwrapped_index = index.unwrap(ip);11802 const unwrapped_index = index.unwrap(ip);
11358 const extra_list = unwrapped_index.getExtra(ip);11803 const extra_list = unwrapped_index.getExtra(ip);
...@@ -11409,14 +11854,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {...@@ -11409,14 +11854,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {
11409 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);11854 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);
11410}11855}
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
11420/// Returns the already-existing field with the same name, if any.11857/// Returns the already-existing field with the same name, if any.
11421pub fn addFieldName(11858pub fn addFieldName(
11422 ip: *InternPool,11859 ip: *InternPool,
...@@ -11436,8 +11873,8 @@ pub fn addFieldName(...@@ -11436,8 +11873,8 @@ pub fn addFieldName(
11436 return null;11873 return null;
11437}11874}
1143811875
11439/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_anon_decl`11876/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_uav`
11440/// encoding instead of `Tag.ptr_anon_decl_aligned` when possible.11877/// encoding instead of `Tag.ptr_uav_aligned` when possible.
11441fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {11878fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
11442 if (a_ty == b_ty) return true;11879 if (a_ty == b_ty) return true;
11443 const b_info = ip.indexToKey(b_ty).ptr_type;11880 const b_info = ip.indexToKey(b_ty).ptr_type;
...@@ -11607,3 +12044,7 @@ pub fn getErrorValue(...@@ -11607,3 +12044,7 @@ pub fn getErrorValue(
11607pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {12044pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
11608 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);12045 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
11609}12046}
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) = .{},...@@ -16,16 +16,14 @@ air_instructions: std.MultiArrayList(Air.Inst) = .{},
16air_extra: std.ArrayListUnmanaged(u32) = .{},16air_extra: std.ArrayListUnmanaged(u32) = .{},
17/// Maps ZIR to AIR.17/// Maps ZIR to AIR.
18inst_map: InstMap = .{},18inst_map: InstMap = .{},
19/// When analyzing an inline function call, owner_decl is the Decl of the caller.19/// The "owner" of a `Sema` represents the root "thing" that is being analyzed.
20owner_decl: *Decl,20/// This does not change throughout the entire lifetime of a `Sema`. For instance,
21owner_decl_index: InternPool.DeclIndex,21/// when analyzing a runtime function body, this is always `func` of that function,
22/// For an inline or comptime function call, this will be the root parent function22/// even if an inline/comptime function call is being analyzed.
23/// which contains the callsite. Corresponds to `owner_decl`.23owner: AnalUnit,
24/// This could be `none`, a `func_decl`, or a `func_instance`.
25owner_func_index: InternPool.Index,
26/// The function this ZIR code is the body of, according to the source code.24/// 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 of25/// This starts out the same as `sema.owner.func` if applicable, and then diverges
28/// an inline or comptime function call.26/// in the case of an inline or comptime function call.
29/// This could be `none`, a `func_decl`, or a `func_instance`.27/// This could be `none`, a `func_decl`, or a `func_instance`.
30func_index: InternPool.Index,28func_index: InternPool.Index,
31/// Whether the type of func_index has a calling convention of `.Naked`.29/// Whether the type of func_index has a calling convention of `.Naked`.
...@@ -48,7 +46,6 @@ branch_count: u32 = 0,...@@ -48,7 +46,6 @@ branch_count: u32 = 0,
48/// Populated when returning `error.ComptimeBreak`. Used to communicate the46/// Populated when returning `error.ComptimeBreak`. Used to communicate the
49/// break instruction up the stack to find the corresponding Block.47/// break instruction up the stack to find the corresponding Block.
50comptime_break_inst: Zir.Inst.Index = undefined,48comptime_break_inst: Zir.Inst.Index = undefined,
51decl_val_table: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Air.Inst.Ref) = .{},
52/// When doing a generic function instantiation, this array collects a value49/// When doing a generic function instantiation, this array collects a value
53/// for each parameter of the generic owner. `none` for non-comptime parameters.50/// for each parameter of the generic owner. `none` for non-comptime parameters.
54/// This is a separate array from `block.params` so that it can be passed51/// This is a separate array from `block.params` so that it can be passed
...@@ -79,10 +76,6 @@ no_partial_func_ty: bool = false,...@@ -79,10 +76,6 @@ no_partial_func_ty: bool = false,
79/// here so the values can be dropped without any cleanup.76/// here so the values can be dropped without any cleanup.
80unresolved_inferred_allocs: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{},77unresolved_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
86/// While analyzing a type which has a special InternPool index, this is set to the index at which79/// While analyzing a type which has a special InternPool index, this is set to the index at which
87/// the struct/enum/union type created should be placed. Otherwise, it is `.none`.80/// the struct/enum/union type created should be placed. Otherwise, it is `.none`.
88builtin_type_target_index: InternPool.Index = .none,81builtin_type_target_index: InternPool.Index = .none,
...@@ -177,7 +170,6 @@ const trace = @import("tracy.zig").trace;...@@ -177,7 +170,6 @@ const trace = @import("tracy.zig").trace;
177const Namespace = Module.Namespace;170const Namespace = Module.Namespace;
178const CompileError = Module.CompileError;171const CompileError = Module.CompileError;
179const SemaError = Module.SemaError;172const SemaError = Module.SemaError;
180const Decl = Module.Decl;
181const LazySrcLoc = Zcu.LazySrcLoc;173const LazySrcLoc = Zcu.LazySrcLoc;
182const RangeSet = @import("RangeSet.zig");174const RangeSet = @import("RangeSet.zig");
183const target_util = @import("target.zig");175const target_util = @import("target.zig");
...@@ -394,7 +386,7 @@ pub const Block = struct {...@@ -394,7 +386,7 @@ pub const Block = struct {
394 /// The name of the current "context" for naming namespace types.386 /// The name of the current "context" for naming namespace types.
395 /// The interpretation of this depends on the name strategy in ZIR, but the name387 /// The interpretation of this depends on the name strategy in ZIR, but the name
396 /// is always incorporated into the type name somehow.388 /// is always incorporated into the type name somehow.
397 /// See `Sema.createAnonymousDeclTypeNamed`.389 /// See `Sema.createTypeName`.
398 type_name_ctx: InternPool.NullTerminatedString,390 type_name_ctx: InternPool.NullTerminatedString,
399391
400 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.392 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.
...@@ -440,8 +432,8 @@ pub const Block = struct {...@@ -440,8 +432,8 @@ pub const Block = struct {
440 try sema.errNote(ci.src, parent, prefix ++ "it is inside a @cImport", .{});432 try sema.errNote(ci.src, parent, prefix ++ "it is inside a @cImport", .{});
441 },433 },
442 .comptime_ret_ty => |rt| {434 .comptime_ret_ty => |rt| {
443 const ret_ty_src: LazySrcLoc = if (try sema.funcDeclSrc(rt.func)) |fn_decl| .{435 const ret_ty_src: LazySrcLoc = if (try sema.funcDeclSrcInst(rt.func)) |fn_decl_inst| .{
444 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,436 .base_node_inst = fn_decl_inst,
445 .offset = .{ .node_offset_fn_type_ret_ty = 0 },437 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
446 } else rt.func_src;438 } else rt.func_src;
447 if (rt.return_ty.isGenericPoison()) {439 if (rt.return_ty.isGenericPoison()) {
...@@ -871,7 +863,6 @@ pub fn deinit(sema: *Sema) void {...@@ -871,7 +863,6 @@ pub fn deinit(sema: *Sema) void {
871 sema.air_instructions.deinit(gpa);863 sema.air_instructions.deinit(gpa);
872 sema.air_extra.deinit(gpa);864 sema.air_extra.deinit(gpa);
873 sema.inst_map.deinit(gpa);865 sema.inst_map.deinit(gpa);
874 sema.decl_val_table.deinit(gpa);
875 {866 {
876 var it = sema.post_hoc_blocks.iterator();867 var it = sema.post_hoc_blocks.iterator();
877 while (it.next()) |entry| {868 while (it.next()) |entry| {
...@@ -2170,7 +2161,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value...@@ -2170,7 +2161,7 @@ fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value
2170fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {2161fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2171 const val = (try sema.resolveValue(inst)) orelse return null;2162 const val = (try sema.resolveValue(inst)) orelse return null;
2172 if (sema.pt.zcu.intern_pool.getBackingAddrTag(val.toIntern())) |addr| switch (addr) {2163 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,
2174 .int => {},2165 .int => {},
2175 .eu_payload, .opt_payload, .arr_elem, .field => unreachable,2166 .eu_payload, .opt_payload, .arr_elem, .field => unreachable,
2176 };2167 };
...@@ -2503,7 +2494,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error...@@ -2503,7 +2494,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
2503 @setCold(true);2494 @setCold(true);
2504 const gpa = sema.gpa;2495 const gpa = sema.gpa;
2505 const mod = sema.pt.zcu;2496 const mod = sema.pt.zcu;
2506 const ip = &mod.intern_pool;
25072497
2508 if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) {2498 if (build_options.enable_debug_extensions and mod.comp.debug_compile_errors) {
2509 var all_references = mod.resolveReferences() catch @panic("out of memory");2499 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...@@ -2531,10 +2521,10 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
25312521
2532 const use_ref_trace = if (mod.comp.reference_trace) |n| n > 0 else mod.failed_analysis.count() == 0;2522 const use_ref_trace = if (mod.comp.reference_trace) |n| n > 0 else mod.failed_analysis.count() == 0;
2533 if (use_ref_trace) {2523 if (use_ref_trace) {
2534 err_msg.reference_trace_root = sema.ownerUnit().toOptional();2524 err_msg.reference_trace_root = sema.owner.toOptional();
2535 }2525 }
25362526
2537 const gop = try mod.failed_analysis.getOrPut(gpa, sema.ownerUnit());2527 const gop = try mod.failed_analysis.getOrPut(gpa, sema.owner);
2538 if (gop.found_existing) {2528 if (gop.found_existing) {
2539 // If there are multiple errors for the same Decl, prefer the first one added.2529 // If there are multiple errors for the same Decl, prefer the first one added.
2540 sema.err = null;2530 sema.err = null;
...@@ -2544,16 +2534,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error...@@ -2544,16 +2534,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
2544 gop.value_ptr.* = err_msg;2534 gop.value_ptr.* = err_msg;
2545 }2535 }
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
2557 return error.AnalysisFail;2537 return error.AnalysisFail;
2558}2538}
25592539
...@@ -2662,7 +2642,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2662,7 +2642,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2662 const pt = sema.pt;2642 const pt = sema.pt;
2663 const zcu = pt.zcu;2643 const zcu = pt.zcu;
2664 const ip = &zcu.intern_pool;2644 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
2667 const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len);2648 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...@@ -2704,8 +2685,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2704 sema.code.nullTerminatedString(str),2685 sema.code.nullTerminatedString(str),
2705 .no_embedded_nulls,2686 .no_embedded_nulls,
2706 );2687 );
2707 const decl = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?2688 const nav = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
2708 break :capture InternPool.CaptureValue.wrap(.{ .decl_val = decl });2689 break :capture InternPool.CaptureValue.wrap(.{ .nav_val = nav });
2709 },2690 },
2710 .decl_ref => |str| capture: {2691 .decl_ref => |str| capture: {
2711 const decl_name = try ip.getOrPutString(2692 const decl_name = try ip.getOrPutString(
...@@ -2714,8 +2695,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2714,8 +2695,8 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2714 sema.code.nullTerminatedString(str),2695 sema.code.nullTerminatedString(str),
2715 .no_embedded_nulls,2696 .no_embedded_nulls,
2716 );2697 );
2717 const decl = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?2698 const nav = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
2718 break :capture InternPool.CaptureValue.wrap(.{ .decl_ref = decl });2699 break :capture InternPool.CaptureValue.wrap(.{ .nav_ref = nav });
2719 },2700 },
2720 };2701 };
2721 }2702 }
...@@ -2740,19 +2721,24 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {...@@ -2740,19 +2721,24 @@ fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2740fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {2721fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
2741 const pt = sema.pt;2722 const pt = sema.pt;
2742 const zcu = pt.zcu;2723 const zcu = pt.zcu;
2724 const ip = &zcu.intern_pool;
27432725
2744 if (!zcu.comp.incremental) return false;2726 if (!zcu.comp.incremental) return false;
27452727
2746 const decl_index = Type.fromInterned(ty).getOwnerDecl(zcu);2728 const cau_index = switch (ip.indexToKey(ty)) {
2747 const decl_as_depender = AnalUnit.wrap(.{ .decl = decl_index });2729 .struct_type => ip.loadStructType(ty).cau.unwrap().?,
2748 const was_outdated = zcu.outdated.swapRemove(decl_as_depender) or2730 .union_type => ip.loadUnionType(ty).cau,
2749 zcu.potentially_outdated.swapRemove(decl_as_depender);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);
2750 if (!was_outdated) return false;2737 if (!was_outdated) return false;
2751 _ = zcu.outdated_ready.swapRemove(decl_as_depender);2738 _ = zcu.outdated_ready.swapRemove(cau_unit);
2752 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));2739 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, cau_unit);
2753 zcu.intern_pool.remove(pt.tid, ty);2740 zcu.intern_pool.remove(pt.tid, ty);
2754 zcu.declPtr(decl_index).analysis = .dependency_failure;2741 try zcu.markDependeeOutdated(.{ .interned = ty });
2755 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
2756 return true;2742 return true;
2757}2743}
27582744
...@@ -2816,7 +2802,6 @@ fn zirStructDecl(...@@ -2816,7 +2802,6 @@ fn zirStructDecl(
2816 .any_default_inits = small.any_default_inits,2802 .any_default_inits = small.any_default_inits,
2817 .inits_resolved = false,2803 .inits_resolved = false,
2818 .any_aligned_fields = small.any_aligned_fields,2804 .any_aligned_fields = small.any_aligned_fields,
2819 .has_namespace = true or decls_len > 0, // TODO: see below
2820 .key = .{ .declared = .{2805 .key = .{ .declared = .{
2821 .zir_index = tracked_inst,2806 .zir_index = tracked_inst,
2822 .captures = captures,2807 .captures = captures,
...@@ -2831,73 +2816,65 @@ fn zirStructDecl(...@@ -2831,73 +2816,65 @@ fn zirStructDecl(
2831 });2816 });
2832 errdefer wip_ty.cancel(ip, pt.tid);2817 errdefer wip_ty.cancel(ip, pt.tid);
28332818
2834 const new_decl_index = try sema.createAnonymousDeclTypeNamed(2819 wip_ty.setName(ip, try sema.createTypeName(
2835 block,2820 block,
2836 Value.fromInterned(wip_ty.index),
2837 small.name_strategy,2821 small.name_strategy,
2838 "struct",2822 "struct",
2839 inst,2823 inst,
2840 );2824 wip_ty.index,
2841 mod.declPtr(new_decl_index).owns_tv = true;2825 ));
2842 errdefer pt.abortAnonDecl(new_decl_index);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
2844 if (pt.zcu.comp.incremental) {2836 if (pt.zcu.comp.incremental) {
2845 try ip.addDependency(2837 try ip.addDependency(
2846 sema.gpa,2838 sema.gpa,
2847 AnalUnit.wrap(.{ .decl = new_decl_index }),2839 AnalUnit.wrap(.{ .cau = new_cau_index }),
2848 .{ .src_hash = try block.trackZir(inst) },2840 .{ .src_hash = tracked_inst },
2849 );2841 );
2850 }2842 }
28512843
2852 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.2844 const decls = sema.code.bodySlice(extra_index, decls_len);
2853 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{2845 try pt.scanNamespace(new_namespace_index, decls);
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 }
28642846
2865 try pt.finalizeAnonDecl(new_decl_index);
2866 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });2847 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
2867 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));2848 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
2868 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));2849 try sema.declareDependency(.{ .interned = wip_ty.index });
2850 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
2869}2851}
28702852
2871fn createAnonymousDeclTypeNamed(2853fn createTypeName(
2872 sema: *Sema,2854 sema: *Sema,
2873 block: *Block,2855 block: *Block,
2874 val: Value,
2875 name_strategy: Zir.Inst.NameStrategy,2856 name_strategy: Zir.Inst.NameStrategy,
2876 anon_prefix: []const u8,2857 anon_prefix: []const u8,
2877 inst: ?Zir.Inst.Index,2858 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 {
2879 const pt = sema.pt;2862 const pt = sema.pt;
2880 const zcu = pt.zcu;2863 const zcu = pt.zcu;
2864 const gpa = zcu.gpa;
2881 const ip = &zcu.intern_pool;2865 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
2887 switch (name_strategy) {2867 switch (name_strategy) {
2888 .anon => {}, // handled after switch2868 .anon => {}, // handled after switch
2889 .parent => {2869 .parent => return block.type_name_ctx,
2890 try pt.initNewAnonDecl(new_decl_index, val, block.type_name_ctx, .none);
2891 return new_decl_index;
2892 },
2893 .func => func_strat: {2870 .func => func_strat: {
2894 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));2871 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));
2895 const zir_tags = sema.code.instructions.items(.tag);2872 const zir_tags = sema.code.instructions.items(.tag);
28962873
2897 var buf = std.ArrayList(u8).init(gpa);2874 var buf: std.ArrayListUnmanaged(u8) = .{};
2898 defer buf.deinit();2875 defer buf.deinit(gpa);
28992876
2900 const writer = buf.writer();2877 const writer = buf.writer(gpa);
2901 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});2878 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});
29022879
2903 var arg_i: usize = 0;2880 var arg_i: usize = 0;
...@@ -2931,23 +2908,18 @@ fn createAnonymousDeclTypeNamed(...@@ -2931,23 +2908,18 @@ fn createAnonymousDeclTypeNamed(
2931 };2908 };
29322909
2933 try writer.writeByte(')');2910 try writer.writeByte(')');
2934 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);2911 return 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;
2937 },2912 },
2938 .dbg_var => {2913 .dbg_var => {
2914 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
2939 const ref = inst.?.toRef();2915 const ref = inst.?.toRef();
2940 const zir_tags = sema.code.instructions.items(.tag);2916 const zir_tags = sema.code.instructions.items(.tag);
2941 const zir_data = sema.code.instructions.items(.data);2917 const zir_data = sema.code.instructions.items(.data);
2942 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {2918 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
2943 .dbg_var_ptr, .dbg_var_val => {2919 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
2944 if (zir_data[i].str_op.operand != ref) continue;2920 return ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
2945
2946 const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
2947 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),2921 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
2948 }, .no_embedded_nulls);2922 }, .no_embedded_nulls);
2949 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2950 return new_decl_index;
2951 },2923 },
2952 else => {},2924 else => {},
2953 };2925 };
...@@ -2955,20 +2927,19 @@ fn createAnonymousDeclTypeNamed(...@@ -2955,20 +2927,19 @@ fn createAnonymousDeclTypeNamed(
2955 },2927 },
2956 }2928 }
29572929
2958 // anon strat handling.2930 // anon strat handling
29592931
2960 // It would be neat to have "struct:line:column" but this name has2932 // It would be neat to have "struct:line:column" but this name has
2961 // to survive incremental updates, where it may have been shifted down2933 // to survive incremental updates, where it may have been shifted down
2962 // or up to a different line, but unchanged, and thus not unnecessarily2934 // or up to a different line, but unchanged, and thus not unnecessarily
2963 // semantically analyzed.2935 // semantically analyzed.
2964 // This name is also used as the key in the parent namespace so it cannot be2936 // TODO: that would be possible, by detecting line number changes and renaming
2965 // renamed.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}", .{2940 return ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2968 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),2941 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
2969 }, .no_embedded_nulls) catch unreachable;2942 }, .no_embedded_nulls);
2970 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2971 return new_decl_index;
2972}2943}
29732944
2974fn zirEnumDecl(2945fn zirEnumDecl(
...@@ -3040,7 +3011,6 @@ fn zirEnumDecl(...@@ -3040,7 +3011,6 @@ fn zirEnumDecl(
3040 } else false;3011 } else false;
30413012
3042 const enum_init: InternPool.EnumTypeInit = .{3013 const enum_init: InternPool.EnumTypeInit = .{
3043 .has_namespace = true or decls_len > 0, // TODO: see below
3044 .has_values = any_values,3014 .has_values = any_values,
3045 .tag_mode = if (small.nonexhaustive)3015 .tag_mode = if (small.nonexhaustive)
3046 .nonexhaustive3016 .nonexhaustive
...@@ -3068,60 +3038,50 @@ fn zirEnumDecl(...@@ -3068,60 +3038,50 @@ fn zirEnumDecl(
30683038
3069 errdefer if (!done) wip_ty.cancel(ip, pt.tid);3039 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(
3072 block,3042 block,
3073 Value.fromInterned(wip_ty.index),
3074 small.name_strategy,3043 small.name_strategy,
3075 "enum",3044 "enum",
3076 inst,3045 inst,
3046 wip_ty.index,
3077 );3047 );
3078 const new_decl = mod.declPtr(new_decl_index);3048 wip_ty.setName(ip, type_name);
3079 new_decl.owns_tv = true;3049
3080 errdefer if (!done) pt.abortAnonDecl(new_decl_index);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
3082 if (pt.zcu.comp.incremental) {3059 if (pt.zcu.comp.incremental) {
3083 try mod.intern_pool.addDependency(3060 try mod.intern_pool.addDependency(
3084 gpa,3061 gpa,
3085 AnalUnit.wrap(.{ .decl = new_decl_index }),3062 AnalUnit.wrap(.{ .cau = new_cau_index }),
3086 .{ .src_hash = try block.trackZir(inst) },3063 .{ .src_hash = try block.trackZir(inst) },
3087 );3064 );
3088 }3065 }
30893066
3090 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.3067 try pt.scanNamespace(new_namespace_index, decls);
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);
30973068
3098 if (new_namespace_index.unwrap()) |ns| {3069 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3099 try pt.scanNamespace(ns, decls, new_decl);3070 try sema.declareDependency(.{ .interned = wip_ty.index });
3100 }
31013071
3102 // We've finished the initial construction of this type, and are about to perform analysis.3072 // 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.3073 // Set the Cau and namespace appropriately, and don't destroy anything on failure.
3104 wip_ty.prepare(ip, new_decl_index, new_namespace_index);3074 wip_ty.prepare(ip, new_cau_index, new_namespace_index);
3105 done = true;3075 done = true;
31063076
3107 const int_tag_ty = ty: {3077 const int_tag_ty = ty: {
3108 // We create a block for the field type instructions because they3078 // We create a block for the field type instructions because they
3109 // may need to reference Decls from inside the enum namespace.3079 // may need to reference Decls from inside the enum namespace.
3110 // Within the field type, default value, and alignment expressions, the "owner decl"3080 // Within the field type, default value, and alignment expressions, the owner should be the enum's `Cau`.
3111 // should be the enum itself.
31123081
3113 const prev_owner_decl = sema.owner_decl;3082 const prev_owner = sema.owner;
3114 const prev_owner_decl_index = sema.owner_decl_index;3083 sema.owner = AnalUnit.wrap(.{ .cau = new_cau_index });
3115 sema.owner_decl = new_decl;3084 defer sema.owner = prev_owner;
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;
31253085
3126 const prev_func_index = sema.func_index;3086 const prev_func_index = sema.func_index;
3127 sema.func_index = .none;3087 sema.func_index = .none;
...@@ -3130,12 +3090,12 @@ fn zirEnumDecl(...@@ -3130,12 +3090,12 @@ fn zirEnumDecl(
3130 var enum_block: Block = .{3090 var enum_block: Block = .{
3131 .parent = null,3091 .parent = null,
3132 .sema = sema,3092 .sema = sema,
3133 .namespace = new_namespace_index.unwrap() orelse block.namespace,3093 .namespace = new_namespace_index,
3134 .instructions = .{},3094 .instructions = .{},
3135 .inlining = null,3095 .inlining = null,
3136 .is_comptime = true,3096 .is_comptime = true,
3137 .src_base_inst = tracked_inst,3097 .src_base_inst = tracked_inst,
3138 .type_name_ctx = new_decl.name,3098 .type_name_ctx = type_name,
3139 };3099 };
3140 defer enum_block.instructions.deinit(sema.gpa);3100 defer enum_block.instructions.deinit(sema.gpa);
31413101
...@@ -3253,7 +3213,6 @@ fn zirEnumDecl(...@@ -3253,7 +3213,6 @@ fn zirEnumDecl(
3253 }3213 }
3254 }3214 }
32553215
3256 try pt.finalizeAnonDecl(new_decl_index);
3257 return Air.internedToRef(wip_ty.index);3216 return Air.internedToRef(wip_ty.index);
3258}3217}
32593218
...@@ -3317,7 +3276,6 @@ fn zirUnionDecl(...@@ -3317,7 +3276,6 @@ fn zirUnionDecl(
3317 .assumed_pointer_aligned = false,3276 .assumed_pointer_aligned = false,
3318 .alignment = .none,3277 .alignment = .none,
3319 },3278 },
3320 .has_namespace = true or decls_len != 0, // TODO: see below
3321 .fields_len = fields_len,3279 .fields_len = fields_len,
3322 .enum_tag_ty = .none, // set later3280 .enum_tag_ty = .none, // set later
3323 .field_types = &.{}, // set later3281 .field_types = &.{}, // set later
...@@ -3336,41 +3294,38 @@ fn zirUnionDecl(...@@ -3336,41 +3294,38 @@ fn zirUnionDecl(
3336 });3294 });
3337 errdefer wip_ty.cancel(ip, pt.tid);3295 errdefer wip_ty.cancel(ip, pt.tid);
33383296
3339 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3297 wip_ty.setName(ip, try sema.createTypeName(
3340 block,3298 block,
3341 Value.fromInterned(wip_ty.index),
3342 small.name_strategy,3299 small.name_strategy,
3343 "union",3300 "union",
3344 inst,3301 inst,
3345 );3302 wip_ty.index,
3346 mod.declPtr(new_decl_index).owns_tv = true;3303 ));
3347 errdefer pt.abortAnonDecl(new_decl_index);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
3349 if (pt.zcu.comp.incremental) {3314 if (pt.zcu.comp.incremental) {
3350 try mod.intern_pool.addDependency(3315 try mod.intern_pool.addDependency(
3351 gpa,3316 gpa,
3352 AnalUnit.wrap(.{ .decl = new_decl_index }),3317 AnalUnit.wrap(.{ .cau = new_cau_index }),
3353 .{ .src_hash = try block.trackZir(inst) },3318 .{ .src_hash = try block.trackZir(inst) },
3354 );3319 );
3355 }3320 }
33563321
3357 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.3322 const decls = sema.code.bodySlice(extra_index, decls_len);
3358 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{3323 try pt.scanNamespace(new_namespace_index, decls);
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 }
33693324
3370 try pt.finalizeAnonDecl(new_decl_index);
3371 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });3325 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
3372 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));3326 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3373 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3327 try sema.declareDependency(.{ .interned = wip_ty.index });
3328 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
3374}3329}
33753330
3376fn zirOpaqueDecl(3331fn zirOpaqueDecl(
...@@ -3410,7 +3365,6 @@ fn zirOpaqueDecl(...@@ -3410,7 +3365,6 @@ fn zirOpaqueDecl(
3410 extra_index += captures_len;3365 extra_index += captures_len;
34113366
3412 const opaque_init: InternPool.OpaqueTypeInit = .{3367 const opaque_init: InternPool.OpaqueTypeInit = .{
3413 .has_namespace = decls_len != 0,
3414 .key = .{ .declared = .{3368 .key = .{ .declared = .{
3415 .zir_index = tracked_inst,3369 .zir_index = tracked_inst,
3416 .captures = captures,3370 .captures = captures,
...@@ -3418,47 +3372,31 @@ fn zirOpaqueDecl(...@@ -3418,47 +3372,31 @@ fn zirOpaqueDecl(
3418 };3372 };
3419 // No `wrapWipTy` needed as no std.builtin types are opaque.3373 // No `wrapWipTy` needed as no std.builtin types are opaque.
3420 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {3374 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {
3421 .existing => |ty| wip: {3375 // No `maybeRemoveOutdatedType` as opaque types are never outdated.
3422 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3376 .existing => |ty| return Air.internedToRef(ty),
3423 break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip;
3424 },
3425 .wip => |wip| wip,3377 .wip => |wip| wip,
3426 };3378 };
3427 errdefer wip_ty.cancel(ip, pt.tid);3379 errdefer wip_ty.cancel(ip, pt.tid);
34283380
3429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3381 wip_ty.setName(ip, try sema.createTypeName(
3430 block,3382 block,
3431 Value.fromInterned(wip_ty.index),
3432 small.name_strategy,3383 small.name_strategy,
3433 "opaque",3384 "opaque",
3434 inst,3385 inst,
3435 );3386 wip_ty.index,
3436 mod.declPtr(new_decl_index).owns_tv = true;3387 ));
3437 errdefer pt.abortAnonDecl(new_decl_index);
34383388
3439 if (pt.zcu.comp.incremental) {3389 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
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(.{
3448 .parent = block.namespace.toOptional(),3390 .parent = block.namespace.toOptional(),
3449 .decl_index = new_decl_index,3391 .owner_type = wip_ty.index,
3450 .file_scope = block.getFileScopeIndex(mod),3392 .file_scope = block.getFileScopeIndex(mod),
3451 })).toOptional() else .none;3393 });
3452 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);3394 errdefer pt.destroyNamespace(new_namespace_index);
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 }
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));
3462}3400}
34633401
3464fn zirErrorSetDecl(3402fn zirErrorSetDecl(
...@@ -3774,7 +3712,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3774,7 +3712,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3774 // might have already done our job and created an anon decl ref.3712 // might have already done our job and created an anon decl ref.
3775 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {3713 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
3776 .ptr => |ptr| switch (ptr.base_addr) {3714 .ptr => |ptr| switch (ptr.base_addr) {
3777 .anon_decl => {3715 .uav => {
3778 // The comptime-ification was already done for us.3716 // The comptime-ification was already done for us.
3779 // Just make sure the pointer is const.3717 // Just make sure the pointer is const.
3780 return sema.makePtrConst(block, alloc);3718 return sema.makePtrConst(block, alloc);
...@@ -3799,7 +3737,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3799,7 +3737,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3799 // Promote the constant to an anon decl.3737 // Promote the constant to an anon decl.
3800 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{3738 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{
3801 .ty = alloc_ty.toIntern(),3739 .ty = alloc_ty.toIntern(),
3802 .base_addr = .{ .anon_decl = .{3740 .base_addr = .{ .uav = .{
3803 .val = interned.toIntern(),3741 .val = interned.toIntern(),
3804 .orig_ty = alloc_ty.toIntern(),3742 .orig_ty = alloc_ty.toIntern(),
3805 } },3743 } },
...@@ -4097,7 +4035,7 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4097,7 +4035,7 @@ fn finishResolveComptimeKnownAllocPtr(
4097 } else {4035 } else {
4098 return try pt.intern(.{ .ptr = .{4036 return try pt.intern(.{ .ptr = .{
4099 .ty = alloc_ty.toIntern(),4037 .ty = alloc_ty.toIntern(),
4100 .base_addr = .{ .anon_decl = .{4038 .base_addr = .{ .uav = .{
4101 .orig_ty = alloc_ty.toIntern(),4039 .orig_ty = alloc_ty.toIntern(),
4102 .val = result_val,4040 .val = result_val,
4103 } },4041 } },
...@@ -4250,7 +4188,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4250,7 +4188,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4250 }4188 }
42514189
4252 const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) {4190 const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) {
4253 .anon_decl => |a| a.val,4191 .uav => |a| a.val,
4254 .comptime_alloc => |i| val: {4192 .comptime_alloc => |i| val: {
4255 const alloc = sema.getComptimeAlloc(i);4193 const alloc = sema.getComptimeAlloc(i);
4256 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();4194 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();
...@@ -5505,22 +5443,23 @@ fn failWithBadMemberAccess(...@@ -5505,22 +5443,23 @@ fn failWithBadMemberAccess(
5505 field_name: InternPool.NullTerminatedString,5443 field_name: InternPool.NullTerminatedString,
5506) CompileError {5444) CompileError {
5507 const pt = sema.pt;5445 const pt = sema.pt;
5508 const mod = pt.zcu;5446 const zcu = pt.zcu;
5509 const kw_name = switch (agg_ty.zigTypeTag(mod)) {5447 const ip = &zcu.intern_pool;
5448 const kw_name = switch (agg_ty.zigTypeTag(zcu)) {
5510 .Union => "union",5449 .Union => "union",
5511 .Struct => "struct",5450 .Struct => "struct",
5512 .Opaque => "opaque",5451 .Opaque => "opaque",
5513 .Enum => "enum",5452 .Enum => "enum",
5514 else => unreachable,5453 else => unreachable,
5515 };5454 };
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) {
5517 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{5456 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),
5519 });5458 });
5520 };5459 };
55215460
5522 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{5461 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),
5524 });5463 });
5525}5464}
55265465
...@@ -5535,13 +5474,12 @@ fn failWithBadStructFieldAccess(...@@ -5535,13 +5474,12 @@ fn failWithBadStructFieldAccess(
5535 const pt = sema.pt;5474 const pt = sema.pt;
5536 const zcu = pt.zcu;5475 const zcu = pt.zcu;
5537 const ip = &zcu.intern_pool;5476 const ip = &zcu.intern_pool;
5538 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
55395477
5540 const msg = msg: {5478 const msg = msg: {
5541 const msg = try sema.errMsg(5479 const msg = try sema.errMsg(
5542 field_src,5480 field_src,
5543 "no field named '{}' in struct '{}'",5481 "no field named '{}' in struct '{}'",
5544 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },5482 .{ field_name.fmt(ip), struct_type.name.fmt(ip) },
5545 );5483 );
5546 errdefer msg.destroy(sema.gpa);5484 errdefer msg.destroy(sema.gpa);
5547 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});5485 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
...@@ -5562,13 +5500,12 @@ fn failWithBadUnionFieldAccess(...@@ -5562,13 +5500,12 @@ fn failWithBadUnionFieldAccess(
5562 const zcu = pt.zcu;5500 const zcu = pt.zcu;
5563 const ip = &zcu.intern_pool;5501 const ip = &zcu.intern_pool;
5564 const gpa = sema.gpa;5502 const gpa = sema.gpa;
5565 const decl = zcu.declPtr(union_obj.decl);
55665503
5567 const msg = msg: {5504 const msg = msg: {
5568 const msg = try sema.errMsg(5505 const msg = try sema.errMsg(
5569 field_src,5506 field_src,
5570 "no field named '{}' in union '{}'",5507 "no field named '{}' in union '{}'",
5571 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },5508 .{ field_name.fmt(ip), union_obj.name.fmt(ip) },
5572 );5509 );
5573 errdefer msg.destroy(gpa);5510 errdefer msg.destroy(gpa);
5574 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});5511 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
...@@ -5659,7 +5596,7 @@ fn storeToInferredAllocComptime(...@@ -5659,7 +5596,7 @@ fn storeToInferredAllocComptime(
5659 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {5596 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
5660 iac.ptr = try pt.intern(.{ .ptr = .{5597 iac.ptr = try pt.intern(.{ .ptr = .{
5661 .ty = alloc_ty.toIntern(),5598 .ty = alloc_ty.toIntern(),
5662 .base_addr = .{ .anon_decl = .{5599 .base_addr = .{ .uav = .{
5663 .val = operand_val.toIntern(),5600 .val = operand_val.toIntern(),
5664 .orig_ty = alloc_ty.toIntern(),5601 .orig_ty = alloc_ty.toIntern(),
5665 } },5602 } },
...@@ -5748,11 +5685,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air....@@ -5748,11 +5685,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.
5748 .ty = array_ty.toIntern(),5685 .ty = array_ty.toIntern(),
5749 .storage = .{ .bytes = string },5686 .storage = .{ .bytes = string },
5750 } });5687 } });
5751 return anonDeclRef(sema, val);5688 return sema.uavRef(val);
5752}5689}
57535690
5754fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {5691fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5755 return Air.internedToRef(try refValue(sema, val));5692 return Air.internedToRef(try sema.refValue(val));
5756}5693}
57575694
5758fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {5695fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
...@@ -5767,7 +5704,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {...@@ -5767,7 +5704,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5767 })).toIntern();5704 })).toIntern();
5768 return pt.intern(.{ .ptr = .{5705 return pt.intern(.{ .ptr = .{
5769 .ty = ptr_ty,5706 .ty = ptr_ty,
5770 .base_addr = .{ .anon_decl = .{5707 .base_addr = .{ .uav = .{
5771 .val = val,5708 .val = val,
5772 .orig_ty = ptr_ty,5709 .orig_ty = ptr_ty,
5773 } },5710 } },
...@@ -5866,7 +5803,7 @@ fn zirCompileLog(...@@ -5866,7 +5803,7 @@ fn zirCompileLog(
5866 }5803 }
5867 try writer.print("\n", .{});5804 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);
5870 if (!gop.found_existing) gop.value_ptr.* = .{5807 if (!gop.found_existing) gop.value_ptr.* = .{
5871 .base_node_inst = block.src_base_inst,5808 .base_node_inst = block.src_base_inst,
5872 .node_offset = src_node,5809 .node_offset = src_node,
...@@ -6021,7 +5958,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6021,7 +5958,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
6021 if (!comp.config.link_libc)5958 if (!comp.config.link_libc)
6022 try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});5959 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);
6025 if (!gop.found_existing) {5962 if (!gop.found_existing) {
6026 gop.value_ptr.* = c_import_res.errors;5963 gop.value_ptr.* = c_import_res.errors;
6027 c_import_res.errors = std.zig.ErrorBundle.empty;5964 c_import_res.errors = std.zig.ErrorBundle.empty;
...@@ -6069,13 +6006,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6069,13 +6006,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
6069 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6006 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60706007
6071 const path_digest = zcu.filePathDigest(result.file_index);6008 const path_digest = zcu.filePathDigest(result.file_index);
6072 const root_decl = zcu.fileRootDecl(result.file_index);6009 const old_root_type = zcu.fileRootType(result.file_index);
6073 pt.astGenFile(result.file, path_digest, root_decl) catch |err|6010 pt.astGenFile(result.file, path_digest, old_root_type) catch |err|
6074 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6011 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.
6076 try pt.ensureFileAnalyzed(result.file_index);6016 try pt.ensureFileAnalyzed(result.file_index);
6077 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;6017 return Air.internedToRef(zcu.fileRootType(result.file_index));
6078 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);
6079}6018}
60806019
6081fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6020fn 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...@@ -6423,36 +6362,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6423 defer tracy.end();6362 defer tracy.end();
64246363
6425 const pt = sema.pt;6364 const pt = sema.pt;
6426 const mod = pt.zcu;6365 const zcu = pt.zcu;
6366 const ip = &zcu.intern_pool;
6427 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6367 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
6428 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;6368 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
6429 const src = block.nodeOffset(inst_data.src_node);6369 const src = block.nodeOffset(inst_data.src_node);
6430 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);6370 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
6431 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);6371 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
6432 const decl_name = try mod.intern_pool.getOrPutString(6372 const decl_name = try ip.getOrPutString(
6433 mod.gpa,6373 zcu.gpa,
6434 pt.tid,6374 pt.tid,
6435 sema.code.nullTerminatedString(extra.decl_name),6375 sema.code.nullTerminatedString(extra.decl_name),
6436 .no_embedded_nulls,6376 .no_embedded_nulls,
6437 );6377 );
6438 const decl_index = if (extra.namespace != .none) index_blk: {6378 const nav_index = if (extra.namespace != .none) index_blk: {
6439 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);6379 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);6382 const lookup = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false) orelse
6443 break :index_blk maybe_index orelse
6444 return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name);6383 return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name);
6384
6385 break :index_blk lookup.nav;
6445 } else try sema.lookupIdentifier(block, operand_src, decl_name);6386 } else try sema.lookupIdentifier(block, operand_src, decl_name);
6446 const options = try sema.resolveExportOptions(block, options_src, extra.options);6387 const options = try sema.resolveExportOptions(block, options_src, extra.options);
6447 {6388
6448 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));6389 try sema.ensureNavResolved(src, nav_index);
6449 try sema.ensureDeclAnalyzed(decl_index);6390
6450 const exported_decl = mod.declPtr(decl_index);6391 // Make sure to export the owner Nav if applicable.
6451 if (exported_decl.val.getFunction(mod)) |function| {6392 const exported_nav = switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) {
6452 return sema.analyzeExport(block, src, options, function.owner_decl);6393 .variable => |v| v.owner_nav,
6453 }6394 .@"extern" => |e| e.owner_nav,
6454 }6395 .func => |f| f.owner_nav,
6455 try sema.analyzeExport(block, src, options, decl_index);6396 else => nav_index,
6397 };
6398 try sema.analyzeExport(block, src, options, exported_nav);
6456}6399}
64576400
6458fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {6401fn 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...@@ -6460,7 +6403,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6460 defer tracy.end();6403 defer tracy.end();
64616404
6462 const pt = sema.pt;6405 const pt = sema.pt;
6463 const mod = pt.zcu;6406 const zcu = pt.zcu;
6407 const ip = &zcu.intern_pool;
6464 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6408 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
6465 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;6409 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
6466 const src = block.nodeOffset(inst_data.src_node);6410 const src = block.nodeOffset(inst_data.src_node);
...@@ -6472,17 +6416,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6472,17 +6416,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6472 const options = try sema.resolveExportOptions(block, options_src, extra.options);6416 const options = try sema.resolveExportOptions(block, options_src, extra.options);
6473 if (options.linkage == .internal)6417 if (options.linkage == .internal)
6474 return;6418 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, .{6420 // If the value has an owner Nav, export that instead.
6481 .opts = options,6421 const maybe_owner_nav = switch (ip.indexToKey(operand.toIntern())) {
6482 .src = src,6422 .variable => |v| v.owner_nav,
6483 .exported = .{ .value = operand.toIntern() },6423 .@"extern" => |e| e.owner_nav,
6484 .status = .in_progress,6424 .func => |f| f.owner_nav,
6485 });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 }
6486}6437}
64876438
6488pub fn analyzeExport(6439pub fn analyzeExport(
...@@ -6490,22 +6441,22 @@ pub fn analyzeExport(...@@ -6490,22 +6441,22 @@ pub fn analyzeExport(
6490 block: *Block,6441 block: *Block,
6491 src: LazySrcLoc,6442 src: LazySrcLoc,
6492 options: Module.Export.Options,6443 options: Module.Export.Options,
6493 exported_decl_index: InternPool.DeclIndex,6444 exported_nav_index: InternPool.Nav.Index,
6494) !void {6445) !void {
6495 const gpa = sema.gpa;6446 const gpa = sema.gpa;
6496 const pt = sema.pt;6447 const pt = sema.pt;
6497 const mod = pt.zcu;6448 const zcu = pt.zcu;
6449 const ip = &zcu.intern_pool;
64986450
6499 if (options.linkage == .internal)6451 if (options.linkage == .internal)
6500 return;6452 return;
65016453
6502 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = exported_decl_index }));6454 try sema.ensureNavResolved(src, exported_nav_index);
6503 try sema.ensureDeclAnalyzed(exported_decl_index);6455 const exported_nav = ip.getNav(exported_nav_index);
6504 const exported_decl = mod.declPtr(exported_decl_index);6456 const export_ty = Type.fromInterned(exported_nav.typeOf(ip));
6505 const export_ty = exported_decl.typeOf(mod);
65066457
6507 if (!try sema.validateExternType(export_ty, .other)) {6458 if (!try sema.validateExternType(export_ty, .other)) {
6508 const msg = msg: {6459 return sema.failWithOwnedErrorMsg(block, msg: {
6509 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});6460 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
6510 errdefer msg.destroy(gpa);6461 errdefer msg.destroy(gpa);
65116462
...@@ -6513,59 +6464,50 @@ pub fn analyzeExport(...@@ -6513,59 +6464,50 @@ pub fn analyzeExport(
65136464
6514 try sema.addDeclaredHereNote(msg, export_ty);6465 try sema.addDeclaredHereNote(msg, export_ty);
6515 break :msg msg;6466 break :msg msg;
6516 };6467 });
6517 return sema.failWithOwnedErrorMsg(block, msg);
6518 }6468 }
65196469
6520 // TODO: some backends might support re-exporting extern decls6470 // TODO: some backends might support re-exporting extern decls
6521 if (exported_decl.isExtern(mod)) {6471 if (exported_nav.isExtern(ip)) {
6522 return sema.fail(block, src, "export target cannot be extern", .{});6472 return sema.fail(block, src, "export target cannot be extern", .{});
6523 }6473 }
65246474
6525 try sema.maybeQueueFuncBodyAnalysis(src, exported_decl_index);6475 try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index);
65266476
6527 try sema.exports.append(gpa, .{6477 try sema.exports.append(gpa, .{
6528 .opts = options,6478 .opts = options,
6529 .src = src,6479 .src = src,
6530 .exported = .{ .decl_index = exported_decl_index },6480 .exported = .{ .nav = exported_nav_index },
6531 .status = .in_progress,6481 .status = .in_progress,
6532 });6482 });
6533}6483}
65346484
6535fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6485fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6536 const pt = sema.pt;6486 const pt = sema.pt;
6537 const mod = pt.zcu;6487 const zcu = pt.zcu;
6538 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6488 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6539 const operand_src = block.builtinCallArgSrc(extra.node, 0);6489 const operand_src = block.builtinCallArgSrc(extra.node, 0);
6540 const src = block.nodeOffset(extra.node);6490 const src = block.nodeOffset(extra.node);
6541 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);6491 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
6542 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {6498 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
6543 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{6499 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
6544 alignment.toByteUnits().?,6500 alignment.toByteUnits().?,
6545 });6501 });
6546 }6502 }
65476503
6548 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);6504 switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) {
6549 switch (fn_owner_decl.typeOf(mod).fnCallingConvention(mod)) {
6550 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),6505 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
6551 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),6506 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
6552 else => if (block.inlining != null) {6507 else => {},
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);
6565 }6508 }
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);
6569}6511}
65706512
6571fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6513fn 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)...@@ -6577,16 +6519,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
6577 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{6519 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{
6578 .needed_comptime_reason = "operand to @setCold must be comptime-known",6520 .needed_comptime_reason = "operand to @setCold must be comptime-known",
6579 });6521 });
6580 if (sema.func_index == .none) return; // does nothing outside a function6522 // TODO: should `@setCold` apply to the parent in an inline call?
6581 ip.funcSetCold(sema.func_index, is_cold);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);
6582}6529}
65836530
6584fn zirDisableInstrumentation(sema: *Sema) CompileError!void {6531fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
6585 const pt = sema.pt;6532 const pt = sema.pt;
6586 const mod = pt.zcu;6533 const mod = pt.zcu;
6587 const ip = &mod.intern_pool;6534 const ip = &mod.intern_pool;
6588 if (sema.func_index == .none) return; // does nothing outside a function6535 const func = switch (sema.owner.unwrap()) {
6589 ip.funcSetDisableInstrumentation(sema.func_index);6536 .func => |func| func,
6537 .cau => return, // does nothing outside a function
6538 };
6539 ip.funcSetDisableInstrumentation(func);
6590}6540}
65916541
6592fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6542fn 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...@@ -6760,8 +6710,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6760 inst_data.get(sema.code),6710 inst_data.get(sema.code),
6761 .no_embedded_nulls,6711 .no_embedded_nulls,
6762 );6712 );
6763 const decl_index = try sema.lookupIdentifier(block, src, decl_name);6713 const nav_index = try sema.lookupIdentifier(block, src, decl_name);
6764 return sema.analyzeDeclRef(src, decl_index);6714 return sema.analyzeNavRef(src, nav_index);
6765}6715}
67666716
6767fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6717fn 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...@@ -6775,17 +6725,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6775 inst_data.get(sema.code),6725 inst_data.get(sema.code),
6776 .no_embedded_nulls,6726 .no_embedded_nulls,
6777 );6727 );
6778 const decl = try sema.lookupIdentifier(block, src, decl_name);6728 const nav = try sema.lookupIdentifier(block, src, decl_name);
6779 return sema.analyzeDeclVal(block, src, decl);6729 return sema.analyzeNavVal(block, src, nav);
6780}6730}
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 {
6783 const pt = sema.pt;6733 const pt = sema.pt;
6784 const mod = pt.zcu;6734 const mod = pt.zcu;
6785 var namespace = block.namespace;6735 var namespace = block.namespace;
6786 while (true) {6736 while (true) {
6787 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {6737 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |lookup| {
6788 return decl_index;6738 assert(lookup.accessible);
6739 return lookup.nav;
6789 }6740 }
6790 namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break;6741 namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break;
6791 }6742 }
...@@ -6798,69 +6749,74 @@ fn lookupInNamespace(...@@ -6798,69 +6749,74 @@ fn lookupInNamespace(
6798 sema: *Sema,6749 sema: *Sema,
6799 block: *Block,6750 block: *Block,
6800 src: LazySrcLoc,6751 src: LazySrcLoc,
6801 opt_namespace_index: InternPool.OptionalNamespaceIndex,6752 namespace_index: InternPool.NamespaceIndex,
6802 ident_name: InternPool.NullTerminatedString,6753 ident_name: InternPool.NullTerminatedString,
6803 observe_usingnamespace: bool,6754 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} {
6805 const pt = sema.pt;6761 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;6765 const namespace = zcu.namespacePtr(namespace_index);
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 }
68146766
6815 if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) {6767 const adapter: Zcu.Namespace.NameAdapter = .{ .zcu = zcu };
6816 const src_file = mod.namespacePtr(block.namespace).file_scope;
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)) {
6818 const gpa = sema.gpa;6772 const gpa = sema.gpa;
6819 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{};6773 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{};
6820 defer checked_namespaces.deinit(gpa);6774 defer checked_namespaces.deinit(gpa);
68216775
6822 // Keep track of name conflicts for error notes.6776 // Keep track of name conflicts for error notes.
6823 var candidates: std.ArrayListUnmanaged(InternPool.DeclIndex) = .{};6777 var candidates: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{};
6824 defer candidates.deinit(gpa);6778 defer candidates.deinit(gpa);
68256779
6826 try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file);6780 try checked_namespaces.put(gpa, namespace, {});
6827 var check_i: usize = 0;6781 var check_i: usize = 0;
68286782
6829 while (check_i < checked_namespaces.count()) : (check_i += 1) {6783 while (check_i < checked_namespaces.count()) : (check_i += 1) {
6830 const check_ns = checked_namespaces.keys()[check_i];6784 const check_ns = checked_namespaces.keys()[check_i];
6831 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {6785 const Pass = enum { @"pub", priv };
6832 // Skip decls which are not marked pub, which are in a different6786 for ([2]Pass{ .@"pub", .priv }) |pass| {
6833 // file than the `a.b`/`@hasDecl` syntax.6787 if (pass == .priv and src_file != check_ns.file_scope) {
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.
6851 continue;6788 continue;
6852 }6789 }
6853 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index);6790
6854 const ns_ty = sub_usingnamespace_decl.val.toType();6791 const decls, const usingnamespaces = switch (pass) {
6855 const sub_ns = mod.namespacePtrUnwrap(ns_ty.getNamespaceIndex(mod)) orelse continue;6792 .@"pub" => .{ &check_ns.pub_decls, &check_ns.pub_usingnamespace },
6856 try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScopeIndex(mod));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 }
6857 }6806 }
6858 }6807 }
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 };
6861 var i: usize = 0;6817 var i: usize = 0;
6862 while (i < candidates.items.len) {6818 while (i < candidates.items.len) {
6863 if (candidates.items[i] == sema.owner_decl_index) {6819 if (candidates.items[i] == skip_nav) {
6864 _ = candidates.orderedRemove(i);6820 _ = candidates.orderedRemove(i);
6865 } else {6821 } else {
6866 i += 1;6822 i += 1;
...@@ -6870,48 +6826,50 @@ fn lookupInNamespace(...@@ -6870,48 +6826,50 @@ fn lookupInNamespace(
68706826
6871 switch (candidates.items.len) {6827 switch (candidates.items.len) {
6872 0 => {},6828 0 => {},
6873 1 => {6829 1 => return .{
6874 const decl_index = candidates.items[0];6830 .nav = candidates.items[0],
6875 return decl_index;6831 .accessible = true,
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);
6891 },6832 },
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 }),
6892 }6841 }
6893 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {6842 } else if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6894 return decl_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 };
6895 }6852 }
68966853
6897 return null;6854 return null;
6898}6855}
68996856
6900fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {6857fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedInst.Index {
6901 const pt = sema.pt;6858 const pt = sema.pt;
6902 const mod = pt.zcu;6859 const zcu = pt.zcu;
6903 const func_val = (try sema.resolveValue(func_inst)) orelse return null;6860 const ip = &zcu.intern_pool;
6904 if (func_val.isUndef(mod)) return null;6861 const func_val = try sema.resolveValue(func_inst) orelse return null;
6905 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {6862 if (func_val.isUndef(zcu)) return null;
6906 .extern_func => |extern_func| extern_func.decl,6863 const nav = switch (ip.indexToKey(func_val.toIntern())) {
6907 .func => |func| func.owner_decl,6864 .@"extern" => |e| e.owner_nav,
6865 .func => |f| f.owner_nav,
6908 .ptr => |ptr| switch (ptr.base_addr) {6866 .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,
6910 else => return null,6868 else => return null,
6911 },6869 },
6912 else => return null,6870 else => return null,
6913 };6871 };
6914 return mod.declPtr(owner_decl_index);6872 return ip.getNav(nav).srcInst(ip);
6915}6873}
69166874
6917pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {6875pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
...@@ -7100,11 +7058,12 @@ fn zirCall(...@@ -7100,11 +7058,12 @@ fn zirCall(
7100 const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1);7058 const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1);
7101 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);7059 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 or7061 switch (sema.owner.unwrap()) {
7104 !mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn)7062 .cau => input_is_error = false,
7105 {7063 .func => |owner_func| if (!mod.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) {
7106 // No errorable fn actually called; we have no error return trace7064 // No errorable fn actually called; we have no error return trace
7107 input_is_error = false;7065 input_is_error = false;
7066 },
7108 }7067 }
71097068
7110 if (block.ownerModule().error_tracing and7069 if (block.ownerModule().error_tracing and
...@@ -7199,7 +7158,7 @@ fn checkCallArgumentCount(...@@ -7199,7 +7158,7 @@ fn checkCallArgumentCount(
7199 return func_ty;7158 return func_ty;
7200 }7159 }
72017160
7202 const maybe_decl = try sema.funcDeclSrc(func);7161 const maybe_func_inst = try sema.funcDeclSrcInst(func);
7203 const member_str = if (member_fn) "member function " else "";7162 const member_str = if (member_fn) "member function " else "";
7204 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";7163 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
7205 const msg = msg: {7164 const msg = msg: {
...@@ -7215,9 +7174,9 @@ fn checkCallArgumentCount(...@@ -7215,9 +7174,9 @@ fn checkCallArgumentCount(
7215 );7174 );
7216 errdefer msg.destroy(sema.gpa);7175 errdefer msg.destroy(sema.gpa);
72177176
7218 if (maybe_decl) |fn_decl| {7177 if (maybe_func_inst) |func_inst| {
7219 try sema.errNote(.{7178 try sema.errNote(.{
7220 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,7179 .base_node_inst = func_inst,
7221 .offset = LazySrcLoc.Offset.nodeOffset(0),7180 .offset = LazySrcLoc.Offset.nodeOffset(0),
7222 }, msg, "function declared here", .{});7181 }, msg, "function declared here", .{});
7223 }7182 }
...@@ -7544,7 +7503,7 @@ fn analyzeCall(...@@ -7544,7 +7503,7 @@ fn analyzeCall(
7544 if (func_val.isUndef(mod))7503 if (func_val.isUndef(mod))
7545 return sema.failWithUseOfUndef(block, call_src);7504 return sema.failWithUseOfUndef(block, call_src);
7546 if (cc == .Naked) {7505 if (cc == .Naked) {
7547 const maybe_decl = try sema.funcDeclSrc(func);7506 const maybe_func_inst = try sema.funcDeclSrcInst(func);
7548 const msg = msg: {7507 const msg = msg: {
7549 const msg = try sema.errMsg(7508 const msg = try sema.errMsg(
7550 func_src,7509 func_src,
...@@ -7553,8 +7512,8 @@ fn analyzeCall(...@@ -7553,8 +7512,8 @@ fn analyzeCall(
7553 );7512 );
7554 errdefer msg.destroy(sema.gpa);7513 errdefer msg.destroy(sema.gpa);
75557514
7556 if (maybe_decl) |fn_decl| try sema.errNote(.{7515 if (maybe_func_inst) |func_inst| try sema.errNote(.{
7557 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,7516 .base_node_inst = func_inst,
7558 .offset = LazySrcLoc.Offset.nodeOffset(0),7517 .offset = LazySrcLoc.Offset.nodeOffset(0),
7559 }, msg, "function declared here", .{});7518 }, msg, "function declared here", .{});
7560 break :msg msg;7519 break :msg msg;
...@@ -7654,33 +7613,32 @@ fn analyzeCall(...@@ -7654,33 +7613,32 @@ fn analyzeCall(
7654 .block_comptime_reason = comptime_reason,7613 .block_comptime_reason = comptime_reason,
7655 });7614 });
7656 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {7615 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", .{
7658 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7617 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7659 }),7618 }),
7660 .func => func_val.toIntern(),7619 .func => func_val.toIntern(),
7661 .ptr => |ptr| blk: {7620 .ptr => |ptr| blk: {
7662 switch (ptr.base_addr) {7621 switch (ptr.base_addr) {
7663 .decl => |decl| if (ptr.byte_offset == 0) {7622 .nav => |nav_index| if (ptr.byte_offset == 0) {
7664 const func_val_ptr = mod.declPtr(decl).val.toIntern();7623 const nav = ip.getNav(nav_index);
7665 const intern_index = mod.intern_pool.indexToKey(func_val_ptr);7624 if (nav.isExtern(ip))
7666 if (intern_index == .extern_func or (intern_index == .variable and intern_index.variable.is_extern))
7667 return sema.fail(block, call_src, "{s} call of extern function pointer", .{7625 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",
7669 });7627 });
7670 break :blk func_val_ptr;7628 break :blk nav.status.resolved.val;
7671 },7629 },
7672 else => {},7630 else => {},
7673 }7631 }
7674 assert(callee_ty.isPtrAtRuntime(mod));7632 assert(callee_ty.isPtrAtRuntime(mod));
7675 return sema.fail(block, call_src, "{s} call of function pointer", .{7633 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",
7677 });7635 });
7678 },7636 },
7679 else => unreachable,7637 else => unreachable,
7680 };7638 };
7681 if (func_ty_info.is_var_args) {7639 if (func_ty_info.is_var_args) {
7682 return sema.fail(block, call_src, "{s} call of variadic function", .{7640 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",
7684 });7642 });
7685 }7643 }
76867644
...@@ -7712,7 +7670,12 @@ fn analyzeCall(...@@ -7712,7 +7670,12 @@ fn analyzeCall(
7712 };7670 };
77137671
7714 const module_fn = mod.funcInfo(module_fn_index);7672 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
7717 // We effectively want a child Sema here, but can't literally do that, because we need AIR7680 // We effectively want a child Sema here, but can't literally do that, because we need AIR
7718 // to be shared. InlineCallSema is a wrapper which handles this for us. While `ics` is in7681 // to be shared. InlineCallSema is a wrapper which handles this for us. While `ics` is in
...@@ -7720,7 +7683,7 @@ fn analyzeCall(...@@ -7720,7 +7683,7 @@ fn analyzeCall(
7720 // whenever performing an operation where the difference matters.7683 // whenever performing an operation where the difference matters.
7721 var ics = InlineCallSema.init(7684 var ics = InlineCallSema.init(
7722 sema,7685 sema,
7723 fn_owner_decl.getFileScope(mod).zir,7686 mod.cauFileScope(fn_cau_index).zir,
7724 module_fn_index,7687 module_fn_index,
7725 block.error_return_trace_index,7688 block.error_return_trace_index,
7726 );7689 );
...@@ -7729,7 +7692,8 @@ fn analyzeCall(...@@ -7729,7 +7692,8 @@ fn analyzeCall(
7729 var child_block: Block = .{7692 var child_block: Block = .{
7730 .parent = null,7693 .parent = null,
7731 .sema = sema,7694 .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,
7733 .instructions = .{},7697 .instructions = .{},
7734 .label = null,7698 .label = null,
7735 .inlining = &inlining,7699 .inlining = &inlining,
...@@ -7740,8 +7704,8 @@ fn analyzeCall(...@@ -7740,8 +7704,8 @@ fn analyzeCall(
7740 .runtime_cond = block.runtime_cond,7704 .runtime_cond = block.runtime_cond,
7741 .runtime_loop = block.runtime_loop,7705 .runtime_loop = block.runtime_loop,
7742 .runtime_index = block.runtime_index,7706 .runtime_index = block.runtime_index,
7743 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,7707 .src_base_inst = fn_cau.zir_index,
7744 .type_name_ctx = fn_owner_decl.name,7708 .type_name_ctx = fn_nav.fqn,
7745 };7709 };
77467710
7747 const merges = &child_block.inlining.?.merges;7711 const merges = &child_block.inlining.?.merges;
...@@ -7759,7 +7723,7 @@ fn analyzeCall(...@@ -7759,7 +7723,7 @@ fn analyzeCall(
7759 // comptime memory is mutated.7723 // comptime memory is mutated.
7760 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);7724 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)).?;
7763 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);7727 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);
7764 var new_fn_info: InternPool.GetFuncTypeKey = .{7728 var new_fn_info: InternPool.GetFuncTypeKey = .{
7765 .param_types = new_param_types,7729 .param_types = new_param_types,
...@@ -7809,9 +7773,6 @@ fn analyzeCall(...@@ -7809,9 +7773,6 @@ fn analyzeCall(
7809 _ = ics.callee();7773 _ = ics.callee();
78107774
7811 if (!inlining.has_comptime_args) {7775 if (!inlining.has_comptime_args) {
7812 if (module_fn.analysisUnordered(ip).state == .sema_failure)
7813 return error.AnalysisFail;
7814
7815 var block_it = block;7776 var block_it = block;
7816 while (block_it.inlining) |parent_inlining| {7777 while (block_it.inlining) |parent_inlining| {
7817 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {7778 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {
...@@ -7957,8 +7918,11 @@ fn analyzeCall(...@@ -7957,8 +7918,11 @@ fn analyzeCall(
79577918
7958 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);7919 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)) {7921 switch (sema.owner.unwrap()) {
7961 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);7922 .cau => {},
7923 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7924 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
7925 },
7962 }7926 }
79637927
7964 if (try sema.resolveValue(func)) |func_val| {7928 if (try sema.resolveValue(func)) |func_val| {
...@@ -7994,7 +7958,7 @@ fn analyzeCall(...@@ -7994,7 +7958,7 @@ fn analyzeCall(
7994 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {7958 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
7995 .func => break :skip_safety,7959 .func => break :skip_safety,
7996 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {7960 .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,
7998 else => {},7962 else => {},
7999 },7963 },
8000 else => {},7964 else => {},
...@@ -8018,18 +7982,18 @@ fn analyzeCall(...@@ -8018,18 +7982,18 @@ fn analyzeCall(
80187982
8019fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {7983fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
8020 const pt = sema.pt;7984 const pt = sema.pt;
8021 const mod = pt.zcu;7985 const zcu = pt.zcu;
8022 const target = mod.getTarget();7986 const target = zcu.getTarget();
8023 const backend = mod.comp.getZigBackend();7987 const backend = zcu.comp.getZigBackend();
8024 if (!target_util.supportsTailCall(target, backend)) {7988 if (!target_util.supportsTailCall(target, backend)) {
8025 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", .{7989 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", .{
8026 @tagName(backend), @tagName(target.cpu.arch),7990 @tagName(backend), @tagName(target.cpu.arch),
8027 });7991 });
8028 }7992 }
8029 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);7993 const owner_func_ty = Type.fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty);
8030 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {7994 if (owner_func_ty.toIntern() != func_ty.toIntern()) {
8031 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{7995 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),
8033 });7997 });
8034 }7998 }
8035 _ = try block.addUnOp(.ret, result);7999 _ = try block.addUnOp(.ret, result);
...@@ -8191,7 +8155,7 @@ fn instantiateGenericCall(...@@ -8191,7 +8155,7 @@ fn instantiateGenericCall(
8191 });8155 });
8192 const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {8156 const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {
8193 .func => func_val.toIntern(),8157 .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,
8195 else => unreachable,8159 else => unreachable,
8196 };8160 };
8197 const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func;8161 const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func;
...@@ -8207,10 +8171,10 @@ fn instantiateGenericCall(...@@ -8207,10 +8171,10 @@ fn instantiateGenericCall(
8207 // The actual monomorphization happens via adding `func_instance` to8171 // The actual monomorphization happens via adding `func_instance` to
8208 // `InternPool`.8172 // `InternPool`.
82098173
8210 const fn_owner_decl = zcu.declPtr(generic_owner_func.owner_decl);8174 // Since we are looking at the generic owner here, it has a `Cau`.
8211 const namespace_index = fn_owner_decl.src_namespace;8175 const fn_nav = ip.getNav(generic_owner_func.owner_nav);
8212 const namespace = zcu.namespacePtr(namespace_index);8176 const fn_cau = ip.getCau(fn_nav.analysis_owner.unwrap().?);
8213 const fn_zir = namespace.fileScope(zcu).zir;8177 const fn_zir = zcu.namespacePtr(fn_cau.namespace).fileScope(zcu).zir;
8214 const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip));8178 const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip));
82158179
8216 const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());8180 const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());
...@@ -8232,15 +8196,13 @@ fn instantiateGenericCall(...@@ -8232,15 +8196,13 @@ fn instantiateGenericCall(
8232 // We pass the generic callsite's owner decl here because whatever `Decl`8196 // We pass the generic callsite's owner decl here because whatever `Decl`
8233 // dependencies are chased at this point should be attached to the8197 // dependencies are chased at this point should be attached to the
8234 // callsite, not the `Decl` associated with the `func_instance`.8198 // callsite, not the `Decl` associated with the `func_instance`.
8235 .owner_decl = sema.owner_decl,8199 .owner = sema.owner,
8236 .owner_decl_index = sema.owner_decl_index,8200 .func_index = sema.func_index,
8237 .func_index = sema.owner_func_index,
8238 // This may not be known yet, since the calling convention could be generic, but there8201 // This may not be known yet, since the calling convention could be generic, but there
8239 // should be no illegal instructions encountered while creating the function anyway.8202 // should be no illegal instructions encountered while creating the function anyway.
8240 .func_is_naked = false,8203 .func_is_naked = false,
8241 .fn_ret_ty = Type.void,8204 .fn_ret_ty = Type.void,
8242 .fn_ret_ty_ies = null,8205 .fn_ret_ty_ies = null,
8243 .owner_func_index = .none,
8244 .comptime_args = comptime_args,8206 .comptime_args = comptime_args,
8245 .generic_owner = generic_owner,8207 .generic_owner = generic_owner,
8246 .generic_call_src = call_src,8208 .generic_call_src = call_src,
...@@ -8253,12 +8215,12 @@ fn instantiateGenericCall(...@@ -8253,12 +8215,12 @@ fn instantiateGenericCall(
8253 var child_block: Block = .{8215 var child_block: Block = .{
8254 .parent = null,8216 .parent = null,
8255 .sema = &child_sema,8217 .sema = &child_sema,
8256 .namespace = namespace_index,8218 .namespace = fn_cau.namespace,
8257 .instructions = .{},8219 .instructions = .{},
8258 .inlining = null,8220 .inlining = null,
8259 .is_comptime = true,8221 .is_comptime = true,
8260 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,8222 .src_base_inst = fn_cau.zir_index,
8261 .type_name_ctx = fn_owner_decl.name,8223 .type_name_ctx = fn_nav.fqn,
8262 };8224 };
8263 defer child_block.instructions.deinit(gpa);8225 defer child_block.instructions.deinit(gpa);
82648226
...@@ -8421,10 +8383,11 @@ fn instantiateGenericCall(...@@ -8421,10 +8383,11 @@ fn instantiateGenericCall(
84218383
8422 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);8384 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
84238385
8424 if (sema.owner_func_index != .none and8386 switch (sema.owner.unwrap()) {
8425 Type.fromInterned(func_ty_info.return_type).isError(zcu))8387 .cau => {},
8426 {8388 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
8427 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);8389 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
8390 },
8428 }8391 }
84298392
8430 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));8393 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));
...@@ -9366,10 +9329,11 @@ fn zirFunc(...@@ -9366,10 +9329,11 @@ fn zirFunc(
9366 inferred_error_set: bool,9329 inferred_error_set: bool,
9367) CompileError!Air.Inst.Ref {9330) CompileError!Air.Inst.Ref {
9368 const pt = sema.pt;9331 const pt = sema.pt;
9369 const mod = pt.zcu;9332 const zcu = pt.zcu;
9333 const ip = &zcu.intern_pool;
9370 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9334 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
9371 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);9335 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9372 const target = mod.getTarget();9336 const target = zcu.getTarget();
9373 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });9337 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
93749338
9375 var extra_index = extra.end;9339 var extra_index = extra.end;
...@@ -9410,11 +9374,17 @@ fn zirFunc(...@@ -9410,11 +9374,17 @@ fn zirFunc(
9410 // the callconv based on whether it is exported. Otherwise, the callconv defaults9374 // the callconv based on whether it is exported. Otherwise, the callconv defaults
9411 // to `.Unspecified`.9375 // to `.Unspecified`.
9412 const cc: std.builtin.CallingConvention = if (has_body) cc: {9376 const cc: std.builtin.CallingConvention = if (has_body) cc: {
9413 const fn_is_exported = if (sema.generic_owner != .none) exported: {9377 const func_decl_cau = if (sema.generic_owner != .none) cau: {
9414 const generic_owner_fn = mod.funcInfo(sema.generic_owner);9378 const generic_owner_fn = zcu.funcInfo(sema.generic_owner);
9415 const generic_owner_decl = mod.declPtr(generic_owner_fn.owner_decl);9379 // The generic owner definitely has a `Cau` for the corresponding function declaration.
9416 break :exported generic_owner_decl.is_exported;9380 const generic_owner_nav = ip.getNav(generic_owner_fn.owner_nav);
9417 } else sema.owner_decl.is_exported;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 };
9418 break :cc if (fn_is_exported) .C else .Unspecified;9388 break :cc if (fn_is_exported) .C else .Unspecified;
9419 } else .Unspecified;9389 } else .Unspecified;
94209390
...@@ -9613,10 +9583,10 @@ fn funcCommon(...@@ -9613,10 +9583,10 @@ fn funcCommon(
9613 is_noinline: bool,9583 is_noinline: bool,
9614) CompileError!Air.Inst.Ref {9584) CompileError!Air.Inst.Ref {
9615 const pt = sema.pt;9585 const pt = sema.pt;
9616 const mod = pt.zcu;9586 const zcu = pt.zcu;
9617 const gpa = sema.gpa;9587 const gpa = sema.gpa;
9618 const target = mod.getTarget();9588 const target = zcu.getTarget();
9619 const ip = &mod.intern_pool;9589 const ip = &zcu.intern_pool;
9620 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });9590 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
9621 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });9591 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
9622 const func_src = block.nodeOffset(src_node_offset);9592 const func_src = block.nodeOffset(src_node_offset);
...@@ -9664,8 +9634,8 @@ fn funcCommon(...@@ -9664,8 +9634,8 @@ fn funcCommon(
9664 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) {9634 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) {
9665 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});9635 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});
9666 }9636 }
9667 if (!param_ty.isValidParamType(mod)) {9637 if (!param_ty.isValidParamType(zcu)) {
9668 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";9638 const opaque_str = if (param_ty.zigTypeTag(zcu) == .Opaque) "opaque " else "";
9669 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{9639 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
9670 opaque_str, param_ty.fmt(pt),9640 opaque_str, param_ty.fmt(pt),
9671 });9641 });
...@@ -9699,7 +9669,7 @@ fn funcCommon(...@@ -9699,7 +9669,7 @@ fn funcCommon(
9699 return sema.failWithOwnedErrorMsg(block, msg);9669 return sema.failWithOwnedErrorMsg(block, msg);
9700 }9670 }
9701 if (is_source_decl and !this_generic and is_noalias and9671 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)))
9703 {9673 {
9704 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});9674 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
9705 }9675 }
...@@ -9707,7 +9677,7 @@ fn funcCommon(...@@ -9707,7 +9677,7 @@ fn funcCommon(
9707 .Interrupt => if (target.cpu.arch.isX86()) {9677 .Interrupt => if (target.cpu.arch.isX86()) {
9708 const err_code_size = target.ptrBitWidth();9678 const err_code_size = target.ptrBitWidth();
9709 switch (i) {9679 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", .{}),
9711 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}),9681 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}),
9712 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),9682 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),
9713 }9683 }
...@@ -9769,14 +9739,11 @@ fn funcCommon(...@@ -9769,14 +9739,11 @@ fn funcCommon(
9769 );9739 );
9770 }9740 }
97719741
9772 // extern_func and func_decl functions take ownership of `sema.owner_decl`.9742 const section_name: InternPool.OptionalNullTerminatedString = switch (section) {
9773 sema.owner_decl.@"linksection" = switch (section) {
9774 .generic => .none,9743 .generic => .none,
9775 .default => .none,9744 .default => .none,
9776 .explicit => |section_name| section_name.toOptional(),9745 .explicit => |name| name.toOptional(),
9777 };9746 };
9778 sema.owner_decl.alignment = alignment orelse .none;
9779 sema.owner_decl.@"addrspace" = address_space orelse .generic;
97809747
9781 if (inferred_error_set) {9748 if (inferred_error_set) {
9782 assert(!is_extern);9749 assert(!is_extern);
...@@ -9784,7 +9751,7 @@ fn funcCommon(...@@ -9784,7 +9751,7 @@ fn funcCommon(
9784 if (!ret_poison)9751 if (!ret_poison)
9785 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9752 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9786 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{9753 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9787 .owner_decl = sema.owner_decl_index,9754 .owner_nav = sema.getOwnerCauNav(),
97889755
9789 .param_types = param_types,9756 .param_types = param_types,
9790 .noalias_bits = noalias_bits,9757 .noalias_bits = noalias_bits,
...@@ -9804,6 +9771,13 @@ fn funcCommon(...@@ -9804,6 +9771,13 @@ fn funcCommon(
9804 .lbrace_column = @as(u16, @truncate(src_locs.columns)),9771 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9805 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),9772 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9806 });9773 });
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 });
9807 return finishFunc(9781 return finishFunc(
9808 sema,9782 sema,
9809 block,9783 block,
...@@ -9846,11 +9820,20 @@ fn funcCommon(...@@ -9846,11 +9820,20 @@ fn funcCommon(
9846 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{9820 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
9847 .node_offset_lib_name = src_node_offset,9821 .node_offset_lib_name = src_node_offset,
9848 }), lib_name);9822 }), lib_name);
9849 const func_index = try ip.getExternFunc(gpa, pt.tid, .{9823 const func_index = try pt.getExtern(.{
9824 .name = sema.getOwnerCauNavName(),
9850 .ty = func_ty,9825 .ty = func_ty,
9851 .decl = sema.owner_decl_index,9826 .lib_name = try ip.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls),
9852 .lib_name = try mod.intern_pool.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`
9853 });9834 });
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.
9854 return finishFunc(9837 return finishFunc(
9855 sema,9838 sema,
9856 block,9839 block,
...@@ -9872,7 +9855,7 @@ fn funcCommon(...@@ -9872,7 +9855,7 @@ fn funcCommon(
98729855
9873 if (has_body) {9856 if (has_body) {
9874 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{9857 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9875 .owner_decl = sema.owner_decl_index,9858 .owner_nav = sema.getOwnerCauNav(),
9876 .ty = func_ty,9859 .ty = func_ty,
9877 .cc = cc,9860 .cc = cc,
9878 .is_noinline = is_noinline,9861 .is_noinline = is_noinline,
...@@ -9882,6 +9865,13 @@ fn funcCommon(...@@ -9882,6 +9865,13 @@ fn funcCommon(
9882 .lbrace_column = @as(u16, @truncate(src_locs.columns)),9865 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9883 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),9866 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9884 });9867 });
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 });
9885 return finishFunc(9875 return finishFunc(
9886 sema,9876 sema,
9887 block,9877 block,
...@@ -11179,7 +11169,7 @@ const SwitchProngAnalysis = struct {...@@ -11179,7 +11169,7 @@ const SwitchProngAnalysis = struct {
11179 return block.addStructFieldVal(spa.operand, field_index, field_ty);11169 return block.addStructFieldVal(spa.operand, field_index, field_ty);
11180 }11170 }
11181 } else if (capture_byref) {11171 } else if (capture_byref) {
11182 return anonDeclRef(sema, item_val.toIntern());11172 return sema.uavRef(item_val.toIntern());
11183 } else {11173 } else {
11184 return inline_case_capture;11174 return inline_case_capture;
11185 }11175 }
...@@ -13946,10 +13936,9 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13946,10 +13936,9 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13946 } });13936 } });
13947 }13937 }
1394813938
13949 const namespace = container_type.getNamespaceIndex(mod);13939 const namespace = container_type.getNamespace(mod).unwrap() orelse return .bool_false;
13950 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl_index| {13940 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
13951 const decl = mod.declPtr(decl_index);13941 if (lookup.accessible) {
13952 if (decl.is_pub or decl.getFileScope(mod) == block.getFileScope(mod)) {
13953 return .bool_true;13942 return .bool_true;
13954 }13943 }
13955 }13944 }
...@@ -13981,9 +13970,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13981,9 +13970,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13981 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });13970 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
13982 },13971 },
13983 };13972 };
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.
13984 try pt.ensureFileAnalyzed(result.file_index);13976 try pt.ensureFileAnalyzed(result.file_index);
13985 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;13977 return Air.internedToRef(zcu.fileRootType(result.file_index));
13986 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);
13987}13978}
1398813979
13989fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13980fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -16970,7 +16961,7 @@ fn analyzeArithmetic(...@@ -16970,7 +16961,7 @@ fn analyzeArithmetic(
16970 if (block.wantSafety() and want_safety and scalar_tag == .Int) {16961 if (block.wantSafety() and want_safety and scalar_tag == .Int) {
16971 if (mod.backendSupportsFeature(.safety_checked_instructions)) {16962 if (mod.backendSupportsFeature(.safety_checked_instructions)) {
16972 if (air_tag != air_tag_safe) {16963 if (air_tag != air_tag_safe) {
16973 _ = try sema.preparePanicId(block, .integer_overflow);16964 _ = try sema.preparePanicId(block, src, .integer_overflow);
16974 }16965 }
16975 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);16966 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
16976 } else {16967 } else {
...@@ -17158,13 +17149,11 @@ fn zirAsm(...@@ -17158,13 +17149,11 @@ fn zirAsm(
17158 if (is_volatile) {17149 if (is_volatile) {
17159 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});17150 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});
17160 }17151 }
17161 try mod.addGlobalAssembly(sema.owner_decl_index, asm_source);17152 try mod.addGlobalAssembly(sema.owner.unwrap().cau, asm_source);
17162 return .void_value;17153 return .void_value;
17163 }17154 }
1716417155
17165 if (block.is_comptime) {17156 try sema.requireRuntimeBlock(block, src, null);
17166 try sema.requireRuntimeBlock(block, src, null);
17167 }
1716817157
17169 var extra_i = extra.end;17158 var extra_i = extra.end;
17170 var output_type_bits = extra.data.output_type_bits;17159 var output_type_bits = extra.data.output_type_bits;
...@@ -17646,18 +17635,17 @@ fn zirThis(...@@ -17646,18 +17635,17 @@ fn zirThis(
17646 block: *Block,17635 block: *Block,
17647 extended: Zir.Inst.Extended.InstData,17636 extended: Zir.Inst.Extended.InstData,
17648) CompileError!Air.Inst.Ref {17637) CompileError!Air.Inst.Ref {
17638 _ = extended;
17649 const pt = sema.pt;17639 const pt = sema.pt;
17650 const mod = pt.zcu;17640 const namespace = pt.zcu.namespacePtr(block.namespace);
17651 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;17641 return Air.internedToRef(namespace.owner_type);
17652 const src = block.nodeOffset(@bitCast(extended.operand));
17653 return sema.analyzeDeclVal(block, src, this_decl_index);
17654}17642}
1765517643
17656fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17644fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
17657 const pt = sema.pt;17645 const pt = sema.pt;
17658 const mod = pt.zcu;17646 const mod = pt.zcu;
17659 const ip = &mod.intern_pool;17647 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
17662 const src_node: i32 = @bitCast(extended.operand);17650 const src_node: i32 = @bitCast(extended.operand);
17663 const src = block.nodeOffset(src_node);17651 const src = block.nodeOffset(src_node);
...@@ -17665,8 +17653,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -17665,8 +17653,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
17665 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {17653 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {
17666 .@"comptime" => |index| return Air.internedToRef(index),17654 .@"comptime" => |index| return Air.internedToRef(index),
17667 .runtime => |index| index,17655 .runtime => |index| index,
17668 .decl_val => |decl_index| return sema.analyzeDeclVal(block, src, decl_index),17656 .nav_val => |nav| return sema.analyzeNavVal(block, src, nav),
17669 .decl_ref => |decl_index| return sema.analyzeDeclRef(src, decl_index),17657 .nav_ref => |nav| return sema.analyzeNavRef(src, nav),
17670 };17658 };
1767117659
17672 // The comptime case is handled already above. Runtime case below.17660 // The comptime case is handled already above. Runtime case below.
...@@ -17764,20 +17752,19 @@ fn zirBuiltinSrc(...@@ -17764,20 +17752,19 @@ fn zirBuiltinSrc(
17764 block: *Block,17752 block: *Block,
17765 extended: Zir.Inst.Extended.InstData,17753 extended: Zir.Inst.Extended.InstData,
17766) CompileError!Air.Inst.Ref {17754) CompileError!Air.Inst.Ref {
17767 _ = block;
17768 const tracy = trace(@src());17755 const tracy = trace(@src());
17769 defer tracy.end();17756 defer tracy.end();
1777017757
17771 const pt = sema.pt;17758 const pt = sema.pt;
17772 const zcu = pt.zcu;17759 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);
17775 const ip = &zcu.intern_pool;17760 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;
17776 const gpa = sema.gpa;17763 const gpa = sema.gpa;
17777 const file_scope = fn_owner_decl.getFileScope(zcu);17764 const file_scope = block.getFileScope(zcu);
1777817765
17779 const func_name_val = v: {17766 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);
17781 const array_ty = try pt.intern(.{ .array_type = .{17768 const array_ty = try pt.intern(.{ .array_type = .{
17782 .len = func_name_len,17769 .len = func_name_len,
17783 .sentinel = .zero_u8,17770 .sentinel = .zero_u8,
...@@ -17787,11 +17774,11 @@ fn zirBuiltinSrc(...@@ -17787,11 +17774,11 @@ fn zirBuiltinSrc(
17787 .ty = .slice_const_u8_sentinel_0_type,17774 .ty = .slice_const_u8_sentinel_0_type,
17788 .ptr = try pt.intern(.{ .ptr = .{17775 .ptr = try pt.intern(.{ .ptr = .{
17789 .ty = .manyptr_const_u8_sentinel_0_type,17776 .ty = .manyptr_const_u8_sentinel_0_type,
17790 .base_addr = .{ .anon_decl = .{17777 .base_addr = .{ .uav = .{
17791 .orig_ty = .slice_const_u8_sentinel_0_type,17778 .orig_ty = .slice_const_u8_sentinel_0_type,
17792 .val = try pt.intern(.{ .aggregate = .{17779 .val = try pt.intern(.{ .aggregate = .{
17793 .ty = array_ty,17780 .ty = array_ty,
17794 .storage = .{ .bytes = fn_owner_decl.name.toString() },17781 .storage = .{ .bytes = fn_name.toString() },
17795 } }),17782 } }),
17796 } },17783 } },
17797 .byte_offset = 0,17784 .byte_offset = 0,
...@@ -17811,7 +17798,7 @@ fn zirBuiltinSrc(...@@ -17811,7 +17798,7 @@ fn zirBuiltinSrc(
17811 .ty = .slice_const_u8_sentinel_0_type,17798 .ty = .slice_const_u8_sentinel_0_type,
17812 .ptr = try pt.intern(.{ .ptr = .{17799 .ptr = try pt.intern(.{ .ptr = .{
17813 .ty = .manyptr_const_u8_sentinel_0_type,17800 .ty = .manyptr_const_u8_sentinel_0_type,
17814 .base_addr = .{ .anon_decl = .{17801 .base_addr = .{ .uav = .{
17815 .orig_ty = .slice_const_u8_sentinel_0_type,17802 .orig_ty = .slice_const_u8_sentinel_0_type,
17816 .val = try pt.intern(.{ .aggregate = .{17803 .val = try pt.intern(.{ .aggregate = .{
17817 .ty = array_ty,17804 .ty = array_ty,
...@@ -17837,7 +17824,7 @@ fn zirBuiltinSrc(...@@ -17837,7 +17824,7 @@ fn zirBuiltinSrc(
17837 .ty = .slice_const_u8_sentinel_0_type,17824 .ty = .slice_const_u8_sentinel_0_type,
17838 .ptr = try pt.intern(.{ .ptr = .{17825 .ptr = try pt.intern(.{ .ptr = .{
17839 .ty = .manyptr_const_u8_sentinel_0_type,17826 .ty = .manyptr_const_u8_sentinel_0_type,
17840 .base_addr = .{ .anon_decl = .{17827 .base_addr = .{ .uav = .{
17841 .orig_ty = .slice_const_u8_sentinel_0_type,17828 .orig_ty = .slice_const_u8_sentinel_0_type,
17842 .val = try pt.intern(.{ .aggregate = .{17829 .val = try pt.intern(.{ .aggregate = .{
17843 .ty = array_ty,17830 .ty = array_ty,
...@@ -17902,25 +17889,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17902,25 +17889,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17902 .val = .void_value,17889 .val = .void_value,
17903 } }))),17890 } }))),
17904 .Fn => {17891 .Fn => {
17905 const fn_info_decl_index = (try sema.namespaceLookup(17892 const fn_info_nav = try sema.namespaceLookup(
17906 block,17893 block,
17907 src,17894 src,
17908 type_info_ty.getNamespaceIndex(mod),17895 type_info_ty.getNamespaceIndex(mod),
17909 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),17896 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),
17910 )).?;17897 ) orelse @panic("std.builtin.Type is corrupt");
17911 try sema.ensureDeclAnalyzed(fn_info_decl_index);17898 try sema.ensureNavResolved(src, fn_info_nav);
17912 const fn_info_decl = mod.declPtr(fn_info_decl_index);17899 const fn_info_ty = Type.fromInterned(ip.getNav(fn_info_nav).status.resolved.val);
17913 const fn_info_ty = fn_info_decl.val.toType();
1791417900
17915 const param_info_decl_index = (try sema.namespaceLookup(17901 const param_info_nav = try sema.namespaceLookup(
17916 block,17902 block,
17917 src,17903 src,
17918 fn_info_ty.getNamespaceIndex(mod),17904 fn_info_ty.getNamespaceIndex(mod),
17919 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),17905 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),
17920 )).?;17906 ) orelse @panic("std.builtin.Type is corrupt");
17921 try sema.ensureDeclAnalyzed(param_info_decl_index);17907 try sema.ensureNavResolved(src, param_info_nav);
17922 const param_info_decl = mod.declPtr(param_info_decl_index);17908 const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val);
17923 const param_info_ty = param_info_decl.val.toType();
1792417909
17925 const func_ty_info = mod.typeToFunc(ty).?;17910 const func_ty_info = mod.typeToFunc(ty).?;
17926 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);17911 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...@@ -17972,7 +17957,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17972 .ty = slice_ty,17957 .ty = slice_ty,
17973 .ptr = try pt.intern(.{ .ptr = .{17958 .ptr = try pt.intern(.{ .ptr = .{
17974 .ty = manyptr_ty,17959 .ty = manyptr_ty,
17975 .base_addr = .{ .anon_decl = .{17960 .base_addr = .{ .uav = .{
17976 .orig_ty = manyptr_ty,17961 .orig_ty = manyptr_ty,
17977 .val = new_decl_val,17962 .val = new_decl_val,
17978 } },17963 } },
...@@ -18014,15 +17999,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18014,15 +17999,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18014 } })));17999 } })));
18015 },18000 },
18016 .Int => {18001 .Int => {
18017 const int_info_decl_index = (try sema.namespaceLookup(18002 const int_info_nav = try sema.namespaceLookup(
18018 block,18003 block,
18019 src,18004 src,
18020 type_info_ty.getNamespaceIndex(mod),18005 type_info_ty.getNamespaceIndex(mod),
18021 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),18006 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),
18022 )).?;18007 ) orelse @panic("std.builtin.Type is corrupt");
18023 try sema.ensureDeclAnalyzed(int_info_decl_index);18008 try sema.ensureNavResolved(src, int_info_nav);
18024 const int_info_decl = mod.declPtr(int_info_decl_index);18009 const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val);
18025 const int_info_ty = int_info_decl.val.toType();
1802618010
18027 const signedness_ty = try pt.getBuiltinType("Signedness");18011 const signedness_ty = try pt.getBuiltinType("Signedness");
18028 const info = ty.intInfo(mod);18012 const info = ty.intInfo(mod);
...@@ -18042,15 +18026,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18042,15 +18026,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18042 } })));18026 } })));
18043 },18027 },
18044 .Float => {18028 .Float => {
18045 const float_info_decl_index = (try sema.namespaceLookup(18029 const float_info_nav = try sema.namespaceLookup(
18046 block,18030 block,
18047 src,18031 src,
18048 type_info_ty.getNamespaceIndex(mod),18032 type_info_ty.getNamespaceIndex(mod),
18049 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),18033 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),
18050 )).?;18034 ) orelse @panic("std.builtin.Type is corrupt");
18051 try sema.ensureDeclAnalyzed(float_info_decl_index);18035 try sema.ensureNavResolved(src, float_info_nav);
18052 const float_info_decl = mod.declPtr(float_info_decl_index);18036 const float_info_ty = Type.fromInterned(ip.getNav(float_info_nav).status.resolved.val);
18053 const float_info_ty = float_info_decl.val.toType();
1805418037
18055 const field_vals = .{18038 const field_vals = .{
18056 // bits: u16,18039 // bits: u16,
...@@ -18074,26 +18057,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18074,26 +18057,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1807418057
18075 const addrspace_ty = try pt.getBuiltinType("AddressSpace");18058 const addrspace_ty = try pt.getBuiltinType("AddressSpace");
18076 const pointer_ty = t: {18059 const pointer_ty = t: {
18077 const decl_index = (try sema.namespaceLookup(18060 const nav = try sema.namespaceLookup(
18078 block,18061 block,
18079 src,18062 src,
18080 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),18063 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18081 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),18064 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),
18082 )).?;18065 ) orelse @panic("std.builtin.Type is corrupt");
18083 try sema.ensureDeclAnalyzed(decl_index);18066 try sema.ensureNavResolved(src, nav);
18084 const decl = mod.declPtr(decl_index);18067 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18085 break :t decl.val.toType();
18086 };18068 };
18087 const ptr_size_ty = t: {18069 const ptr_size_ty = t: {
18088 const decl_index = (try sema.namespaceLookup(18070 const nav = try sema.namespaceLookup(
18089 block,18071 block,
18090 src,18072 src,
18091 pointer_ty.getNamespaceIndex(mod),18073 pointer_ty.getNamespaceIndex(mod),
18092 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),18074 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),
18093 )).?;18075 ) orelse @panic("std.builtin.Type is corrupt");
18094 try sema.ensureDeclAnalyzed(decl_index);18076 try sema.ensureNavResolved(src, nav);
18095 const decl = mod.declPtr(decl_index);18077 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18096 break :t decl.val.toType();
18097 };18078 };
1809818079
18099 const field_values = .{18080 const field_values = .{
...@@ -18128,15 +18109,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18128,15 +18109,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18128 },18109 },
18129 .Array => {18110 .Array => {
18130 const array_field_ty = t: {18111 const array_field_ty = t: {
18131 const array_field_ty_decl_index = (try sema.namespaceLookup(18112 const nav = try sema.namespaceLookup(
18132 block,18113 block,
18133 src,18114 src,
18134 type_info_ty.getNamespaceIndex(mod),18115 type_info_ty.getNamespaceIndex(mod),
18135 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),18116 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),
18136 )).?;18117 ) orelse @panic("std.builtin.Type is corrupt");
18137 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);18118 try sema.ensureNavResolved(src, nav);
18138 const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index);18119 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18139 break :t array_field_ty_decl.val.toType();
18140 };18120 };
1814118121
18142 const info = ty.arrayInfo(mod);18122 const info = ty.arrayInfo(mod);
...@@ -18159,15 +18139,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18159,15 +18139,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18159 },18139 },
18160 .Vector => {18140 .Vector => {
18161 const vector_field_ty = t: {18141 const vector_field_ty = t: {
18162 const vector_field_ty_decl_index = (try sema.namespaceLookup(18142 const nav = try sema.namespaceLookup(
18163 block,18143 block,
18164 src,18144 src,
18165 type_info_ty.getNamespaceIndex(mod),18145 type_info_ty.getNamespaceIndex(mod),
18166 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),18146 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),
18167 )).?;18147 ) orelse @panic("std.builtin.Type is corrupt");
18168 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);18148 try sema.ensureNavResolved(src, nav);
18169 const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index);18149 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18170 break :t vector_field_ty_decl.val.toType();
18171 };18150 };
1817218151
18173 const info = ty.arrayInfo(mod);18152 const info = ty.arrayInfo(mod);
...@@ -18188,15 +18167,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18188,15 +18167,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18188 },18167 },
18189 .Optional => {18168 .Optional => {
18190 const optional_field_ty = t: {18169 const optional_field_ty = t: {
18191 const optional_field_ty_decl_index = (try sema.namespaceLookup(18170 const nav = try sema.namespaceLookup(
18192 block,18171 block,
18193 src,18172 src,
18194 type_info_ty.getNamespaceIndex(mod),18173 type_info_ty.getNamespaceIndex(mod),
18195 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),18174 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),
18196 )).?;18175 ) orelse @panic("std.builtin.Type is corrupt");
18197 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);18176 try sema.ensureNavResolved(src, nav);
18198 const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index);18177 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18199 break :t optional_field_ty_decl.val.toType();
18200 };18178 };
1820118179
18202 const field_values = .{18180 const field_values = .{
...@@ -18215,15 +18193,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18215,15 +18193,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18215 .ErrorSet => {18193 .ErrorSet => {
18216 // Get the Error type18194 // Get the Error type
18217 const error_field_ty = t: {18195 const error_field_ty = t: {
18218 const set_field_ty_decl_index = (try sema.namespaceLookup(18196 const nav = try sema.namespaceLookup(
18219 block,18197 block,
18220 src,18198 src,
18221 type_info_ty.getNamespaceIndex(mod),18199 type_info_ty.getNamespaceIndex(mod),
18222 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),18200 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),
18223 )).?;18201 ) orelse @panic("std.builtin.Type is corrupt");
18224 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);18202 try sema.ensureNavResolved(src, nav);
18225 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);18203 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18226 break :t set_field_ty_decl.val.toType();
18227 };18204 };
1822818205
18229 // Build our list of Error values18206 // Build our list of Error values
...@@ -18251,7 +18228,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18251,7 +18228,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18251 .ty = .slice_const_u8_sentinel_0_type,18228 .ty = .slice_const_u8_sentinel_0_type,
18252 .ptr = try pt.intern(.{ .ptr = .{18229 .ptr = try pt.intern(.{ .ptr = .{
18253 .ty = .manyptr_const_u8_sentinel_0_type,18230 .ty = .manyptr_const_u8_sentinel_0_type,
18254 .base_addr = .{ .anon_decl = .{18231 .base_addr = .{ .uav = .{
18255 .val = new_decl_val,18232 .val = new_decl_val,
18256 .orig_ty = .slice_const_u8_sentinel_0_type,18233 .orig_ty = .slice_const_u8_sentinel_0_type,
18257 } },18234 } },
...@@ -18298,7 +18275,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18298,7 +18275,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18298 .ty = slice_errors_ty.toIntern(),18275 .ty = slice_errors_ty.toIntern(),
18299 .ptr = try pt.intern(.{ .ptr = .{18276 .ptr = try pt.intern(.{ .ptr = .{
18300 .ty = manyptr_errors_ty,18277 .ty = manyptr_errors_ty,
18301 .base_addr = .{ .anon_decl = .{18278 .base_addr = .{ .uav = .{
18302 .orig_ty = manyptr_errors_ty,18279 .orig_ty = manyptr_errors_ty,
18303 .val = new_decl_val,18280 .val = new_decl_val,
18304 } },18281 } },
...@@ -18321,15 +18298,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18321,15 +18298,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18321 },18298 },
18322 .ErrorUnion => {18299 .ErrorUnion => {
18323 const error_union_field_ty = t: {18300 const error_union_field_ty = t: {
18324 const error_union_field_ty_decl_index = (try sema.namespaceLookup(18301 const nav = try sema.namespaceLookup(
18325 block,18302 block,
18326 src,18303 src,
18327 type_info_ty.getNamespaceIndex(mod),18304 type_info_ty.getNamespaceIndex(mod),
18328 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),18305 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),
18329 )).?;18306 ) orelse @panic("std.builtin.Type is corrupt");
18330 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);18307 try sema.ensureNavResolved(src, nav);
18331 const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index);18308 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18332 break :t error_union_field_ty_decl.val.toType();
18333 };18309 };
1833418310
18335 const field_values = .{18311 const field_values = .{
...@@ -18351,15 +18327,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18351,15 +18327,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18351 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);18327 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1835218328
18353 const enum_field_ty = t: {18329 const enum_field_ty = t: {
18354 const enum_field_ty_decl_index = (try sema.namespaceLookup(18330 const nav = try sema.namespaceLookup(
18355 block,18331 block,
18356 src,18332 src,
18357 type_info_ty.getNamespaceIndex(mod),18333 type_info_ty.getNamespaceIndex(mod),
18358 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),18334 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),
18359 )).?;18335 ) orelse @panic("std.builtin.Type is corrupt");
18360 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);18336 try sema.ensureNavResolved(src, nav);
18361 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);18337 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18362 break :t enum_field_ty_decl.val.toType();
18363 };18338 };
1836418339
18365 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);18340 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...@@ -18392,7 +18367,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18392 .ty = .slice_const_u8_sentinel_0_type,18367 .ty = .slice_const_u8_sentinel_0_type,
18393 .ptr = try pt.intern(.{ .ptr = .{18368 .ptr = try pt.intern(.{ .ptr = .{
18394 .ty = .manyptr_const_u8_sentinel_0_type,18369 .ty = .manyptr_const_u8_sentinel_0_type,
18395 .base_addr = .{ .anon_decl = .{18370 .base_addr = .{ .uav = .{
18396 .val = new_decl_val,18371 .val = new_decl_val,
18397 .orig_ty = .slice_const_u8_sentinel_0_type,18372 .orig_ty = .slice_const_u8_sentinel_0_type,
18398 } },18373 } },
...@@ -18435,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18435,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18435 .ty = slice_ty,18410 .ty = slice_ty,
18436 .ptr = try pt.intern(.{ .ptr = .{18411 .ptr = try pt.intern(.{ .ptr = .{
18437 .ty = manyptr_ty,18412 .ty = manyptr_ty,
18438 .base_addr = .{ .anon_decl = .{18413 .base_addr = .{ .uav = .{
18439 .val = new_decl_val,18414 .val = new_decl_val,
18440 .orig_ty = manyptr_ty,18415 .orig_ty = manyptr_ty,
18441 } },18416 } },
...@@ -18445,18 +18420,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18445,18 +18420,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18445 } });18420 } });
18446 };18421 };
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
18450 const type_enum_ty = t: {18425 const type_enum_ty = t: {
18451 const type_enum_ty_decl_index = (try sema.namespaceLookup(18426 const nav = try sema.namespaceLookup(
18452 block,18427 block,
18453 src,18428 src,
18454 type_info_ty.getNamespaceIndex(mod),18429 type_info_ty.getNamespaceIndex(mod),
18455 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),18430 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),
18456 )).?;18431 ) orelse @panic("std.builtin.Type is corrupt");
18457 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);18432 try sema.ensureNavResolved(src, nav);
18458 const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index);18433 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18459 break :t type_enum_ty_decl.val.toType();
18460 };18434 };
1846118435
18462 const field_values = .{18436 const field_values = .{
...@@ -18480,27 +18454,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18480,27 +18454,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18480 },18454 },
18481 .Union => {18455 .Union => {
18482 const type_union_ty = t: {18456 const type_union_ty = t: {
18483 const type_union_ty_decl_index = (try sema.namespaceLookup(18457 const nav = try sema.namespaceLookup(
18484 block,18458 block,
18485 src,18459 src,
18486 type_info_ty.getNamespaceIndex(mod),18460 type_info_ty.getNamespaceIndex(mod),
18487 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),18461 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),
18488 )).?;18462 ) orelse @panic("std.builtin.Type is corrupt");
18489 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);18463 try sema.ensureNavResolved(src, nav);
18490 const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index);18464 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18491 break :t type_union_ty_decl.val.toType();
18492 };18465 };
1849318466
18494 const union_field_ty = t: {18467 const union_field_ty = t: {
18495 const union_field_ty_decl_index = (try sema.namespaceLookup(18468 const nav = try sema.namespaceLookup(
18496 block,18469 block,
18497 src,18470 src,
18498 type_info_ty.getNamespaceIndex(mod),18471 type_info_ty.getNamespaceIndex(mod),
18499 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),18472 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),
18500 )).?;18473 ) orelse @panic("std.builtin.Type is corrupt");
18501 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);18474 try sema.ensureNavResolved(src, nav);
18502 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);18475 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18503 break :t union_field_ty_decl.val.toType();
18504 };18476 };
1850518477
18506 try ty.resolveLayout(pt); // Getting alignment requires type layout18478 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...@@ -18528,7 +18500,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18528 .ty = .slice_const_u8_sentinel_0_type,18500 .ty = .slice_const_u8_sentinel_0_type,
18529 .ptr = try pt.intern(.{ .ptr = .{18501 .ptr = try pt.intern(.{ .ptr = .{
18530 .ty = .manyptr_const_u8_sentinel_0_type,18502 .ty = .manyptr_const_u8_sentinel_0_type,
18531 .base_addr = .{ .anon_decl = .{18503 .base_addr = .{ .uav = .{
18532 .val = new_decl_val,18504 .val = new_decl_val,
18533 .orig_ty = .slice_const_u8_sentinel_0_type,18505 .orig_ty = .slice_const_u8_sentinel_0_type,
18534 } },18506 } },
...@@ -18579,7 +18551,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18579,7 +18551,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18579 .ty = slice_ty,18551 .ty = slice_ty,
18580 .ptr = try pt.intern(.{ .ptr = .{18552 .ptr = try pt.intern(.{ .ptr = .{
18581 .ty = manyptr_ty,18553 .ty = manyptr_ty,
18582 .base_addr = .{ .anon_decl = .{18554 .base_addr = .{ .uav = .{
18583 .orig_ty = manyptr_ty,18555 .orig_ty = manyptr_ty,
18584 .val = new_decl_val,18556 .val = new_decl_val,
18585 } },18557 } },
...@@ -18589,7 +18561,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18589,7 +18561,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18589 } });18561 } });
18590 };18562 };
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
18594 const enum_tag_ty_val = try pt.intern(.{ .opt = .{18566 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
18595 .ty = (try pt.optionalType(.type_type)).toIntern(),18567 .ty = (try pt.optionalType(.type_type)).toIntern(),
...@@ -18597,15 +18569,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18597,15 +18569,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18597 } });18569 } });
1859818570
18599 const container_layout_ty = t: {18571 const container_layout_ty = t: {
18600 const decl_index = (try sema.namespaceLookup(18572 const nav = try sema.namespaceLookup(
18601 block,18573 block,
18602 src,18574 src,
18603 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),18575 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18604 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),18576 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18605 )).?;18577 ) orelse @panic("std.builtin.Type is corrupt");
18606 try sema.ensureDeclAnalyzed(decl_index);18578 try sema.ensureNavResolved(src, nav);
18607 const decl = mod.declPtr(decl_index);18579 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18608 break :t decl.val.toType();
18609 };18580 };
1861018581
18611 const field_values = .{18582 const field_values = .{
...@@ -18630,27 +18601,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18630,27 +18601,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18630 },18601 },
18631 .Struct => {18602 .Struct => {
18632 const type_struct_ty = t: {18603 const type_struct_ty = t: {
18633 const type_struct_ty_decl_index = (try sema.namespaceLookup(18604 const nav = try sema.namespaceLookup(
18634 block,18605 block,
18635 src,18606 src,
18636 type_info_ty.getNamespaceIndex(mod),18607 type_info_ty.getNamespaceIndex(mod),
18637 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),18608 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),
18638 )).?;18609 ) orelse @panic("std.builtin.Type is corrupt");
18639 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);18610 try sema.ensureNavResolved(src, nav);
18640 const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index);18611 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18641 break :t type_struct_ty_decl.val.toType();
18642 };18612 };
1864318613
18644 const struct_field_ty = t: {18614 const struct_field_ty = t: {
18645 const struct_field_ty_decl_index = (try sema.namespaceLookup(18615 const nav = try sema.namespaceLookup(
18646 block,18616 block,
18647 src,18617 src,
18648 type_info_ty.getNamespaceIndex(mod),18618 type_info_ty.getNamespaceIndex(mod),
18649 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),18619 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),
18650 )).?;18620 ) orelse @panic("std.builtin.Type is corrupt");
18651 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);18621 try sema.ensureNavResolved(src, nav);
18652 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);18622 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18653 break :t struct_field_ty_decl.val.toType();
18654 };18623 };
1865518624
18656 try ty.resolveLayout(pt); // Getting alignment requires type layout18625 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...@@ -18683,7 +18652,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18683 .ty = .slice_const_u8_sentinel_0_type,18652 .ty = .slice_const_u8_sentinel_0_type,
18684 .ptr = try pt.intern(.{ .ptr = .{18653 .ptr = try pt.intern(.{ .ptr = .{
18685 .ty = .manyptr_const_u8_sentinel_0_type,18654 .ty = .manyptr_const_u8_sentinel_0_type,
18686 .base_addr = .{ .anon_decl = .{18655 .base_addr = .{ .uav = .{
18687 .val = new_decl_val,18656 .val = new_decl_val,
18688 .orig_ty = .slice_const_u8_sentinel_0_type,18657 .orig_ty = .slice_const_u8_sentinel_0_type,
18689 } },18658 } },
...@@ -18747,7 +18716,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18747,7 +18716,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18747 .ty = .slice_const_u8_sentinel_0_type,18716 .ty = .slice_const_u8_sentinel_0_type,
18748 .ptr = try pt.intern(.{ .ptr = .{18717 .ptr = try pt.intern(.{ .ptr = .{
18749 .ty = .manyptr_const_u8_sentinel_0_type,18718 .ty = .manyptr_const_u8_sentinel_0_type,
18750 .base_addr = .{ .anon_decl = .{18719 .base_addr = .{ .uav = .{
18751 .val = new_decl_val,18720 .val = new_decl_val,
18752 .orig_ty = .slice_const_u8_sentinel_0_type,18721 .orig_ty = .slice_const_u8_sentinel_0_type,
18753 } },18722 } },
...@@ -18809,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18809,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18809 .ty = slice_ty,18778 .ty = slice_ty,
18810 .ptr = try pt.intern(.{ .ptr = .{18779 .ptr = try pt.intern(.{ .ptr = .{
18811 .ty = manyptr_ty,18780 .ty = manyptr_ty,
18812 .base_addr = .{ .anon_decl = .{18781 .base_addr = .{ .uav = .{
18813 .orig_ty = manyptr_ty,18782 .orig_ty = manyptr_ty,
18814 .val = new_decl_val,18783 .val = new_decl_val,
18815 } },18784 } },
...@@ -18819,7 +18788,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18819,7 +18788,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18819 } });18788 } });
18820 };18789 };
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
18824 const backing_integer_val = try pt.intern(.{ .opt = .{18793 const backing_integer_val = try pt.intern(.{ .opt = .{
18825 .ty = (try pt.optionalType(.type_type)).toIntern(),18794 .ty = (try pt.optionalType(.type_type)).toIntern(),
...@@ -18830,15 +18799,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18830,15 +18799,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18830 } });18799 } });
1883118800
18832 const container_layout_ty = t: {18801 const container_layout_ty = t: {
18833 const decl_index = (try sema.namespaceLookup(18802 const nav = try sema.namespaceLookup(
18834 block,18803 block,
18835 src,18804 src,
18836 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),18805 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18837 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),18806 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18838 )).?;18807 ) orelse @panic("std.builtin.Type is corrupt");
18839 try sema.ensureDeclAnalyzed(decl_index);18808 try sema.ensureNavResolved(src, nav);
18840 const decl = mod.declPtr(decl_index);18809 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18841 break :t decl.val.toType();
18842 };18810 };
1884318811
18844 const layout = ty.containerLayout(mod);18812 const layout = ty.containerLayout(mod);
...@@ -18866,19 +18834,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18866,19 +18834,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18866 },18834 },
18867 .Opaque => {18835 .Opaque => {
18868 const type_opaque_ty = t: {18836 const type_opaque_ty = t: {
18869 const type_opaque_ty_decl_index = (try sema.namespaceLookup(18837 const nav = try sema.namespaceLookup(
18870 block,18838 block,
18871 src,18839 src,
18872 type_info_ty.getNamespaceIndex(mod),18840 type_info_ty.getNamespaceIndex(mod),
18873 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),18841 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),
18874 )).?;18842 ) orelse @panic("std.builtin.Type is corrupt");
18875 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);18843 try sema.ensureNavResolved(src, nav);
18876 const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index);18844 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18877 break :t type_opaque_ty_decl.val.toType();
18878 };18845 };
1887918846
18880 try ty.resolveFields(pt);18847 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
18883 const field_values = .{18850 const field_values = .{
18884 // decls: []const Declaration,18851 // decls: []const Declaration,
...@@ -18906,19 +18873,19 @@ fn typeInfoDecls(...@@ -18906,19 +18873,19 @@ fn typeInfoDecls(
18906 opt_namespace: InternPool.OptionalNamespaceIndex,18873 opt_namespace: InternPool.OptionalNamespaceIndex,
18907) CompileError!InternPool.Index {18874) CompileError!InternPool.Index {
18908 const pt = sema.pt;18875 const pt = sema.pt;
18909 const mod = pt.zcu;18876 const zcu = pt.zcu;
18877 const ip = &zcu.intern_pool;
18910 const gpa = sema.gpa;18878 const gpa = sema.gpa;
1891118879
18912 const declaration_ty = t: {18880 const declaration_ty = t: {
18913 const declaration_ty_decl_index = (try sema.namespaceLookup(18881 const nav = try sema.namespaceLookup(
18914 block,18882 block,
18915 src,18883 src,
18916 type_info_ty.getNamespaceIndex(mod),18884 type_info_ty.getNamespaceIndex(zcu),
18917 try mod.intern_pool.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),18885 try ip.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
18918 )).?;18886 ) orelse @panic("std.builtin.Type is corrupt");
18919 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);18887 try sema.ensureNavResolved(src, nav);
18920 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);18888 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18921 break :t declaration_ty_decl.val.toType();
18922 };18889 };
1892318890
18924 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);18891 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
...@@ -18927,7 +18894,7 @@ fn typeInfoDecls(...@@ -18927,7 +18894,7 @@ fn typeInfoDecls(
18927 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);18894 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
18928 defer seen_namespaces.deinit();18895 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
18932 const array_decl_ty = try pt.arrayType(.{18899 const array_decl_ty = try pt.arrayType(.{
18933 .len = decl_vals.items.len,18900 .len = decl_vals.items.len,
...@@ -18944,12 +18911,12 @@ fn typeInfoDecls(...@@ -18944,12 +18911,12 @@ fn typeInfoDecls(
18944 .is_const = true,18911 .is_const = true,
18945 },18912 },
18946 })).toIntern();18913 })).toIntern();
18947 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18914 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern();
18948 return try pt.intern(.{ .slice = .{18915 return try pt.intern(.{ .slice = .{
18949 .ty = slice_ty,18916 .ty = slice_ty,
18950 .ptr = try pt.intern(.{ .ptr = .{18917 .ptr = try pt.intern(.{ .ptr = .{
18951 .ty = manyptr_ty,18918 .ty = manyptr_ty,
18952 .base_addr = .{ .anon_decl = .{18919 .base_addr = .{ .uav = .{
18953 .orig_ty = manyptr_ty,18920 .orig_ty = manyptr_ty,
18954 .val = new_decl_val,18921 .val = new_decl_val,
18955 } },18922 } },
...@@ -18962,59 +18929,54 @@ fn typeInfoDecls(...@@ -18962,59 +18929,54 @@ fn typeInfoDecls(
18962fn typeInfoNamespaceDecls(18929fn typeInfoNamespaceDecls(
18963 sema: *Sema,18930 sema: *Sema,
18964 block: *Block,18931 block: *Block,
18932 src: LazySrcLoc,
18965 opt_namespace_index: InternPool.OptionalNamespaceIndex,18933 opt_namespace_index: InternPool.OptionalNamespaceIndex,
18966 declaration_ty: Type,18934 declaration_ty: Type,
18967 decl_vals: *std.ArrayList(InternPool.Index),18935 decl_vals: *std.ArrayList(InternPool.Index),
18968 seen_namespaces: *std.AutoHashMap(*Namespace, void),18936 seen_namespaces: *std.AutoHashMap(*Namespace, void),
18969) !void {18937) !void {
18970 const pt = sema.pt;18938 const pt = sema.pt;
18971 const mod = pt.zcu;18939 const zcu = pt.zcu;
18972 const ip = &mod.intern_pool;18940 const ip = &zcu.intern_pool;
1897318941
18974 const namespace_index = opt_namespace_index.unwrap() orelse return;18942 const namespace_index = opt_namespace_index.unwrap() orelse return;
18975 const namespace = mod.namespacePtr(namespace_index);18943 const namespace = zcu.namespacePtr(namespace_index);
1897618944
18977 const gop = try seen_namespaces.getOrPut(namespace);18945 const gop = try seen_namespaces.getOrPut(namespace);
18978 if (gop.found_existing) return;18946 if (gop.found_existing) return;
1897918947
18980 const decls = namespace.decls.keys();18948 for (namespace.pub_decls.keys()) |nav| {
18981 for (decls) |decl_index| {18949 const name = ip.getNav(nav).name;
18982 const decl = mod.declPtr(decl_index);18950 const name_val = name_val: {
18983 if (!decl.is_pub) continue;18951 const name_len = name.length(ip);
18984 if (decl.kind == .@"usingnamespace") {18952 const array_ty = try pt.arrayType(.{
18985 if (decl.analysis == .in_progress) continue;18953 .len = name_len,
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,
18995 .sentinel = .zero_u8,18954 .sentinel = .zero_u8,
18996 .child = .u8_type,18955 .child = .u8_type,
18997 });18956 });
18998 const new_decl_val = try pt.intern(.{ .aggregate = .{18957 const array_val = try pt.intern(.{ .aggregate = .{
18999 .ty = new_decl_ty.toIntern(),18958 .ty = array_ty.toIntern(),
19000 .storage = .{ .bytes = decl.name.toString() },18959 .storage = .{ .bytes = 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(),
19013 } });18960 } });
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 });
19014 };18977 };
1901518978 const fields = [_]InternPool.Index{
19016 const fields = .{18979 // name: [:0]const u8,
19017 //name: [:0]const u8,
19018 name_val,18980 name_val,
19019 };18981 };
19020 try decl_vals.append(try pt.intern(.{ .aggregate = .{18982 try decl_vals.append(try pt.intern(.{ .aggregate = .{
...@@ -19022,6 +18984,17 @@ fn typeInfoNamespaceDecls(...@@ -19022,6 +18984,17 @@ fn typeInfoNamespaceDecls(
19022 .storage = .{ .elems = &fields },18984 .storage = .{ .elems = &fields },
19023 } }));18985 } }));
19024 }18986 }
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 }
19025}18998}
1902618999
19027fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19000fn 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_...@@ -19906,7 +19879,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19906 return;19879 return;
19907 }19880 }
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;
19910 if (!start_block.ownerModule().error_tracing) return;19883 if (!start_block.ownerModule().error_tracing) return;
1991119884
19912 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere19885 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 {...@@ -19928,7 +19901,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
19928 },19901 },
19929 else => if (ip.isInferredErrorSetType(err_set_ty)) {19902 else => if (ip.isInferredErrorSetType(err_set_ty)) {
19930 const ies = sema.fn_ret_ty_ies.?;19903 const ies = sema.fn_ret_ty_ies.?;
19931 assert(ies.func == sema.func_index);19904 assert(ies.func == sema.owner.unwrap().func);
19932 try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand));19905 try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand));
19933 },19906 },
19934 }19907 }
...@@ -20232,7 +20205,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -20232,7 +20205,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
2023220205
20233 if (is_byref) {20206 if (is_byref) {
20234 const init_val = (try sema.resolveValue(init_ref)).?;20207 const init_val = (try sema.resolveValue(init_ref)).?;
20235 return anonDeclRef(sema, init_val.toIntern());20208 return sema.uavRef(init_val.toIntern());
20236 } else {20209 } else {
20237 return init_ref;20210 return init_ref;
20238 }20211 }
...@@ -21056,7 +21029,7 @@ fn arrayInitAnon(...@@ -21056,7 +21029,7 @@ fn arrayInitAnon(
21056}21029}
2105721030
21058fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {21031fn 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);
21060}21033}
2106121034
21062fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21035fn 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 {...@@ -21163,16 +21136,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21163 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);21136 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
21164 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());21137 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2116521138
21166 if (sema.owner_func_index != .none and21139 switch (sema.owner.unwrap()) {
21167 ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and21140 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
21168 block.ownerModule().error_tracing)21141 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21169 {21142 },
21170 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21143 .cau => {},
21171 }21144 }
21172 return Air.internedToRef((try pt.intern(.{ .opt = .{21145 return Air.internedToRef(try pt.intern(.{ .opt = .{
21173 .ty = opt_ptr_stack_trace_ty.toIntern(),21146 .ty = opt_ptr_stack_trace_ty.toIntern(),
21174 .val = .none,21147 .val = .none,
21175 } })));21148 } }));
21176}21149}
2117721150
21178fn zirFrame(21151fn zirFrame(
...@@ -21369,24 +21342,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21369,24 +21342,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21369 const operand = try sema.resolveInst(inst_data.operand);21342 const operand = try sema.resolveInst(inst_data.operand);
21370 const operand_ty = sema.typeOf(operand);21343 const operand_ty = sema.typeOf(operand);
21371 const pt = sema.pt;21344 const pt = sema.pt;
21372 const mod = pt.zcu;21345 const zcu = pt.zcu;
21373 const ip = &mod.intern_pool;21346 const ip = &zcu.intern_pool;
2137421347
21375 try operand_ty.resolveLayout(pt);21348 try operand_ty.resolveLayout(pt);
21376 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {21349 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
21377 .EnumLiteral => {21350 .EnumLiteral => {
21378 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);21351 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
21379 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;21352 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
21380 return sema.addNullTerminatedStrLit(tag_name);21353 return sema.addNullTerminatedStrLit(tag_name);
21381 },21354 },
21382 .Enum => operand_ty,21355 .Enum => operand_ty,
21383 .Union => operand_ty.unionTagType(mod) orelse21356 .Union => operand_ty.unionTagType(zcu) orelse
21384 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),21357 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),
21385 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{21358 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
21386 operand_ty.fmt(pt),21359 operand_ty.fmt(pt),
21387 }),21360 }),
21388 };21361 };
21389 if (enum_ty.enumFieldCount(mod) == 0) {21362 if (enum_ty.enumFieldCount(zcu) == 0) {
21390 // TODO I don't think this is the correct way to handle this but21363 // TODO I don't think this is the correct way to handle this but
21391 // it prevents a crash.21364 // it prevents a crash.
21392 // https://github.com/ziglang/zig/issues/1590921365 // https://github.com/ziglang/zig/issues/15909
...@@ -21394,26 +21367,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21394,26 +21367,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21394 enum_ty.fmt(pt),21367 enum_ty.fmt(pt),
21395 });21368 });
21396 }21369 }
21397 const enum_decl_index = enum_ty.getOwnerDecl(mod);
21398 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);21370 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
21399 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {21371 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 {
21401 const msg = msg: {21373 const msg = msg: {
21402 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{21374 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),
21404 });21376 });
21405 errdefer msg.destroy(sema.gpa);21377 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", .{});
21407 break :msg msg;21379 break :msg msg;
21408 };21380 };
21409 return sema.failWithOwnedErrorMsg(block, msg);21381 return sema.failWithOwnedErrorMsg(block, msg);
21410 };21382 };
21411 // TODO: write something like getCoercedInts to avoid needing to dupe21383 // 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);
21413 return sema.addNullTerminatedStrLit(field_name);21385 return sema.addNullTerminatedStrLit(field_name);
21414 }21386 }
21415 try sema.requireRuntimeBlock(block, src, operand_src);21387 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)) {
21417 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);21389 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
21418 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);21390 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
21419 }21391 }
...@@ -21810,7 +21782,6 @@ fn zirReify(...@@ -21810,7 +21782,6 @@ fn zirReify(
21810 }21782 }
2181121783
21812 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{21784 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{
21813 .has_namespace = false,
21814 .key = .{ .reified = .{21785 .key = .{ .reified = .{
21815 .zir_index = try block.trackZir(inst),21786 .zir_index = try block.trackZir(inst),
21816 } },21787 } },
...@@ -21820,19 +21791,21 @@ fn zirReify(...@@ -21820,19 +21791,21 @@ fn zirReify(
21820 };21791 };
21821 errdefer wip_ty.cancel(ip, pt.tid);21792 errdefer wip_ty.cancel(ip, pt.tid);
2182221793
21823 const new_decl_index = try sema.createAnonymousDeclTypeNamed(21794 wip_ty.setName(ip, try sema.createTypeName(
21824 block,21795 block,
21825 Value.fromInterned(wip_ty.index),
21826 name_strategy,21796 name_strategy,
21827 "opaque",21797 "opaque",
21828 inst,21798 inst,
21829 );21799 wip_ty.index,
21830 mod.declPtr(new_decl_index).owns_tv = true;21800 ));
21831 errdefer pt.abortAnonDecl(new_decl_index);
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));
21836 },21809 },
21837 .Union => {21810 .Union => {
21838 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21811 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
...@@ -22001,13 +21974,14 @@ fn reifyEnum(...@@ -22001,13 +21974,14 @@ fn reifyEnum(
22001 });21974 });
22002 }21975 }
2200321976
21977 const tracked_inst = try block.trackZir(inst);
21978
22004 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{21979 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
22005 .has_namespace = false,
22006 .has_values = true,21980 .has_values = true,
22007 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,21981 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
22008 .fields_len = fields_len,21982 .fields_len = fields_len,
22009 .key = .{ .reified = .{21983 .key = .{ .reified = .{
22010 .zir_index = try block.trackZir(inst),21984 .zir_index = tracked_inst,
22011 .type_hash = hasher.final(),21985 .type_hash = hasher.final(),
22012 } },21986 } },
22013 })) {21987 })) {
...@@ -22020,17 +21994,23 @@ fn reifyEnum(...@@ -22020,17 +21994,23 @@ fn reifyEnum(
22020 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});21994 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
22021 }21995 }
2202221996
22023 const new_decl_index = try sema.createAnonymousDeclTypeNamed(21997 wip_ty.setName(ip, try sema.createTypeName(
22024 block,21998 block,
22025 Value.fromInterned(wip_ty.index),
22026 name_strategy,21999 name_strategy,
22027 "enum",22000 "enum",
22028 inst,22001 inst,
22029 );22002 wip_ty.index,
22030 mod.declPtr(new_decl_index).owns_tv = true;22003 ));
22031 errdefer pt.abortAnonDecl(new_decl_index);
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);
22034 wip_ty.setTagTy(ip, tag_ty.toIntern());22014 wip_ty.setTagTy(ip, tag_ty.toIntern());
2203522015
22036 for (0..fields_len) |field_idx| {22016 for (0..fields_len) |field_idx| {
...@@ -22076,7 +22056,6 @@ fn reifyEnum(...@@ -22076,7 +22056,6 @@ fn reifyEnum(
22076 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});22056 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
22077 }22057 }
2207822058
22079 try pt.finalizeAnonDecl(new_decl_index);
22080 return Air.internedToRef(wip_ty.index);22059 return Air.internedToRef(wip_ty.index);
22081}22060}
2208222061
...@@ -22134,6 +22113,8 @@ fn reifyUnion(...@@ -22134,6 +22113,8 @@ fn reifyUnion(
22134 }22113 }
22135 }22114 }
2213622115
22116 const tracked_inst = try block.trackZir(inst);
22117
22137 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{22118 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
22138 .flags = .{22119 .flags = .{
22139 .layout = layout,22120 .layout = layout,
...@@ -22152,13 +22133,12 @@ fn reifyUnion(...@@ -22152,13 +22133,12 @@ fn reifyUnion(
22152 .assumed_pointer_aligned = false,22133 .assumed_pointer_aligned = false,
22153 .alignment = .none,22134 .alignment = .none,
22154 },22135 },
22155 .has_namespace = false,
22156 .fields_len = fields_len,22136 .fields_len = fields_len,
22157 .enum_tag_ty = .none, // set later because not yet validated22137 .enum_tag_ty = .none, // set later because not yet validated
22158 .field_types = &.{}, // set later22138 .field_types = &.{}, // set later
22159 .field_aligns = &.{}, // set later22139 .field_aligns = &.{}, // set later
22160 .key = .{ .reified = .{22140 .key = .{ .reified = .{
22161 .zir_index = try block.trackZir(inst),22141 .zir_index = tracked_inst,
22162 .type_hash = hasher.final(),22142 .type_hash = hasher.final(),
22163 } },22143 } },
22164 })) {22144 })) {
...@@ -22167,15 +22147,14 @@ fn reifyUnion(...@@ -22167,15 +22147,14 @@ fn reifyUnion(
22167 };22147 };
22168 errdefer wip_ty.cancel(ip, pt.tid);22148 errdefer wip_ty.cancel(ip, pt.tid);
2216922149
22170 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22150 const type_name = try sema.createTypeName(
22171 block,22151 block,
22172 Value.fromInterned(wip_ty.index),
22173 name_strategy,22152 name_strategy,
22174 "union",22153 "union",
22175 inst,22154 inst,
22155 wip_ty.index,
22176 );22156 );
22177 mod.declPtr(new_decl_index).owns_tv = true;22157 wip_ty.setName(ip, type_name);
22178 errdefer pt.abortAnonDecl(new_decl_index);
2217922158
22180 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);22159 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
22181 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;22160 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
...@@ -22268,7 +22247,7 @@ fn reifyUnion(...@@ -22268,7 +22247,7 @@ fn reifyUnion(
22268 }22247 }
22269 }22248 }
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);
22272 break :tag_ty .{ enum_tag_ty, false };22251 break :tag_ty .{ enum_tag_ty, false };
22273 };22252 };
22274 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error22253 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
...@@ -22315,10 +22294,17 @@ fn reifyUnion(...@@ -22315,10 +22294,17 @@ fn reifyUnion(
22315 loaded_union.setTagType(ip, enum_tag_ty);22294 loaded_union.setTagType(ip, enum_tag_ty);
22316 loaded_union.setStatus(ip, .have_field_types);22295 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
22319 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });22305 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22320 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22306 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22321 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22307 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
22322}22308}
2232322309
22324fn reifyStruct(22310fn reifyStruct(
...@@ -22399,6 +22385,8 @@ fn reifyStruct(...@@ -22399,6 +22385,8 @@ fn reifyStruct(
22399 }22385 }
22400 }22386 }
2240122387
22388 const tracked_inst = try block.trackZir(inst);
22389
22402 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{22390 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
22403 .layout = layout,22391 .layout = layout,
22404 .fields_len = fields_len,22392 .fields_len = fields_len,
...@@ -22409,9 +22397,8 @@ fn reifyStruct(...@@ -22409,9 +22397,8 @@ fn reifyStruct(
22409 .any_default_inits = any_default_inits,22397 .any_default_inits = any_default_inits,
22410 .any_aligned_fields = any_aligned_fields,22398 .any_aligned_fields = any_aligned_fields,
22411 .inits_resolved = true,22399 .inits_resolved = true,
22412 .has_namespace = false,
22413 .key = .{ .reified = .{22400 .key = .{ .reified = .{
22414 .zir_index = try block.trackZir(inst),22401 .zir_index = tracked_inst,
22415 .type_hash = hasher.final(),22402 .type_hash = hasher.final(),
22416 } },22403 } },
22417 })) {22404 })) {
...@@ -22426,15 +22413,13 @@ fn reifyStruct(...@@ -22426,15 +22413,13 @@ fn reifyStruct(
22426 .auto => {},22413 .auto => {},
22427 };22414 };
2242822415
22429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22416 wip_ty.setName(ip, try sema.createTypeName(
22430 block,22417 block,
22431 Value.fromInterned(wip_ty.index),
22432 name_strategy,22418 name_strategy,
22433 "struct",22419 "struct",
22434 inst,22420 inst,
22435 );22421 wip_ty.index,
22436 mod.declPtr(new_decl_index).owns_tv = true;22422 ));
22437 errdefer pt.abortAnonDecl(new_decl_index);
2243822423
22439 const struct_type = ip.loadStructType(wip_ty.index);22424 const struct_type = ip.loadStructType(wip_ty.index);
2244022425
...@@ -22582,10 +22567,17 @@ fn reifyStruct(...@@ -22582,10 +22567,17 @@ fn reifyStruct(
22582 }22567 }
22583 }22568 }
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
22586 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });22578 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22587 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22579 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22588 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22580 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
22589}22581}
2259022582
22591fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {22583fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
...@@ -26028,7 +26020,8 @@ fn zirVarExtended(...@@ -26028,7 +26020,8 @@ fn zirVarExtended(
26028 extended: Zir.Inst.Extended.InstData,26020 extended: Zir.Inst.Extended.InstData,
26029) CompileError!Air.Inst.Ref {26021) CompileError!Air.Inst.Ref {
26030 const pt = sema.pt;26022 const pt = sema.pt;
26031 const mod = pt.zcu;26023 const zcu = pt.zcu;
26024 const ip = &zcu.intern_pool;
26032 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);26025 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
26033 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });26026 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
26034 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });26027 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
...@@ -26075,16 +26068,62 @@ fn zirVarExtended(...@@ -26075,16 +26068,62 @@ fn zirVarExtended(
2607526068
26076 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);26069 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 = .{
26079 .ty = var_ty.toIntern(),26120 .ty = var_ty.toIntern(),
26080 .init = init_val,26121 .init = init_val,
26081 .decl = sema.owner_decl_index,26122 .owner_nav = sema.getOwnerCauNav(),
26082 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),26123 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
26083 .is_extern = small.is_extern,
26084 .is_const = small.is_const,
26085 .is_threadlocal = small.is_threadlocal,26124 .is_threadlocal = small.is_threadlocal,
26086 .is_weak_linkage = false,26125 .is_weak_linkage = false,
26087 } })));26126 } }));
26088}26127}
2608926128
26090fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {26129fn 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...@@ -26255,10 +26294,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26255 else => |e| return e,26294 else => |e| return e,
26256 };26295 };
26257 break :blk mod.toEnum(std.builtin.CallingConvention, cc_val);26296 break :blk mod.toEnum(std.builtin.CallingConvention, cc_val);
26258 } else if (sema.owner_decl.is_exported and has_body)26297 } else cc: {
26259 .C26298 if (has_body) {
26260 else26299 const decl_inst = if (sema.generic_owner != .none) decl_inst: {
26261 .Unspecified;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
26263 const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: {26315 const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: {
26264 const body_len = sema.code.extra[extra_index];26316 const body_len = sema.code.extra[extra_index];
...@@ -26600,42 +26652,32 @@ fn zirBuiltinExtern(...@@ -26600,42 +26652,32 @@ fn zirBuiltinExtern(
2660026652
26601 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);26653 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
2660226654
26655 // TODO: error for threadlocal functions, non-const functions, etc
26656
26603 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {26657 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
26604 ty = try pt.optionalType(ty.toIntern());26658 ty = try pt.optionalType(ty.toIntern());
26605 }26659 }
26606 const ptr_info = ty.ptrInfo(mod);26660 const ptr_info = ty.ptrInfo(mod);
2660726661
26608 const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);26662 const extern_val = try pt.getExtern(.{
26609 errdefer pt.destroyDecl(new_decl_index);26663 .name = options.name,
26610 const new_decl = mod.declPtr(new_decl_index);26664 .ty = ptr_info.child,
26611 try pt.initNewAnonDecl(26665 .lib_name = options.library_name,
26612 new_decl_index,26666 .is_const = ptr_info.flags.is_const,
26613 Value.fromInterned(26667 .is_threadlocal = options.is_thread_local,
26614 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)26668 .is_weak_linkage = options.linkage == .weak,
26615 try ip.getExternFunc(sema.gpa, pt.tid, .{26669 .alignment = ptr_info.flags.alignment,
26616 .ty = ptr_info.child,26670 .@"addrspace" = ptr_info.flags.address_space,
26617 .decl = new_decl_index,26671 // This instruction is just for source locations.
26618 .lib_name = options.library_name,26672 // `builtin_extern` doesn't provide enough information, and isn't currently tracked.
26619 })26673 // So, for now, just use our containing `declaration`.
26620 else26674 .zir_index = switch (sema.owner.unwrap()) {
26621 try pt.intern(.{ .variable = .{26675 .cau => sema.getOwnerCauDeclInst(),
26622 .ty = ptr_info.child,26676 .func => sema.getOwnerFuncDeclInst(),
26623 .init = .none,26677 },
26624 .decl = new_decl_index,26678 .owner_nav = undefined, // ignored by `getExtern`
26625 .lib_name = options.library_name,26679 });
26626 .is_extern = true,26680 const extern_nav = ip.indexToKey(extern_val).@"extern".owner_nav;
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);
2663926681
26640 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{26682 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{
26641 .ty = switch (ip.indexToKey(ty.toIntern())) {26683 .ty = switch (ip.indexToKey(ty.toIntern())) {
...@@ -26643,7 +26685,7 @@ fn zirBuiltinExtern(...@@ -26643,7 +26685,7 @@ fn zirBuiltinExtern(
26643 .opt_type => |child_type| child_type,26685 .opt_type => |child_type| child_type,
26644 else => unreachable,26686 else => unreachable,
26645 },26687 },
26646 .base_addr = .{ .decl = new_decl_index },26688 .base_addr = .{ .nav = extern_nav },
26647 .byte_offset = 0,26689 .byte_offset = 0,
26648 } })), ty)).toIntern());26690 } })), ty)).toIntern());
26649}26691}
...@@ -27129,17 +27171,15 @@ fn explainWhyTypeIsNotPacked(...@@ -27129,17 +27171,15 @@ fn explainWhyTypeIsNotPacked(
27129 }27171 }
27130}27172}
2713127173
27132fn prepareSimplePanic(sema: *Sema) !void {27174fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27133 const pt = sema.pt;27175 const pt = sema.pt;
27134 const mod = pt.zcu;27176 const mod = pt.zcu;
2713527177
27136 if (mod.panic_func_index == .none) {27178 if (mod.panic_func_index == .none) {
27137 const decl_index = (try pt.getBuiltinDecl("panic"));27179 const fn_ref = try sema.analyzeNavVal(block, src, try pt.getBuiltinNav("panic"));
27138 // decl_index may be an alias; we must find the decl that actually27180 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{
27139 // owns the function.27181 .needed_comptime_reason = "panic handler must be comptime-known",
27140 try sema.ensureDeclAnalyzed(decl_index);27182 });
27141 const fn_val = try mod.declPtr(decl_index).valueOrFail();
27142 try sema.declareDependency(.{ .decl_val = decl_index });
27143 assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn);27183 assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn);
27144 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));27184 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));
27145 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());27185 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());
...@@ -27167,16 +27207,16 @@ fn prepareSimplePanic(sema: *Sema) !void {...@@ -27167,16 +27207,16 @@ fn prepareSimplePanic(sema: *Sema) !void {
27167/// Backends depend on panic decls being available when lowering safety-checked27207/// Backends depend on panic decls being available when lowering safety-checked
27168/// instructions. This function ensures the panic function will be available to27208/// instructions. This function ensures the panic function will be available to
27169/// be called during that time.27209/// 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 {
27171 const pt = sema.pt;27211 const pt = sema.pt;
27172 const mod = pt.zcu;27212 const mod = pt.zcu;
27173 const gpa = sema.gpa;27213 const gpa = sema.gpa;
27174 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;27214 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2717527215
27176 try sema.prepareSimplePanic();27216 try sema.prepareSimplePanic(block, src);
2717727217
27178 const panic_messages_ty = try pt.getBuiltinType("panic_messages");27218 const panic_messages_ty = try pt.getBuiltinType("panic_messages");
27179 const msg_decl_index = (sema.namespaceLookup(27219 const msg_nav_index = (sema.namespaceLookup(
27180 block,27220 block,
27181 LazySrcLoc.unneeded,27221 LazySrcLoc.unneeded,
27182 panic_messages_ty.getNamespaceIndex(mod),27222 panic_messages_ty.getNamespaceIndex(mod),
...@@ -27186,9 +27226,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP...@@ -27186,9 +27226,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
27186 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,27226 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27187 error.OutOfMemory => |e| return e,27227 error.OutOfMemory => |e| return e,
27188 }).?;27228 }).?;
27189 try sema.ensureDeclAnalyzed(msg_decl_index);27229 try sema.ensureNavResolved(src, msg_nav_index);
27190 mod.panic_messages[@intFromEnum(panic_id)] = msg_decl_index.toOptional();27230 mod.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27191 return msg_decl_index;27231 return msg_nav_index;
27192}27232}
2719327233
27194fn addSafetyCheck(27234fn addSafetyCheck(
...@@ -27282,10 +27322,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -27282,10 +27322,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
27282 return;27322 return;
27283 }27323 }
2728427324
27285 try sema.prepareSimplePanic();27325 try sema.prepareSimplePanic(block, src);
2728627326
27287 const panic_func = mod.funcInfo(mod.panic_func_index);27327 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);
27289 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);27329 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);
2729027330
27291 const opt_usize_ty = try pt.optionalType(.usize_type);27331 const opt_usize_ty = try pt.optionalType(.usize_type);
...@@ -27455,8 +27495,8 @@ fn safetyCheckFormatted(...@@ -27455,8 +27495,8 @@ fn safetyCheckFormatted(
27455}27495}
2745627496
27457fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void {27497fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void {
27458 const msg_decl_index = try sema.preparePanicId(block, panic_id);27498 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);
27459 const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index);27499 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);
27460 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");27500 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
27461}27501}
2746227502
...@@ -27628,21 +27668,21 @@ fn fieldVal(...@@ -27628,21 +27668,21 @@ fn fieldVal(
27628 return Air.internedToRef(enum_val.toIntern());27668 return Air.internedToRef(enum_val.toIntern());
27629 },27669 },
27630 .Struct, .Opaque => {27670 .Struct, .Opaque => {
27631 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27671 switch (child_type.toIntern()) {
27632 return inst;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 },
27633 }27676 }
27634 return sema.failWithBadMemberAccess(block, child_type, src, field_name);27677 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
27635 },27678 },
27636 else => {27679 else => return sema.failWithOwnedErrorMsg(block, msg: {
27637 const msg = msg: {27680 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});
27638 const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)});27681 errdefer msg.destroy(sema.gpa);
27639 errdefer msg.destroy(sema.gpa);27682 if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
27640 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", .{});
27641 if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});27684 break :msg msg;
27642 break :msg msg;27685 }),
27643 };
27644 return sema.failWithOwnedErrorMsg(block, msg);
27645 },
27646 }27686 }
27647 },27687 },
27648 .Struct => if (is_pointer_to) {27688 .Struct => if (is_pointer_to) {
...@@ -27700,7 +27740,7 @@ fn fieldPtr(...@@ -27700,7 +27740,7 @@ fn fieldPtr(
27700 .Array => {27740 .Array => {
27701 if (field_name.eqlSlice("len", ip)) {27741 if (field_name.eqlSlice("len", ip)) {
27702 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));27742 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());
27704 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27744 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27705 const ptr_info = object_ty.ptrInfo(mod);27745 const ptr_info = object_ty.ptrInfo(mod);
27706 const new_ptr_ty = try pt.ptrTypeSema(.{27746 const new_ptr_ty = try pt.ptrTypeSema(.{
...@@ -27839,7 +27879,7 @@ fn fieldPtr(...@@ -27839,7 +27879,7 @@ fn fieldPtr(
27839 child_type27879 child_type
27840 else27880 else
27841 try pt.singleErrorSetType(field_name);27881 try pt.singleErrorSetType(field_name);
27842 return anonDeclRef(sema, try pt.intern(.{ .err = .{27882 return uavRef(sema, try pt.intern(.{ .err = .{
27843 .ty = error_set_type.toIntern(),27883 .ty = error_set_type.toIntern(),
27844 .name = field_name,27884 .name = field_name,
27845 } }));27885 } }));
...@@ -27853,7 +27893,7 @@ fn fieldPtr(...@@ -27853,7 +27893,7 @@ fn fieldPtr(
27853 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {27893 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
27854 const field_index_u32: u32 = @intCast(field_index);27894 const field_index_u32: u32 = @intCast(field_index);
27855 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);27895 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());
27857 }27897 }
27858 }27898 }
27859 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27899 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
...@@ -27867,7 +27907,7 @@ fn fieldPtr(...@@ -27867,7 +27907,7 @@ fn fieldPtr(
27867 };27907 };
27868 const field_index_u32: u32 = @intCast(field_index);27908 const field_index_u32: u32 = @intCast(field_index);
27869 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);27909 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());
27871 },27911 },
27872 .Struct, .Opaque => {27912 .Struct, .Opaque => {
27873 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27913 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
...@@ -27923,18 +27963,18 @@ fn fieldCallBind(...@@ -27923,18 +27963,18 @@ fn fieldCallBind(
27923 // in `fieldVal`. This function takes a pointer and returns a pointer.27963 // in `fieldVal`. This function takes a pointer and returns a pointer.
2792427964
27925 const pt = sema.pt;27965 const pt = sema.pt;
27926 const mod = pt.zcu;27966 const zcu = pt.zcu;
27927 const ip = &mod.intern_pool;27967 const ip = &zcu.intern_pool;
27928 const raw_ptr_src = src; // TODO better source location27968 const raw_ptr_src = src; // TODO better source location
27929 const raw_ptr_ty = sema.typeOf(raw_ptr);27969 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))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))
27931 raw_ptr_ty.childType(mod)27971 raw_ptr_ty.childType(zcu)
27932 else27972 else
27933 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});27973 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
2793427974
27935 // Optionally dereference a second pointer to get the concrete type.27975 // 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;27976 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .Pointer and inner_ty.ptrSize(zcu) == .One;
27937 const concrete_ty = if (is_double_ptr) inner_ty.childType(mod) else inner_ty;27977 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;
27938 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;27978 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
27939 const object_ptr = if (is_double_ptr)27979 const object_ptr = if (is_double_ptr)
27940 try sema.analyzeLoad(block, src, raw_ptr, src)27980 try sema.analyzeLoad(block, src, raw_ptr, src)
...@@ -27942,36 +27982,36 @@ fn fieldCallBind(...@@ -27942,36 +27982,36 @@ fn fieldCallBind(
27942 raw_ptr;27982 raw_ptr;
2794327983
27944 find_field: {27984 find_field: {
27945 switch (concrete_ty.zigTypeTag(mod)) {27985 switch (concrete_ty.zigTypeTag(zcu)) {
27946 .Struct => {27986 .Struct => {
27947 try concrete_ty.resolveFields(pt);27987 try concrete_ty.resolveFields(pt);
27948 if (mod.typeToStruct(concrete_ty)) |struct_type| {27988 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
27949 const field_index = struct_type.nameIndex(ip, field_name) orelse27989 const field_index = struct_type.nameIndex(ip, field_name) orelse
27950 break :find_field;27990 break :find_field;
27951 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);27991 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2795227992
27953 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);27993 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)) {
27955 if (field_name.eqlSlice("len", ip)) {27995 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)) };
27957 }27997 }
27958 if (field_name.toUnsigned(ip)) |field_index| {27998 if (field_name.toUnsigned(ip)) |field_index| {
27959 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;27999 if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field;
27960 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, mod), field_index, object_ptr);28000 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, zcu), field_index, object_ptr);
27961 }28001 }
27962 } else {28002 } else {
27963 const max = concrete_ty.structFieldCount(mod);28003 const max = concrete_ty.structFieldCount(zcu);
27964 for (0..max) |i_usize| {28004 for (0..max) |i_usize| {
27965 const i: u32 = @intCast(i_usize);28005 const i: u32 = @intCast(i_usize);
27966 if (field_name == concrete_ty.structFieldName(i, mod).unwrap().?) {28006 if (field_name == concrete_ty.structFieldName(i, zcu).unwrap().?) {
27967 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, mod), i, object_ptr);28007 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, zcu), i, object_ptr);
27968 }28008 }
27969 }28009 }
27970 }28010 }
27971 },28011 },
27972 .Union => {28012 .Union => {
27973 try concrete_ty.resolveFields(pt);28013 try concrete_ty.resolveFields(pt);
27974 const union_obj = mod.typeToUnion(concrete_ty).?;28014 const union_obj = zcu.typeToUnion(concrete_ty).?;
27975 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;28015 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
27976 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);28016 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
27977 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };28017 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };
...@@ -27985,23 +28025,23 @@ fn fieldCallBind(...@@ -27985,23 +28025,23 @@ fn fieldCallBind(
27985 }28025 }
2798628026
27987 // If we get here, we need to look for a decl in the struct type instead.28027 // If we get here, we need to look for a decl in the struct type instead.
27988 const found_decl = found_decl: {28028 const found_nav = found_nav: {
27989 const namespace = concrete_ty.getNamespace(mod) orelse28029 const namespace = concrete_ty.getNamespace(zcu).unwrap() orelse
27990 break :found_decl null;28030 break :found_nav null;
27991 const decl_idx = (try sema.namespaceLookup(block, src, namespace, field_name)) orelse28031 const nav_index = try sema.namespaceLookup(block, src, namespace, field_name) orelse
27992 break :found_decl null;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);
27995 const decl_type = sema.typeOf(decl_val);28035 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: {
27997 if (func_type.param_types.len == 0) break :f;28037 if (func_type.param_types.len == 0) break :f;
2799828038
27999 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);28039 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);
28000 if (first_param_type.isGenericPoison() or28040 if (first_param_type.isGenericPoison() or
28001 (first_param_type.zigTypeTag(mod) == .Pointer and28041 (first_param_type.zigTypeTag(zcu) == .Pointer and
28002 (first_param_type.ptrSize(mod) == .One or28042 (first_param_type.ptrSize(zcu) == .One or
28003 first_param_type.ptrSize(mod) == .C) and28043 first_param_type.ptrSize(zcu) == .C) and
28004 first_param_type.childType(mod).eql(concrete_ty, mod)))28044 first_param_type.childType(zcu).eql(concrete_ty, zcu)))
28005 {28045 {
28006 // Note that if the param type is generic poison, we know that it must28046 // Note that if the param type is generic poison, we know that it must
28007 // specifically be `anytype` since it's the first parameter, meaning we28047 // specifically be `anytype` since it's the first parameter, meaning we
...@@ -28012,31 +28052,31 @@ fn fieldCallBind(...@@ -28012,31 +28052,31 @@ fn fieldCallBind(
28012 .func_inst = decl_val,28052 .func_inst = decl_val,
28013 .arg0_inst = object_ptr,28053 .arg0_inst = object_ptr,
28014 } };28054 } };
28015 } else if (first_param_type.eql(concrete_ty, mod)) {28055 } else if (first_param_type.eql(concrete_ty, zcu)) {
28016 const deref = try sema.analyzeLoad(block, src, object_ptr, src);28056 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
28017 return .{ .method = .{28057 return .{ .method = .{
28018 .func_inst = decl_val,28058 .func_inst = decl_val,
28019 .arg0_inst = deref,28059 .arg0_inst = deref,
28020 } };28060 } };
28021 } else if (first_param_type.zigTypeTag(mod) == .Optional) {28061 } else if (first_param_type.zigTypeTag(zcu) == .Optional) {
28022 const child = first_param_type.optionalChild(mod);28062 const child = first_param_type.optionalChild(zcu);
28023 if (child.eql(concrete_ty, mod)) {28063 if (child.eql(concrete_ty, zcu)) {
28024 const deref = try sema.analyzeLoad(block, src, object_ptr, src);28064 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
28025 return .{ .method = .{28065 return .{ .method = .{
28026 .func_inst = decl_val,28066 .func_inst = decl_val,
28027 .arg0_inst = deref,28067 .arg0_inst = deref,
28028 } };28068 } };
28029 } else if (child.zigTypeTag(mod) == .Pointer and28069 } else if (child.zigTypeTag(zcu) == .Pointer and
28030 child.ptrSize(mod) == .One and28070 child.ptrSize(zcu) == .One and
28031 child.childType(mod).eql(concrete_ty, mod))28071 child.childType(zcu).eql(concrete_ty, zcu))
28032 {28072 {
28033 return .{ .method = .{28073 return .{ .method = .{
28034 .func_inst = decl_val,28074 .func_inst = decl_val,
28035 .arg0_inst = object_ptr,28075 .arg0_inst = object_ptr,
28036 } };28076 } };
28037 }28077 }
28038 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and28078 } else if (first_param_type.zigTypeTag(zcu) == .ErrorUnion and
28039 first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod))28079 first_param_type.errorUnionPayload(zcu).eql(concrete_ty, zcu))
28040 {28080 {
28041 const deref = try sema.analyzeLoad(block, src, object_ptr, src);28081 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
28042 return .{ .method = .{28082 return .{ .method = .{
...@@ -28045,7 +28085,7 @@ fn fieldCallBind(...@@ -28045,7 +28085,7 @@ fn fieldCallBind(
28045 } };28085 } };
28046 }28086 }
28047 }28087 }
28048 break :found_decl decl_idx;28088 break :found_nav nav_index;
28049 };28089 };
2805028090
28051 const msg = msg: {28091 const msg = msg: {
...@@ -28055,14 +28095,15 @@ fn fieldCallBind(...@@ -28055,14 +28095,15 @@ fn fieldCallBind(
28055 });28095 });
28056 errdefer msg.destroy(sema.gpa);28096 errdefer msg.destroy(sema.gpa);
28057 try sema.addDeclaredHereNote(msg, concrete_ty);28097 try sema.addDeclaredHereNote(msg, concrete_ty);
28058 if (found_decl) |decl_idx| {28098 if (found_nav) |nav_index| {
28059 const decl = mod.declPtr(decl_idx);28099 try sema.errNote(
28060 try sema.errNote(.{28100 zcu.navSrcLoc(nav_index),
28061 .base_node_inst = decl.zir_decl_index.unwrap().?,28101 msg,
28062 .offset = LazySrcLoc.Offset.nodeOffset(0),28102 "'{}' is not a member function",
28063 }, msg, "'{}' is not a member function", .{field_name.fmt(ip)});28103 .{field_name.fmt(ip)},
28104 );
28064 }28105 }
28065 if (concrete_ty.zigTypeTag(mod) == .ErrorUnion) {28106 if (concrete_ty.zigTypeTag(zcu) == .ErrorUnion) {
28066 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});28107 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
28067 }28108 }
28068 if (is_double_ptr) {28109 if (is_double_ptr) {
...@@ -28117,29 +28158,24 @@ fn namespaceLookup(...@@ -28117,29 +28158,24 @@ fn namespaceLookup(
28117 sema: *Sema,28158 sema: *Sema,
28118 block: *Block,28159 block: *Block,
28119 src: LazySrcLoc,28160 src: LazySrcLoc,
28120 opt_namespace: InternPool.OptionalNamespaceIndex,28161 namespace: InternPool.NamespaceIndex,
28121 decl_name: InternPool.NullTerminatedString,28162 decl_name: InternPool.NullTerminatedString,
28122) CompileError!?InternPool.DeclIndex {28163) CompileError!?InternPool.Nav.Index {
28123 const pt = sema.pt;28164 const pt = sema.pt;
28124 const mod = pt.zcu;28165 const zcu = pt.zcu;
28125 const gpa = sema.gpa;28166 const gpa = sema.gpa;
28126 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {28167 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
28127 const decl = mod.declPtr(decl_index);28168 if (!lookup.accessible) {
28128 if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {28169 return sema.failWithOwnedErrorMsg(block, msg: {
28129 const msg = msg: {
28130 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{28170 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
28131 decl_name.fmt(&mod.intern_pool),28171 decl_name.fmt(&zcu.intern_pool),
28132 });28172 });
28133 errdefer msg.destroy(gpa);28173 errdefer msg.destroy(gpa);
28134 try sema.errNote(.{28174 try sema.errNote(zcu.navSrcLoc(lookup.nav), msg, "declared here", .{});
28135 .base_node_inst = decl.zir_decl_index.unwrap().?,
28136 .offset = LazySrcLoc.Offset.nodeOffset(0),
28137 }, msg, "declared here", .{});
28138 break :msg msg;28175 break :msg msg;
28139 };28176 });
28140 return sema.failWithOwnedErrorMsg(block, msg);
28141 }28177 }
28142 return decl_index;28178 return lookup.nav;
28143 }28179 }
28144 return null;28180 return null;
28145}28181}
...@@ -28148,22 +28184,22 @@ fn namespaceLookupRef(...@@ -28148,22 +28184,22 @@ fn namespaceLookupRef(
28148 sema: *Sema,28184 sema: *Sema,
28149 block: *Block,28185 block: *Block,
28150 src: LazySrcLoc,28186 src: LazySrcLoc,
28151 opt_namespace: InternPool.OptionalNamespaceIndex,28187 namespace: InternPool.NamespaceIndex,
28152 decl_name: InternPool.NullTerminatedString,28188 decl_name: InternPool.NullTerminatedString,
28153) CompileError!?Air.Inst.Ref {28189) CompileError!?Air.Inst.Ref {
28154 const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null;28190 const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null;
28155 return try sema.analyzeDeclRef(src, decl);28191 return try sema.analyzeNavRef(src, nav);
28156}28192}
2815728193
28158fn namespaceLookupVal(28194fn namespaceLookupVal(
28159 sema: *Sema,28195 sema: *Sema,
28160 block: *Block,28196 block: *Block,
28161 src: LazySrcLoc,28197 src: LazySrcLoc,
28162 opt_namespace: InternPool.OptionalNamespaceIndex,28198 namespace: InternPool.NamespaceIndex,
28163 decl_name: InternPool.NullTerminatedString,28199 decl_name: InternPool.NullTerminatedString,
28164) CompileError!?Air.Inst.Ref {28200) CompileError!?Air.Inst.Ref {
28165 const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null;28201 const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null;
28166 return try sema.analyzeDeclVal(block, src, decl);28202 return try sema.analyzeNavVal(block, src, nav);
28167}28203}
2816828204
28169fn structFieldPtr(28205fn structFieldPtr(
...@@ -29200,9 +29236,9 @@ const CoerceOpts = struct {...@@ -29200,9 +29236,9 @@ const CoerceOpts = struct {
2920029236
29201 fn get(info: @This(), sema: *Sema) !?LazySrcLoc {29237 fn get(info: @This(), sema: *Sema) !?LazySrcLoc {
29202 if (info.func_inst == .none) return null;29238 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;
29204 return .{29240 return .{
29205 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,29241 .base_node_inst = func_inst,
29206 .offset = .{ .fn_proto_param_type = .{29242 .offset = .{ .fn_proto_param_type = .{
29207 .fn_proto_node_offset = 0,29243 .fn_proto_node_offset = 0,
29208 .param_index = info.param_i,29244 .param_index = info.param_i,
...@@ -29303,8 +29339,12 @@ fn coerceExtra(...@@ -29303,8 +29339,12 @@ fn coerceExtra(
29303 // Function body to function pointer.29339 // Function body to function pointer.
29304 if (inst_ty.zigTypeTag(zcu) == .Fn) {29340 if (inst_ty.zigTypeTag(zcu) == .Fn) {
29305 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);29341 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
29306 const fn_decl = fn_val.pointerDecl(zcu).?;29342 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
29307 const inst_as_ptr = try sema.analyzeDeclRef(inst_src, fn_decl);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);
29308 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);29348 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
29309 }29349 }
2931029350
...@@ -29846,7 +29886,7 @@ fn coerceExtra(...@@ -29846,7 +29886,7 @@ fn coerceExtra(
29846 errdefer msg.destroy(sema.gpa);29886 errdefer msg.destroy(sema.gpa);
2984729887
29848 const ret_ty_src: LazySrcLoc = .{29888 const ret_ty_src: LazySrcLoc = .{
29849 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,29889 .base_node_inst = sema.getOwnerFuncDeclInst(),
29850 .offset = .{ .node_offset_fn_type_ret_ty = 0 },29890 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
29851 };29891 };
29852 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});29892 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
...@@ -29879,10 +29919,10 @@ fn coerceExtra(...@@ -29879,10 +29919,10 @@ fn coerceExtra(
2987929919
29880 // Add notes about function return type29920 // Add notes about function return type
29881 if (opts.is_ret and29921 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))
29883 {29923 {
29884 const ret_ty_src: LazySrcLoc = .{29924 const ret_ty_src: LazySrcLoc = .{
29885 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,29925 .base_node_inst = sema.getOwnerFuncDeclInst(),
29886 .offset = .{ .node_offset_fn_type_ret_ty = 0 },29926 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
29887 };29927 };
29888 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {29928 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
...@@ -30885,9 +30925,9 @@ fn coerceVarArgParam(...@@ -30885,9 +30925,9 @@ fn coerceVarArgParam(
30885 if (block.is_typeof) return inst;30925 if (block.is_typeof) return inst;
3088630926
30887 const pt = sema.pt;30927 const pt = sema.pt;
30888 const mod = pt.zcu;30928 const zcu = pt.zcu;
30889 const uncasted_ty = sema.typeOf(inst);30929 const uncasted_ty = sema.typeOf(inst);
30890 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {30930 const coerced = switch (uncasted_ty.zigTypeTag(zcu)) {
30891 // TODO consider casting to c_int/f64 if they fit30931 // TODO consider casting to c_int/f64 if they fit
30892 .ComptimeInt, .ComptimeFloat => return sema.fail(30932 .ComptimeInt, .ComptimeFloat => return sema.fail(
30893 block,30933 block,
...@@ -30897,12 +30937,12 @@ fn coerceVarArgParam(...@@ -30897,12 +30937,12 @@ fn coerceVarArgParam(
30897 ),30937 ),
30898 .Fn => fn_ptr: {30938 .Fn => fn_ptr: {
30899 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);30939 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
30900 const fn_decl = fn_val.pointerDecl(mod).?;30940 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
30901 break :fn_ptr try sema.analyzeDeclRef(inst_src, fn_decl);30941 break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav);
30902 },30942 },
30903 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),30943 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
30904 .Float => float: {30944 .Float => float: {
30905 const target = mod.getTarget();30945 const target = zcu.getTarget();
30906 const double_bits = target.c_type_bit_size(.double);30946 const double_bits = target.c_type_bit_size(.double);
30907 const inst_bits = uncasted_ty.floatBits(target);30947 const inst_bits = uncasted_ty.floatBits(target);
30908 if (inst_bits >= double_bits) break :float inst;30948 if (inst_bits >= double_bits) break :float inst;
...@@ -30912,10 +30952,10 @@ fn coerceVarArgParam(...@@ -30912,10 +30952,10 @@ fn coerceVarArgParam(
30912 else => unreachable,30952 else => unreachable,
30913 }30953 }
30914 },30954 },
30915 else => if (uncasted_ty.isAbiInt(mod)) int: {30955 else => if (uncasted_ty.isAbiInt(zcu)) int: {
30916 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;30956 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
30917 const target = mod.getTarget();30957 const target = zcu.getTarget();
30918 const uncasted_info = uncasted_ty.intInfo(mod);30958 const uncasted_info = uncasted_ty.intInfo(zcu);
30919 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {30959 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {
30920 .signed => .int,30960 .signed => .int,
30921 .unsigned => .uint,30961 .unsigned => .uint,
...@@ -32117,23 +32157,14 @@ fn coerceTupleToTuple(...@@ -32117,23 +32157,14 @@ fn coerceTupleToTuple(
32117 } })));32157 } })));
32118}32158}
3211932159
32120fn analyzeDeclVal(32160fn analyzeNavVal(
32121 sema: *Sema,32161 sema: *Sema,
32122 block: *Block,32162 block: *Block,
32123 src: LazySrcLoc,32163 src: LazySrcLoc,
32124 decl_index: InternPool.DeclIndex,32164 nav_index: InternPool.Nav.Index,
32125) CompileError!Air.Inst.Ref {32165) CompileError!Air.Inst.Ref {
32126 if (sema.decl_val_table.get(decl_index)) |result| {32166 const ref = try sema.analyzeNavRefInner(src, nav_index, false);
32127 return result;32167 return sema.analyzeLoad(block, src, ref, src);
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;
32137}32168}
3213832169
32139fn addReferenceEntry(32170fn addReferenceEntry(
...@@ -32148,44 +32179,37 @@ fn addReferenceEntry(...@@ -32148,44 +32179,37 @@ fn addReferenceEntry(
32148 // TODO: we need to figure out how to model inline calls here.32179 // TODO: we need to figure out how to model inline calls here.
32149 // They aren't references in the analysis sense, but ought to show up in the reference trace!32180 // They aren't references in the analysis sense, but ought to show up in the reference trace!
32150 // Would representing inline calls in the reference table cause excessive memory usage?32181 // 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);
32152}32183}
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 {
32155 const pt = sema.pt;32186 const pt = sema.pt;
32156 const mod = pt.zcu;32187 const zcu = pt.zcu;
32157 const ip = &mod.intern_pool;32188 const ip = &zcu.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 }
3216632189
32167 pt.ensureDeclAnalyzed(decl_index) catch |err| {32190 const nav = ip.getNav(nav_index);
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}
3217632191
32177fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {32192 const cau_index = nav.analysis_owner.unwrap() orelse {
32178 const pt = sema.pt;32193 assert(nav.status == .resolved);
32179 const mod = pt.zcu;32194 return;
32180 const ip = &mod.intern_pool;
32181 pt.ensureFuncBodyAnalyzed(func) catch |err| {
32182 if (sema.owner_func_index != .none) {
32183 ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure);
32184 } else {
32185 sema.owner_decl.analysis = .dependency_failure;
32186 }
32187 return err;
32188 };32195 };
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);
32189}32213}
3219032214
32191fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {32215fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
...@@ -32200,55 +32224,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {...@@ -32200,55 +32224,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
32200 } }));32224 } }));
32201}32225}
3220232226
32203fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {32227fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref {
32204 return sema.analyzeDeclRefInner(src, decl_index, true);32228 return sema.analyzeNavRefInner(src, nav_index, true);
32205}32229}
3220632230
32207/// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but32231/// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed, but
32208/// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a32232/// 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` wraps32233/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeNavRef` wraps
32210/// this function with `analyze_fn_body` set to true.32234/// 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 {
32212 const pt = sema.pt;32236 const pt = sema.pt;
32213 const mod = pt.zcu;32237 const zcu = pt.zcu;
32214 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));32238 const ip = &zcu.intern_pool;
32215 try sema.ensureDeclAnalyzed(decl_index);
3221632239
32217 const decl_val = try mod.declPtr(decl_index).valueOrFail();32240 // TODO: if this is a `decl_ref` of a non-variable Nav, only depend on Nav type
32218 const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_val.toIntern())) {32241 try sema.declareDependency(.{ .nav_val = orig_nav_index });
32219 .variable => |variable| variable.decl,32242 try sema.ensureNavResolved(src, orig_nav_index);
32220 .extern_func => |extern_func| extern_func.decl,32243
32221 .func => |func| func.owner_decl,32244 const nav_val = zcu.navValue(orig_nav_index);
32222 else => decl_index,32245 const nav_index, const is_const = switch (ip.indexToKey(nav_val.toIntern())) {
32223 });32246 .variable => |v| .{ v.owner_nav, false },
32224 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type32247 .func => |f| .{ f.owner_nav, true },
32225 try sema.declareDependency(.{ .decl_val = decl_index });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;
32226 const ptr_ty = try pt.ptrTypeSema(.{32252 const ptr_ty = try pt.ptrTypeSema(.{
32227 .child = decl_val.typeOf(mod).toIntern(),32253 .child = nav_val.typeOf(zcu).toIntern(),
32228 .flags = .{32254 .flags = .{
32229 .alignment = owner_decl.alignment,32255 .alignment = nav_info.alignment,
32230 .is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true,32256 .is_const = is_const,
32231 .address_space = owner_decl.@"addrspace",32257 .address_space = nav_info.@"addrspace",
32232 },32258 },
32233 });32259 });
32234 if (analyze_fn_body) {32260 if (analyze_fn_body) {
32235 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);32261 try sema.maybeQueueFuncBodyAnalysis(src, nav_index);
32236 }32262 }
32237 return Air.internedToRef((try pt.intern(.{ .ptr = .{32263 return Air.internedToRef((try pt.intern(.{ .ptr = .{
32238 .ty = ptr_ty.toIntern(),32264 .ty = ptr_ty.toIntern(),
32239 .base_addr = .{ .decl = decl_index },32265 .base_addr = .{ .nav = nav_index },
32240 .byte_offset = 0,32266 .byte_offset = 0,
32241 } })));32267 } })));
32242}32268}
3224332269
32244fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {32270fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void {
32245 const mod = sema.pt.zcu;32271 const zcu = sema.pt.zcu;
32246 const decl = mod.declPtr(decl_index);32272 const ip = &zcu.intern_pool;
32247 const decl_val = try decl.valueOrFail();32273 const nav_val = zcu.navValue(nav_index);
32248 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;32274 if (!ip.isFuncBody(nav_val.toIntern())) return;
32249 if (!try sema.fnHasRuntimeBits(decl_val.typeOf(mod))) return;32275 if (!try sema.fnHasRuntimeBits(nav_val.typeOf(zcu))) return;
32250 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = decl_val.toIntern() }));32276 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() }));
32251 try mod.ensureFuncBodyAnalysisQueued(decl_val.toIntern());32277 try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
32252}32278}
3225332279
32254fn analyzeRef(32280fn analyzeRef(
...@@ -32263,9 +32289,9 @@ fn analyzeRef(...@@ -32263,9 +32289,9 @@ fn analyzeRef(
3226332289
32264 if (try sema.resolveValue(operand)) |val| {32290 if (try sema.resolveValue(operand)) |val| {
32265 switch (mod.intern_pool.indexToKey(val.toIntern())) {32291 switch (mod.intern_pool.indexToKey(val.toIntern())) {
32266 .extern_func => |extern_func| return sema.analyzeDeclRef(src, extern_func.decl),32292 .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav),
32267 .func => |func| return sema.analyzeDeclRef(src, func.owner_decl),32293 .func => |f| return sema.analyzeNavRef(src, f.owner_nav),
32268 else => return anonDeclRef(sema, val.toIntern()),32294 else => return uavRef(sema, val.toIntern()),
32269 }32295 }
32270 }32296 }
3227132297
...@@ -35198,7 +35224,7 @@ pub fn resolveStructAlignment(...@@ -35198,7 +35224,7 @@ pub fn resolveStructAlignment(
35198 const ip = &mod.intern_pool;35224 const ip = &mod.intern_pool;
35199 const target = mod.getTarget();35225 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
35203 assert(struct_type.layout != .@"packed");35229 assert(struct_type.layout != .@"packed");
35204 assert(struct_type.flagsUnordered(ip).alignment == .none);35230 assert(struct_type.flagsUnordered(ip).alignment == .none);
...@@ -35242,7 +35268,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35242,7 +35268,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35242 const ip = &zcu.intern_pool;35268 const ip = &zcu.intern_pool;
35243 const struct_type = zcu.typeToStruct(ty) orelse return;35269 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
35247 if (struct_type.haveLayout(ip))35273 if (struct_type.haveLayout(ip))
35248 return;35274 return;
...@@ -35384,8 +35410,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp...@@ -35384,8 +35410,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35384 const gpa = zcu.gpa;35410 const gpa = zcu.gpa;
35385 const ip = &zcu.intern_pool;35411 const ip = &zcu.intern_pool;
3538635412
35387 const decl_index = struct_type.decl.unwrap().?;35413 const cau_index = struct_type.cau.unwrap().?;
35388 const decl = zcu.declPtr(decl_index);
3538935414
35390 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;35415 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...@@ -35400,13 +35425,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35400 .gpa = gpa,35425 .gpa = gpa,
35401 .arena = analysis_arena.allocator(),35426 .arena = analysis_arena.allocator(),
35402 .code = zir,35427 .code = zir,
35403 .owner_decl = decl,35428 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
35404 .owner_decl_index = decl_index,
35405 .func_index = .none,35429 .func_index = .none,
35406 .func_is_naked = false,35430 .func_is_naked = false,
35407 .fn_ret_ty = Type.void,35431 .fn_ret_ty = Type.void,
35408 .fn_ret_ty_ies = null,35432 .fn_ret_ty_ies = null,
35409 .owner_func_index = .none,
35410 .comptime_err_ret_trace = &comptime_err_ret_trace,35433 .comptime_err_ret_trace = &comptime_err_ret_trace,
35411 };35434 };
35412 defer sema.deinit();35435 defer sema.deinit();
...@@ -35414,12 +35437,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp...@@ -35414,12 +35437,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35414 var block: Block = .{35437 var block: Block = .{
35415 .parent = null,35438 .parent = null,
35416 .sema = &sema,35439 .sema = &sema,
35417 .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,35440 .namespace = ip.getCau(cau_index).namespace,
35418 .instructions = .{},35441 .instructions = .{},
35419 .inlining = null,35442 .inlining = null,
35420 .is_comptime = true,35443 .is_comptime = true,
35421 .src_base_inst = struct_type.zir_index.unwrap().?,35444 .src_base_inst = struct_type.zir_index.unwrap().?,
35422 .type_name_ctx = decl.name,35445 .type_name_ctx = struct_type.name,
35423 };35446 };
35424 defer assert(block.instructions.items.len == 0);35447 defer assert(block.instructions.items.len == 0);
3542535448
...@@ -35544,7 +35567,7 @@ pub fn resolveUnionAlignment(...@@ -35544,7 +35567,7 @@ pub fn resolveUnionAlignment(
35544 const ip = &zcu.intern_pool;35567 const ip = &zcu.intern_pool;
35545 const target = zcu.getTarget();35568 const target = zcu.getTarget();
3554635569
35547 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35570 assert(sema.owner.unwrap().cau == union_type.cau);
3554835571
35549 assert(!union_type.haveLayout(ip));35572 assert(!union_type.haveLayout(ip));
3555035573
...@@ -35584,7 +35607,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35584,7 +35607,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35584 // Load again, since the tag type might have changed due to resolution.35607 // Load again, since the tag type might have changed due to resolution.
35585 const union_type = ip.loadUnionType(ty.ip_index);35608 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
35589 const old_flags = union_type.flagsUnordered(ip);35612 const old_flags = union_type.flagsUnordered(ip);
35590 switch (old_flags.status) {35613 switch (old_flags.status) {
...@@ -35697,7 +35720,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35697,7 +35720,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
35697 const ip = &mod.intern_pool;35720 const ip = &mod.intern_pool;
35698 const struct_type = mod.typeToStruct(ty).?;35721 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
35702 if (struct_type.setFullyResolved(ip)) return;35725 if (struct_type.setFullyResolved(ip)) return;
35703 errdefer struct_type.clearFullyResolved(ip);35726 errdefer struct_type.clearFullyResolved(ip);
...@@ -35720,7 +35743,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35720,7 +35743,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35720 const ip = &mod.intern_pool;35743 const ip = &mod.intern_pool;
35721 const union_obj = mod.typeToUnion(ty).?;35744 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
35725 switch (union_obj.flagsUnordered(ip).status) {35748 switch (union_obj.flagsUnordered(ip).status) {
35726 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},35749 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
...@@ -35754,21 +35777,8 @@ pub fn resolveTypeFieldsStruct(...@@ -35754,21 +35777,8 @@ pub fn resolveTypeFieldsStruct(
35754 const pt = sema.pt;35777 const pt = sema.pt;
35755 const zcu = pt.zcu;35778 const zcu = pt.zcu;
35756 const ip = &zcu.intern_pool;35779 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);35781 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
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 }
3577235782
35773 if (struct_type.haveFieldTypes(ip)) return;35783 if (struct_type.haveFieldTypes(ip)) return;
3577435784
...@@ -35783,13 +35793,7 @@ pub fn resolveTypeFieldsStruct(...@@ -35783,13 +35793,7 @@ pub fn resolveTypeFieldsStruct(
35783 defer struct_type.clearFieldTypesWip(ip);35793 defer struct_type.clearFieldTypesWip(ip);
3578435794
35785 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {35795 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
35786 error.AnalysisFail => {35796 error.AnalysisFail, error.OutOfMemory => |e| return e,
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,
35793 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,35797 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35794 };35798 };
35795}35799}
...@@ -35799,9 +35803,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35799,9 +35803,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35799 const zcu = pt.zcu;35803 const zcu = pt.zcu;
35800 const ip = &zcu.intern_pool;35804 const ip = &zcu.intern_pool;
35801 const struct_type = zcu.typeToStruct(ty) orelse return;35805 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
35806 // Inits can start as resolved35809 // Inits can start as resolved
35807 if (struct_type.haveFieldInits(ip)) return;35810 if (struct_type.haveFieldInits(ip)) return;
...@@ -35819,13 +35822,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35819,13 +35822,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35819 defer struct_type.clearInitsWip(ip);35822 defer struct_type.clearInitsWip(ip);
3582035823
35821 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {35824 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {
35822 error.AnalysisFail => {35825 error.AnalysisFail, error.OutOfMemory => |e| return e,
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,
35829 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,35826 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35830 };35827 };
35831 struct_type.setHaveFieldInits(ip);35828 struct_type.setHaveFieldInits(ip);
...@@ -35835,20 +35832,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35835,20 +35832,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35835 const pt = sema.pt;35832 const pt = sema.pt;
35836 const zcu = pt.zcu;35833 const zcu = pt.zcu;
35837 const ip = &zcu.intern_pool;35834 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 }
35852 switch (union_type.flagsUnordered(ip).status) {35838 switch (union_type.flagsUnordered(ip).status) {
35853 .none => {},35839 .none => {},
35854 .field_types_wip => {35840 .field_types_wip => {
...@@ -35869,14 +35855,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35869,14 +35855,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3586935855
35870 union_type.setStatus(ip, .field_types_wip);35856 union_type.setStatus(ip, .field_types_wip);
35871 errdefer union_type.setStatus(ip, .none);35857 errdefer union_type.setStatus(ip, .none);
35872 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {35858 semaUnionFields(pt, sema.arena, ty.toIntern(), union_type) catch |err| switch (err) {
35873 error.AnalysisFail => {35859 error.AnalysisFail, error.OutOfMemory => |e| return e,
35874 if (owner_decl.analysis == .complete) {
35875 owner_decl.analysis = .dependency_failure;
35876 }
35877 return error.AnalysisFail;
35878 },
35879 error.OutOfMemory => return error.OutOfMemory,
35880 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,35860 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35881 };35861 };
35882 union_type.setStatus(ip, .have_field_types);35862 union_type.setStatus(ip, .have_field_types);
...@@ -35891,28 +35871,28 @@ fn resolveInferredErrorSet(...@@ -35891,28 +35871,28 @@ fn resolveInferredErrorSet(
35891 ies_index: InternPool.Index,35871 ies_index: InternPool.Index,
35892) CompileError!InternPool.Index {35872) CompileError!InternPool.Index {
35893 const pt = sema.pt;35873 const pt = sema.pt;
35894 const mod = pt.zcu;35874 const zcu = pt.zcu;
35895 const ip = &mod.intern_pool;35875 const ip = &zcu.intern_pool;
35896 const func_index = ip.iesFuncIndex(ies_index);35876 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
35901 // TODO: during an incremental update this might not be `.none`, but the35881 // TODO: during an incremental update this might not be `.none`, but the
35902 // function might be out-of-date!35882 // function might be out-of-date!
35903 const resolved_ty = func.resolvedErrorSetUnordered(ip);35883 const resolved_ty = func.resolvedErrorSetUnordered(ip);
35904 if (resolved_ty != .none) return resolved_ty;35884 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 }))) {
35907 return sema.fail(block, src, "unable to resolve inferred error set", .{});35887 return sema.fail(block, src, "unable to resolve inferred error set", .{});
35888 }
3590835889
35909 // In order to ensure that all dependencies are properly added to the set,35890 // In order to ensure that all dependencies are properly added to the set,
35910 // we need to ensure the function body is analyzed of the inferred error35891 // we need to ensure the function body is analyzed of the inferred error
35911 // set. However, in the case of comptime/inline function calls with35892 // set. However, in the case of comptime/inline function calls with
35912 // inferred error sets, each call gets an adhoc InferredErrorSet object, which35893 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
35913 // has no corresponding function body.35894 // has no corresponding function body.
35914 const ies_func_owner_decl = mod.declPtr(func.owner_decl);35895 const ies_func_info = zcu.typeToFunc(Type.fromInterned(func.ty)).?;
35915 const ies_func_info = mod.typeToFunc(ies_func_owner_decl.typeOf(mod)).?;
35916 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,35896 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
35917 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,35897 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
35918 // so here we can simply skip this case.35898 // so here we can simply skip this case.
...@@ -35920,22 +35900,17 @@ fn resolveInferredErrorSet(...@@ -35920,22 +35900,17 @@ fn resolveInferredErrorSet(
35920 assert(ies_func_info.cc == .Inline);35900 assert(ies_func_info.cc == .Inline);
35921 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {35901 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {
35922 if (ies_func_info.is_generic) {35902 if (ies_func_info.is_generic) {
35923 const msg = msg: {35903 return sema.failWithOwnedErrorMsg(block, msg: {
35924 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});35904 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});
35925 errdefer msg.destroy(sema.gpa);35905 errdefer msg.destroy(sema.gpa);
3592635906 try sema.errNote(zcu.navSrcLoc(func.owner_nav), msg, "generic function declared here", .{});
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", .{});
35931 break :msg msg;35907 break :msg msg;
35932 };35908 });
35933 return sema.failWithOwnedErrorMsg(block, msg);
35934 }35909 }
35935 // In this case we are dealing with the actual InferredErrorSet object that35910 // In this case we are dealing with the actual InferredErrorSet object that
35936 // corresponds to the function, not one created to track an inline/comptime call.35911 // corresponds to the function, not one created to track an inline/comptime call.
35937 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));35912 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));
35938 try sema.ensureFuncBodyAnalyzed(func_index);35913 try pt.ensureFuncBodyAnalyzed(func_index);
35939 }35914 }
3594035915
35941 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`35916 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`
...@@ -36092,9 +36067,8 @@ fn semaStructFields(...@@ -36092,9 +36067,8 @@ fn semaStructFields(
36092 const zcu = pt.zcu;36067 const zcu = pt.zcu;
36093 const gpa = zcu.gpa;36068 const gpa = zcu.gpa;
36094 const ip = &zcu.intern_pool;36069 const ip = &zcu.intern_pool;
36095 const decl_index = struct_type.decl.unwrap() orelse return;36070 const cau_index = struct_type.cau.unwrap().?;
36096 const decl = zcu.declPtr(decl_index);36071 const namespace_index = ip.getCau(cau_index).namespace;
36097 const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
36098 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;36072 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36099 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);36073 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
3610036074
...@@ -36119,13 +36093,11 @@ fn semaStructFields(...@@ -36119,13 +36093,11 @@ fn semaStructFields(
36119 .gpa = gpa,36093 .gpa = gpa,
36120 .arena = arena,36094 .arena = arena,
36121 .code = zir,36095 .code = zir,
36122 .owner_decl = decl,36096 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
36123 .owner_decl_index = decl_index,
36124 .func_index = .none,36097 .func_index = .none,
36125 .func_is_naked = false,36098 .func_is_naked = false,
36126 .fn_ret_ty = Type.void,36099 .fn_ret_ty = Type.void,
36127 .fn_ret_ty_ies = null,36100 .fn_ret_ty_ies = null,
36128 .owner_func_index = .none,
36129 .comptime_err_ret_trace = &comptime_err_ret_trace,36101 .comptime_err_ret_trace = &comptime_err_ret_trace,
36130 };36102 };
36131 defer sema.deinit();36103 defer sema.deinit();
...@@ -36138,7 +36110,7 @@ fn semaStructFields(...@@ -36138,7 +36110,7 @@ fn semaStructFields(
36138 .inlining = null,36110 .inlining = null,
36139 .is_comptime = true,36111 .is_comptime = true,
36140 .src_base_inst = struct_type.zir_index.unwrap().?,36112 .src_base_inst = struct_type.zir_index.unwrap().?,
36141 .type_name_ctx = decl.name,36113 .type_name_ctx = struct_type.name,
36142 };36114 };
36143 defer assert(block_scope.instructions.items.len == 0);36115 defer assert(block_scope.instructions.items.len == 0);
3614436116
...@@ -36318,9 +36290,8 @@ fn semaStructFieldInits(...@@ -36318,9 +36290,8 @@ fn semaStructFieldInits(
3631836290
36319 assert(!struct_type.haveFieldInits(ip));36291 assert(!struct_type.haveFieldInits(ip));
3632036292
36321 const decl_index = struct_type.decl.unwrap() orelse return;36293 const cau_index = struct_type.cau.unwrap().?;
36322 const decl = zcu.declPtr(decl_index);36294 const namespace_index = ip.getCau(cau_index).namespace;
36323 const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace;
36324 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;36295 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36325 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);36296 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
36326 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);36297 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
...@@ -36333,13 +36304,11 @@ fn semaStructFieldInits(...@@ -36333,13 +36304,11 @@ fn semaStructFieldInits(
36333 .gpa = gpa,36304 .gpa = gpa,
36334 .arena = arena,36305 .arena = arena,
36335 .code = zir,36306 .code = zir,
36336 .owner_decl = decl,36307 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
36337 .owner_decl_index = decl_index,
36338 .func_index = .none,36308 .func_index = .none,
36339 .func_is_naked = false,36309 .func_is_naked = false,
36340 .fn_ret_ty = Type.void,36310 .fn_ret_ty = Type.void,
36341 .fn_ret_ty_ies = null,36311 .fn_ret_ty_ies = null,
36342 .owner_func_index = .none,
36343 .comptime_err_ret_trace = &comptime_err_ret_trace,36312 .comptime_err_ret_trace = &comptime_err_ret_trace,
36344 };36313 };
36345 defer sema.deinit();36314 defer sema.deinit();
...@@ -36352,7 +36321,7 @@ fn semaStructFieldInits(...@@ -36352,7 +36321,7 @@ fn semaStructFieldInits(
36352 .inlining = null,36321 .inlining = null,
36353 .is_comptime = true,36322 .is_comptime = true,
36354 .src_base_inst = struct_type.zir_index.unwrap().?,36323 .src_base_inst = struct_type.zir_index.unwrap().?,
36355 .type_name_ctx = decl.name,36324 .type_name_ctx = struct_type.name,
36356 };36325 };
36357 defer assert(block_scope.instructions.items.len == 0);36326 defer assert(block_scope.instructions.items.len == 0);
3635836327
...@@ -36449,15 +36418,15 @@ fn semaStructFieldInits(...@@ -36449,15 +36418,15 @@ fn semaStructFieldInits(
36449 try sema.flushExports();36418 try sema.flushExports();
36450}36419}
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 {
36453 const tracy = trace(@src());36422 const tracy = trace(@src());
36454 defer tracy.end();36423 defer tracy.end();
3645536424
36456 const zcu = pt.zcu;36425 const zcu = pt.zcu;
36457 const gpa = zcu.gpa;36426 const gpa = zcu.gpa;
36458 const ip = &zcu.intern_pool;36427 const ip = &zcu.intern_pool;
36459 const decl_index = union_type.decl;36428 const cau_index = union_type.cau;
36460 const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir;36429 const zir = zcu.namespacePtr(union_type.namespace).fileScope(zcu).zir;
36461 const zir_index = union_type.zir_index.resolve(ip);36430 const zir_index = union_type.zir_index.resolve(ip);
36462 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;36431 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
36463 assert(extended.opcode == .union_decl);36432 assert(extended.opcode == .union_decl);
...@@ -36501,8 +36470,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36501,8 +36470,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36501 const body = zir.bodySlice(extra_index, body_len);36470 const body = zir.bodySlice(extra_index, body_len);
36502 extra_index += body.len;36471 extra_index += body.len;
3650336472
36504 const decl = zcu.declPtr(decl_index);
36505
36506 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);36473 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
36507 defer comptime_err_ret_trace.deinit();36474 defer comptime_err_ret_trace.deinit();
3650836475
...@@ -36511,13 +36478,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36511,13 +36478,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36511 .gpa = gpa,36478 .gpa = gpa,
36512 .arena = arena,36479 .arena = arena,
36513 .code = zir,36480 .code = zir,
36514 .owner_decl = decl,36481 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
36515 .owner_decl_index = decl_index,
36516 .func_index = .none,36482 .func_index = .none,
36517 .func_is_naked = false,36483 .func_is_naked = false,
36518 .fn_ret_ty = Type.void,36484 .fn_ret_ty = Type.void,
36519 .fn_ret_ty_ies = null,36485 .fn_ret_ty_ies = null,
36520 .owner_func_index = .none,
36521 .comptime_err_ret_trace = &comptime_err_ret_trace,36486 .comptime_err_ret_trace = &comptime_err_ret_trace,
36522 };36487 };
36523 defer sema.deinit();36488 defer sema.deinit();
...@@ -36525,12 +36490,12 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36525,12 +36490,12 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36525 var block_scope: Block = .{36490 var block_scope: Block = .{
36526 .parent = null,36491 .parent = null,
36527 .sema = &sema,36492 .sema = &sema,
36528 .namespace = union_type.namespace.unwrap().?,36493 .namespace = union_type.namespace,
36529 .instructions = .{},36494 .instructions = .{},
36530 .inlining = null,36495 .inlining = null,
36531 .is_comptime = true,36496 .is_comptime = true,
36532 .src_base_inst = union_type.zir_index,36497 .src_base_inst = union_type.zir_index,
36533 .type_name_ctx = decl.name,36498 .type_name_ctx = union_type.name,
36534 };36499 };
36535 defer assert(block_scope.instructions.items.len == 0);36500 defer assert(block_scope.instructions.items.len == 0);
3653636501
...@@ -36817,10 +36782,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36817,10 +36782,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36817 return sema.failWithOwnedErrorMsg(&block_scope, msg);36782 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36818 }36783 }
36819 } else if (enum_field_vals.count() > 0) {36784 } 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);
36821 union_type.setTagType(ip, enum_ty);36786 union_type.setTagType(ip, enum_ty);
36822 } else {36787 } 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);
36824 union_type.setTagType(ip, enum_ty);36789 union_type.setTagType(ip, enum_ty);
36825 }36790 }
3682636791
...@@ -36839,36 +36804,25 @@ fn generateUnionTagTypeNumbered(...@@ -36839,36 +36804,25 @@ fn generateUnionTagTypeNumbered(
36839 block: *Block,36804 block: *Block,
36840 enum_field_names: []const InternPool.NullTerminatedString,36805 enum_field_names: []const InternPool.NullTerminatedString,
36841 enum_field_vals: []const InternPool.Index,36806 enum_field_vals: []const InternPool.Index,
36842 union_owner_decl: *Module.Decl,36807 union_type: InternPool.Index,
36808 union_name: InternPool.NullTerminatedString,
36843) !InternPool.Index {36809) !InternPool.Index {
36844 const pt = sema.pt;36810 const pt = sema.pt;
36845 const mod = pt.zcu;36811 const mod = pt.zcu;
36846 const gpa = sema.gpa;36812 const gpa = sema.gpa;
36847 const ip = &mod.intern_pool;36813 const ip = &mod.intern_pool;
3684836814
36849 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36850 errdefer pt.destroyDecl(new_decl_index);
36851 const name = try ip.getOrPutStringFmt(36815 const name = try ip.getOrPutStringFmt(
36852 gpa,36816 gpa,
36853 pt.tid,36817 pt.tid,
36854 "@typeInfo({}).Union.tag_type.?",36818 "@typeInfo({}).Union.tag_type.?",
36855 .{union_owner_decl.fqn.fmt(ip)},36819 .{union_name.fmt(ip)},
36856 .no_embedded_nulls,36820 .no_embedded_nulls,
36857 );36821 );
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
36869 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{36823 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36870 .decl = new_decl_index,36824 .name = name,
36871 .owner_union_ty = union_owner_decl.val.toIntern(),36825 .owner_union_ty = union_type,
36872 .tag_ty = if (enum_field_vals.len == 0)36826 .tag_ty = if (enum_field_vals.len == 0)
36873 (try pt.intType(.unsigned, 0)).toIntern()36827 (try pt.intType(.unsigned, 0)).toIntern()
36874 else36828 else
...@@ -36876,11 +36830,9 @@ fn generateUnionTagTypeNumbered(...@@ -36876,11 +36830,9 @@ fn generateUnionTagTypeNumbered(
36876 .names = enum_field_names,36830 .names = enum_field_names,
36877 .values = enum_field_vals,36831 .values = enum_field_vals,
36878 .tag_mode = .explicit,36832 .tag_mode = .explicit,
36833 .parent_namespace = block.namespace,
36879 });36834 });
3688036835
36881 new_decl.val = Value.fromInterned(enum_ty);
36882
36883 try pt.finalizeAnonDecl(new_decl_index);
36884 return enum_ty;36836 return enum_ty;
36885}36837}
3688636838
...@@ -36888,36 +36840,25 @@ fn generateUnionTagTypeSimple(...@@ -36888,36 +36840,25 @@ fn generateUnionTagTypeSimple(
36888 sema: *Sema,36840 sema: *Sema,
36889 block: *Block,36841 block: *Block,
36890 enum_field_names: []const InternPool.NullTerminatedString,36842 enum_field_names: []const InternPool.NullTerminatedString,
36891 union_owner_decl: *Module.Decl,36843 union_type: InternPool.Index,
36844 union_name: InternPool.NullTerminatedString,
36892) !InternPool.Index {36845) !InternPool.Index {
36893 const pt = sema.pt;36846 const pt = sema.pt;
36894 const mod = pt.zcu;36847 const mod = pt.zcu;
36895 const ip = &mod.intern_pool;36848 const ip = &mod.intern_pool;
36896 const gpa = sema.gpa;36849 const gpa = sema.gpa;
3689736850
36898 const new_decl_index = new_decl_index: {36851 const name = try ip.getOrPutStringFmt(
36899 const new_decl_index = try pt.allocateNewDecl(block.namespace);36852 gpa,
36900 errdefer pt.destroyDecl(new_decl_index);36853 pt.tid,
36901 const name = try ip.getOrPutStringFmt(36854 "@typeInfo({}).Union.tag_type.?",
36902 gpa,36855 .{union_name.fmt(ip)},
36903 pt.tid,36856 .no_embedded_nulls,
36904 "@typeInfo({}).Union.tag_type.?",36857 );
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);
3691736858
36918 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{36859 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36919 .decl = new_decl_index,36860 .name = name,
36920 .owner_union_ty = union_owner_decl.val.toIntern(),36861 .owner_union_ty = union_type,
36921 .tag_ty = if (enum_field_names.len == 0)36862 .tag_ty = if (enum_field_names.len == 0)
36922 (try pt.intType(.unsigned, 0)).toIntern()36863 (try pt.intType(.unsigned, 0)).toIntern()
36923 else36864 else
...@@ -36925,13 +36866,9 @@ fn generateUnionTagTypeSimple(...@@ -36925,13 +36866,9 @@ fn generateUnionTagTypeSimple(
36925 .names = enum_field_names,36866 .names = enum_field_names,
36926 .values = &.{},36867 .values = &.{},
36927 .tag_mode = .auto,36868 .tag_mode = .auto,
36869 .parent_namespace = block.namespace,
36928 });36870 });
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);
36935 return enum_ty;36872 return enum_ty;
36936}36873}
3693736874
...@@ -37057,9 +36994,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37057,9 +36994,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37057 // values, not types36994 // values, not types
37058 .undef,36995 .undef,
37059 .simple_value,36996 .simple_value,
37060 .ptr_decl,36997 .ptr_nav,
37061 .ptr_anon_decl,36998 .ptr_uav,
37062 .ptr_anon_decl_aligned,36999 .ptr_uav_aligned,
37063 .ptr_comptime_alloc,37000 .ptr_comptime_alloc,
37064 .ptr_comptime_field,37001 .ptr_comptime_field,
37065 .ptr_int,37002 .ptr_int,
...@@ -37096,7 +37033,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37096,7 +37033,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37096 .float_c_longdouble_f128,37033 .float_c_longdouble_f128,
37097 .float_comptime_float,37034 .float_comptime_float,
37098 .variable,37035 .variable,
37099 .extern_func,37036 .@"extern",
37100 .func_decl,37037 .func_decl,
37101 .func_instance,37038 .func_instance,
37102 .func_coerced,37039 .func_coerced,
...@@ -37965,7 +37902,7 @@ fn intFitsInType(...@@ -37965,7 +37902,7 @@ fn intFitsInType(
37965 .zero_usize, .zero_u8 => return true,37902 .zero_usize, .zero_u8 => return true,
37966 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {37903 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
37967 .undef => return true,37904 .undef => return true,
37968 .variable, .extern_func, .func, .ptr => {37905 .variable, .@"extern", .func, .ptr => {
37969 const target = mod.getTarget();37906 const target = mod.getTarget();
37970 const ptr_bits = target.ptrBitWidth();37907 const ptr_bits = target.ptrBitWidth();
37971 return switch (info.signedness) {37908 return switch (info.signedness) {
...@@ -38240,24 +38177,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {...@@ -38240,24 +38177,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
38240 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would38177 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
38241 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve38178 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
38242 // the loop.38179 // the loop.
38243 if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) {38180 switch (sema.owner.unwrap()) {
38244 return;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 => {},
38245 }38188 }
3824638189
38247 const depender = AnalUnit.wrap(38190 try zcu.intern_pool.addDependency(sema.gpa, sema.owner, dependee);
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);
38254}38191}
3825538192
38256fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {38193fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
38257 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {38194 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
38258 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),38195 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),
38259 .ptr => |ptr| switch (ptr.base_addr) {38196 .ptr => |ptr| switch (ptr.base_addr) {
38260 .anon_decl, .decl, .int => false,38197 .uav, .nav, .int => false,
38261 .comptime_field => true,38198 .comptime_field => true,
38262 .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const,38199 .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const,
38263 .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)),38200 .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)),
...@@ -38388,19 +38325,17 @@ pub fn flushExports(sema: *Sema) !void {...@@ -38388,19 +38325,17 @@ pub fn flushExports(sema: *Sema) !void {
38388 const zcu = sema.pt.zcu;38325 const zcu = sema.pt.zcu;
38389 const gpa = zcu.gpa;38326 const gpa = zcu.gpa;
3839038327
38391 const unit = sema.ownerUnit();
38392
38393 // There may be existing exports. For instance, a struct may export38328 // There may be existing exports. For instance, a struct may export
38394 // things during both field type resolution and field default resolution.38329 // things during both field type resolution and field default resolution.
38395 //38330 //
38396 // So, pick up and delete any existing exports. This strategy performs38331 // So, pick up and delete any existing exports. This strategy performs
38397 // redundant work, but that's okay, because this case is exceedingly rare.38332 // 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| {
38399 try sema.exports.append(gpa, zcu.all_exports.items[export_idx]);38334 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| {
38401 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);38336 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
38402 }38337 }
38403 zcu.deleteUnitExports(unit);38338 zcu.deleteUnitExports(sema.owner);
3840438339
38405 // `sema.exports` is completed; store the data into the `Zcu`.38340 // `sema.exports` is completed; store the data into the `Zcu`.
38406 if (sema.exports.items.len == 1) {38341 if (sema.exports.items.len == 1) {
...@@ -38410,24 +38345,55 @@ pub fn flushExports(sema: *Sema) !void {...@@ -38410,24 +38345,55 @@ pub fn flushExports(sema: *Sema) !void {
38410 break :idx zcu.all_exports.items.len - 1;38345 break :idx zcu.all_exports.items.len - 1;
38411 };38346 };
38412 zcu.all_exports.items[export_idx] = sema.exports.items[0];38347 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));
38414 } else {38349 } else {
38415 try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);38350 try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);
38416 const exports_base = zcu.all_exports.items.len;38351 const exports_base = zcu.all_exports.items.len;
38417 try zcu.all_exports.appendSlice(gpa, sema.exports.items);38352 try zcu.all_exports.appendSlice(gpa, sema.exports.items);
38418 zcu.multi_exports.putAssumeCapacityNoClobber(unit, .{38353 zcu.multi_exports.putAssumeCapacityNoClobber(sema.owner, .{
38419 .index = @intCast(exports_base),38354 .index = @intCast(exports_base),
38420 .len = @intCast(sema.exports.items.len),38355 .len = @intCast(sema.exports.items.len),
38421 });38356 });
38422 }38357 }
38423}38358}
3842438359
38425pub fn ownerUnit(sema: Sema) AnalUnit {38360/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38426 if (sema.owner_func_index != .none) {38361/// the corresponding `Nav`.
38427 return AnalUnit.wrap(.{ .func = sema.owner_func_index });38362fn getOwnerCauNav(sema: *Sema) InternPool.Nav.Index {
38428 } else {38363 const cau = sema.owner.unwrap().cau;
38429 return AnalUnit.wrap(.{ .decl = sema.owner_decl_index });38364 return sema.pt.zcu.intern_pool.getCau(cau).owner.unwrap().nav;
38430 }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;
38431}38397}
3843238398
38433pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;38399pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;
src/Sema/bitcast.zig+1-1
...@@ -254,7 +254,7 @@ const UnpackValueBits = struct {...@@ -254,7 +254,7 @@ const UnpackValueBits = struct {
254 .error_set_type,254 .error_set_type,
255 .inferred_error_set_type,255 .inferred_error_set_type,
256 .variable,256 .variable,
257 .extern_func,257 .@"extern",
258 .func,258 .func,
259 .err,259 .err,
260 .error_union,260 .error_union,
src/Sema/comptime_ptr_access.zig+16-8
...@@ -217,15 +217,23 @@ fn loadComptimePtrInner(...@@ -217,15 +217,23 @@ fn loadComptimePtrInner(
217 };217 };
218218
219 const base_val: MutableValue = switch (ptr.base_addr) {219 const base_val: MutableValue = switch (ptr.base_addr) {
220 .decl => |decl_index| val: {220 .nav => |nav| val: {
221 try sema.declareDependency(.{ .decl_val = decl_index });221 try sema.declareDependency(.{ .nav_val = nav });
222 try sema.ensureDeclAnalyzed(decl_index);222 try sema.ensureNavResolved(src, nav);
223 const decl = zcu.declPtr(decl_index);223 const val = ip.getNav(nav).status.resolved.val;
224 if (decl.val.getVariable(zcu) != null) return .runtime_load;224 switch (ip.indexToKey(val)) {
225 break :val .{ .interned = decl.val.toIntern() };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 }
226 },234 },
227 .comptime_alloc => |alloc_index| sema.getComptimeAlloc(alloc_index).val,235 .comptime_alloc => |alloc_index| sema.getComptimeAlloc(alloc_index).val,
228 .anon_decl => |anon_decl| .{ .interned = anon_decl.val },236 .uav => |uav| .{ .interned = uav.val },
229 .comptime_field => |val| .{ .interned = val },237 .comptime_field => |val| .{ .interned = val },
230 .int => return .runtime_load,238 .int => return .runtime_load,
231 .eu_payload => |base_ptr_ip| val: {239 .eu_payload => |base_ptr_ip| val: {
...@@ -580,7 +588,7 @@ fn prepareComptimePtrStore(...@@ -580,7 +588,7 @@ fn prepareComptimePtrStore(
580588
581 // `base_strat` will not be an error case.589 // `base_strat` will not be an error case.
582 const base_strat: ComptimeStoreStrategy = switch (ptr.base_addr) {590 const base_strat: ComptimeStoreStrategy = switch (ptr.base_addr) {
583 .decl, .anon_decl, .int => return .runtime_store,591 .nav, .uav, .int => return .runtime_store,
584 .comptime_field => return .comptime_field,592 .comptime_field => return .comptime_field,
585 .comptime_alloc => |alloc_index| .{ .direct = .{593 .comptime_alloc => |alloc_index| .{ .direct = .{
586 .alloc = alloc_index,594 .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...@@ -268,9 +268,9 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
268 return;268 return;
269 },269 },
270 .inferred_error_set_type => |func_index| {270 .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);
272 try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{272 try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{
273 owner_decl.fqn.fmt(ip),273 func_nav.fqn.fmt(ip),
274 });274 });
275 },275 },
276 .error_set_type => |error_set_type| {276 .error_set_type => |error_set_type| {
...@@ -331,15 +331,11 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -331,15 +331,11 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
331 .generic_poison => unreachable,331 .generic_poison => unreachable,
332 },332 },
333 .struct_type => {333 .struct_type => {
334 const struct_type = ip.loadStructType(ty.toIntern());334 const name = ip.loadStructType(ty.toIntern()).name;
335 if (struct_type.decl.unwrap()) |decl_index| {335 if (name == .empty) {
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 {
342 try writer.writeAll("@TypeOf(.{})");336 try writer.writeAll("@TypeOf(.{})");
337 } else {
338 try writer.print("{}", .{name.fmt(ip)});
343 }339 }
344 },340 },
345 .anon_struct_type => |anon_struct| {341 .anon_struct_type => |anon_struct| {
...@@ -366,16 +362,16 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -366,16 +362,16 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
366 },362 },
367363
368 .union_type => {364 .union_type => {
369 const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl);365 const name = ip.loadUnionType(ty.toIntern()).name;
370 try writer.print("{}", .{decl.fqn.fmt(ip)});366 try writer.print("{}", .{name.fmt(ip)});
371 },367 },
372 .opaque_type => {368 .opaque_type => {
373 const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl);369 const name = ip.loadOpaqueType(ty.toIntern()).name;
374 try writer.print("{}", .{decl.fqn.fmt(ip)});370 try writer.print("{}", .{name.fmt(ip)});
375 },371 },
376 .enum_type => {372 .enum_type => {
377 const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl);373 const name = ip.loadEnumType(ty.toIntern()).name;
378 try writer.print("{}", .{decl.fqn.fmt(ip)});374 try writer.print("{}", .{name.fmt(ip)});
379 },375 },
380 .func_type => |fn_info| {376 .func_type => |fn_info| {
381 if (fn_info.is_noinline) {377 if (fn_info.is_noinline) {
...@@ -427,7 +423,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -427,7 +423,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
427 .undef,423 .undef,
428 .simple_value,424 .simple_value,
429 .variable,425 .variable,
430 .extern_func,426 .@"extern",
431 .func,427 .func,
432 .int,428 .int,
433 .err,429 .err,
...@@ -645,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced(...@@ -645,7 +641,7 @@ pub fn hasRuntimeBitsAdvanced(
645 .undef,641 .undef,
646 .simple_value,642 .simple_value,
647 .variable,643 .variable,
648 .extern_func,644 .@"extern",
649 .func,645 .func,
650 .int,646 .int,
651 .err,647 .err,
...@@ -757,7 +753,7 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {...@@ -757,7 +753,7 @@ pub fn hasWellDefinedLayout(ty: Type, mod: *Module) bool {
757 .undef,753 .undef,
758 .simple_value,754 .simple_value,
759 .variable,755 .variable,
760 .extern_func,756 .@"extern",
761 .func,757 .func,
762 .int,758 .int,
763 .err,759 .err,
...@@ -1108,7 +1104,7 @@ pub fn abiAlignmentAdvanced(...@@ -1108,7 +1104,7 @@ pub fn abiAlignmentAdvanced(
1108 .undef,1104 .undef,
1109 .simple_value,1105 .simple_value,
1110 .variable,1106 .variable,
1111 .extern_func,1107 .@"extern",
1112 .func,1108 .func,
1113 .int,1109 .int,
1114 .err,1110 .err,
...@@ -1483,7 +1479,7 @@ pub fn abiSizeAdvanced(...@@ -1483,7 +1479,7 @@ pub fn abiSizeAdvanced(
1483 .undef,1479 .undef,
1484 .simple_value,1480 .simple_value,
1485 .variable,1481 .variable,
1486 .extern_func,1482 .@"extern",
1487 .func,1483 .func,
1488 .int,1484 .int,
1489 .err,1485 .err,
...@@ -1813,7 +1809,7 @@ pub fn bitSizeAdvanced(...@@ -1813,7 +1809,7 @@ pub fn bitSizeAdvanced(
1813 .undef,1809 .undef,
1814 .simple_value,1810 .simple_value,
1815 .variable,1811 .variable,
1816 .extern_func,1812 .@"extern",
1817 .func,1813 .func,
1818 .int,1814 .int,
1819 .err,1815 .err,
...@@ -2351,7 +2347,7 @@ pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType {...@@ -2351,7 +2347,7 @@ pub fn intInfo(starting_ty: Type, mod: *Module) InternPool.Key.IntType {
2351 .undef,2347 .undef,
2352 .simple_value,2348 .simple_value,
2353 .variable,2349 .variable,
2354 .extern_func,2350 .@"extern",
2355 .func,2351 .func,
2356 .int,2352 .int,
2357 .err,2353 .err,
...@@ -2700,7 +2696,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {...@@ -2700,7 +2696,7 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
2700 .undef,2696 .undef,
2701 .simple_value,2697 .simple_value,
2702 .variable,2698 .variable,
2703 .extern_func,2699 .@"extern",
2704 .func,2700 .func,
2705 .int,2701 .int,
2706 .err,2702 .err,
...@@ -2899,7 +2895,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve...@@ -2899,7 +2895,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, pt: Zcu.PerThread, comptime strat: Resolve
2899 .undef,2895 .undef,
2900 .simple_value,2896 .simple_value,
2901 .variable,2897 .variable,
2902 .extern_func,2898 .@"extern",
2903 .func,2899 .func,
2904 .int,2900 .int,
2905 .err,2901 .err,
...@@ -2972,41 +2968,27 @@ pub fn indexableHasLen(ty: Type, mod: *Module) bool {...@@ -2972,41 +2968,27 @@ pub fn indexableHasLen(ty: Type, mod: *Module) bool {
2972}2968}
29732969
2974/// Asserts that the type can have a namespace.2970/// Asserts that the type can have a namespace.
2975pub fn getNamespaceIndex(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex {2971pub fn getNamespaceIndex(ty: Type, zcu: *Zcu) InternPool.NamespaceIndex {
2976 return ty.getNamespace(zcu).?;2972 return ty.getNamespace(zcu).unwrap().?;
2977}2973}
29782974
2979/// Returns null if the type has no namespace.2975/// 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 {
2981 const ip = &zcu.intern_pool;2977 const ip = &zcu.intern_pool;
2982 return switch (ip.indexToKey(ty.toIntern())) {2978 return switch (ip.indexToKey(ty.toIntern())) {
2983 .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace,2979 .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(),
2984 .struct_type => ip.loadStructType(ty.toIntern()).namespace,2980 .struct_type => ip.loadStructType(ty.toIntern()).namespace,
2985 .union_type => ip.loadUnionType(ty.toIntern()).namespace,2981 .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(),
2986 .enum_type => ip.loadEnumType(ty.toIntern()).namespace,2982 .enum_type => ip.loadEnumType(ty.toIntern()).namespace.toOptional(),
29872983 else => .none,
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,
3007 };2984 };
3008}2985}
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
3010// Works for vectors and vectors of integers.2992// Works for vectors and vectors of integers.
3011pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {2993pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3012 const mod = pt.zcu;2994 const mod = pt.zcu;
...@@ -3321,21 +3303,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {...@@ -3321,21 +3303,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {
3321 }3303 }
3322}3304}
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
3339pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {3306pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {
3340 const ip = &zcu.intern_pool;3307 const ip = &zcu.intern_pool;
3341 return .{3308 return .{
...@@ -3366,7 +3333,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {...@@ -3366,7 +3333,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {
3366 .struct_type => {3333 .struct_type => {
3367 const struct_type = ip.loadStructType(ty.toIntern());3334 const struct_type = ip.loadStructType(ty.toIntern());
3368 if (struct_type.layout == .@"packed") return false;3335 if (struct_type.layout == .@"packed") return false;
3369 if (struct_type.decl == .none) return false;3336 if (struct_type.cau == .none) return false;
3370 return struct_type.flagsUnordered(ip).is_tuple;3337 return struct_type.flagsUnordered(ip).is_tuple;
3371 },3338 },
3372 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,3339 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,
...@@ -3388,7 +3355,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {...@@ -3388,7 +3355,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {
3388 .struct_type => {3355 .struct_type => {
3389 const struct_type = ip.loadStructType(ty.toIntern());3356 const struct_type = ip.loadStructType(ty.toIntern());
3390 if (struct_type.layout == .@"packed") return false;3357 if (struct_type.layout == .@"packed") return false;
3391 if (struct_type.decl == .none) return false;3358 if (struct_type.cau == .none) return false;
3392 return struct_type.flagsUnordered(ip).is_tuple;3359 return struct_type.flagsUnordered(ip).is_tuple;
3393 },3360 },
3394 .anon_struct_type => true,3361 .anon_struct_type => true,
...@@ -3444,6 +3411,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {...@@ -3444,6 +3411,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3444 };3411 };
3445}3412}
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
3447pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {3429pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3448 const ip = &zcu.intern_pool;3430 const ip = &zcu.intern_pool;
3449 const tracked = switch (ip.indexToKey(ty.toIntern())) {3431 const tracked = switch (ip.indexToKey(ty.toIntern())) {
...@@ -3471,7 +3453,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {...@@ -3471,7 +3453,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3471 };3453 };
3472}3454}
34733455
3474/// Given a namespace type, returns its list of caotured values.3456/// Given a namespace type, returns its list of captured values.
3475pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {3457pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
3476 const ip = &zcu.intern_pool;3458 const ip = &zcu.intern_pool;
3477 return switch (ip.indexToKey(ty.toIntern())) {3459 return switch (ip.indexToKey(ty.toIntern())) {
...@@ -3773,7 +3755,11 @@ fn resolveStructInner(...@@ -3773,7 +3755,11 @@ fn resolveStructInner(
3773 const gpa = zcu.gpa;3755 const gpa = zcu.gpa;
37743756
3775 const struct_obj = zcu.typeToStruct(ty).?;3757 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
3778 var analysis_arena = std.heap.ArenaAllocator.init(gpa);3764 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3779 defer analysis_arena.deinit();3765 defer analysis_arena.deinit();
...@@ -3786,24 +3772,30 @@ fn resolveStructInner(...@@ -3786,24 +3772,30 @@ fn resolveStructInner(
3786 .gpa = gpa,3772 .gpa = gpa,
3787 .arena = analysis_arena.allocator(),3773 .arena = analysis_arena.allocator(),
3788 .code = undefined, // This ZIR will not be used.3774 .code = undefined, // This ZIR will not be used.
3789 .owner_decl = zcu.declPtr(owner_decl_index),3775 .owner = owner,
3790 .owner_decl_index = owner_decl_index,
3791 .func_index = .none,3776 .func_index = .none,
3792 .func_is_naked = false,3777 .func_is_naked = false,
3793 .fn_ret_ty = Type.void,3778 .fn_ret_ty = Type.void,
3794 .fn_ret_ty_ies = null,3779 .fn_ret_ty_ies = null,
3795 .owner_func_index = .none,
3796 .comptime_err_ret_trace = &comptime_err_ret_trace,3780 .comptime_err_ret_trace = &comptime_err_ret_trace,
3797 };3781 };
3798 defer sema.deinit();3782 defer sema.deinit();
37993783
3800 switch (resolution) {3784 (switch (resolution) {
3801 .fields => return sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),3785 .fields => sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),
3802 .inits => return sema.resolveStructFieldInits(ty),3786 .inits => sema.resolveStructFieldInits(ty),
3803 .alignment => return sema.resolveStructAlignment(ty.toIntern(), struct_obj),3787 .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3804 .layout => return sema.resolveStructLayout(ty),3788 .layout => sema.resolveStructLayout(ty),
3805 .full => return sema.resolveStructFully(ty),3789 .full => sema.resolveStructFully(ty),
3806 }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 };
3807}3799}
38083800
3809/// `ty` must be a union.3801/// `ty` must be a union.
...@@ -3816,7 +3808,11 @@ fn resolveUnionInner(...@@ -3816,7 +3808,11 @@ fn resolveUnionInner(
3816 const gpa = zcu.gpa;3808 const gpa = zcu.gpa;
38173809
3818 const union_obj = zcu.typeToUnion(ty).?;3810 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
3821 var analysis_arena = std.heap.ArenaAllocator.init(gpa);3817 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3822 defer analysis_arena.deinit();3818 defer analysis_arena.deinit();
...@@ -3829,23 +3825,29 @@ fn resolveUnionInner(...@@ -3829,23 +3825,29 @@ fn resolveUnionInner(
3829 .gpa = gpa,3825 .gpa = gpa,
3830 .arena = analysis_arena.allocator(),3826 .arena = analysis_arena.allocator(),
3831 .code = undefined, // This ZIR will not be used.3827 .code = undefined, // This ZIR will not be used.
3832 .owner_decl = zcu.declPtr(owner_decl_index),3828 .owner = owner,
3833 .owner_decl_index = owner_decl_index,
3834 .func_index = .none,3829 .func_index = .none,
3835 .func_is_naked = false,3830 .func_is_naked = false,
3836 .fn_ret_ty = Type.void,3831 .fn_ret_ty = Type.void,
3837 .fn_ret_ty_ies = null,3832 .fn_ret_ty_ies = null,
3838 .owner_func_index = .none,
3839 .comptime_err_ret_trace = &comptime_err_ret_trace,3833 .comptime_err_ret_trace = &comptime_err_ret_trace,
3840 };3834 };
3841 defer sema.deinit();3835 defer sema.deinit();
38423836
3843 switch (resolution) {3837 (switch (resolution) {
3844 .fields => return sema.resolveTypeFieldsUnion(ty, union_obj),3838 .fields => sema.resolveTypeFieldsUnion(ty, union_obj),
3845 .alignment => return sema.resolveUnionAlignment(ty, union_obj),3839 .alignment => sema.resolveUnionAlignment(ty, union_obj),
3846 .layout => return sema.resolveUnionLayout(ty),3840 .layout => sema.resolveUnionLayout(ty),
3847 .full => return sema.resolveUnionFully(ty),3841 .full => sema.resolveUnionFully(ty),
3848 }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 };
3849}3851}
38503852
3851/// Fully resolves a simple type. This is usually a nop, but for builtin types with3853/// 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 {...@@ -3945,6 +3947,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {
3945 });3947 });
3946}3948}
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
3948pub const @"u1": Type = .{ .ip_index = .u1_type };3960pub const @"u1": Type = .{ .ip_index = .u1_type };
3949pub const @"u8": Type = .{ .ip_index = .u8_type };3961pub const @"u8": Type = .{ .ip_index = .u8_type };
3950pub const @"u16": Type = .{ .ip_index = .u16_type };3962pub 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 {...@@ -227,13 +227,6 @@ pub fn getFunction(val: Value, mod: *Module) ?InternPool.Key.Func {
227 };227 };
228}228}
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
237pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {230pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
238 return switch (mod.intern_pool.indexToKey(val.toIntern())) {231 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
239 .variable => |variable| variable,232 .variable => |variable| variable,
...@@ -319,17 +312,8 @@ pub fn toBool(val: Value) bool {...@@ -319,17 +312,8 @@ pub fn toBool(val: Value) bool {
319 };312 };
320}313}
321314
322fn ptrHasIntAddr(val: Value, mod: *Module) bool {315fn ptrHasIntAddr(val: Value, zcu: *Zcu) bool {
323 var check = val;316 return zcu.intern_pool.getBackingAddrTag(val.toIntern()).? == .int;
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 };
333}317}
334318
335/// Write a Value's contents to `buffer`.319/// Write a Value's contents to `buffer`.
...@@ -1058,7 +1042,7 @@ pub fn orderAgainstZeroAdvanced(...@@ -1058,7 +1042,7 @@ pub fn orderAgainstZeroAdvanced(
1058 .bool_true => .gt,1042 .bool_true => .gt,
1059 else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) {1043 else => switch (pt.zcu.intern_pool.indexToKey(lhs.toIntern())) {
1060 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {1044 .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,
1062 .int => .eq,1046 .int => .eq,
1063 else => unreachable,1047 else => unreachable,
1064 },1048 },
...@@ -1130,11 +1114,11 @@ pub fn compareHeteroAdvanced(...@@ -1130,11 +1114,11 @@ pub fn compareHeteroAdvanced(
1130 pt: Zcu.PerThread,1114 pt: Zcu.PerThread,
1131 comptime strat: ResolveStrat,1115 comptime strat: ResolveStrat,
1132) !bool {1116) !bool {
1133 if (lhs.pointerDecl(pt.zcu)) |lhs_decl| {1117 if (lhs.pointerNav(pt.zcu)) |lhs_nav| {
1134 if (rhs.pointerDecl(pt.zcu)) |rhs_decl| {1118 if (rhs.pointerNav(pt.zcu)) |rhs_nav| {
1135 switch (op) {1119 switch (op) {
1136 .eq => return lhs_decl == rhs_decl,1120 .eq => return lhs_nav == rhs_nav,
1137 .neq => return lhs_decl != rhs_decl,1121 .neq => return lhs_nav != rhs_nav,
1138 else => {},1122 else => {},
1139 }1123 }
1140 } else {1124 } else {
...@@ -1144,7 +1128,7 @@ pub fn compareHeteroAdvanced(...@@ -1144,7 +1128,7 @@ pub fn compareHeteroAdvanced(
1144 else => {},1128 else => {},
1145 }1129 }
1146 }1130 }
1147 } else if (rhs.pointerDecl(pt.zcu)) |_| {1131 } else if (rhs.pointerNav(pt.zcu)) |_| {
1148 switch (op) {1132 switch (op) {
1149 .eq => return false,1133 .eq => return false,
1150 .neq => return true,1134 .neq => return true,
...@@ -1252,12 +1236,12 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {...@@ -1252,12 +1236,12 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {
1252 .payload => |payload| Value.fromInterned(payload).canMutateComptimeVarState(zcu),1236 .payload => |payload| Value.fromInterned(payload).canMutateComptimeVarState(zcu),
1253 },1237 },
1254 .ptr => |ptr| switch (ptr.base_addr) {1238 .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.
1256 .int => false,1240 .int => false,
1257 .comptime_alloc => true, // A comptime alloc is either mutable or references comptime-mutable memory.1241 .comptime_alloc => true, // A comptime alloc is either mutable or references comptime-mutable memory.
1258 .comptime_field => true, // Comptime field pointers are comptime-mutable, albeit only to the "correct" value.1242 .comptime_field => true, // Comptime field pointers are comptime-mutable, albeit only to the "correct" value.
1259 .eu_payload, .opt_payload => |base| Value.fromInterned(base).canMutateComptimeVarState(zcu),1243 .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),
1261 .arr_elem, .field => |base_index| Value.fromInterned(base_index.base).canMutateComptimeVarState(zcu),1245 .arr_elem, .field => |base_index| Value.fromInterned(base_index.base).canMutateComptimeVarState(zcu),
1262 },1246 },
1263 .slice => |slice| return Value.fromInterned(slice.ptr).canMutateComptimeVarState(zcu),1247 .slice => |slice| return Value.fromInterned(slice.ptr).canMutateComptimeVarState(zcu),
...@@ -1273,16 +1257,17 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {...@@ -1273,16 +1257,17 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {
1273 };1257 };
1274}1258}
12751259
1276/// Gets the decl referenced by this pointer. If the pointer does not point1260/// Gets the `Nav` 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),1261/// to a `Nav`, or if it points to some part of one (like a field or element),
1278/// this function returns null.1262/// returns null.
1279pub fn pointerDecl(val: Value, mod: *Module) ?InternPool.DeclIndex {1263pub fn pointerNav(val: Value, mod: *Module) ?InternPool.Nav.Index {
1280 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1264 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1281 .variable => |variable| variable.decl,1265 // TODO: these 3 cases are weird; these aren't pointer values!
1282 .extern_func => |extern_func| extern_func.decl,1266 .variable => |v| v.owner_nav,
1283 .func => |func| func.owner_decl,1267 .@"extern" => |e| e.owner_nav,
1268 .func => |func| func.owner_nav,
1284 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {1269 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1285 .decl => |decl| decl,1270 .nav => |nav| nav,
1286 else => null,1271 else => null,
1287 } else null,1272 } else null,
1288 else => null,1273 else => null,
...@@ -1341,10 +1326,14 @@ pub fn isLazySize(val: Value, mod: *Module) bool {...@@ -1341,10 +1326,14 @@ pub fn isLazySize(val: Value, mod: *Module) bool {
1341 };1326 };
1342}1327}
13431328
1344pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {1329pub fn isPtrToThreadLocal(val: Value, zcu: *Zcu) bool {
1345 const backing_decl = mod.intern_pool.getBackingDecl(val.toIntern()).unwrap() orelse return false;1330 const ip = &zcu.intern_pool;
1346 const variable = mod.declPtr(backing_decl).getOwnedVariable(mod) orelse return false;1331 const nav = ip.getBackingNav(val.toIntern()).unwrap() orelse return false;
1347 return variable.is_threadlocal;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 };
1348}1337}
13491338
1350// Asserts that the provided start/end are in-bounds.1339// Asserts that the provided start/end are in-bounds.
...@@ -4031,8 +4020,8 @@ pub const PointerDeriveStep = union(enum) {...@@ -4031,8 +4020,8 @@ pub const PointerDeriveStep = union(enum) {
4031 addr: u64,4020 addr: u64,
4032 ptr_ty: Type,4021 ptr_ty: Type,
4033 },4022 },
4034 decl_ptr: InternPool.DeclIndex,4023 nav_ptr: InternPool.Nav.Index,
4035 anon_decl_ptr: InternPool.Key.Ptr.BaseAddr.AnonDecl,4024 uav_ptr: InternPool.Key.Ptr.BaseAddr.Uav,
4036 comptime_alloc_ptr: struct {4025 comptime_alloc_ptr: struct {
4037 val: Value,4026 val: Value,
4038 ptr_ty: Type,4027 ptr_ty: Type,
...@@ -4069,8 +4058,8 @@ pub const PointerDeriveStep = union(enum) {...@@ -4069,8 +4058,8 @@ pub const PointerDeriveStep = union(enum) {
4069 pub fn ptrType(step: PointerDeriveStep, pt: Zcu.PerThread) !Type {4058 pub fn ptrType(step: PointerDeriveStep, pt: Zcu.PerThread) !Type {
4070 return switch (step) {4059 return switch (step) {
4071 .int => |int| int.ptr_ty,4060 .int => |int| int.ptr_ty,
4072 .decl_ptr => |decl| try pt.zcu.declPtr(decl).declPtrType(pt),4061 .nav_ptr => |nav| try pt.navPtrType(nav),
4073 .anon_decl_ptr => |ad| Type.fromInterned(ad.orig_ty),4062 .uav_ptr => |uav| Type.fromInterned(uav.orig_ty),
4074 .comptime_alloc_ptr => |info| info.ptr_ty,4063 .comptime_alloc_ptr => |info| info.ptr_ty,
4075 .comptime_field_ptr => |val| try pt.singleConstPtrType(val.typeOf(pt.zcu)),4064 .comptime_field_ptr => |val| try pt.singleConstPtrType(val.typeOf(pt.zcu)),
4076 .offset_and_cast => |oac| oac.new_ptr_ty,4065 .offset_and_cast => |oac| oac.new_ptr_ty,
...@@ -4098,17 +4087,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh...@@ -4098,17 +4087,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
4098 .addr = ptr.byte_offset,4087 .addr = ptr.byte_offset,
4099 .ptr_ty = Type.fromInterned(ptr.ty),4088 .ptr_ty = Type.fromInterned(ptr.ty),
4100 } },4089 } },
4101 .decl => |decl| .{ .decl_ptr = decl },4090 .nav => |nav| .{ .nav_ptr = nav },
4102 .anon_decl => |ad| base: {4091 .uav => |uav| base: {
4103 // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be.4092 // A slight tweak: `orig_ty` here is sometimes not `const`, but it ought to be.
4104 // TODO: fix this in the sites interning anon decls!4093 // TODO: fix this in the sites interning anon decls!
4105 const const_ty = try pt.ptrType(info: {4094 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);
4107 info.flags.is_const = true;4096 info.flags.is_const = true;
4108 break :info info;4097 break :info info;
4109 });4098 });
4110 break :base .{ .anon_decl_ptr = .{4099 break :base .{ .uav_ptr = .{
4111 .val = ad.val,4100 .val = uav.val,
4112 .orig_ty = const_ty.toIntern(),4101 .orig_ty = const_ty.toIntern(),
4113 } };4102 } };
4114 },4103 },
...@@ -4357,7 +4346,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaErro...@@ -4357,7 +4346,7 @@ pub fn resolveLazy(val: Value, arena: Allocator, pt: Zcu.PerThread) Zcu.SemaErro
4357 },4346 },
4358 .ptr => |ptr| {4347 .ptr => |ptr| {
4359 switch (ptr.base_addr) {4348 switch (ptr.base_addr) {
4360 .decl, .comptime_alloc, .anon_decl, .int => return val,4349 .nav, .comptime_alloc, .uav, .int => return val,
4361 .comptime_field => |field_val| {4350 .comptime_field => |field_val| {
4362 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern();4351 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern();
4363 return if (resolved_field_val == field_val)4352 return if (resolved_field_val == field_val)
src/Zcu.zig+143-521
...@@ -118,8 +118,15 @@ embed_table: std.StringArrayHashMapUnmanaged(*EmbedFile) = .{},...@@ -118,8 +118,15 @@ embed_table: std.StringArrayHashMapUnmanaged(*EmbedFile) = .{},
118/// is not yet implemented.118/// is not yet implemented.
119intern_pool: InternPool = .{},119intern_pool: InternPool = .{},
120120
121analysis_in_progress: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{},
121/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.122/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.
122failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .{},123failed_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) = .{},
123/// Keep track of one `@compileLog` callsite per `AnalUnit`.130/// Keep track of one `@compileLog` callsite per `AnalUnit`.
124/// The value is the source location of the `@compileLog` call, convertible to a `LazySrcLoc`.131/// The value is the source location of the `@compileLog` call, convertible to a `LazySrcLoc`.
125compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {132compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
...@@ -155,12 +162,12 @@ outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .{},...@@ -155,12 +162,12 @@ outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .{},
155/// Such `AnalUnit`s are ready for immediate re-analysis.162/// Such `AnalUnit`s are ready for immediate re-analysis.
156/// See `findOutdatedToAnalyze` for details.163/// See `findOutdatedToAnalyze` for details.
157outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{},164outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{},
158/// This contains a set of Decls which may not be in `outdated`, but are the165/// This contains a set of struct types whose corresponding `Cau` may not be in
159/// root Decls of files which have updated source and thus must be re-analyzed.166/// `outdated`, but are the root types of files which have updated source and
160/// If such a Decl is only in this set, the struct type index may be preserved167/// thus must be re-analyzed. If such a type is only in this set, the struct type
161/// (only the namespace might change). If such a Decl is also `outdated`, the168/// index may be preserved (only the namespace might change). If its owned `Cau`
162/// struct type index must be recreated.169/// is also outdated, the struct type index must be recreated.
163outdated_file_root: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},170outdated_file_root: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{},
164/// This contains a list of AnalUnit whose analysis or codegen failed, but the171/// This contains a list of AnalUnit whose analysis or codegen failed, but the
165/// failure was something like running out of disk space, and trying again may172/// failure was something like running out of disk space, and trying again may
166/// succeed. On the next update, we will flush this list, marking all members of173/// succeed. On the next update, we will flush this list, marking all members of
...@@ -179,12 +186,9 @@ stage1_flags: packed struct {...@@ -179,12 +186,9 @@ stage1_flags: packed struct {
179186
180compile_log_text: std.ArrayListUnmanaged(u8) = .{},187compile_log_text: std.ArrayListUnmanaged(u8) = .{},
181188
182emit_h: ?*GlobalEmitH,189test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .{},
183
184test_functions: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
185190
186/// TODO: the key here will be a `Cau.Index`.191global_assembly: std.AutoArrayHashMapUnmanaged(InternPool.Cau.Index, []u8) = .{},
187global_assembly: std.AutoArrayHashMapUnmanaged(Decl.Index, []u8) = .{},
188192
189/// Key is the `AnalUnit` *performing* the reference. This representation allows193/// Key is the `AnalUnit` *performing* the reference. This representation allows
190/// incremental updates to quickly delete references caused by a specific `AnalUnit`.194/// incremental updates to quickly delete references caused by a specific `AnalUnit`.
...@@ -196,7 +200,7 @@ all_references: std.ArrayListUnmanaged(Reference) = .{},...@@ -196,7 +200,7 @@ all_references: std.ArrayListUnmanaged(Reference) = .{},
196/// Freelist of indices in `all_references`.200/// Freelist of indices in `all_references`.
197free_references: std.ArrayListUnmanaged(u32) = .{},201free_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,
200/// The panic function body.204/// The panic function body.
201panic_func_index: InternPool.Index = .none,205panic_func_index: InternPool.Index = .none,
202null_stack_trace: InternPool.Index = .none,206null_stack_trace: InternPool.Index = .none,
...@@ -250,45 +254,25 @@ pub const CImportError = struct {...@@ -250,45 +254,25 @@ pub const CImportError = struct {
250 }254 }
251};255};
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
273pub const ErrorInt = u32;257pub const ErrorInt = u32;
274258
275pub const Exported = union(enum) {259pub const Exported = union(enum) {
276 /// The Decl being exported. Note this is *not* the Decl performing the export.260 /// The Nav being exported. Note this is *not* the Nav corresponding to the AnalUnit performing the export.
277 decl_index: Decl.Index,261 nav: InternPool.Nav.Index,
278 /// Constant value being exported.262 /// Constant value being exported.
279 value: InternPool.Index,263 uav: InternPool.Index,
280264
281 pub fn getValue(exported: Exported, zcu: *Zcu) Value {265 pub fn getValue(exported: Exported, zcu: *Zcu) Value {
282 return switch (exported) {266 return switch (exported) {
283 .decl_index => |decl_index| zcu.declPtr(decl_index).val,267 .nav => |nav| zcu.navValue(nav),
284 .value => |value| Value.fromInterned(value),268 .uav => |uav| Value.fromInterned(uav),
285 };269 };
286 }270 }
287271
288 pub fn getAlign(exported: Exported, zcu: *Zcu) Alignment {272 pub fn getAlign(exported: Exported, zcu: *Zcu) Alignment {
289 return switch (exported) {273 return switch (exported) {
290 .decl_index => |decl_index| zcu.declPtr(decl_index).alignment,274 .nav => |nav| zcu.intern_pool.getNav(nav).status.resolved.alignment,
291 .value => .none,275 .uav => .none,
292 };276 };
293 }277 }
294};278};
...@@ -324,302 +308,54 @@ pub const Reference = struct {...@@ -324,302 +308,54 @@ pub const Reference = struct {
324 src: LazySrcLoc,308 src: LazySrcLoc,
325};309};
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
591/// The container that structs, enums, unions, and opaques have.311/// The container that structs, enums, unions, and opaques have.
592pub const Namespace = struct {312pub const Namespace = struct {
593 parent: OptionalIndex,313 parent: OptionalIndex,
594 file_scope: File.Index,314 file_scope: File.Index,
595 /// Will be a struct, enum, union, or opaque.315 /// Will be a struct, enum, union, or opaque.
596 decl_index: Decl.Index,316 owner_type: InternPool.Index,
597 /// Direct children of the namespace.317 /// Members of the namespace which are marked `pub`.
598 /// Declaration order is preserved via entry order.318 pub_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .{},
599 /// These are only declarations named directly by the AST; anonymous319 /// Members of the namespace which are *not* marked `pub`.
600 /// declarations are not stored here.320 priv_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .{},
601 decls: std.ArrayHashMapUnmanaged(Decl.Index, void, DeclContext, true) = .{},321 /// All `usingnamespace` declarations in this namespace which are marked `pub`.
602 /// Key is usingnamespace Decl itself. To find the namespace being included,322 pub_usingnamespace: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{},
603 /// the Decl Value has to be resolved as a Type which has a Namespace.323 /// All `usingnamespace` declarations in this namespace which are *not* marked `pub`.
604 /// Value is whether the usingnamespace decl is marked `pub`.324 priv_usingnamespace: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{},
605 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},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
607 pub const Index = InternPool.NamespaceIndex;329 pub const Index = InternPool.NamespaceIndex;
608 pub const OptionalIndex = InternPool.OptionalNamespaceIndex;330 pub const OptionalIndex = InternPool.OptionalNamespaceIndex;
609331
610 const DeclContext = struct {332 const NavNameContext = struct {
611 zcu: *Zcu,333 zcu: *Zcu,
612334
613 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {335 pub fn hash(ctx: NavNameContext, nav: InternPool.Nav.Index) u32 {
614 const decl = ctx.zcu.declPtr(decl_index);336 const name = ctx.zcu.intern_pool.getNav(nav).name;
615 return std.hash.uint32(@intFromEnum(decl.name));337 return std.hash.uint32(@intFromEnum(name));
616 }338 }
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 {
619 _ = b_index;341 _ = b_index;
620 const a_decl = ctx.zcu.declPtr(a_decl_index);342 const a_name = ctx.zcu.intern_pool.getNav(a_nav).name;
621 const b_decl = ctx.zcu.declPtr(b_decl_index);343 const b_name = ctx.zcu.intern_pool.getNav(b_nav).name;
622 return a_decl.name == b_decl.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;
623 }359 }
624 };360 };
625361
...@@ -631,25 +367,6 @@ pub const Namespace = struct {...@@ -631,25 +367,6 @@ pub const Namespace = struct {
631 return ip.filePtr(ns.file_scope);367 return ip.filePtr(ns.file_scope);
632 }368 }
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
653 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"370 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
654 pub fn renderFullyQualifiedDebugName(371 pub fn renderFullyQualifiedDebugName(
655 ns: Namespace,372 ns: Namespace,
...@@ -678,44 +395,9 @@ pub const Namespace = struct {...@@ -678,44 +395,9 @@ pub const Namespace = struct {
678 tid: Zcu.PerThread.Id,395 tid: Zcu.PerThread.Id,
679 name: InternPool.NullTerminatedString,396 name: InternPool.NullTerminatedString,
680 ) !InternPool.NullTerminatedString {397 ) !InternPool.NullTerminatedString {
681 const strings = ip.getLocal(tid).getMutableStrings(gpa);398 const ns_name = Type.fromInterned(ns.owner_type).containerTypeName(ip);
682 // Protects reads of interned strings from being reallocated during the call to399 if (name == .empty) return ns_name;
683 // renderFullyQualifiedName.400 return ip.getOrPutStringFmt(gpa, tid, "{}.{}", .{ ns_name.fmt(ip), name.fmt(ip) }, .no_embedded_nulls);
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();
719 }401 }
720};402};
721403
...@@ -2428,16 +2110,13 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2428,16 +2110,13 @@ pub fn deinit(zcu: *Zcu) void {
2428 for (zcu.failed_analysis.values()) |value| {2110 for (zcu.failed_analysis.values()) |value| {
2429 value.destroy(gpa);2111 value.destroy(gpa);
2430 }2112 }
2431 zcu.failed_analysis.deinit(gpa);2113 for (zcu.failed_codegen.values()) |value| {
24322114 value.destroy(gpa);
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);
2440 }2115 }
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
2442 for (zcu.failed_files.values()) |value| {2121 for (zcu.failed_files.values()) |value| {
2443 if (value) |msg| msg.destroy(gpa);2122 if (value) |msg| msg.destroy(gpa);
...@@ -2486,26 +2165,14 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2486,26 +2165,14 @@ pub fn deinit(zcu: *Zcu) void {
2486 zcu.intern_pool.deinit(gpa);2165 zcu.intern_pool.deinit(gpa);
2487}2166}
24882167
2489pub fn declPtr(mod: *Zcu, index: Decl.Index) *Decl {2168pub fn namespacePtr(zcu: *Zcu, index: Namespace.Index) *Namespace {
2490 return mod.intern_pool.declPtr(index);2169 return zcu.intern_pool.namespacePtr(index);
2491}
2492
2493pub fn namespacePtr(mod: *Zcu, index: Namespace.Index) *Namespace {
2494 return mod.intern_pool.namespacePtr(index);
2495}2170}
24962171
2497pub fn namespacePtrUnwrap(mod: *Zcu, index: Namespace.OptionalIndex) ?*Namespace {2172pub fn namespacePtrUnwrap(mod: *Zcu, index: Namespace.OptionalIndex) ?*Namespace {
2498 return mod.namespacePtr(index.unwrap() orelse return null);2173 return mod.namespacePtr(index.unwrap() orelse return null);
2499}2174}
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
2509// TODO https://github.com/ziglang/zig/issues/86432176// TODO https://github.com/ziglang/zig/issues/8643
2510pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;2177pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8;
2511pub const HackDataLayout = extern struct {2178pub const HackDataLayout = extern struct {
...@@ -2642,8 +2309,12 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -2642,8 +2309,12 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
2642 // If this is a Decl, we must recursively mark dependencies on its tyval2309 // If this is a Decl, we must recursively mark dependencies on its tyval
2643 // as no longer PO.2310 // as no longer PO.
2644 switch (depender.unwrap()) {2311 switch (depender.unwrap()) {
2645 .decl => |decl_index| try zcu.markPoDependeeUpToDate(.{ .decl_val = decl_index }),2312 .cau => |cau| switch (zcu.intern_pool.getCau(cau).owner.unwrap()) {
2646 .func => |func_index| try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index }),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 }),
2647 }2318 }
2648 }2319 }
2649}2320}
...@@ -2651,9 +2322,13 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {...@@ -2651,9 +2322,13 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
2651/// Given a AnalUnit which is newly outdated or PO, mark all AnalUnits which may2322/// Given a AnalUnit which is newly outdated or PO, mark all AnalUnits which may
2652/// in turn be PO, due to a dependency on the original AnalUnit's tyval or IES.2323/// in turn be PO, due to a dependency on the original AnalUnit's tyval or IES.
2653fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUnit) !void {2324fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUnit) !void {
2654 var it = zcu.intern_pool.dependencyIterator(switch (maybe_outdated.unwrap()) {2325 const ip = &zcu.intern_pool;
2655 .decl => |decl_index| .{ .decl_val = decl_index }, // TODO: also `decl_ref` deps when introduced2326 var it = ip.dependencyIterator(switch (maybe_outdated.unwrap()) {
2656 .func => |func_index| .{ .func_ies = func_index },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
2657 });2332 });
26582333
2659 while (it.next()) |po| {2334 while (it.next()) |po| {
...@@ -2680,6 +2355,8 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni...@@ -2680,6 +2355,8 @@ fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUni
2680pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {2355pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
2681 if (!zcu.comp.incremental) return null;2356 if (!zcu.comp.incremental) return null;
26822357
2358 if (true) @panic("TODO: findOutdatedToAnalyze");
2359
2683 if (zcu.outdated.count() == 0 and zcu.potentially_outdated.count() == 0) {2360 if (zcu.outdated.count() == 0 and zcu.potentially_outdated.count() == 0) {
2684 log.debug("findOutdatedToAnalyze: no outdated depender", .{});2361 log.debug("findOutdatedToAnalyze: no outdated depender", .{});
2685 return null;2362 return null;
...@@ -2742,6 +2419,8 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {...@@ -2742,6 +2419,8 @@ pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
2742 zcu.potentially_outdated.count(),2419 zcu.potentially_outdated.count(),
2743 });2420 });
27442421
2422 const Decl = {};
2423
2745 var chosen_decl_idx: ?Decl.Index = null;2424 var chosen_decl_idx: ?Decl.Index = null;
2746 var chosen_decl_dependers: u32 = undefined;2425 var chosen_decl_dependers: u32 = undefined;
27472426
...@@ -2939,65 +2618,20 @@ pub fn mapOldZirToNew(...@@ -2939,65 +2618,20 @@ pub fn mapOldZirToNew(
2939/// analyzed, and for ensuring it can exist at runtime (see2618/// analyzed, and for ensuring it can exist at runtime (see
2940/// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body2619/// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body
2941/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.2620/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.
2942pub fn ensureFuncBodyAnalysisQueued(mod: *Zcu, func_index: InternPool.Index) !void {2621pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void {
2943 const ip = &mod.intern_pool;2622 const ip = &zcu.intern_pool;
2944 const func = mod.funcInfo(func_index);2623 const func = zcu.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);
29692624
2970 switch (func.analysisUnordered(ip).state) {2625 switch (func.analysisUnordered(ip).state) {
2971 .none => {},2626 .unreferenced => {}, // We're the first reference!
2972 .queued => return,2627 .queued => return, // Analysis is already queued.
2973 // As above, we don't need to forward errors here.2628 .analyzed => return, // Analysis is complete; if it's out-of-date, it'll be re-analyzed later this update.
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 });
2990 }2629 }
2630
2631 try zcu.comp.queueJob(.{ .analyze_func = func_index });
2991 func.setAnalysisState(ip, .queued);2632 func.setAnalysisState(ip, .queued);
2992}2633}
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
3001pub const ImportFileResult = struct {2635pub const ImportFileResult = struct {
3002 file: *File,2636 file: *File,
3003 file_index: File.Index,2637 file_index: File.Index,
...@@ -3171,14 +2805,15 @@ pub fn handleUpdateExports(...@@ -3171,14 +2805,15 @@ pub fn handleUpdateExports(
3171 };2805 };
3172}2806}
31732807
3174pub fn addGlobalAssembly(mod: *Zcu, decl_index: Decl.Index, source: []const u8) !void {2808pub fn addGlobalAssembly(zcu: *Zcu, cau: InternPool.Cau.Index, source: []const u8) !void {
3175 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);2809 const gpa = zcu.gpa;
2810 const gop = try zcu.global_assembly.getOrPut(gpa, cau);
3176 if (gop.found_existing) {2811 if (gop.found_existing) {
3177 const new_value = try std.fmt.allocPrint(mod.gpa, "{s}\n{s}", .{ gop.value_ptr.*, source });2812 const new_value = try std.fmt.allocPrint(gpa, "{s}\n{s}", .{ gop.value_ptr.*, source });
3178 mod.gpa.free(gop.value_ptr.*);2813 gpa.free(gop.value_ptr.*);
3179 gop.value_ptr.* = new_value;2814 gop.value_ptr.* = new_value;
3180 } else {2815 } else {
3181 gop.value_ptr.* = try mod.gpa.dupe(u8, source);2816 gop.value_ptr.* = try gpa.dupe(u8, source);
3182 }2817 }
3183}2818}
31842819
...@@ -3315,10 +2950,6 @@ pub fn atomicPtrAlignment(...@@ -3315,10 +2950,6 @@ pub fn atomicPtrAlignment(
3315 return error.BadType;2950 return error.BadType;
3316}2951}
33172952
3318pub fn declFileScope(mod: *Zcu, decl_index: Decl.Index) *File {
3319 return mod.declPtr(decl_index).getFileScope(mod);
3320}
3321
3322/// Returns null in the following cases:2953/// Returns null in the following cases:
3323/// * `@TypeOf(.{})`2954/// * `@TypeOf(.{})`
3324/// * A struct which has no fields (`struct {}`).2955/// * A struct which has no fields (`struct {}`).
...@@ -3352,16 +2983,8 @@ pub fn typeToFunc(mod: *Zcu, ty: Type) ?InternPool.Key.FuncType {...@@ -3352,16 +2983,8 @@ pub fn typeToFunc(mod: *Zcu, ty: Type) ?InternPool.Key.FuncType {
3352 return mod.intern_pool.indexToFuncType(ty.toIntern());2983 return mod.intern_pool.indexToFuncType(ty.toIntern());
3353}2984}
33542985
3355pub fn funcOwnerDeclPtr(mod: *Zcu, func_index: InternPool.Index) *Decl {2986pub fn iesFuncIndex(zcu: *const Zcu, ies_index: InternPool.Index) InternPool.Index {
3356 return mod.declPtr(mod.funcOwnerDeclIndex(func_index));2987 return zcu.intern_pool.iesFuncIndex(ies_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);
3365}2988}
33662989
3367pub fn funcInfo(mod: *Zcu, func_index: InternPool.Index) InternPool.Key.Func {2990pub 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 {...@@ -3372,44 +2995,6 @@ pub fn toEnum(mod: *Zcu, comptime E: type, val: Value) E {
3372 return mod.intern_pool.toEnum(E, val.toIntern());2995 return mod.intern_pool.toEnum(E, val.toIntern());
3373}2996}
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
3413pub const UnionLayout = struct {2998pub const UnionLayout = struct {
3414 abi_size: u64,2999 abi_size: u64,
3415 abi_align: Alignment,3000 abi_align: Alignment,
...@@ -3468,19 +3053,20 @@ pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File {...@@ -3468,19 +3053,20 @@ pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File {
3468 return zcu.intern_pool.filePtr(file_index);3053 return zcu.intern_pool.filePtr(file_index);
3469}3054}
34703055
3471/// Returns the `Decl` of the struct that represents this `File`.3056/// Returns the struct that represents this `File`.
3472pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex {3057/// If the struct has not been created, returns `.none`.
3058pub fn fileRootType(zcu: *const Zcu, file_index: File.Index) InternPool.Index {
3473 const ip = &zcu.intern_pool;3059 const ip = &zcu.intern_pool;
3474 const file_index_unwrapped = file_index.unwrap(ip);3060 const file_index_unwrapped = file_index.unwrap(ip);
3475 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();3061 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];
3477}3063}
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 {
3480 const ip = &zcu.intern_pool;3066 const ip = &zcu.intern_pool;
3481 const file_index_unwrapped = file_index.unwrap(ip);3067 const file_index_unwrapped = file_index.unwrap(ip);
3482 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();3068 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;
3484}3070}
34853071
3486pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {3072pub 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 {...@@ -3489,3 +3075,39 @@ pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {
3489 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();3075 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3490 return files.view().items(.bin_digest)[file_index_unwrapped.index];3076 return files.view().items(.bin_digest)[file_index_unwrapped.index];
3491}3077}
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,...@@ -6,26 +6,6 @@ tid: Id,
6pub const IdBacking = u7;6pub const IdBacking = u7;
7pub const Id = if (InternPool.single_threaded) enum { main } else enum(IdBacking) { main, _ };7pub 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
29fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {9fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
30 const zcu = pt.zcu;10 const zcu = pt.zcu;
31 const gpa = zcu.gpa;11 const gpa = zcu.gpa;
...@@ -40,9 +20,6 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {...@@ -40,9 +20,6 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
40 file.unload(gpa);20 file.unload(gpa);
41 }21 }
42 file.references.deinit(gpa);22 file.references.deinit(gpa);
43 if (zcu.fileRootDecl(file_index).unwrap()) |root_decl| {
44 pt.zcu.intern_pool.destroyDecl(pt.tid, root_decl);
45 }
46 if (file.prev_zir) |prev_zir| {23 if (file.prev_zir) |prev_zir| {
47 prev_zir.deinit(gpa);24 prev_zir.deinit(gpa);
48 gpa.destroy(prev_zir);25 gpa.destroy(prev_zir);
...@@ -62,7 +39,7 @@ pub fn astGenFile(...@@ -62,7 +39,7 @@ pub fn astGenFile(
62 pt: Zcu.PerThread,39 pt: Zcu.PerThread,
63 file: *Zcu.File,40 file: *Zcu.File,
64 path_digest: Cache.BinDigest,41 path_digest: Cache.BinDigest,
65 opt_root_decl: Zcu.Decl.OptionalIndex,42 old_root_type: InternPool.Index,
66) !void {43) !void {
67 dev.check(.ast_gen);44 dev.check(.ast_gen);
68 assert(!file.mod.isBuiltin());45 assert(!file.mod.isBuiltin());
...@@ -323,13 +300,13 @@ pub fn astGenFile(...@@ -323,13 +300,13 @@ pub fn astGenFile(
323 return error.AnalysisFail;300 return error.AnalysisFail;
324 }301 }
325302
326 if (opt_root_decl.unwrap()) |root_decl| {303 if (old_root_type != .none) {
327 // The root of this file must be re-analyzed, since the file has changed.304 // The root of this file must be re-analyzed, since the file has changed.
328 comp.mutex.lock();305 comp.mutex.lock();
329 defer comp.mutex.unlock();306 defer comp.mutex.unlock();
330307
331 log.debug("outdated root Decl: {}", .{root_decl});308 log.debug("outdated file root type: {}", .{old_root_type});
332 try zcu.outdated_file_root.put(gpa, root_decl, {});309 try zcu.outdated_file_root.put(gpa, old_root_type, {});
333 }310 }
334}311}
335312
...@@ -491,137 +468,171 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {...@@ -491,137 +468,171 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
491 }468 }
492}469}
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.
495pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {473pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
496 if (pt.zcu.fileRootDecl(file_index).unwrap()) |existing_root| {474 const file_root_type = pt.zcu.fileRootType(file_index);
497 return pt.ensureDeclAnalyzed(existing_root);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);
498 } else {478 } else {
499 return pt.semaFile(file_index);479 return pt.semaFile(file_index);
500 }480 }
501}481}
502482
503/// This ensures that the Decl will have an up-to-date Type and Value populated.483/// This ensures that the state of the `Cau`, and of its corresponding `Nav` or type,
504/// However the resolution status of the Type may not be fully resolved.484/// is fully up-to-date. Note that the type of the `Nav` may not be fully resolved.
505/// For example an inferred error set is not resolved until after `analyzeFnBody`.485/// Returns `error.AnalysisFail` if the `Cau` has an error.
506/// is called.486pub fn ensureCauAnalyzed(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) Zcu.SemaError!void {
507pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.SemaError!void {
508 dev.check(.sema);
509
510 const tracy = trace(@src());487 const tracy = trace(@src());
511 defer tracy.end();488 defer tracy.end();
512489
513 const mod = pt.zcu;490 const zcu = pt.zcu;
514 const ip = &mod.intern_pool;491 const gpa = zcu.gpa;
515 const decl = mod.declPtr(decl_index);492 const ip = &zcu.intern_pool;
516493
517 log.debug("ensureDeclAnalyzed '{d}' (name '{}')", .{494 const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index });
518 @intFromEnum(decl_index),495 const cau = ip.getCau(cau_index);
519 decl.name.fmt(ip),496 const inst_info = cau.zir_index.resolveFull(ip);
520 });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-analysis502 // Determine whether or not this Cau is outdated, i.e. requires re-analysis
523 // even if `complete`. If a Decl is PO, we pessismistically assume that it503 // even if `complete`. If a Cau is PO, we pessismistically assume that it
524 // *does* require re-analysis, to ensure that the Decl is definitely504 // *does* require re-analysis, to ensure that the Cau is definitely
525 // up-to-date when this function returns.505 // up-to-date when this function returns.
526506
527 // If analysis occurs in a poor order, this could result in over-analysis.507 // If analysis occurs in a poor order, this could result in over-analysis.
528 // We do our best to avoid this by the other dependency logic in this file508 // 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 listed509 // which tries to limit re-analysis to Caus whose previously listed
530 // dependencies are all up-to-date.510 // dependencies are all up-to-date.
531511
532 const decl_as_depender = InternPool.AnalUnit.wrap(.{ .decl = decl_index });512 const cau_outdated = zcu.outdated.swapRemove(anal_unit) or
533 const decl_was_outdated = mod.outdated.swapRemove(decl_as_depender) or513 zcu.potentially_outdated.swapRemove(anal_unit);
534 mod.potentially_outdated.swapRemove(decl_as_depender);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) {543 if (zcu.fileByIndex(inst_info.file).status != .success_zir) {
537 _ = mod.outdated_ready.swapRemove(decl_as_depender);544 return error.AnalysisFail;
538 }545 }
539546
540 const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated;547 if (!cau_outdated and !file_root_outdated) {
541548 // We can trust the current information about this `Cau`.
542 switch (decl.analysis) {549 if (zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit)) {
543 .in_progress => unreachable,550 return error.AnalysisFail;
544551 }
545 .file_failure => return error.AnalysisFail,552 // If it wasn't failed and wasn't marked outdated, then either...
546553 // * it is a type and is up-to-date, or
547 .sema_failure,554 // * it is a `comptime` decl and is up-to-date, or
548 .dependency_failure,555 // * it is another decl and is EITHER up-to-date OR never-referenced (so unresolved)
549 .codegen_failure,556 // We just need to check for that last case.
550 => if (!was_outdated) return error.AnalysisFail,557 switch (cau.owner.unwrap()) {
551558 .type, .none => return,
552 .complete => if (!was_outdated) return,559 .nav => |nav| if (ip.getNav(nav).status == .resolved) return,
553560 }
554 .unreferenced => {},
555 }561 }
556562
557 if (was_outdated) {563 // `cau_outdated` can be true in the initial update for `comptime` declarations,
558 dev.check(.incremental);564 // so this isn't a `dev.check`.
559 // The exports this Decl performs will be re-discovered, so we remove them here565 if (cau_outdated and dev.env.supports(.incremental)) {
566 // The exports this `Cau` performs will be re-discovered, so we remove them here
560 // prior to re-analysis.567 // prior to re-analysis.
561 mod.deleteUnitExports(decl_as_depender);568 zcu.deleteUnitExports(anal_unit);
562 mod.deleteUnitReferences(decl_as_depender);569 zcu.deleteUnitReferences(anal_unit);
563 }570 }
564571
565 const sema_result: Zcu.SemaDeclResult = blk: {572 const sema_result: SemaCauResult = res: {
566 if (decl.zir_decl_index == .none and !mod.declIsRoot(decl_index)) {573 if (inst_info.inst == .main_struct_inst) {
567 // Anonymous decl. We don't semantically analyze these.574 const changed = try pt.semaFileUpdate(inst_info.file, cau_outdated);
568 break :blk .{575 break :res .{
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 .{
577 .invalidate_decl_val = changed,576 .invalidate_decl_val = changed,
578 .invalidate_decl_ref = changed,577 .invalidate_decl_ref = changed,
579 };578 };
580 }579 }
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);
583 defer decl_prog_node.end();586 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) {
586 error.AnalysisFail => {589 error.AnalysisFail => {
587 if (decl.analysis == .in_progress) {590 if (!zcu.failed_analysis.contains(anal_unit)) {
588 // If this decl caused the compile error, the analysis field would591 // If this `Cau` caused the error, it would have an entry in `failed_analysis`.
589 // be changed to indicate it was this Decl's fault. Because this592 // Since it does not, this must be a transitive failure.
590 // did not happen, we infer here that it was a dependency failure.593 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
591 decl.analysis = .dependency_failure;
592 }594 }
593 return error.AnalysisFail;595 return error.AnalysisFail;
594 },596 },
595 error.GenericPoison => unreachable,597 error.GenericPoison => unreachable,
596 else => |e| {598 error.ComptimeBreak => unreachable,
597 decl.analysis = .sema_failure;599 error.ComptimeReturn => unreachable,
598 try mod.failed_analysis.ensureUnusedCapacity(mod.gpa, 1);600 error.OutOfMemory => {
599 try mod.retryable_failures.append(mod.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));601 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
600 mod.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(602 try zcu.retryable_failures.append(gpa, anal_unit);
601 mod.gpa,603 zcu.failed_analysis.putAssumeCapacityNoClobber(anal_unit, try Zcu.ErrorMsg.create(
602 decl.navSrcLoc(mod),604 gpa,
603 "unable to analyze: {s}",605 .{ .base_node_inst = cau.zir_index, .offset = Zcu.LazySrcLoc.Offset.nodeOffset(0) },
604 .{@errorName(e)},606 "unable to analyze: OutOfMemory",
607 .{},
605 ));608 ));
606 return error.AnalysisFail;609 return error.AnalysisFail;
607 },610 },
608 };611 };
609 };612 };
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
611 // TODO: we do not yet have separate dependencies for decl values vs types.619 // TODO: we do not yet have separate dependencies for decl values vs types.
612 if (decl_was_outdated) {620 const invalidate = sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref;
613 if (sema_result.invalidate_decl_val or sema_result.invalidate_decl_ref) {621 const dependee: InternPool.Dependee = switch (cau.owner.unwrap()) {
614 log.debug("Decl tv invalidated ('{d}')", .{@intFromEnum(decl_index)});622 .none => return, // there are no dependencies on a `comptime` decl!
615 // This dependency was marked as PO, meaning dependees were waiting623 .nav => |nav_index| .{ .nav_val = nav_index },
616 // on its analysis result, and it has turned out to be outdated.624 .type => |ty| .{ .interned = ty },
617 // Update dependees accordingly.625 };
618 try mod.markDependeeOutdated(.{ .decl_val = decl_index });626
619 } else {627 if (invalidate) {
620 log.debug("Decl tv up-to-date ('{d}')", .{@intFromEnum(decl_index)});628 // This dependency was marked as PO, meaning dependees were waiting
621 // This dependency was previously PO, but turned out to be up-to-date.629 // on its analysis result, and it has turned out to be outdated.
622 // We do not need to queue successive analysis.630 // Update dependees accordingly.
623 try mod.markPoDependeeUpToDate(.{ .decl_val = decl_index });631 try zcu.markDependeeOutdated(dependee);
624 }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);
625 }636 }
626}637}
627638
...@@ -636,28 +647,32 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -636,28 +647,32 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
636 const ip = &zcu.intern_pool;647 const ip = &zcu.intern_pool;
637648
638 // We only care about the uncoerced function.649 // We only care about the uncoerced function.
639 // We need to do this for the "orphaned function" check below to be valid.
640 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);650 const func_index = ip.unwrapCoercedFunc(maybe_coerced_func_index);
641651
642 const func = zcu.funcInfo(maybe_coerced_func_index);652 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 '{}')", .{654 log.debug("ensureFuncBodyAnalyzed {d}", .{@intFromEnum(func_index)});
647 @intFromEnum(func_index),
648 decl.name.fmt(ip),
649 });
650655
651 // First, our owner decl must be up-to-date. This will always be the case656 // Here's an interesting question: is this function actually valid?
652 // during the first update, but may not on successive updates if we happen657 // Maybe the signature changed, so we'll end up creating a whole different `func`
653 // to get analyzed before our parent decl.658 // in the InternPool, and this one is a waste of time to analyze. Worse, we'd be
654 try pt.ensureDeclAnalyzed(decl_index);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 owner665 try pt.ensureCauAnalyzed(cau: {
657 // decl now refers to a different function, making this one orphaned. If666 const func_nav = if (func.generic_owner == .none)
658 // that's the case, we should remove this function from the binary.667 func.owner_nav
659 if (decl.val.ip_index != func_index) {668 else
660 try zcu.markDependeeOutdated(.{ .func_ies = func_index });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
661 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));676 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
662 ip.remove(pt.tid, func_index);677 ip.remove(pt.tid, func_index);
663 @panic("TODO: remove orphaned function from binary");678 @panic("TODO: remove orphaned function from binary");
...@@ -670,58 +685,40 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -670,58 +685,40 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
670 else685 else
671 .none;686 .none;
672687
673 switch (decl.analysis) {688 const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index });
674 .unreferenced => unreachable,689 const func_outdated = zcu.outdated.swapRemove(anal_unit) or
675 .in_progress => unreachable,690 zcu.potentially_outdated.swapRemove(anal_unit);
676
677 .codegen_failure => unreachable, // functions do not perform constant value generation
678691
679 .file_failure,692 if (func_outdated) {
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 dev.check(.incremental);693 dev.check(.incremental);
693 _ = zcu.outdated_ready.swapRemove(func_as_depender);694 _ = zcu.outdated_ready.swapRemove(anal_unit);
694 zcu.deleteUnitExports(func_as_depender);695 zcu.deleteUnitExports(anal_unit);
695 zcu.deleteUnitReferences(func_as_depender);696 zcu.deleteUnitReferences(anal_unit);
696 }697 }
697698
698 switch (func.analysisUnordered(ip).state) {699 if (!func_outdated) {
699 .success => if (!was_outdated) return,700 // We can trust the current information about this function.
700 .sema_failure,701 if (zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit)) {
701 .dependency_failure,702 return error.AnalysisFail;
702 .codegen_failure,703 }
703 => if (!was_outdated) return error.AnalysisFail,704 switch (func.analysisUnordered(ip).state) {
704 .none, .queued => {},705 .unreferenced => {}, // this is the first reference
705 .in_progress => unreachable,706 .queued => {}, // we're waiting on first-time analysis
706 .inline_only => unreachable, // don't queue work for this707 .analyzed => return, // up-to-date
708 }
707 }709 }
708710
709 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{711 log.debug("analyze and generate fn body '{d}'; reason='{s}'", .{
710 @intFromEnum(func_index),712 @intFromEnum(func_index),
711 if (was_outdated) "outdated" else "never analyzed",713 if (func_outdated) "outdated" else "never analyzed",
712 });714 });
713715
714 var tmp_arena = std.heap.ArenaAllocator.init(gpa);716 var air = pt.analyzeFnBody(func_index) catch |err| switch (err) {
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) {
719 error.AnalysisFail => {717 error.AnalysisFail => {
720 if (func.analysisUnordered(ip).state == .in_progress) {718 if (!zcu.failed_analysis.contains(anal_unit)) {
721 // If this decl caused the compile error, the analysis field would719 // If this function caused the error, it would have an entry in `failed_analysis`.
722 // be changed to indicate it was this Decl's fault. Because this720 // Since it does not, this must be a transitive failure.
723 // did not happen, we infer here that it was a dependency failure.721 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
724 func.setAnalysisState(ip, .dependency_failure);
725 }722 }
726 return error.AnalysisFail;723 return error.AnalysisFail;
727 },724 },
...@@ -729,18 +726,14 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -729,18 +726,14 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
729 };726 };
730 errdefer air.deinit(gpa);727 errdefer air.deinit(gpa);
731728
732 const invalidate_ies_deps = i: {729 if (func_outdated) {
733 if (!was_outdated) break :i false;730 if (!func.analysisUnordered(ip).inferred_error_set or func.resolvedErrorSetUnordered(ip) != old_resolved_ies) {
734 if (!func.analysisUnordered(ip).inferred_error_set) break :i true;731 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});
735 const new_resolved_ies = func.resolvedErrorSetUnordered(ip);732 try zcu.markDependeeOutdated(.{ .interned = func_index });
736 break :i new_resolved_ies != old_resolved_ies;733 } else {
737 };734 log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)});
738 if (invalidate_ies_deps) {735 try zcu.markPoDependeeUpToDate(.{ .interned = func_index });
739 log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)});736 }
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 });
744 }737 }
745738
746 const comp = zcu.comp;739 const comp = zcu.comp;
...@@ -773,16 +766,16 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -773,16 +766,16 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
773 }766 }
774767
775 const func = zcu.funcInfo(func_index);768 const func = zcu.funcInfo(func_index);
776 const decl_index = func.owner_decl;769 const nav_index = func.owner_nav;
777 const decl = zcu.declPtr(decl_index);770 const nav = ip.getNav(nav_index);
778771
779 var liveness = try Liveness.analyze(gpa, air, ip);772 var liveness = try Liveness.analyze(gpa, air, ip);
780 defer liveness.deinit(gpa);773 defer liveness.deinit(gpa);
781774
782 if (build_options.enable_debug_extensions and comp.verbose_air) {775 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)});
784 @import("../print_air.zig").dump(pt, air, liveness);777 @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)});
786 }779 }
787780
788 if (std.debug.runtime_safety) {781 if (std.debug.runtime_safety) {
...@@ -797,23 +790,18 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -797,23 +790,18 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
797 verify.verify() catch |err| switch (err) {790 verify.verify() catch |err| switch (err) {
798 error.OutOfMemory => return error.OutOfMemory,791 error.OutOfMemory => return error.OutOfMemory,
799 else => {792 else => {
800 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);793 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
801 zcu.failed_analysis.putAssumeCapacityNoClobber(794 gpa,
802 InternPool.AnalUnit.wrap(.{ .func = func_index }),795 zcu.navSrcLoc(nav_index),
803 try Zcu.ErrorMsg.create(796 "invalid liveness: {s}",
804 gpa,797 .{@errorName(err)},
805 decl.navSrcLoc(zcu),798 ));
806 "invalid liveness: {s}",
807 .{@errorName(err)},
808 ),
809 );
810 func.setAnalysisState(ip, .codegen_failure);
811 return;799 return;
812 },800 },
813 };801 };
814 }802 }
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);
817 defer codegen_prog_node.end();805 defer codegen_prog_node.end();
818806
819 if (!air.typesFullyResolved(zcu)) {807 if (!air.typesFullyResolved(zcu)) {
...@@ -821,22 +809,21 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -821,22 +809,21 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
821 // Correcting this failure will involve changing a type this function809 // Correcting this failure will involve changing a type this function
822 // depends on, hence triggering re-analysis of this function, so this810 // depends on, hence triggering re-analysis of this function, so this
823 // interacts correctly with incremental compilation.811 // 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.
825 } else if (comp.bin_file) |lf| {814 } else if (comp.bin_file) |lf| {
826 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {815 lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
827 error.OutOfMemory => return error.OutOfMemory,816 error.OutOfMemory => return error.OutOfMemory,
828 error.AnalysisFail => {817 error.AnalysisFail => {
829 func.setAnalysisState(ip, .codegen_failure);818 assert(zcu.failed_codegen.contains(nav_index));
830 },819 },
831 else => {820 else => {
832 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);821 try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
833 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .func = func_index }), try Zcu.ErrorMsg.create(
834 gpa,822 gpa,
835 decl.navSrcLoc(zcu),823 zcu.navSrcLoc(nav_index),
836 "unable to codegen: {s}",824 "unable to codegen: {s}",
837 .{@errorName(err)},825 .{@errorName(err)},
838 ));826 ));
839 func.setAnalysisState(ip, .codegen_failure);
840 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));827 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
841 },828 },
842 };829 };
...@@ -851,17 +838,16 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -851,17 +838,16 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
851pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {838pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
852 dev.check(.sema);839 dev.check(.sema);
853 const import_file_result = try pt.importPkg(pkg);840 const import_file_result = try pt.importPkg(pkg);
854 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);841 const root_type = pt.zcu.fileRootType(import_file_result.file_index);
855 if (root_decl_index == .none) {842 if (root_type == .none) {
856 return pt.semaFile(import_file_result.file_index);843 return pt.semaFile(import_file_result.file_index);
857 }844 }
858}845}
859846
860fn getFileRootStruct(847fn createFileRootStruct(
861 pt: Zcu.PerThread,848 pt: Zcu.PerThread,
862 decl_index: Zcu.Decl.Index,
863 namespace_index: Zcu.Namespace.Index,
864 file_index: Zcu.File.Index,849 file_index: Zcu.File.Index,
850 namespace_index: Zcu.Namespace.Index,
865) Allocator.Error!InternPool.Index {851) Allocator.Error!InternPool.Index {
866 const zcu = pt.zcu;852 const zcu = pt.zcu;
867 const gpa = zcu.gpa;853 const gpa = zcu.gpa;
...@@ -901,7 +887,6 @@ fn getFileRootStruct(...@@ -901,7 +887,6 @@ fn getFileRootStruct(
901 .any_default_inits = small.any_default_inits,887 .any_default_inits = small.any_default_inits,
902 .inits_resolved = false,888 .inits_resolved = false,
903 .any_aligned_fields = small.any_aligned_fields,889 .any_aligned_fields = small.any_aligned_fields,
904 .has_namespace = true,
905 .key = .{ .declared = .{890 .key = .{ .declared = .{
906 .zir_index = tracked_inst,891 .zir_index = tracked_inst,
907 .captures = &.{},892 .captures = &.{},
...@@ -912,34 +897,37 @@ fn getFileRootStruct(...@@ -912,34 +897,37 @@ fn getFileRootStruct(
912 };897 };
913 errdefer wip_ty.cancel(ip, pt.tid);898 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
915 if (zcu.comp.incremental) {904 if (zcu.comp.incremental) {
916 try ip.addDependency(905 try ip.addDependency(
917 gpa,906 gpa,
918 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),907 InternPool.AnalUnit.wrap(.{ .cau = new_cau_index }),
919 .{ .src_hash = tracked_inst },908 .{ .src_hash = tracked_inst },
920 );909 );
921 }910 }
922911
923 const decl = zcu.declPtr(decl_index);912 try pt.scanNamespace(namespace_index, decls);
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);
930 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });913 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);
932}916}
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.
935/// If `type_outdated`, the struct type itself is considered outdated and is919/// If `type_outdated`, the struct type itself is considered outdated and is
936/// reconstructed at a new InternPool index. Otherwise, the namespace is just920/// reconstructed at a new InternPool index. Otherwise, the namespace is just
937/// re-analyzed. Returns whether the decl's tyval was invalidated.921/// re-analyzed. Returns whether the decl's tyval was invalidated.
922/// Returns `error.AnalysisFail` if the file has an error.
938fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {923fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {
939 const zcu = pt.zcu;924 const zcu = pt.zcu;
940 const ip = &zcu.intern_pool;925 const ip = &zcu.intern_pool;
941 const file = zcu.fileByIndex(file_index);926 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
944 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{932 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
945 file.mod.fully_qualified_name,933 file.mod.fully_qualified_name,
...@@ -948,33 +936,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:...@@ -948,33 +936,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
948 });936 });
949937
950 if (file.status != .success_zir) {938 if (file.status != .success_zir) {
951 if (decl.analysis == .file_failure) {939 return error.AnalysisFail;
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;
964 }940 }
965941
966 assert(decl.has_tv);
967 assert(decl.owns_tv);
968
969 if (type_outdated) {942 if (type_outdated) {
970 // Invalidate the existing type, reusing the decl and namespace.943 // Invalidate the existing type, reusing its namespace.
971 const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?;944 const file_root_type_cau = ip.loadStructType(file_root_type).cau.unwrap().?;
972 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{945 ip.removeDependenciesForDepender(
973 .decl = file_root_decl,946 zcu.gpa,
974 }));947 InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }),
975 ip.remove(pt.tid, decl.val.toIntern());948 );
976 decl.val = undefined;949 ip.remove(pt.tid, file_root_type);
977 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);950 _ = try pt.createFileRootStruct(file_index, namespace_index);
978 return true;951 return true;
979 }952 }
980953
...@@ -994,7 +967,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:...@@ -994,7 +967,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
994 const decls = file.zir.bodySlice(extra_index, decls_len);967 const decls = file.zir.bodySlice(extra_index, decls_len);
995968
996 if (!type_outdated) {969 if (!type_outdated) {
997 try pt.scanNamespace(decl.src_namespace, decls, decl);970 try pt.scanNamespace(namespace_index, decls);
998 }971 }
999972
1000 return false;973 return false;
...@@ -1009,43 +982,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -1009,43 +982,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1009 const zcu = pt.zcu;982 const zcu = pt.zcu;
1010 const gpa = zcu.gpa;983 const gpa = zcu.gpa;
1011 const file = zcu.fileByIndex(file_index);984 const file = zcu.fileByIndex(file_index);
1012 assert(zcu.fileRootDecl(file_index) == .none);985 assert(zcu.fileRootType(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;
1041986
1042 if (file.status != .success_zir) {987 if (file.status != .success_zir) {
1043 new_decl.analysis = .file_failure;988 return error.AnalysisFail;
1044 return;
1045 }989 }
1046 assert(file.zir_loaded);990 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);
1049 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);998 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
1050999
1051 switch (zcu.comp.cache_use) {1000 switch (zcu.comp.cache_use) {
...@@ -1067,98 +1016,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -1067,98 +1016,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10671016
1068 whole.cache_manifest_mutex.lock();1017 whole.cache_manifest_mutex.lock();
1069 defer whole.cache_manifest_mutex.unlock();1018 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 };
1071 },1026 },
1072 .incremental => {},1027 .incremental => {},
1073 }1028 }
1074}1029}
10751030
1076fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {1031const SemaCauResult = packed struct {
1077 const tracy = trace(@src());1032 /// Whether the value of a `decl_val` of the corresponding Nav changed.
1078 defer tracy.end();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 {
1080 const zcu = pt.zcu;1043 const zcu = pt.zcu;
1081 const decl = zcu.declPtr(decl_index);1044 const gpa = zcu.gpa;
1082 const ip = &zcu.intern_pool;1045 const ip = &zcu.intern_pool;
10831046
1084 if (decl.getFileScope(zcu).status != .success_zir) {1047 const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index });
1085 return error.AnalysisFail;
1086 }
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) {1054 if (file.status != .success_zir) {
1091 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).1055 return error.AnalysisFail;
1092 return pt.semaAnonOwnerDecl(decl_index);
1093 }1056 }
10941057
1095 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});1058 // We are about to re-analyze this `Cau`; drop its depenndencies.
1096 log.debug("decl name '{}'", .{decl.fqn.fmt(ip)});1059 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
1097 defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)});
10981060
1099 const old_has_tv = decl.has_tv;1061 const builtin_type_target_index: InternPool.Index = switch (cau.owner.unwrap()) {
1100 // The following values are ignored if `!old_has_tv`1062 .none => ip_index: {
1101 const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined;1063 // `comptime` decl -- we will re-analyze its body.
1102 const old_val = decl.val;1064 // This declaration has no value so is definitely not a std.builtin type.
1103 const old_align = decl.alignment;1065 break :ip_index .none;
1104 const old_linksection = decl.@"linksection";1066 },
1105 const old_addrspace = decl.@"addrspace";1067 .type => |ty| {
1106 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|1068 // This is an incremental update, and this type is being re-analyzed because it is outdated.
1107 prev_func.analysisUnordered(ip).state == .inline_only1069 // The type must be recreated at a new `InternPool.Index`.
1108 else1070 // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed.
1109 false;1071 ip.remove(pt.tid, ty);
11101072 return .{
1111 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);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;1125 const is_usingnamespace = switch (cau.owner.unwrap()) {
1114 const zir = decl.getFileScope(zcu).zir;1126 .nav => |nav| ip.getNav(nav).is_usingnamespace,
11151127 .none, .type => false,
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;
1157 };1128 };
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
1163 var analysis_arena = std.heap.ArenaAllocator.init(gpa);1135 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
1164 defer analysis_arena.deinit();1136 defer analysis_arena.deinit();
...@@ -1171,224 +1143,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1171,224 +1143,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1171 .gpa = gpa,1143 .gpa = gpa,
1172 .arena = analysis_arena.allocator(),1144 .arena = analysis_arena.allocator(),
1173 .code = zir,1145 .code = zir,
1174 .owner_decl = decl,1146 .owner = anal_unit,
1175 .owner_decl_index = decl_index,
1176 .func_index = .none,1147 .func_index = .none,
1177 .func_is_naked = false,1148 .func_is_naked = false,
1178 .fn_ret_ty = Type.void,1149 .fn_ret_ty = Type.void,
1179 .fn_ret_ty_ies = null,1150 .fn_ret_ty_ies = null,
1180 .owner_func_index = .none,
1181 .comptime_err_ret_trace = &comptime_err_ret_trace,1151 .comptime_err_ret_trace = &comptime_err_ret_trace,
1182 .builtin_type_target_index = builtin_type_target_index,1152 .builtin_type_target_index = builtin_type_target_index,
1183 };1153 };
1184 defer sema.deinit();1154 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.1156 // Every `Cau` has a dependency on the source of its own ZIR instruction.
1187 try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{1157 try sema.declareDependency(.{ .src_hash = cau.zir_index });
1188 .file = decl.getFileScopeIndex(zcu),
1189 .inst = decl_inst,
1190 }) });
11911158
1192 var block_scope: Sema.Block = .{1159 var block: Sema.Block = .{
1193 .parent = null,1160 .parent = null,
1194 .sema = &sema,1161 .sema = &sema,
1195 .namespace = decl.src_namespace,1162 .namespace = cau.namespace,
1196 .instructions = .{},1163 .instructions = .{},
1197 .inlining = null,1164 .inlining = null,
1198 .is_comptime = true,1165 .is_comptime = true,
1199 .src_base_inst = decl.zir_decl_index.unwrap().?,1166 .src_base_inst = cau.zir_index,
1200 .type_name_ctx = decl.name,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),
1201 };1188 };
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);1192 const nav_index = switch (cau.owner.unwrap()) {
1207 // We'll do some other bits with the Sema. Clear the type target index just1193 .none => {
1208 // in case they analyze any type.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.
1209 sema.builtin_type_target_index = .none;1208 sema.builtin_type_target_index = .none;
1210 const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 });1209
1211 const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 });1210 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
1212 const address_space_src = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 });1211 const section_src = block.src(.{ .node_offset_var_decl_section = 0 });
1213 const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 });1212 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
1214 const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 });1213 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
1215 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);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);
1216 const decl_ty = decl_val.typeOf(zcu);1217 const decl_ty = decl_val.typeOf(zcu);
12171218
1218 // Note this resolves the type of the Decl, not the value; if this Decl1219 switch (decl_val.toIntern()) {
1219 // is a struct, for example, this resolves `type` (which needs no resolution),1220 .generic_poison => unreachable, // assertion failure
1220 // not the struct itself.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.
1221 try decl_ty.resolveLayout(pt);1227 try decl_ty.resolveLayout(pt);
12221228
1223 if (decl.kind == .@"usingnamespace") {1229 // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`.
1224 if (!decl_ty.eql(Type.type, zcu)) {1230 if (is_usingnamespace) {
1225 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});1231 if (decl_ty.toIntern() != .type_type) {
1232 return sema.fail(&block, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
1226 }1233 }
1227 const ty = decl_val.toType();1234 if (decl_val.toType().getNamespace(zcu) == .none) {
1228 if (ty.getNamespace(zcu) == null) {1235 return sema.fail(&block, ty_src, "type {} has no namespace", .{decl_val.toType().fmt(pt)});
1229 return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(pt)});
1230 }1236 }
12311237 ip.resolveNavValue(nav_index, .{
1232 decl.val = ty.toValue();1238 .val = decl_val.toIntern(),
1233 decl.alignment = .none;1239 .alignment = .none,
1234 decl.@"linksection" = .none;1240 .@"linksection" = .none,
1235 decl.has_tv = true;1241 .@"addrspace" = .generic,
1236 decl.owns_tv = false;1242 });
1237 decl.analysis = .complete;1243 // TODO: usingnamespace cannot participate in incremental compilation
12381244 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1239 // TODO: usingnamespace cannot currently participate in incremental compilation
1240 return .{1245 return .{
1241 .invalidate_decl_val = true,1246 .invalidate_decl_val = true,
1242 .invalidate_decl_ref = true,1247 .invalidate_decl_ref = true,
1243 };1248 };
1244 }1249 }
12451250
1246 var queue_linker_work = true;1251 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
1247 var is_func = false;1252 .func => |f| .{ f.owner_nav == nav_index, false },
1248 var is_inline = false;1253 .variable => |v| .{ false, v.owner_nav == nav_index },
1249 switch (decl_val.toIntern()) {1254 .@"extern" => .{ false, false },
1250 .generic_poison => unreachable,1255 else => .{ false, true },
1251 .unreachable_value => unreachable,1256 };
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 }
12741257
1275 decl.val = decl_val;1258 if (nav_already_populated) {
1276 // Function linksection, align, and addrspace were already set by Sema1259 // This is a function declaration.
1277 if (!is_func) {1260 // Logic in `Sema.funcCommon` has already populated the `Nav` for us.
1278 decl.alignment = blk: {1261 assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern());
1279 const align_body = decl_bodies.align_body orelse break :blk .none;1262 } else {
1280 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);1263 // Keep in sync with logic in `Sema.zirVarExtended`.
1281 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);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);
1282 };1268 };
1283 decl.@"linksection" = blk: {1269
1284 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;1270 const @"linksection": InternPool.OptionalNullTerminatedString = ls: {
1285 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);1271 const linksection_body = decl_bodies.linksection_body orelse break :ls .none;
1286 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{1272 const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst);
1273 const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{
1287 .needed_comptime_reason = "linksection must be comptime-known",1274 .needed_comptime_reason = "linksection must be comptime-known",
1288 });1275 });
1289 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {1276 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", .{});
1291 } else if (bytes.len == 0) {1278 } 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", .{});
1293 }1280 }
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);
1295 };1282 };
1296 decl.@"addrspace" = blk: {1283
1284 const @"addrspace": std.builtin.AddressSpace = as: {
1297 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {1285 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
1286 .func => .function,
1298 .variable => .variable,1287 .variable => .variable,
1299 .extern_func, .func => .function,1288 .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type)
1289 .function
1290 else
1291 .variable,
1300 else => .constant,1292 else => .constant,
1301 };1293 };
1302
1303 const target = zcu.getTarget();1294 const target = zcu.getTarget();
13041295 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
1305 const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) {
1306 .function => target_util.defaultAddressSpace(target, .function),1296 .function => target_util.defaultAddressSpace(target, .function),
1307 .variable => target_util.defaultAddressSpace(target, .global_mutable),1297 .variable => target_util.defaultAddressSpace(target, .global_mutable),
1308 .constant => target_util.defaultAddressSpace(target, .global_constant),1298 .constant => target_util.defaultAddressSpace(target, .global_constant),
1309 else => unreachable,1299 else => unreachable,
1310 };1300 };
1311 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);1301 const addrspace_ref = try sema.resolveInlineBody(&block, addrspace_body, inst_info.inst);
1312 break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);1302 break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx);
1313 };1303 };
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) {1305 ip.resolveNavValue(nav_index, .{
1341 try zcu.comp.queueJob(.{ .emit_h_decl = decl_index });1306 .val = decl_val.toIntern(),
1342 }1307 .alignment = alignment,
1308 .@"linksection" = @"linksection",
1309 .@"addrspace" = @"addrspace",
1310 });
1343 }1311 }
13441312
1345 if (decl.is_exported) {1313 // Mark the `Cau` as completed before evaluating the export!
1346 const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });1314 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1347 if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});1315
1348 // The scope needs to have the decl in it.1316 if (zir_decl.flags.is_export) {
1349 try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);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);
1350 }1321 }
13511322
1352 try sema.flushExports();1323 try sema.flushExports();
13531324
1354 return result;1325 queue_codegen: {
1355}1326 if (!queue_linker_work) break :queue_codegen;
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);
13601327
1361 assert(decl.has_tv);1328 // Needed for codegen_nav which will call updateDecl and then the
1362 assert(decl.owns_tv);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)) {1337 try zcu.comp.queueJob(.{ .codegen_nav = nav_index });
1367 .Fn => @panic("TODO: update fn instance"),
1368 .Type => {},
1369 else => unreachable,
1370 }1338 }
13711339
1372 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*1340 switch (old_nav_info.status) {
1373 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.1341 .unresolved => return .{
1374 //1342 .invalidate_decl_val = true,
1375 // However, as soon as we make that, the context that created us will require re-analysis anyway1343 .invalidate_decl_ref = true,
1376 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction1344 },
1377 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,1345 .resolved => |old| {
1378 // why should we bother implementing it here too when the Sema logic will be hit right after?1346 const new = ip.getNav(nav_index).status.resolved;
1379 //1347 return .{
1380 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely1348 .invalidate_decl_val = new.val != old.val,
1381 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type1349 .invalidate_decl_ref = ip.typeOf(new.val) != ip.typeOf(old.val) or
1382 // with a new Decl.1350 new.alignment != old.alignment or
1383 //1351 new.@"linksection" != old.@"linksection" or
1384 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.1352 new.@"addrspace" != old.@"addrspace",
1385 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));1353 };
1386 zcu.intern_pool.remove(pt.tid, decl.val.toIntern());1354 },
1387 decl.analysis = .dependency_failure;1355 }
1388 return .{
1389 .invalidate_decl_val = true,
1390 .invalidate_decl_ref = true,
1391 };
1392}1356}
13931357
1394pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {1358pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
...@@ -1426,7 +1390,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {...@@ -1426,7 +1390,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1426 const file_index = try ip.createFile(gpa, pt.tid, .{1390 const file_index = try ip.createFile(gpa, pt.tid, .{
1427 .bin_digest = path_digest,1391 .bin_digest = path_digest,
1428 .file = builtin_file,1392 .file = builtin_file,
1429 .root_decl = .none,1393 .root_type = .none,
1430 });1394 });
1431 keep_resolved_path = true; // It's now owned by import_table.1395 keep_resolved_path = true; // It's now owned by import_table.
1432 gop.value_ptr.* = file_index;1396 gop.value_ptr.* = file_index;
...@@ -1453,7 +1417,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {...@@ -1453,7 +1417,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1453 const new_file_index = try ip.createFile(gpa, pt.tid, .{1417 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1454 .bin_digest = path_digest,1418 .bin_digest = path_digest,
1455 .file = new_file,1419 .file = new_file,
1456 .root_decl = .none,1420 .root_type = .none,
1457 });1421 });
1458 keep_resolved_path = true; // It's now owned by import_table.1422 keep_resolved_path = true; // It's now owned by import_table.
1459 gop.value_ptr.* = new_file_index;1423 gop.value_ptr.* = new_file_index;
...@@ -1563,7 +1527,7 @@ pub fn importFile(...@@ -1563,7 +1527,7 @@ pub fn importFile(
1563 const new_file_index = try ip.createFile(gpa, pt.tid, .{1527 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1564 .bin_digest = path_digest,1528 .bin_digest = path_digest,
1565 .file = new_file,1529 .file = new_file,
1566 .root_decl = .none,1530 .root_type = .none,
1567 });1531 });
1568 keep_resolved_path = true; // It's now owned by import_table.1532 keep_resolved_path = true; // It's now owned by import_table.
1569 gop.value_ptr.* = new_file_index;1533 gop.value_ptr.* = new_file_index;
...@@ -1726,7 +1690,7 @@ fn newEmbedFile(...@@ -1726,7 +1690,7 @@ fn newEmbedFile(
1726 })).toIntern();1690 })).toIntern();
1727 const ptr_val = try pt.intern(.{ .ptr = .{1691 const ptr_val = try pt.intern(.{ .ptr = .{
1728 .ty = ptr_ty,1692 .ty = ptr_ty,
1729 .base_addr = .{ .anon_decl = .{1693 .base_addr = .{ .uav = .{
1730 .val = array_val,1694 .val = array_val,
1731 .orig_ty = ptr_ty,1695 .orig_ty = ptr_ty,
1732 } },1696 } },
...@@ -1748,39 +1712,70 @@ pub fn scanNamespace(...@@ -1748,39 +1712,70 @@ pub fn scanNamespace(
1748 pt: Zcu.PerThread,1712 pt: Zcu.PerThread,
1749 namespace_index: Zcu.Namespace.Index,1713 namespace_index: Zcu.Namespace.Index,
1750 decls: []const Zir.Inst.Index,1714 decls: []const Zir.Inst.Index,
1751 parent_decl: *Zcu.Decl,
1752) Allocator.Error!void {1715) Allocator.Error!void {
1753 const tracy = trace(@src());1716 const tracy = trace(@src());
1754 defer tracy.end();1717 defer tracy.end();
17551718
1756 const zcu = pt.zcu;1719 const zcu = pt.zcu;
1720 const ip = &zcu.intern_pool;
1757 const gpa = zcu.gpa;1721 const gpa = zcu.gpa;
1758 const namespace = zcu.namespacePtr(namespace_index);1722 const namespace = zcu.namespacePtr(namespace_index);
17591723
1760 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather1724 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather
1761 // than their name. We'll build an efficient mapping now, then discard the current `decls`.1725 // 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) = .{};
1763 defer existing_by_inst.deinit(gpa);1728 defer existing_by_inst.deinit(gpa);
17641729
1765 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));1730 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(
17661731 namespace.pub_decls.count() + namespace.priv_decls.count() +
1767 for (namespace.decls.keys()) |decl_index| {1732 namespace.pub_usingnamespace.items.len + namespace.priv_usingnamespace.items.len +
1768 const decl = zcu.declPtr(decl_index);1733 namespace.other_decls.items.len,
1769 existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);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 }
1770 }1765 }
17711766
1772 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};1767 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
1773 defer seen_decls.deinit(gpa);1768 defer seen_decls.deinit(gpa);
17741769
1775 namespace.decls.clearRetainingCapacity();1770 namespace.pub_decls.clearRetainingCapacity();
1776 try namespace.decls.ensureTotalCapacity(gpa, decls.len);1771 namespace.priv_decls.clearRetainingCapacity();
17771772 namespace.pub_usingnamespace.clearRetainingCapacity();
1778 namespace.usingnamespace_set.clearRetainingCapacity();1773 namespace.priv_usingnamespace.clearRetainingCapacity();
1774 namespace.other_decls.clearRetainingCapacity();
17791775
1780 var scan_decl_iter: ScanDeclIter = .{1776 var scan_decl_iter: ScanDeclIter = .{
1781 .pt = pt,1777 .pt = pt,
1782 .namespace_index = namespace_index,1778 .namespace_index = namespace_index,
1783 .parent_decl = parent_decl,
1784 .seen_decls = &seen_decls,1779 .seen_decls = &seen_decls,
1785 .existing_by_inst = &existing_by_inst,1780 .existing_by_inst = &existing_by_inst,
1786 .pass = .named,1781 .pass = .named,
...@@ -1792,34 +1787,17 @@ pub fn scanNamespace(...@@ -1792,34 +1787,17 @@ pub fn scanNamespace(
1792 for (decls) |decl_inst| {1787 for (decls) |decl_inst| {
1793 try scan_decl_iter.scanDecl(decl_inst);1788 try scan_decl_iter.scanDecl(decl_inst);
1794 }1789 }
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 }
1810}1790}
18111791
1812const ScanDeclIter = struct {1792const ScanDeclIter = struct {
1813 pt: Zcu.PerThread,1793 pt: Zcu.PerThread,
1814 namespace_index: Zcu.Namespace.Index,1794 namespace_index: Zcu.Namespace.Index,
1815 parent_decl: *Zcu.Decl,
1816 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),1795 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),
1818 /// Decl scanning is run in two passes, so that we can detect when a generated1797 /// Decl scanning is run in two passes, so that we can detect when a generated
1819 /// name would clash with an explicit name and use a different one.1798 /// name would clash with an explicit name and use a different one.
1820 pass: enum { named, unnamed },1799 pass: enum { named, unnamed },
1821 usingnamespace_index: usize = 0,1800 usingnamespace_index: usize = 0,
1822 comptime_index: usize = 0,
1823 unnamed_test_index: usize = 0,1801 unnamed_test_index: usize = 0,
18241802
1825 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {1803 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
...@@ -1843,37 +1821,35 @@ const ScanDeclIter = struct {...@@ -1843,37 +1821,35 @@ const ScanDeclIter = struct {
18431821
1844 const pt = iter.pt;1822 const pt = iter.pt;
1845 const zcu = pt.zcu;1823 const zcu = pt.zcu;
1824 const comp = zcu.comp;
1846 const namespace_index = iter.namespace_index;1825 const namespace_index = iter.namespace_index;
1847 const namespace = zcu.namespacePtr(namespace_index);1826 const namespace = zcu.namespacePtr(namespace_index);
1848 const gpa = zcu.gpa;1827 const gpa = zcu.gpa;
1849 const zir = namespace.fileScope(zcu).zir;1828 const file = namespace.fileScope(zcu);
1829 const zir = file.zir;
1850 const ip = &zcu.intern_pool;1830 const ip = &zcu.intern_pool;
18511831
1852 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;1832 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
1853 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);1833 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
1854 const declaration = extra.data;1834 const declaration = extra.data;
18551835
1856 // Every Decl needs a name.1836 const Kind = enum { @"comptime", @"usingnamespace", @"test", named };
1857 const decl_name: InternPool.NullTerminatedString, const kind: Zcu.Decl.Kind, const is_named_test: bool = switch (declaration.name) {1837
1838 const maybe_name: InternPool.OptionalNullTerminatedString, const kind: Kind, const is_named_test: bool = switch (declaration.name) {
1858 .@"comptime" => info: {1839 .@"comptime" => info: {
1859 if (iter.pass != .unnamed) return;1840 if (iter.pass != .unnamed) return;
1860 const i = iter.comptime_index;
1861 iter.comptime_index += 1;
1862 break :info .{1841 break :info .{
1863 try iter.avoidNameConflict("comptime_{d}", .{i}),1842 .none,
1864 .@"comptime",1843 .@"comptime",
1865 false,1844 false,
1866 };1845 };
1867 },1846 },
1868 .@"usingnamespace" => info: {1847 .@"usingnamespace" => info: {
1869 // TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.1848 if (iter.pass != .unnamed) return;
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;
1873 const i = iter.usingnamespace_index;1849 const i = iter.usingnamespace_index;
1874 iter.usingnamespace_index += 1;1850 iter.usingnamespace_index += 1;
1875 break :info .{1851 break :info .{
1876 try iter.avoidNameConflict("usingnamespace_{d}", .{i}),1852 (try iter.avoidNameConflict("usingnamespace_{d}", .{i})).toOptional(),
1877 .@"usingnamespace",1853 .@"usingnamespace",
1878 false,1854 false,
1879 };1855 };
...@@ -1883,7 +1859,7 @@ const ScanDeclIter = struct {...@@ -1883,7 +1859,7 @@ const ScanDeclIter = struct {
1883 const i = iter.unnamed_test_index;1859 const i = iter.unnamed_test_index;
1884 iter.unnamed_test_index += 1;1860 iter.unnamed_test_index += 1;
1885 break :info .{1861 break :info .{
1886 try iter.avoidNameConflict("test_{d}", .{i}),1862 (try iter.avoidNameConflict("test_{d}", .{i})).toOptional(),
1887 .@"test",1863 .@"test",
1888 false,1864 false,
1889 };1865 };
...@@ -1894,7 +1870,7 @@ const ScanDeclIter = struct {...@@ -1894,7 +1870,7 @@ const ScanDeclIter = struct {
1894 assert(declaration.flags.has_doc_comment);1870 assert(declaration.flags.has_doc_comment);
1895 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));1871 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
1896 break :info .{1872 break :info .{
1897 try iter.avoidNameConflict("decltest.{s}", .{name}),1873 (try iter.avoidNameConflict("decltest.{s}", .{name})).toOptional(),
1898 .@"test",1874 .@"test",
1899 true,1875 true,
1900 };1876 };
...@@ -1903,7 +1879,7 @@ const ScanDeclIter = struct {...@@ -1903,7 +1879,7 @@ const ScanDeclIter = struct {
1903 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.1879 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
1904 if (iter.pass != .unnamed) return;1880 if (iter.pass != .unnamed) return;
1905 break :info .{1881 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(),
1907 .@"test",1883 .@"test",
1908 true,1884 true,
1909 };1885 };
...@@ -1917,132 +1893,144 @@ const ScanDeclIter = struct {...@@ -1917,132 +1893,144 @@ const ScanDeclIter = struct {
1917 );1893 );
1918 try iter.seen_decls.putNoClobber(gpa, name, {});1894 try iter.seen_decls.putNoClobber(gpa, name, {});
1919 break :info .{1895 break :info .{
1920 name,1896 name.toOptional(),
1921 .named,1897 .named,
1922 false,1898 false,
1923 };1899 };
1924 },1900 },
1925 };1901 };
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);
1934 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{1903 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
1935 .file = parent_file_scope_index,1904 .file = namespace.file_scope,
1936 .inst = decl_inst,1905 .inst = decl_inst,
1937 });1906 });
19381907
1939 // We create a Decl for it regardless of analysis status.1908 const existing_cau = iter.existing_by_inst.get(tracked_inst);
19401909
1941 const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {1910 const cau, const want_analysis = switch (kind) {
1942 // We need only update this existing Decl.1911 .@"comptime" => cau: {
1943 const decl = zcu.declPtr(decl_index);1912 const cau = existing_cau orelse try ip.createComptimeCau(gpa, pt.tid, tracked_inst, namespace_index);
1944 const was_exported = decl.is_exported;1913
1945 assert(decl.kind == kind); // ZIR tracking should preserve this1914 // For a `comptime` declaration, whether to re-analyze is based solely on whether the
1946 decl.name = decl_name;1915 // `Cau` is outdated. So, add this one to `outdated` and `outdated_ready` if not already.
1947 decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);1916 const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
1948 decl.is_pub = declaration.flags.is_pub;1917 if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| {
1949 decl.is_exported = declaration.flags.is_export;1918 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1950 break :decl_index .{ was_exported, decl_index };1919 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1951 } else decl_index: {1920 zcu.outdated.putAssumeCapacityNoClobber(unit, kv.value);
1952 // Create and set up a new Decl.1921 if (kv.value == 0) { // no PO deps
1953 const new_decl_index = try pt.allocateNewDecl(namespace_index);1922 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1954 const new_decl = zcu.declPtr(new_decl_index);1923 }
1955 new_decl.kind = kind;1924 } else if (!zcu.outdated.contains(unit)) {
1956 new_decl.name = decl_name;1925 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1957 new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);1926 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1958 new_decl.is_pub = declaration.flags.is_pub;1927 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
1959 new_decl.is_exported = declaration.flags.is_export;1928 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1960 new_decl.zir_decl_index = tracked_inst.toOptional();1929 }
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 });
19671930
1968 const comp = zcu.comp;1931 break :cau .{ cau, true };
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;
1976 },1932 },
1977 .named => false,1933 else => cau: {
1978 .@"test" => a: {1934 const name = maybe_name.unwrap().?;
1979 if (!comp.config.is_test) break :a false;1935 const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name);
1980 if (decl_mod != zcu.main_mod) break :a false;1936 const cau, const nav = if (existing_cau) |cau_index| cau_nav: {
1981 if (is_named_test and comp.test_filters.len > 0) {1937 const nav_index = ip.getCau(cau_index).owner.unwrap().nav;
1982 const decl_fqn = decl.fqn.toSlice(ip);1938 const nav = ip.getNav(nav_index);
1983 for (comp.test_filters) |test_filter| {1939 assert(nav.name == name);
1984 if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break;1940 assert(nav.fqn == fqn);
1985 } else break :a false;1941 break :cau_nav .{ cau_index, nav_index };
1986 }1942 } else try ip.createPairedCauNav(gpa, pt.tid, name, fqn, tracked_inst, namespace_index, kind == .@"usingnamespace");
1987 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update1943 const want_analysis = switch (kind) {
1988 break :a true;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 };
1989 },1981 },
1990 };1982 };
19911983
1992 if (want_analysis) {1984 if (want_analysis or declaration.flags.is_export) {
1993 // We will not queue analysis if the decl has been analyzed on a previous update and1985 log.debug(
1994 // `is_export` is unchanged. In this case, the incremental update mechanism will handle1986 "scanDecl queue analyze_cau file='{s}' cau_index={d}",
1995 // re-analysis for us if necessary.1987 .{ namespace.fileScope(zcu).sub_file_path, cau },
1996 if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {1988 );
1997 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{1989 try comp.queueJob(.{ .analyze_cau = cau });
1998 namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index,
1999 });
2000 try comp.queueJob(.{ .analyze_decl = decl_index });
2001 }
2002 }1990 }
20031991
2004 if (decl.getOwnedFunction(zcu) != null) {1992 // TODO: we used to do line number updates here, but this is an inappropriate place for this logic to live.
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 }
2011 }1993 }
2012};1994};
20131995
2014/// Cancel the creation of an anon decl and delete any references to it.1996fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!Air {
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 {
2029 const tracy = trace(@src());1997 const tracy = trace(@src());
2030 defer tracy.end();1998 defer tracy.end();
20311999
2032 const mod = pt.zcu;2000 const zcu = pt.zcu;
2033 const gpa = mod.gpa;2001 const gpa = zcu.gpa;
2034 const ip = &mod.intern_pool;2002 const ip = &zcu.intern_pool;
2035 const func = mod.funcInfo(func_index);2003
2036 const decl_index = func.owner_decl;2004 const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index });
2037 const decl = mod.declPtr(decl_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)});2025 const func_nav = ip.getNav(func.owner_nav);
2040 defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
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);
2043 defer decl_prog_node.end();2028 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
2047 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);2035 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
2048 defer comptime_err_ret_trace.deinit();2036 defer comptime_err_ret_trace.deinit();
...@@ -2052,21 +2040,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2052,21 +2040,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2052 // the runtime-known parameters only, not to be confused with the2040 // the runtime-known parameters only, not to be confused with the
2053 // generic_owner function type, which potentially has more parameters,2041 // generic_owner function type, which potentially has more parameters,
2054 // including comptime parameters.2042 // including comptime parameters.
2055 const fn_ty = decl.typeOf(mod);2043 const fn_ty = Type.fromInterned(func.ty);
2056 const fn_ty_info = mod.typeToFunc(fn_ty).?;2044 const fn_ty_info = zcu.typeToFunc(fn_ty).?;
20572045
2058 var sema: Sema = .{2046 var sema: Sema = .{
2059 .pt = pt,2047 .pt = pt,
2060 .gpa = gpa,2048 .gpa = gpa,
2061 .arena = arena,2049 .arena = analysis_arena.allocator(),
2062 .code = decl.getFileScope(mod).zir,2050 .code = zir,
2063 .owner_decl = decl,2051 .owner = anal_unit,
2064 .owner_decl_index = decl_index,
2065 .func_index = func_index,2052 .func_index = func_index,
2066 .func_is_naked = fn_ty_info.cc == .Naked,2053 .func_is_naked = fn_ty_info.cc == .Naked,
2067 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),2054 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
2068 .fn_ret_ty_ies = null,2055 .fn_ret_ty_ies = null,
2069 .owner_func_index = func_index,
2070 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),2056 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),
2071 .comptime_err_ret_trace = &comptime_err_ret_trace,2057 .comptime_err_ret_trace = &comptime_err_ret_trace,
2072 };2058 };
...@@ -2074,11 +2060,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2074,11 +2060,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20742060
2075 // Every runtime function has a dependency on the source of the Decl it originates from.2061 // Every runtime function has a dependency on the source of the Decl it originates from.
2076 // It also depends on the value of its owner Decl.2062 // It also depends on the value of its owner Decl.
2077 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });2063 try sema.declareDependency(.{ .src_hash = decl_cau.zir_index });
2078 try sema.declareDependency(.{ .decl_val = decl_index });2064 try sema.declareDependency(.{ .nav_val = func.owner_nav });
20792065
2080 if (func.analysisUnordered(ip).inferred_error_set) {2066 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);
2082 ies.* = .{ .func = func_index };2068 ies.* = .{ .func = func_index };
2083 sema.fn_ret_ty_ies = ies;2069 sema.fn_ret_ty_ies = ies;
2084 }2070 }
...@@ -2094,19 +2080,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2094,19 +2080,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2094 var inner_block: Sema.Block = .{2080 var inner_block: Sema.Block = .{
2095 .parent = null,2081 .parent = null,
2096 .sema = &sema,2082 .sema = &sema,
2097 .namespace = decl.src_namespace,2083 .namespace = decl_cau.namespace,
2098 .instructions = .{},2084 .instructions = .{},
2099 .inlining = null,2085 .inlining = null,
2100 .is_comptime = false,2086 .is_comptime = false,
2101 .src_base_inst = inst: {2087 .src_base_inst = decl_cau.zir_index,
2102 const owner_info = if (func.generic_owner == .none)2088 .type_name_ctx = func_nav.fqn,
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,
2110 };2089 };
2111 defer inner_block.instructions.deinit(gpa);2090 defer inner_block.instructions.deinit(gpa);
21122091
...@@ -2144,10 +2123,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2144,10 +2123,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2144 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);2123 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
2145 if (gop.found_existing) continue; // provided above by comptime arg2124 if (gop.found_existing) continue; // provided above by comptime arg
21462125
2147 const inst_info = sema.code.instructions.get(@intFromEnum(inst));2126 const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
2148 const param_name: Zir.NullTerminatedString = switch (inst_info.tag) {2127 const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
2149 .param_anytype => inst_info.data.str_tok.start,2128 .param_anytype => param_inst_info.data.str_tok.start,
2150 .param => sema.code.extraData(Zir.Inst.Param, inst_info.data.pl_tok.payload_index).data.name,2129 .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
2151 else => unreachable,2130 else => unreachable,
2152 };2131 };
21532132
...@@ -2179,8 +2158,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2179,8 +2158,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2179 });2158 });
2180 }2159 }
21812160
2182 func.setAnalysisState(ip, .in_progress);
2183
2184 const last_arg_index = inner_block.instructions.items.len;2161 const last_arg_index = inner_block.instructions.items.len;
21852162
2186 // Save the error trace as our first action in the function.2163 // 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...@@ -2190,9 +2167,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2190 inner_block.error_return_trace_index = error_return_trace_index;2167 inner_block.error_return_trace_index = error_return_trace_index;
21912168
2192 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {2169 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
2193 // TODO make these unreachable instead of @panic2170 error.GenericPoison => unreachable,
2194 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),2171 error.ComptimeReturn => unreachable,
2195 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
2196 else => |e| return e,2172 else => |e| return e,
2197 };2173 };
21982174
...@@ -2207,14 +2183,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2207,14 +2183,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
22072183
2208 // If we don't get an error return trace from a caller, create our own.2184 // If we don't get an error return trace from a caller, create our own.
2209 if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and2185 if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and
2210 mod.comp.config.any_error_tracing and2186 zcu.comp.config.any_error_tracing and
2211 !sema.fn_ret_ty.isError(mod))2187 !sema.fn_ret_ty.isError(zcu))
2212 {2188 {
2213 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {2189 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
2214 // TODO make these unreachable instead of @panic2190 error.GenericPoison => unreachable,
2215 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),2191 error.ComptimeReturn => unreachable,
2216 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),2192 error.ComptimeBreak => unreachable,
2217 error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
2218 else => |e| return e,2193 else => |e| return e,
2219 };2194 };
2220 }2195 }
...@@ -2239,35 +2214,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2239,35 +2214,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2239 error.GenericPoison => unreachable,2214 error.GenericPoison => unreachable,
2240 error.ComptimeReturn => unreachable,2215 error.ComptimeReturn => unreachable,
2241 error.ComptimeBreak => unreachable,2216 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 },
2248 else => |e| return e,2217 else => |e| return e,
2249 };2218 };
2250 assert(ies.resolved != .none);2219 assert(ies.resolved != .none);
2251 ip.funcSetIesResolved(func_index, ies.resolved);2220 ip.funcSetIesResolved(func_index, ies.resolved);
2252 }2221 }
22532222
2254 func.setAnalysisState(ip, .success);2223 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
22552224
2256 // Finally we must resolve the return type and parameter types so that backends2225 // Finally we must resolve the return type and parameter types so that backends
2257 // have full access to type information.2226 // have full access to type information.
2258 // Crucially, this happens *after* we set the function state to success above,2227 // Crucially, this happens *after* we set the function state to success above,
2259 // so that dependencies on the function body will now be satisfied rather than2228 // so that dependencies on the function body will now be satisfied rather than
2260 // result in circular dependency errors.2229 // 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.
2261 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {2232 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
2262 error.GenericPoison => unreachable,2233 error.GenericPoison => unreachable,
2263 error.ComptimeReturn => unreachable,2234 error.ComptimeReturn => unreachable,
2264 error.ComptimeBreak => unreachable,2235 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 },
2271 else => |e| return e,2236 else => |e| return e,
2272 };2237 };
22732238
...@@ -2287,36 +2252,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index)...@@ -2287,36 +2252,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index)
2287 return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index);2252 return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index);
2288}2253}
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
2320pub fn getErrorValue(2255pub fn getErrorValue(
2321 pt: Zcu.PerThread,2256 pt: Zcu.PerThread,
2322 name: InternPool.NullTerminatedString,2257 name: InternPool.NullTerminatedString,
...@@ -2328,25 +2263,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err...@@ -2328,25 +2263,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err
2328 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));2263 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
2329}2264}
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
2350fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {2266fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
2351 switch (file.status) {2267 switch (file.status) {
2352 .success_zir, .retryable_failure => {},2268 .success_zir, .retryable_failure => {},
...@@ -2367,35 +2283,35 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -2367,35 +2283,35 @@ pub fn processExports(pt: Zcu.PerThread) !void {
2367 const zcu = pt.zcu;2283 const zcu = pt.zcu;
2368 const gpa = zcu.gpa;2284 const gpa = zcu.gpa;
23692285
2370 // First, construct a mapping of every exported value and Decl to the indices of all its different exports.2286 // First, construct a mapping of every exported value and Nav to the indices of all its different exports.
2371 var decl_exports: std.AutoArrayHashMapUnmanaged(Zcu.Decl.Index, std.ArrayListUnmanaged(u32)) = .{};2287 var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .{};
2372 var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};2288 var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
2373 defer {2289 defer {
2374 for (decl_exports.values()) |*exports| {2290 for (nav_exports.values()) |*exports| {
2375 exports.deinit(gpa);2291 exports.deinit(gpa);
2376 }2292 }
2377 decl_exports.deinit(gpa);2293 nav_exports.deinit(gpa);
2378 for (value_exports.values()) |*exports| {2294 for (uav_exports.values()) |*exports| {
2379 exports.deinit(gpa);2295 exports.deinit(gpa);
2380 }2296 }
2381 value_exports.deinit(gpa);2297 uav_exports.deinit(gpa);
2382 }2298 }
23832299
2384 // We note as a heuristic:2300 // We note as a heuristic:
2385 // * It is rare to export a value.2301 // * 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.
2387 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.2303 // 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
2390 for (zcu.single_exports.values()) |export_idx| {2306 for (zcu.single_exports.values()) |export_idx| {
2391 const exp = zcu.all_exports.items[export_idx];2307 const exp = zcu.all_exports.items[export_idx];
2392 const value_ptr, const found_existing = switch (exp.exported) {2308 const value_ptr, const found_existing = switch (exp.exported) {
2393 .decl_index => |i| gop: {2309 .nav => |nav| gop: {
2394 const gop = try decl_exports.getOrPut(gpa, i);2310 const gop = try nav_exports.getOrPut(gpa, nav);
2395 break :gop .{ gop.value_ptr, gop.found_existing };2311 break :gop .{ gop.value_ptr, gop.found_existing };
2396 },2312 },
2397 .value => |i| gop: {2313 .uav => |uav| gop: {
2398 const gop = try value_exports.getOrPut(gpa, i);2314 const gop = try uav_exports.getOrPut(gpa, uav);
2399 break :gop .{ gop.value_ptr, gop.found_existing };2315 break :gop .{ gop.value_ptr, gop.found_existing };
2400 },2316 },
2401 };2317 };
...@@ -2406,12 +2322,12 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -2406,12 +2322,12 @@ pub fn processExports(pt: Zcu.PerThread) !void {
2406 for (zcu.multi_exports.values()) |info| {2322 for (zcu.multi_exports.values()) |info| {
2407 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {2323 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {
2408 const value_ptr, const found_existing = switch (exp.exported) {2324 const value_ptr, const found_existing = switch (exp.exported) {
2409 .decl_index => |i| gop: {2325 .nav => |nav| gop: {
2410 const gop = try decl_exports.getOrPut(gpa, i);2326 const gop = try nav_exports.getOrPut(gpa, nav);
2411 break :gop .{ gop.value_ptr, gop.found_existing };2327 break :gop .{ gop.value_ptr, gop.found_existing };
2412 },2328 },
2413 .value => |i| gop: {2329 .uav => |uav| gop: {
2414 const gop = try value_exports.getOrPut(gpa, i);2330 const gop = try uav_exports.getOrPut(gpa, uav);
2415 break :gop .{ gop.value_ptr, gop.found_existing };2331 break :gop .{ gop.value_ptr, gop.found_existing };
2416 },2332 },
2417 };2333 };
...@@ -2424,13 +2340,13 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -2424,13 +2340,13 @@ pub fn processExports(pt: Zcu.PerThread) !void {
2424 var symbol_exports: SymbolExports = .{};2340 var symbol_exports: SymbolExports = .{};
2425 defer symbol_exports.deinit(gpa);2341 defer symbol_exports.deinit(gpa);
24262342
2427 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {2343 for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| {
2428 const exported: Zcu.Exported = .{ .decl_index = exported_decl };2344 const exported: Zcu.Exported = .{ .nav = exported_nav };
2429 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);2345 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
2430 }2346 }
24312347
2432 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {2348 for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| {
2433 const exported: Zcu.Exported = .{ .value = exported_value };2349 const exported: Zcu.Exported = .{ .uav = exported_uav };
2434 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);2350 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
2435 }2351 }
2436}2352}
...@@ -2467,20 +2383,31 @@ fn processExportsInner(...@@ -2467,20 +2383,31 @@ fn processExportsInner(
2467 }2383 }
24682384
2469 switch (exported) {2385 switch (exported) {
2470 .decl_index => |idx| if (failed: {2386 .nav => |nav_index| if (failed: {
2471 const decl = zcu.declPtr(idx);2387 const nav = ip.getNav(nav_index);
2472 if (decl.analysis != .complete) break :failed true;2388 if (zcu.failed_codegen.contains(nav_index)) break :failed true;
2473 // Check if has owned function2389 if (nav.analysis_owner.unwrap()) |cau| {
2474 if (!decl.owns_tv) break :failed false;2390 const cau_unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
2475 if (decl.typeOf(zcu).zigTypeTag(zcu) != .Fn) break :failed false;2391 if (zcu.failed_analysis.contains(cau_unit)) break :failed true;
2476 // Check if owned function failed2392 if (zcu.transitive_failed_analysis.contains(cau_unit)) break :failed true;
2477 break :failed zcu.funcInfo(decl.val.toIntern()).analysisUnordered(ip).state != .success;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;
2478 }) {2405 }) {
2479 // This `Decl` is failed, so was never sent to codegen.2406 // This `Decl` is failed, so was never sent to codegen.
2480 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?2407 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?
2481 return;2408 return;
2482 },2409 },
2483 .value => {},2410 .uav => {},
2484 }2411 }
24852412
2486 if (zcu.comp.bin_file) |lf| {2413 if (zcu.comp.bin_file) |lf| {
...@@ -2499,46 +2426,49 @@ pub fn populateTestFunctions(...@@ -2499,46 +2426,49 @@ pub fn populateTestFunctions(
2499 const ip = &zcu.intern_pool;2426 const ip = &zcu.intern_pool;
2500 const builtin_mod = zcu.root_mod.getBuiltinDependency();2427 const builtin_mod = zcu.root_mod.getBuiltinDependency();
2501 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;2428 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
2502 const root_decl_index = zcu.fileRootDecl(builtin_file_index);2429 pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) {
2503 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);2430 error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt
2504 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);2431 error.OutOfMemory => |e| return e,
2505 const test_functions_str = try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls);2432 };
2506 const decl_index = builtin_namespace.decls.getKeyAdapted(2433 const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index));
2507 test_functions_str,2434 const builtin_namespace = builtin_root_type.getNamespace(zcu).unwrap().?;
2508 Zcu.DeclAdapter{ .zcu = zcu },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 },
2509 ).?;2438 ).?;
2510 {2439 {
2511 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`2440 // We have to call `ensureCauAnalyzed` here in case `builtin.test_functions`
2512 // was not referenced by start code.2441 // was not referenced by start code.
2513 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);2442 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
2514 defer {2443 defer {
2515 zcu.sema_prog_node.end();2444 zcu.sema_prog_node.end();
2516 zcu.sema_prog_node = std.Progress.Node.none;2445 zcu.sema_prog_node = std.Progress.Node.none;
2517 }2446 }
2518 try pt.ensureDeclAnalyzed(decl_index);2447 const cau_index = ip.getNav(nav_index).analysis_owner.unwrap().?;
2448 try pt.ensureCauAnalyzed(cau_index);
2519 }2449 }
25202450
2521 const decl = zcu.declPtr(decl_index);2451 const test_fns_val = zcu.navValue(nav_index);
2522 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);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: {
2525 // Add zcu.test_functions to an array decl then make the test_functions2455 // Add zcu.test_functions to an array decl then make the test_functions
2526 // decl reference it as a slice.2456 // decl reference it as a slice.
2527 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());2457 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
2528 defer gpa.free(test_fn_vals);2458 defer gpa.free(test_fn_vals);
25292459
2530 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {2460 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_nav_index| {
2531 const test_decl = zcu.declPtr(test_decl_index);2461 const test_nav = ip.getNav(test_nav_index);
2532 const test_decl_name = test_decl.fqn;2462 const test_nav_name = test_nav.fqn;
2533 const test_decl_name_len = test_decl_name.length(ip);2463 const test_nav_name_len = test_nav_name.length(ip);
2534 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {2464 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = n: {
2535 const test_name_ty = try pt.arrayType(.{2465 const test_name_ty = try pt.arrayType(.{
2536 .len = test_decl_name_len,2466 .len = test_nav_name_len,
2537 .child = .u8_type,2467 .child = .u8_type,
2538 });2468 });
2539 const test_name_val = try pt.intern(.{ .aggregate = .{2469 const test_name_val = try pt.intern(.{ .aggregate = .{
2540 .ty = test_name_ty.toIntern(),2470 .ty = test_name_ty.toIntern(),
2541 .storage = .{ .bytes = test_decl_name.toString() },2471 .storage = .{ .bytes = test_nav_name.toString() },
2542 } });2472 } });
2543 break :n .{2473 break :n .{
2544 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),2474 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),
...@@ -2552,23 +2482,18 @@ pub fn populateTestFunctions(...@@ -2552,23 +2482,18 @@ pub fn populateTestFunctions(
2552 .ty = .slice_const_u8_type,2482 .ty = .slice_const_u8_type,
2553 .ptr = try pt.intern(.{ .ptr = .{2483 .ptr = try pt.intern(.{ .ptr = .{
2554 .ty = .manyptr_const_u8_type,2484 .ty = .manyptr_const_u8_type,
2555 .base_addr = .{ .anon_decl = test_name_anon_decl },2485 .base_addr = .{ .uav = test_name_anon_decl },
2556 .byte_offset = 0,2486 .byte_offset = 0,
2557 } }),2487 } }),
2558 .len = try pt.intern(.{ .int = .{2488 .len = try pt.intern(.{ .int = .{
2559 .ty = .usize_type,2489 .ty = .usize_type,
2560 .storage = .{ .u64 = test_decl_name_len },2490 .storage = .{ .u64 = test_nav_name_len },
2561 } }),2491 } }),
2562 } }),2492 } }),
2563 // func2493 // func
2564 try pt.intern(.{ .ptr = .{2494 try pt.intern(.{ .ptr = .{
2565 .ty = try pt.intern(.{ .ptr_type = .{2495 .ty = (try pt.navPtrType(test_nav_index)).toIntern(),
2566 .child = test_decl.typeOf(zcu).toIntern(),2496 .base_addr = .{ .nav = test_nav_index },
2567 .flags = .{
2568 .is_const = true,
2569 },
2570 } }),
2571 .base_addr = .{ .decl = test_decl_index },
2572 .byte_offset = 0,2497 .byte_offset = 0,
2573 } }),2498 } }),
2574 };2499 };
...@@ -2601,22 +2526,16 @@ pub fn populateTestFunctions(...@@ -2601,22 +2526,16 @@ pub fn populateTestFunctions(
2601 .size = .Slice,2526 .size = .Slice,
2602 },2527 },
2603 });2528 });
2604 const new_val = decl.val;
2605 const new_init = try pt.intern(.{ .slice = .{2529 const new_init = try pt.intern(.{ .slice = .{
2606 .ty = new_ty.toIntern(),2530 .ty = new_ty.toIntern(),
2607 .ptr = try pt.intern(.{ .ptr = .{2531 .ptr = try pt.intern(.{ .ptr = .{
2608 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),2532 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
2609 .base_addr = .{ .anon_decl = array_anon_decl },2533 .base_addr = .{ .uav = array_anon_decl },
2610 .byte_offset = 0,2534 .byte_offset = 0,
2611 } }),2535 } }),
2612 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),2536 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
2613 } });2537 } });
2614 ip.mutateVarInit(decl.val.toIntern(), new_init);2538 ip.mutateVarInit(test_fns_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;
2620 }2539 }
2621 {2540 {
2622 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);2541 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
...@@ -2625,40 +2544,45 @@ pub fn populateTestFunctions(...@@ -2625,40 +2544,45 @@ pub fn populateTestFunctions(
2625 zcu.codegen_prog_node = std.Progress.Node.none;2544 zcu.codegen_prog_node = std.Progress.Node.none;
2626 }2545 }
26272546
2628 try pt.linkerUpdateDecl(decl_index);2547 try pt.linkerUpdateNav(nav_index);
2629 }2548 }
2630}2549}
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 {
2633 const zcu = pt.zcu;2552 const zcu = pt.zcu;
2634 const comp = zcu.comp;2553 const comp = zcu.comp;
26352554
2636 const decl = zcu.declPtr(decl_index);2555 const nav = zcu.intern_pool.getNav(nav_index);
26372556 const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0);
2638 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(&zcu.intern_pool), 0);
2639 defer codegen_prog_node.end();2557 defer codegen_prog_node.end();
26402558
2641 if (comp.bin_file) |lf| {2559 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) {
2643 error.OutOfMemory => return error.OutOfMemory,2561 error.OutOfMemory => return error.OutOfMemory,
2644 error.AnalysisFail => {2562 error.AnalysisFail => {
2645 decl.analysis = .codegen_failure;2563 assert(zcu.failed_codegen.contains(nav_index));
2646 },2564 },
2647 else => {2565 else => {
2648 const gpa = zcu.gpa;2566 const gpa = zcu.gpa;
2649 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);2567 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
2650 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(2568 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, try Zcu.ErrorMsg.create(
2651 gpa,2569 gpa,
2652 decl.navSrcLoc(zcu),2570 zcu.navSrcLoc(nav_index),
2653 "unable to codegen: {s}",2571 "unable to codegen: {s}",
2654 .{@errorName(err)},2572 .{@errorName(err)},
2655 ));2573 ));
2656 decl.analysis = .codegen_failure;2574 if (nav.analysis_owner.unwrap()) |cau| {
2657 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));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 }
2658 },2582 },
2659 };2583 };
2660 } else if (zcu.llvm_object) |llvm_object| {2584 } 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) {
2662 error.OutOfMemory => return error.OutOfMemory,2586 error.OutOfMemory => return error.OutOfMemory,
2663 };2587 };
2664 }2588 }
...@@ -2750,9 +2674,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool...@@ -2750,9 +2674,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool
2750 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);2674 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
2751}2675}
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.
2754pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {2680pub 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()));
2756}2701}
27572702
2758pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {2703pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
...@@ -3237,24 +3182,28 @@ pub fn structPackedFieldBitOffset(...@@ -3237,24 +3182,28 @@ pub fn structPackedFieldBitOffset(
3237}3182}
32383183
3239pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {3184pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {
3240 const decl_index = try pt.getBuiltinDecl(name);3185 const zcu = pt.zcu;
3241 pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");3186 const ip = &zcu.intern_pool;
3242 return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern());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);
3243}3190}
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 {
3246 const zcu = pt.zcu;3193 const zcu = pt.zcu;
3247 const gpa = zcu.gpa;3194 const gpa = zcu.gpa;
3248 const ip = &zcu.intern_pool;3195 const ip = &zcu.intern_pool;
3249 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");3196 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().?;3197 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3251 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;3198 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?);
3252 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);3199 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'");3200 const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
3254 pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");3201 @panic("lib/std.zig is corrupt and missing 'builtin'");
3255 const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");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"));
3256 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);3205 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");
3258}3207}
32593208
3260pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {3209pub 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...@@ -3264,6 +3213,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type
3264 return ty;3213 return ty;
3265}3214}
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
3267const Air = @import("../Air.zig");3257const Air = @import("../Air.zig");
3268const Allocator = std.mem.Allocator;3258const Allocator = std.mem.Allocator;
3269const assert = std.debug.assert;3259const assert = std.debug.assert;
src/arch/aarch64/CodeGen.zig+40-41
...@@ -52,7 +52,7 @@ bin_file: *link.File,...@@ -52,7 +52,7 @@ bin_file: *link.File,
52debug_output: DebugInfoOutput,52debug_output: DebugInfoOutput,
53target: *const std.Target,53target: *const std.Target,
54func_index: InternPool.Index,54func_index: InternPool.Index,
55owner_decl: InternPool.DeclIndex,55owner_nav: InternPool.Nav.Index,
56err_msg: ?*ErrorMsg,56err_msg: ?*ErrorMsg,
57args: []MCValue,57args: []MCValue,
58ret_mcv: MCValue,58ret_mcv: MCValue,
...@@ -184,7 +184,7 @@ const DbgInfoReloc = struct {...@@ -184,7 +184,7 @@ const DbgInfoReloc = struct {
184 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {184 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
185 switch (function.debug_output) {185 switch (function.debug_output) {
186 .dwarf => |dw| {186 .dwarf => |dw| {
187 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {187 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
188 .register => |reg| .{ .register = reg.dwarfLocOp() },188 .register => |reg| .{ .register = reg.dwarfLocOp() },
189 .stack_offset,189 .stack_offset,
190 .stack_argument_offset,190 .stack_argument_offset,
...@@ -202,7 +202,7 @@ const DbgInfoReloc = struct {...@@ -202,7 +202,7 @@ const DbgInfoReloc = struct {
202 else => unreachable, // not a possible argument202 else => unreachable, // not a possible argument
203203
204 };204 };
205 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.owner_decl, loc);205 try dw.genArgDbgInfo(reloc.name, reloc.ty, function.owner_nav, loc);
206 },206 },
207 .plan9 => {},207 .plan9 => {},
208 .none => {},208 .none => {},
...@@ -218,7 +218,7 @@ const DbgInfoReloc = struct {...@@ -218,7 +218,7 @@ const DbgInfoReloc = struct {
218218
219 switch (function.debug_output) {219 switch (function.debug_output) {
220 .dwarf => |dw| {220 .dwarf => |dw| {
221 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {221 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
222 .register => |reg| .{ .register = reg.dwarfLocOp() },222 .register => |reg| .{ .register = reg.dwarfLocOp() },
223 .ptr_stack_offset,223 .ptr_stack_offset,
224 .stack_offset,224 .stack_offset,
...@@ -248,7 +248,7 @@ const DbgInfoReloc = struct {...@@ -248,7 +248,7 @@ const DbgInfoReloc = struct {
248 break :blk .nop;248 break :blk .nop;
249 },249 },
250 };250 };
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);
252 },252 },
253 .plan9 => {},253 .plan9 => {},
254 .none => {},254 .none => {},
...@@ -341,11 +341,9 @@ pub fn generate(...@@ -341,11 +341,9 @@ pub fn generate(
341 const zcu = pt.zcu;341 const zcu = pt.zcu;
342 const gpa = zcu.gpa;342 const gpa = zcu.gpa;
343 const func = zcu.funcInfo(func_index);343 const func = zcu.funcInfo(func_index);
344 const fn_owner_decl = zcu.declPtr(func.owner_decl);344 const fn_type = Type.fromInterned(func.ty);
345 assert(fn_owner_decl.has_tv);345 const file_scope = zcu.navFileScope(func.owner_nav);
346 const fn_type = fn_owner_decl.typeOf(zcu);346 const target = &file_scope.mod.resolved_target.result;
347 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
348 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
349347
350 var branch_stack = std.ArrayList(Branch).init(gpa);348 var branch_stack = std.ArrayList(Branch).init(gpa);
351 defer {349 defer {
...@@ -364,7 +362,7 @@ pub fn generate(...@@ -364,7 +362,7 @@ pub fn generate(
364 .target = target,362 .target = target,
365 .bin_file = lf,363 .bin_file = lf,
366 .func_index = func_index,364 .func_index = func_index,
367 .owner_decl = func.owner_decl,365 .owner_nav = func.owner_nav,
368 .err_msg = null,366 .err_msg = null,
369 .args = undefined, // populated after `resolveCallingConventionValues`367 .args = undefined, // populated after `resolveCallingConventionValues`
370 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`368 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
...@@ -4053,8 +4051,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -4053,8 +4051,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
4053 @panic("TODO store");4051 @panic("TODO store");
4054 },4052 },
4055 .coff => blk: {4053 .coff => blk: {
4056 const coff_file = self.bin_file.cast(link.File.Coff).?;4054 const coff_file = self.bin_file.cast(.coff).?;
4057 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);4055 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
4058 break :blk coff_file.getAtom(atom).getSymbolIndex().?;4056 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
4059 },4057 },
4060 else => unreachable, // unsupported target format4058 else => unreachable, // unsupported target format
...@@ -4289,6 +4287,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4289,6 +4287,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4289 const ty = self.typeOf(callee);4287 const ty = self.typeOf(callee);
4290 const pt = self.pt;4288 const pt = self.pt;
4291 const mod = pt.zcu;4289 const mod = pt.zcu;
4290 const ip = &mod.intern_pool;
42924291
4293 const fn_ty = switch (ty.zigTypeTag(mod)) {4292 const fn_ty = switch (ty.zigTypeTag(mod)) {
4294 .Fn => ty,4293 .Fn => ty,
...@@ -4351,19 +4350,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4351,19 +4350,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43514350
4352 // Due to incremental compilation, how function calls are generated depends4351 // Due to incremental compilation, how function calls are generated depends
4353 // on linking.4352 // on linking.
4354 if (try self.air.value(callee, pt)) |func_value| {4353 if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
4355 if (func_value.getFunction(mod)) |func| {4354 .func => |func| {
4356 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4355 if (self.bin_file.cast(.elf)) |elf_file| {
4357 const zo = elf_file.zigObjectPtr().?;4356 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);
4359 const sym = zo.symbol(sym_index);4358 const sym = zo.symbol(sym_index);
4360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);4359 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
4361 const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));4360 const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
4362 try self.genSetReg(Type.usize, .x30, .{ .memory = got_addr });4361 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| {
4364 _ = macho_file;4363 _ = macho_file;
4365 @panic("TODO airCall");4364 @panic("TODO airCall");
4366 // const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);4365 // const atom = try macho_file.getOrCreateAtomForNav(func.owner_nav);
4367 // const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;4366 // const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
4368 // try self.genSetReg(Type.u64, .x30, .{4367 // try self.genSetReg(Type.u64, .x30, .{
4369 // .linker_load = .{4368 // .linker_load = .{
...@@ -4371,8 +4370,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4371,8 +4370,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4371 // .sym_index = sym_index,4370 // .sym_index = sym_index,
4372 // },4371 // },
4373 // });4372 // });
4374 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {4373 } else if (self.bin_file.cast(.coff)) |coff_file| {
4375 const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);4374 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
4376 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;4375 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
4377 try self.genSetReg(Type.u64, .x30, .{4376 try self.genSetReg(Type.u64, .x30, .{
4378 .linker_load = .{4377 .linker_load = .{
...@@ -4380,8 +4379,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4380,8 +4379,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4380 .sym_index = sym_index,4379 .sym_index = sym_index,
4381 },4380 },
4382 });4381 });
4383 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {4382 } else if (self.bin_file.cast(.plan9)) |p9| {
4384 const atom_index = try p9.seeDecl(func.owner_decl);4383 const atom_index = try p9.seeNav(pt, func.owner_nav);
4385 const atom = p9.getAtom(atom_index);4384 const atom = p9.getAtom(atom_index);
4386 try self.genSetReg(Type.usize, .x30, .{ .memory = atom.getOffsetTableAddress(p9) });4385 try self.genSetReg(Type.usize, .x30, .{ .memory = atom.getOffsetTableAddress(p9) });
4387 } else unreachable;4386 } else unreachable;
...@@ -4390,14 +4389,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4390,14 +4389,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4390 .tag = .blr,4389 .tag = .blr,
4391 .data = .{ .reg = .x30 },4390 .data = .{ .reg = .x30 },
4392 });4391 });
4393 } else if (func_value.getExternFunc(mod)) |extern_func| {4392 },
4394 const decl_name = mod.declPtr(extern_func.decl).name.toSlice(&mod.intern_pool);4393 .@"extern" => |@"extern"| {
4395 const lib_name = extern_func.lib_name.toSlice(&mod.intern_pool);4394 const nav_name = ip.getNav(@"extern".owner_nav).name.toSlice(ip);
4396 if (self.bin_file.cast(link.File.MachO)) |macho_file| {4395 const lib_name = @"extern".lib_name.toSlice(ip);
4396 if (self.bin_file.cast(.macho)) |macho_file| {
4397 _ = macho_file;4397 _ = macho_file;
4398 @panic("TODO airCall");4398 @panic("TODO airCall");
4399 // const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);4399 // const sym_index = try macho_file.getGlobalSymbol(nav_name, lib_name);
4400 // const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);4400 // const atom = try macho_file.getOrCreateAtomForNav(self.owner_nav);
4401 // const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;4401 // const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
4402 // _ = try self.addInst(.{4402 // _ = try self.addInst(.{
4403 // .tag = .call_extern,4403 // .tag = .call_extern,
...@@ -4408,8 +4408,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4408,8 +4408,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4408 // },4408 // },
4409 // },4409 // },
4410 // });4410 // });
4411 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {4411 } else if (self.bin_file.cast(.coff)) |coff_file| {
4412 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);4412 const sym_index = try coff_file.getGlobalSymbol(nav_name, lib_name);
4413 try self.genSetReg(Type.u64, .x30, .{4413 try self.genSetReg(Type.u64, .x30, .{
4414 .linker_load = .{4414 .linker_load = .{
4415 .type = .import,4415 .type = .import,
...@@ -4423,9 +4423,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4423,9 +4423,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4423 } else {4423 } else {
4424 return self.fail("TODO implement calling extern functions", .{});4424 return self.fail("TODO implement calling extern functions", .{});
4425 }4425 }
4426 } else {4426 },
4427 return self.fail("TODO implement calling bitcasted functions", .{});4427 else => return self.fail("TODO implement calling bitcasted functions", .{}),
4428 }
4429 } else {4428 } else {
4430 assert(ty.zigTypeTag(mod) == .Pointer);4429 assert(ty.zigTypeTag(mod) == .Pointer);
4431 const mcv = try self.resolveInst(callee);4430 const mcv = try self.resolveInst(callee);
...@@ -5594,8 +5593,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5594,8 +5593,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5594 @panic("TODO genSetStack");5593 @panic("TODO genSetStack");
5595 },5594 },
5596 .coff => blk: {5595 .coff => blk: {
5597 const coff_file = self.bin_file.cast(link.File.Coff).?;5596 const coff_file = self.bin_file.cast(.coff).?;
5598 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);5597 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
5599 break :blk coff_file.getAtom(atom).getSymbolIndex().?;5598 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5600 },5599 },
5601 else => unreachable, // unsupported target format5600 else => unreachable, // unsupported target format
...@@ -5717,8 +5716,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5717,8 +5716,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5717 // break :blk macho_file.getAtom(atom).getSymbolIndex().?;5716 // break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5718 },5717 },
5719 .coff => blk: {5718 .coff => blk: {
5720 const coff_file = self.bin_file.cast(link.File.Coff).?;5719 const coff_file = self.bin_file.cast(.coff).?;
5721 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);5720 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
5722 break :blk coff_file.getAtom(atom).getSymbolIndex().?;5721 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5723 },5722 },
5724 else => unreachable, // unsupported target format5723 else => unreachable, // unsupported target format
...@@ -5915,8 +5914,8 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5915,8 +5914,8 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5915 // break :blk macho_file.getAtom(atom).getSymbolIndex().?;5914 // break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5916 },5915 },
5917 .coff => blk: {5916 .coff => blk: {
5918 const coff_file = self.bin_file.cast(link.File.Coff).?;5917 const coff_file = self.bin_file.cast(.coff).?;
5919 const atom = try coff_file.getOrCreateAtomForDecl(self.owner_decl);5918 const atom = try coff_file.getOrCreateAtomForNav(self.owner_nav);
5920 break :blk coff_file.getAtom(atom).getSymbolIndex().?;5919 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5921 },5920 },
5922 else => unreachable, // unsupported target format5921 else => unreachable, // unsupported target format
...@@ -6226,7 +6225,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {...@@ -6226,7 +6225,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
6226 self.pt,6225 self.pt,
6227 self.src_loc,6226 self.src_loc,
6228 val,6227 val,
6229 self.owner_decl,6228 self.target.*,
6230 )) {6229 )) {
6231 .mcv => |mcv| switch (mcv) {6230 .mcv => |mcv| switch (mcv) {
6232 .none => .none,6231 .none => .none,
src/arch/aarch64/Emit.zig+4-4
...@@ -687,7 +687,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -687,7 +687,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
687 };687 };
688 _ = offset;688 _ = offset;
689689
690 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {690 if (emit.bin_file.cast(.macho)) |macho_file| {
691 _ = macho_file;691 _ = macho_file;
692 @panic("TODO mirCallExtern");692 @panic("TODO mirCallExtern");
693 // // Add relocation to the decl.693 // // Add relocation to the decl.
...@@ -701,7 +701,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -701,7 +701,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
701 // .pcrel = true,701 // .pcrel = true,
702 // .length = 2,702 // .length = 2,
703 // });703 // });
704 } else if (emit.bin_file.cast(link.File.Coff)) |_| {704 } else if (emit.bin_file.cast(.coff)) |_| {
705 unreachable; // Calling imports is handled via `.load_memory_import`705 unreachable; // Calling imports is handled via `.load_memory_import`
706 } else {706 } else {
707 return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});707 return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});
...@@ -903,7 +903,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -903,7 +903,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
903 else => unreachable,903 else => unreachable,
904 }904 }
905905
906 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {906 if (emit.bin_file.cast(.macho)) |macho_file| {
907 _ = macho_file;907 _ = macho_file;
908 @panic("TODO mirLoadMemoryPie");908 @panic("TODO mirLoadMemoryPie");
909 // const Atom = link.File.MachO.Atom;909 // const Atom = link.File.MachO.Atom;
...@@ -932,7 +932,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -932,7 +932,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
932 // else => unreachable,932 // else => unreachable,
933 // },933 // },
934 // } });934 // } });
935 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {935 } else if (emit.bin_file.cast(.coff)) |coff_file| {
936 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;936 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
937 const target = switch (tag) {937 const target = switch (tag) {
938 .load_memory_got,938 .load_memory_got,
src/arch/arm/CodeGen.zig+21-20
...@@ -262,7 +262,7 @@ const DbgInfoReloc = struct {...@@ -262,7 +262,7 @@ const DbgInfoReloc = struct {
262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
263 switch (function.debug_output) {263 switch (function.debug_output) {
264 .dwarf => |dw| {264 .dwarf => |dw| {
265 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {265 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
266 .register => |reg| .{ .register = reg.dwarfLocOp() },266 .register => |reg| .{ .register = reg.dwarfLocOp() },
267 .stack_offset,267 .stack_offset,
268 .stack_argument_offset,268 .stack_argument_offset,
...@@ -280,7 +280,7 @@ const DbgInfoReloc = struct {...@@ -280,7 +280,7 @@ const DbgInfoReloc = struct {
280 else => unreachable, // not a possible argument280 else => unreachable, // not a possible argument
281 };281 };
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);
284 },284 },
285 .plan9 => {},285 .plan9 => {},
286 .none => {},286 .none => {},
...@@ -296,7 +296,7 @@ const DbgInfoReloc = struct {...@@ -296,7 +296,7 @@ const DbgInfoReloc = struct {
296296
297 switch (function.debug_output) {297 switch (function.debug_output) {
298 .dwarf => |dw| {298 .dwarf => |dw| {
299 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {299 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (reloc.mcv) {
300 .register => |reg| .{ .register = reg.dwarfLocOp() },300 .register => |reg| .{ .register = reg.dwarfLocOp() },
301 .ptr_stack_offset,301 .ptr_stack_offset,
302 .stack_offset,302 .stack_offset,
...@@ -323,7 +323,7 @@ const DbgInfoReloc = struct {...@@ -323,7 +323,7 @@ const DbgInfoReloc = struct {
323 break :blk .nop;323 break :blk .nop;
324 },324 },
325 };325 };
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);
327 },327 },
328 .plan9 => {},328 .plan9 => {},
329 .none => {},329 .none => {},
...@@ -346,11 +346,9 @@ pub fn generate(...@@ -346,11 +346,9 @@ pub fn generate(
346 const zcu = pt.zcu;346 const zcu = pt.zcu;
347 const gpa = zcu.gpa;347 const gpa = zcu.gpa;
348 const func = zcu.funcInfo(func_index);348 const func = zcu.funcInfo(func_index);
349 const fn_owner_decl = zcu.declPtr(func.owner_decl);349 const func_ty = Type.fromInterned(func.ty);
350 assert(fn_owner_decl.has_tv);350 const file_scope = zcu.navFileScope(func.owner_nav);
351 const fn_type = fn_owner_decl.typeOf(zcu);351 const target = &file_scope.mod.resolved_target.result;
352 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
353 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
354352
355 var branch_stack = std.ArrayList(Branch).init(gpa);353 var branch_stack = std.ArrayList(Branch).init(gpa);
356 defer {354 defer {
...@@ -372,7 +370,7 @@ pub fn generate(...@@ -372,7 +370,7 @@ pub fn generate(
372 .err_msg = null,370 .err_msg = null,
373 .args = undefined, // populated after `resolveCallingConventionValues`371 .args = undefined, // populated after `resolveCallingConventionValues`
374 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`372 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
375 .fn_type = fn_type,373 .fn_type = func_ty,
376 .arg_index = 0,374 .arg_index = 0,
377 .branch_stack = &branch_stack,375 .branch_stack = &branch_stack,
378 .src_loc = src_loc,376 .src_loc = src_loc,
...@@ -385,7 +383,7 @@ pub fn generate(...@@ -385,7 +383,7 @@ pub fn generate(
385 defer function.exitlude_jump_relocs.deinit(gpa);383 defer function.exitlude_jump_relocs.deinit(gpa);
386 defer function.dbg_info_relocs.deinit(gpa);384 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) {
389 error.CodegenFail => return Result{ .fail = function.err_msg.? },387 error.CodegenFail => return Result{ .fail = function.err_msg.? },
390 error.OutOfRegisters => return Result{388 error.OutOfRegisters => return Result{
391 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),389 .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...@@ -4264,6 +4262,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4264 const ty = self.typeOf(callee);4262 const ty = self.typeOf(callee);
4265 const pt = self.pt;4263 const pt = self.pt;
4266 const mod = pt.zcu;4264 const mod = pt.zcu;
4265 const ip = &mod.intern_pool;
42674266
4268 const fn_ty = switch (ty.zigTypeTag(mod)) {4267 const fn_ty = switch (ty.zigTypeTag(mod)) {
4269 .Fn => ty,4268 .Fn => ty,
...@@ -4333,16 +4332,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4333,16 +4332,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43334332
4334 // Due to incremental compilation, how function calls are generated depends4333 // Due to incremental compilation, how function calls are generated depends
4335 // on linking.4334 // on linking.
4336 if (try self.air.value(callee, pt)) |func_value| {4335 if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
4337 if (func_value.getFunction(mod)) |func| {4336 .func => |func| {
4338 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4337 if (self.bin_file.cast(.elf)) |elf_file| {
4339 const zo = elf_file.zigObjectPtr().?;4338 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);
4341 const sym = zo.symbol(sym_index);4340 const sym = zo.symbol(sym_index);
4342 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);4341 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
4343 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));4342 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
4344 try self.genSetReg(Type.usize, .lr, .{ .memory = got_addr });4343 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)) |_| {
4346 unreachable; // unsupported architecture for MachO4345 unreachable; // unsupported architecture for MachO
4347 } else {4346 } else {
4348 return self.fail("TODO implement call on {s} for {s}", .{4347 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...@@ -4350,11 +4349,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4350 @tagName(self.target.cpu.arch),4349 @tagName(self.target.cpu.arch),
4351 });4350 });
4352 }4351 }
4353 } else if (func_value.getExternFunc(mod)) |_| {4352 },
4353 .@"extern" => {
4354 return self.fail("TODO implement calling extern functions", .{});4354 return self.fail("TODO implement calling extern functions", .{});
4355 } else {4355 },
4356 else => {
4356 return self.fail("TODO implement calling bitcasted functions", .{});4357 return self.fail("TODO implement calling bitcasted functions", .{});
4357 }4358 },
4358 } else {4359 } else {
4359 assert(ty.zigTypeTag(mod) == .Pointer);4360 assert(ty.zigTypeTag(mod) == .Pointer);
4360 const mcv = try self.resolveInst(callee);4361 const mcv = try self.resolveInst(callee);
...@@ -6178,7 +6179,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {...@@ -6178,7 +6179,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
6178 pt,6179 pt,
6179 self.src_loc,6180 self.src_loc,
6180 val,6181 val,
6181 pt.zcu.funcOwnerDeclIndex(self.func_index),6182 self.target.*,
6182 )) {6183 )) {
6183 .mcv => |mcv| switch (mcv) {6184 .mcv => |mcv| switch (mcv) {
6184 .none => .none,6185 .none => .none,
src/arch/riscv64/CodeGen.zig+40-77
...@@ -118,26 +118,18 @@ const RegisterOffset = struct { reg: Register, off: i32 = 0 };...@@ -118,26 +118,18 @@ const RegisterOffset = struct { reg: Register, off: i32 = 0 };
118pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };118pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
119119
120const Owner = union(enum) {120const Owner = union(enum) {
121 func_index: InternPool.Index,121 nav_index: InternPool.Nav.Index,
122 lazy_sym: link.File.LazySymbol,122 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
131 fn getSymbolIndex(owner: Owner, func: *Func) !u32 {124 fn getSymbolIndex(owner: Owner, func: *Func) !u32 {
132 const pt = func.pt;125 const pt = func.pt;
133 switch (owner) {126 switch (owner) {
134 .func_index => |func_index| {127 .nav_index => |nav_index| {
135 const decl_index = func.pt.zcu.funcOwnerDeclIndex(func_index);128 const elf_file = func.bin_file.cast(.elf).?;
136 const elf_file = func.bin_file.cast(link.File.Elf).?;129 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);
137 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
138 },130 },
139 .lazy_sym => |lazy_sym| {131 .lazy_sym => |lazy_sym| {
140 const elf_file = func.bin_file.cast(link.File.Elf).?;132 const elf_file = func.bin_file.cast(.elf).?;
141 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|133 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
142 func.fail("{s} creating lazy symbol", .{@errorName(err)});134 func.fail("{s} creating lazy symbol", .{@errorName(err)});
143 },135 },
...@@ -767,12 +759,8 @@ pub fn generate(...@@ -767,12 +759,8 @@ pub fn generate(
767 const gpa = zcu.gpa;759 const gpa = zcu.gpa;
768 const ip = &zcu.intern_pool;760 const ip = &zcu.intern_pool;
769 const func = zcu.funcInfo(func_index);761 const func = zcu.funcInfo(func_index);
770 const fn_owner_decl = zcu.declPtr(func.owner_decl);762 const fn_type = Type.fromInterned(func.ty);
771 assert(fn_owner_decl.has_tv);763 const mod = zcu.navFileScope(func.owner_nav).mod;
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;
776764
777 var branch_stack = std.ArrayList(Branch).init(gpa);765 var branch_stack = std.ArrayList(Branch).init(gpa);
778 defer {766 defer {
...@@ -789,9 +777,9 @@ pub fn generate(...@@ -789,9 +777,9 @@ pub fn generate(
789 .mod = mod,777 .mod = mod,
790 .bin_file = bin_file,778 .bin_file = bin_file,
791 .liveness = liveness,779 .liveness = liveness,
792 .target = target,780 .target = &mod.resolved_target.result,
793 .debug_output = debug_output,781 .debug_output = debug_output,
794 .owner = .{ .func_index = func_index },782 .owner = .{ .nav_index = func.owner_nav },
795 .err_msg = null,783 .err_msg = null,
796 .args = undefined, // populated after `resolveCallingConventionValues`784 .args = undefined, // populated after `resolveCallingConventionValues`
797 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`785 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
...@@ -818,7 +806,7 @@ pub fn generate(...@@ -818,7 +806,7 @@ pub fn generate(
818 function.mir_instructions.deinit(gpa);806 function.mir_instructions.deinit(gpa);
819 }807 }
820808
821 wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)});809 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
822810
823 try function.frame_allocs.resize(gpa, FrameIndex.named_count);811 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
824 function.frame_allocs.set(812 function.frame_allocs.set(
...@@ -1074,22 +1062,22 @@ fn fmtWipMir(func: *Func, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir)...@@ -1074,22 +1062,22 @@ fn fmtWipMir(func: *Func, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir)
1074 return .{ .data = .{ .func = func, .inst = inst } };1062 return .{ .data = .{ .func = func, .inst = inst } };
1075}1063}
10761064
1077const FormatDeclData = struct {1065const FormatNavData = struct {
1078 zcu: *Zcu,1066 ip: *const InternPool,
1079 decl_index: InternPool.DeclIndex,1067 nav_index: InternPool.Nav.Index,
1080};1068};
1081fn formatDecl(1069fn formatNav(
1082 data: FormatDeclData,1070 data: FormatNavData,
1083 comptime _: []const u8,1071 comptime _: []const u8,
1084 _: std.fmt.FormatOptions,1072 _: std.fmt.FormatOptions,
1085 writer: anytype,1073 writer: anytype,
1086) @TypeOf(writer).Error!void {1074) @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)});
1088}1076}
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) {
1090 return .{ .data = .{1078 return .{ .data = .{
1091 .zcu = func.pt.zcu,1079 .ip = ip,
1092 .decl_index = decl_index,1080 .nav_index = nav_index,
1093 } };1081 } };
1094}1082}
10951083
...@@ -1393,9 +1381,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1393,9 +1381,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1393 const pt = func.pt;1381 const pt = func.pt;
1394 const mod = pt.zcu;1382 const mod = pt.zcu;
1395 const ip = &mod.intern_pool;1383 const ip = &mod.intern_pool;
1396 switch (lazy_sym.ty.zigTypeTag(mod)) {1384 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(mod)) {
1397 .Enum => {1385 .Enum => {
1398 const enum_ty = lazy_sym.ty;1386 const enum_ty = Type.fromInterned(lazy_sym.ty);
1399 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});1387 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
14001388
1401 const param_regs = abi.Registers.Integer.function_arg_regs;1389 const param_regs = abi.Registers.Integer.function_arg_regs;
...@@ -1408,11 +1396,11 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1408,11 +1396,11 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1408 const data_reg, const data_lock = try func.allocReg(.int);1396 const data_reg, const data_lock = try func.allocReg(.int);
1409 defer func.register_manager.unlockReg(data_lock);1397 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).?;
1412 const zo = elf_file.zigObjectPtr().?;1400 const zo = elf_file.zigObjectPtr().?;
1413 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{1401 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{
1414 .kind = .const_data,1402 .kind = .const_data,
1415 .ty = enum_ty,1403 .ty = enum_ty.toIntern(),
1416 }) catch |err|1404 }) catch |err|
1417 return func.fail("{s} creating lazy symbol", .{@errorName(err)});1405 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 {...@@ -1479,7 +1467,7 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1479 },1467 },
1480 else => return func.fail(1468 else => return func.fail(
1481 "TODO implement {s} for {}",1469 "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) },
1483 ),1471 ),
1484 }1472 }
1485}1473}
...@@ -4682,17 +4670,14 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {...@@ -4682,17 +4670,14 @@ fn airFieldParentPtr(func: *Func, inst: Air.Inst.Index) !void {
4682}4670}
46834671
4684fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {4672fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4685 const pt = func.pt;
4686 const zcu = pt.zcu;
4687 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4673 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4688 const ty = arg.ty.toType();4674 const ty = arg.ty.toType();
4689 const owner_decl = func.owner.getDecl(zcu);
4690 if (arg.name == .none) return;4675 if (arg.name == .none) return;
4691 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));4676 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
46924677
4693 switch (func.debug_output) {4678 switch (func.debug_output) {
4694 .dwarf => |dw| switch (mcv) {4679 .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, .{
4696 .register = reg.dwarfLocOp(),4681 .register = reg.dwarfLocOp(),
4697 }),4682 }),
4698 .load_frame => {},4683 .load_frame => {},
...@@ -4940,14 +4925,14 @@ fn genCall(...@@ -4940,14 +4925,14 @@ fn genCall(
4940 switch (switch (func_key) {4925 switch (switch (func_key) {
4941 else => func_key,4926 else => func_key,
4942 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {4927 .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()),
4944 else => func_key,4929 else => func_key,
4945 } else func_key,4930 } else func_key,
4946 }) {4931 }) {
4947 .func => |func_val| {4932 .func => |func_val| {
4948 if (func.bin_file.cast(link.File.Elf)) |elf_file| {4933 if (func.bin_file.cast(.elf)) |elf_file| {
4949 const zo = elf_file.zigObjectPtr().?;4934 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
4952 if (func.mod.pic) {4937 if (func.mod.pic) {
4953 return func.fail("TODO: genCall pic", .{});4938 return func.fail("TODO: genCall pic", .{});
...@@ -4964,19 +4949,18 @@ fn genCall(...@@ -4964,19 +4949,18 @@ fn genCall(
4964 }4949 }
4965 } else unreachable; // not a valid riscv64 format4950 } else unreachable; // not a valid riscv64 format
4966 },4951 },
4967 .extern_func => |extern_func| {4952 .@"extern" => |@"extern"| {
4968 const owner_decl = zcu.declPtr(extern_func.decl);4953 const lib_name = @"extern".lib_name.toSlice(&zcu.intern_pool);
4969 const lib_name = extern_func.lib_name.toSlice(&zcu.intern_pool);4954 const name = @"extern".name.toSlice(&zcu.intern_pool);
4970 const decl_name = owner_decl.name.toSlice(&zcu.intern_pool);
4971 const atom_index = try func.owner.getSymbolIndex(func);4955 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).?;
4974 _ = try func.addInst(.{4958 _ = try func.addInst(.{
4975 .tag = .pseudo_extern_fn_reloc,4959 .tag = .pseudo_extern_fn_reloc,
4976 .data = .{ .reloc = .{4960 .data = .{ .reloc = .{
4977 .register = .ra,4961 .register = .ra,
4978 .atom_index = atom_index,4962 .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),
4980 } },4964 } },
4981 });4965 });
4982 },4966 },
...@@ -5213,8 +5197,6 @@ fn genVarDbgInfo(...@@ -5213,8 +5197,6 @@ fn genVarDbgInfo(
5213 mcv: MCValue,5197 mcv: MCValue,
5214 name: [:0]const u8,5198 name: [:0]const u8,
5215) !void {5199) !void {
5216 const pt = func.pt;
5217 const zcu = pt.zcu;
5218 const is_ptr = switch (tag) {5200 const is_ptr = switch (tag) {
5219 .dbg_var_ptr => true,5201 .dbg_var_ptr => true,
5220 .dbg_var_val => false,5202 .dbg_var_val => false,
...@@ -5223,7 +5205,7 @@ fn genVarDbgInfo(...@@ -5223,7 +5205,7 @@ fn genVarDbgInfo(
52235205
5224 switch (func.debug_output) {5206 switch (func.debug_output) {
5225 .dwarf => |dw| {5207 .dwarf => |dw| {
5226 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {5208 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (mcv) {
5227 .register => |reg| .{ .register = reg.dwarfLocOp() },5209 .register => |reg| .{ .register = reg.dwarfLocOp() },
5228 .memory => |address| .{ .memory = address },5210 .memory => |address| .{ .memory = address },
5229 .load_symbol => |sym_off| loc: {5211 .load_symbol => |sym_off| loc: {
...@@ -5238,7 +5220,7 @@ fn genVarDbgInfo(...@@ -5238,7 +5220,7 @@ fn genVarDbgInfo(
5238 break :blk .nop;5220 break :blk .nop;
5239 },5221 },
5240 };5222 };
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);
5242 },5224 },
5243 .plan9 => {},5225 .plan9 => {},
5244 .none => {},5226 .none => {},
...@@ -7804,7 +7786,6 @@ fn airMemcpy(func: *Func, inst: Air.Inst.Index) !void {...@@ -7804,7 +7786,6 @@ fn airMemcpy(func: *Func, inst: Air.Inst.Index) !void {
78047786
7805fn airTagName(func: *Func, inst: Air.Inst.Index) !void {7787fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
7806 const pt = func.pt;7788 const pt = func.pt;
7807 const zcu = pt.zcu;
78087789
7809 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7790 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
7810 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {7791 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
...@@ -7820,7 +7801,7 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {...@@ -7820,7 +7801,7 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
7820 const operand = try func.resolveInst(un_op);7801 const operand = try func.resolveInst(un_op);
7821 try func.genSetReg(enum_ty, param_regs[1], operand);7802 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() };
7824 const elf_file = func.bin_file.cast(link.File.Elf).?;7805 const elf_file = func.bin_file.cast(link.File.Elf).?;
7825 const zo = elf_file.zigObjectPtr().?;7806 const zo = elf_file.zigObjectPtr().?;
7826 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|7807 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 {...@@ -8033,32 +8014,14 @@ fn getResolvedInstValue(func: *Func, inst: Air.Inst.Index) *InstTracking {
80338014
8034fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {8015fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
8035 const pt = func.pt;8016 const pt = func.pt;
8036 const zcu = pt.zcu;
8037 const gpa = func.gpa;
80388017
8039 const owner_decl_index = func.owner.getDecl(zcu);
8040 const lf = func.bin_file;8018 const lf = func.bin_file;
8041 const src_loc = func.src_loc;8019 const src_loc = func.src_loc;
80428020
8043 if (val.isUndef(pt.zcu)) {8021 const result = if (val.isUndef(pt.zcu))
8044 const local_sym_index = lf.lowerUnnamedConst(pt, val, owner_decl_index) catch |err| {8022 try lf.lowerUav(pt, val.toIntern(), .none, src_loc)
8045 const msg = try ErrorMsg.create(gpa, src_loc, "lowering unnamed undefined constant failed: {s}", .{@errorName(err)});8023 else
8046 func.err_msg = msg;8024 try codegen.genTypedValue(lf, pt, src_loc, val, func.target.*);
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 );
8062 const mcv: MCValue = switch (result) {8025 const mcv: MCValue = switch (result) {
8063 .mcv => |mcv| switch (mcv) {8026 .mcv => |mcv| switch (mcv) {
8064 .none => .none,8027 .none => .none,
src/arch/riscv64/Emit.zig+3-3
...@@ -49,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -49,7 +49,7 @@ pub fn emitMir(emit: *Emit) Error!void {
49 .Lib => emit.lower.link_mode == .static,49 .Lib => emit.lower.link_mode == .static,
50 };50 };
5151
52 const elf_file = emit.bin_file.cast(link.File.Elf).?;52 const elf_file = emit.bin_file.cast(.elf).?;
53 const zo = elf_file.zigObjectPtr().?;53 const zo = elf_file.zigObjectPtr().?;
5454
55 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;55 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
...@@ -81,7 +81,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -81,7 +81,7 @@ pub fn emitMir(emit: *Emit) Error!void {
81 });81 });
82 },82 },
83 .load_tlv_reloc => |symbol| {83 .load_tlv_reloc => |symbol| {
84 const elf_file = emit.bin_file.cast(link.File.Elf).?;84 const elf_file = emit.bin_file.cast(.elf).?;
85 const zo = elf_file.zigObjectPtr().?;85 const zo = elf_file.zigObjectPtr().?;
8686
87 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;87 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
...@@ -107,7 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -107,7 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void {
107 });107 });
108 },108 },
109 .call_extern_fn_reloc => |symbol| {109 .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).?;
111 const zo = elf_file.zigObjectPtr().?;111 const zo = elf_file.zigObjectPtr().?;
112 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;112 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(...@@ -273,11 +273,9 @@ pub fn generate(
273 const zcu = pt.zcu;273 const zcu = pt.zcu;
274 const gpa = zcu.gpa;274 const gpa = zcu.gpa;
275 const func = zcu.funcInfo(func_index);275 const func = zcu.funcInfo(func_index);
276 const fn_owner_decl = zcu.declPtr(func.owner_decl);276 const func_ty = Type.fromInterned(func.ty);
277 assert(fn_owner_decl.has_tv);277 const file_scope = zcu.navFileScope(func.owner_nav);
278 const fn_type = fn_owner_decl.typeOf(zcu);278 const target = &file_scope.mod.resolved_target.result;
279 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
280 const target = &namespace.fileScope(zcu).mod.resolved_target.result;
281279
282 var branch_stack = std.ArrayList(Branch).init(gpa);280 var branch_stack = std.ArrayList(Branch).init(gpa);
283 defer {281 defer {
...@@ -300,7 +298,7 @@ pub fn generate(...@@ -300,7 +298,7 @@ pub fn generate(
300 .err_msg = null,298 .err_msg = null,
301 .args = undefined, // populated after `resolveCallingConventionValues`299 .args = undefined, // populated after `resolveCallingConventionValues`
302 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`300 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
303 .fn_type = fn_type,301 .fn_type = func_ty,
304 .arg_index = 0,302 .arg_index = 0,
305 .branch_stack = &branch_stack,303 .branch_stack = &branch_stack,
306 .src_loc = src_loc,304 .src_loc = src_loc,
...@@ -312,7 +310,7 @@ pub fn generate(...@@ -312,7 +310,7 @@ pub fn generate(
312 defer function.blocks.deinit(gpa);310 defer function.blocks.deinit(gpa);
313 defer function.exitlude_jump_relocs.deinit(gpa);311 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) {
316 error.CodegenFail => return Result{ .fail = function.err_msg.? },314 error.CodegenFail => return Result{ .fail = function.err_msg.? },
317 error.OutOfRegisters => return Result{315 error.OutOfRegisters => return Result{
318 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),316 .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...@@ -1306,6 +1304,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1306 const ty = self.typeOf(callee);1304 const ty = self.typeOf(callee);
1307 const pt = self.pt;1305 const pt = self.pt;
1308 const mod = pt.zcu;1306 const mod = pt.zcu;
1307 const ip = &mod.intern_pool;
1309 const fn_ty = switch (ty.zigTypeTag(mod)) {1308 const fn_ty = switch (ty.zigTypeTag(mod)) {
1310 .Fn => ty,1309 .Fn => ty,
1311 .Pointer => ty.childType(mod),1310 .Pointer => ty.childType(mod),
...@@ -1349,46 +1348,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -1349,46 +1348,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13491348
1350 // Due to incremental compilation, how function calls are generated depends1349 // Due to incremental compilation, how function calls are generated depends
1351 // on linking.1350 // on linking.
1352 if (try self.air.value(callee, pt)) |func_value| {1351 if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
1353 if (self.bin_file.tag == link.File.Elf.base_tag) {1352 .func => |func| {
1354 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {1353 const got_addr = if (self.bin_file.cast(.elf)) |elf_file| blk: {
1355 .func => |func| {1354 const zo = elf_file.zigObjectPtr().?;
1356 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {1355 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
1357 const zo = elf_file.zigObjectPtr().?;1356 const sym = zo.symbol(sym_index);
1358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);1357 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
1359 const sym = zo.symbol(sym_index);1358 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));
1360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);1359 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");
1361 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));1360
1362 } else unreachable;1361 try self.genSetReg(Type.usize, .o7, .{ .memory = got_addr });
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 });
13771362
1378 // TODO Find a way to fill this delay slot1363 _ = try self.addInst(.{
1379 _ = try self.addInst(.{1364 .tag = .jmpl,
1380 .tag = .nop,1365 .data = .{
1381 .data = .{ .nop = {} },1366 .arithmetic_3op = .{
1382 });1367 .is_imm = false,
1383 },1368 .rd = .o7,
1384 .extern_func => {1369 .rs1 = .o7,
1385 return self.fail("TODO implement calling extern functions", .{});1370 .rs2_or_imm = .{ .rs2 = .g0 },
1386 },1371 },
1387 else => {
1388 return self.fail("TODO implement calling bitcasted functions", .{});
1389 },1372 },
1390 }1373 });
1391 } else @panic("TODO SPARCv9 currently does not support non-ELF binaries");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 },
1392 } else {1387 } else {
1393 assert(ty.zigTypeTag(mod) == .Pointer);1388 assert(ty.zigTypeTag(mod) == .Pointer);
1394 const mcv = try self.resolveInst(callee);1389 const mcv = try self.resolveInst(callee);
...@@ -3614,13 +3609,13 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -3614,13 +3609,13 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3614 const mod = pt.zcu;3609 const mod = pt.zcu;
3615 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;3610 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
3616 const ty = arg.ty.toType();3611 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;
3618 if (arg.name == .none) return;3613 if (arg.name == .none) return;
3619 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));3614 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
36203615
3621 switch (self.debug_output) {3616 switch (self.debug_output) {
3622 .dwarf => |dw| switch (mcv) {3617 .dwarf => |dw| switch (mcv) {
3623 .register => |reg| try dw.genArgDbgInfo(name, ty, owner_decl, .{3618 .register => |reg| try dw.genArgDbgInfo(name, ty, owner_nav, .{
3624 .register = reg.dwarfLocOp(),3619 .register = reg.dwarfLocOp(),
3625 }),3620 }),
3626 else => {},3621 else => {},
...@@ -4153,7 +4148,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {...@@ -4153,7 +4148,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
4153 pt,4148 pt,
4154 self.src_loc,4149 self.src_loc,
4155 val,4150 val,
4156 pt.zcu.funcOwnerDeclIndex(self.func_index),4151 self.target.*,
4157 )) {4152 )) {
4158 .mcv => |mcv| switch (mcv) {4153 .mcv => |mcv| switch (mcv) {
4159 .none => .none,4154 .none => .none,
src/arch/wasm/CodeGen.zig+194-197
...@@ -640,8 +640,8 @@ const CodeGen = @This();...@@ -640,8 +640,8 @@ const CodeGen = @This();
640640
641/// Reference to the function declaration the code641/// Reference to the function declaration the code
642/// section belongs to642/// section belongs to
643decl: *Decl,643owner_nav: InternPool.Nav.Index,
644decl_index: InternPool.DeclIndex,644src_loc: Zcu.LazySrcLoc,
645/// Current block depth. Used to calculate the relative difference between a break645/// Current block depth. Used to calculate the relative difference between a break
646/// and block646/// and block
647block_depth: u32 = 0,647block_depth: u32 = 0,
...@@ -681,7 +681,7 @@ locals: std.ArrayListUnmanaged(u8),...@@ -681,7 +681,7 @@ locals: std.ArrayListUnmanaged(u8),
681/// are enabled also.681/// are enabled also.
682simd_immediates: std.ArrayListUnmanaged([16]u8) = .{},682simd_immediates: std.ArrayListUnmanaged([16]u8) = .{},
683/// The Target we're emitting (used to call intInfo)683/// The Target we're emitting (used to call intInfo)
684target: std.Target,684target: *const std.Target,
685/// Represents the wasm binary file that is being linked.685/// Represents the wasm binary file that is being linked.
686bin_file: *link.File.Wasm,686bin_file: *link.File.Wasm,
687pt: Zcu.PerThread,687pt: Zcu.PerThread,
...@@ -765,8 +765,7 @@ pub fn deinit(func: *CodeGen) void {...@@ -765,8 +765,7 @@ pub fn deinit(func: *CodeGen) void {
765765
766/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig766/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
767fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {767fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
768 const src_loc = func.decl.navSrcLoc(func.pt.zcu);768 func.err_msg = try Zcu.ErrorMsg.create(func.gpa, func.src_loc, fmt, args);
769 func.err_msg = try Zcu.ErrorMsg.create(func.gpa, src_loc, fmt, args);
770 return error.CodegenFail;769 return error.CodegenFail;
771}770}
772771
...@@ -803,8 +802,14 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {...@@ -803,8 +802,14 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
803 //802 //
804 // In the other cases, we will simply lower the constant to a value that fits803 // In the other cases, we will simply lower the constant to a value that fits
805 // into a single local (such as a pointer, integer, bool, etc).804 // into a single local (such as a pointer, integer, bool, etc).
806 const result: WValue = if (isByRef(ty, pt))805 const result: WValue = if (isByRef(ty, pt, func.target.*))
807 .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index) }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 }
808 else813 else
809 try func.lowerConstant(val, ty);814 try func.lowerConstant(val, ty);
810815
...@@ -995,9 +1000,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32...@@ -995,9 +1000,8 @@ fn addExtraAssumeCapacity(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32
995}1000}
9961001
997/// Using a given `Type`, returns the corresponding valtype for .auto callconv1002/// 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 {
999 const mod = pt.zcu;1004 const mod = pt.zcu;
1000 const target = mod.getTarget();
1001 const ip = &mod.intern_pool;1005 const ip = &mod.intern_pool;
1002 return switch (ty.zigTypeTag(mod)) {1006 return switch (ty.zigTypeTag(mod)) {
1003 .Float => switch (ty.floatBits(target)) {1007 .Float => switch (ty.floatBits(target)) {
...@@ -1015,19 +1019,19 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {...@@ -1015,19 +1019,19 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
1015 .Struct => blk: {1019 .Struct => blk: {
1016 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {1020 if (pt.zcu.typeToPackedStruct(ty)) |packed_struct| {
1017 const backing_int_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));1021 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);
1019 } else {1023 } else {
1020 break :blk .i32;1024 break :blk .i32;
1021 }1025 }
1022 },1026 },
1023 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {1027 .Vector => switch (determineSimdStoreStrategy(ty, pt, target)) {
1024 .direct => .v128,1028 .direct => .v128,
1025 .unrolled => .i32,1029 .unrolled => .i32,
1026 },1030 },
1027 .Union => switch (ty.containerLayout(pt.zcu)) {1031 .Union => switch (ty.containerLayout(pt.zcu)) {
1028 .@"packed" => blk: {1032 .@"packed" => blk: {
1029 const int_ty = pt.intType(.unsigned, @as(u16, @intCast(ty.bitSize(pt)))) catch @panic("out of memory");1033 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);
1031 },1035 },
1032 else => .i32,1036 else => .i32,
1033 },1037 },
...@@ -1036,17 +1040,17 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {...@@ -1036,17 +1040,17 @@ fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype {
1036}1040}
10371041
1038/// Using a given `Type`, returns the byte representation of its wasm value type1042/// Using a given `Type`, returns the byte representation of its wasm value type
1039fn genValtype(ty: Type, pt: Zcu.PerThread) u8 {1043fn genValtype(ty: Type, pt: Zcu.PerThread, target: std.Target) u8 {
1040 return wasm.valtype(typeToValtype(ty, pt));1044 return wasm.valtype(typeToValtype(ty, pt, target));
1041}1045}
10421046
1043/// Using a given `Type`, returns the corresponding wasm value type1047/// Using a given `Type`, returns the corresponding wasm value type
1044/// Differently from `genValtype` this also allows `void` to create a block1048/// Differently from `genValtype` this also allows `void` to create a block
1045/// with no return type1049/// with no return type
1046fn genBlockType(ty: Type, pt: Zcu.PerThread) u8 {1050fn genBlockType(ty: Type, pt: Zcu.PerThread, target: std.Target) u8 {
1047 return switch (ty.ip_index) {1051 return switch (ty.ip_index) {
1048 .void_type, .noreturn_type => wasm.block_empty,1052 .void_type, .noreturn_type => wasm.block_empty,
1049 else => genValtype(ty, pt),1053 else => genValtype(ty, pt, target),
1050 };1054 };
1051}1055}
10521056
...@@ -1108,7 +1112,7 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {...@@ -1108,7 +1112,7 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
1108/// Returns a corresponding `Wvalue` with `local` as active tag1112/// Returns a corresponding `Wvalue` with `local` as active tag
1109fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {1113fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1110 const pt = func.pt;1114 const pt = func.pt;
1111 const valtype = typeToValtype(ty, pt);1115 const valtype = typeToValtype(ty, pt, func.target.*);
1112 const index_or_null = switch (valtype) {1116 const index_or_null = switch (valtype) {
1113 .i32 => func.free_locals_i32.popOrNull(),1117 .i32 => func.free_locals_i32.popOrNull(),
1114 .i64 => func.free_locals_i64.popOrNull(),1118 .i64 => func.free_locals_i64.popOrNull(),
...@@ -1128,7 +1132,7 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -1128,7 +1132,7 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1128/// to use a zero-initialized local.1132/// to use a zero-initialized local.
1129fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {1133fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1130 const pt = func.pt;1134 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.*));
1132 const initial_index = func.local_index;1136 const initial_index = func.local_index;
1133 func.local_index += 1;1137 func.local_index += 1;
1134 return .{ .local = .{ .value = initial_index, .references = 1 } };1138 return .{ .local = .{ .value = initial_index, .references = 1 } };
...@@ -1142,6 +1146,7 @@ fn genFunctype(...@@ -1142,6 +1146,7 @@ fn genFunctype(
1142 params: []const InternPool.Index,1146 params: []const InternPool.Index,
1143 return_type: Type,1147 return_type: Type,
1144 pt: Zcu.PerThread,1148 pt: Zcu.PerThread,
1149 target: std.Target,
1145) !wasm.Type {1150) !wasm.Type {
1146 const mod = pt.zcu;1151 const mod = pt.zcu;
1147 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);1152 var temp_params = std.ArrayList(wasm.Valtype).init(gpa);
...@@ -1149,16 +1154,16 @@ fn genFunctype(...@@ -1149,16 +1154,16 @@ fn genFunctype(
1149 var returns = std.ArrayList(wasm.Valtype).init(gpa);1154 var returns = std.ArrayList(wasm.Valtype).init(gpa);
1150 defer returns.deinit();1155 defer returns.deinit();
11511156
1152 if (firstParamSRet(cc, return_type, pt)) {1157 if (firstParamSRet(cc, return_type, pt, target)) {
1153 try temp_params.append(.i32); // memory address is always a 32-bit handle1158 try temp_params.append(.i32); // memory address is always a 32-bit handle
1154 } else if (return_type.hasRuntimeBitsIgnoreComptime(pt)) {1159 } else if (return_type.hasRuntimeBitsIgnoreComptime(pt)) {
1155 if (cc == .C) {1160 if (cc == .C) {
1156 const res_classes = abi.classifyType(return_type, pt);1161 const res_classes = abi.classifyType(return_type, pt);
1157 assert(res_classes[0] == .direct and res_classes[1] == .none);1162 assert(res_classes[0] == .direct and res_classes[1] == .none);
1158 const scalar_type = abi.scalarType(return_type, pt);1163 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));
1160 } else {1165 } else {
1161 try returns.append(typeToValtype(return_type, pt));1166 try returns.append(typeToValtype(return_type, pt, target));
1162 }1167 }
1163 } else if (return_type.isError(mod)) {1168 } else if (return_type.isError(mod)) {
1164 try returns.append(.i32);1169 try returns.append(.i32);
...@@ -1175,9 +1180,9 @@ fn genFunctype(...@@ -1175,9 +1180,9 @@ fn genFunctype(
1175 if (param_classes[1] == .none) {1180 if (param_classes[1] == .none) {
1176 if (param_classes[0] == .direct) {1181 if (param_classes[0] == .direct) {
1177 const scalar_type = abi.scalarType(param_type, pt);1182 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));
1179 } else {1184 } else {
1180 try temp_params.append(typeToValtype(param_type, pt));1185 try temp_params.append(typeToValtype(param_type, pt, target));
1181 }1186 }
1182 } else {1187 } else {
1183 // i128/f1281188 // i128/f128
...@@ -1185,7 +1190,7 @@ fn genFunctype(...@@ -1185,7 +1190,7 @@ fn genFunctype(
1185 try temp_params.append(.i64);1190 try temp_params.append(.i64);
1186 }1191 }
1187 },1192 },
1188 else => try temp_params.append(typeToValtype(param_type, pt)),1193 else => try temp_params.append(typeToValtype(param_type, pt, target)),
1189 }1194 }
1190 }1195 }
11911196
...@@ -1205,25 +1210,23 @@ pub fn generate(...@@ -1205,25 +1210,23 @@ pub fn generate(
1205 code: *std.ArrayList(u8),1210 code: *std.ArrayList(u8),
1206 debug_output: codegen.DebugInfoOutput,1211 debug_output: codegen.DebugInfoOutput,
1207) codegen.CodeGenError!codegen.Result {1212) codegen.CodeGenError!codegen.Result {
1208 _ = src_loc;
1209 const zcu = pt.zcu;1213 const zcu = pt.zcu;
1210 const gpa = zcu.gpa;1214 const gpa = zcu.gpa;
1211 const func = zcu.funcInfo(func_index);1215 const func = zcu.funcInfo(func_index);
1212 const decl = zcu.declPtr(func.owner_decl);1216 const file_scope = zcu.navFileScope(func.owner_nav);
1213 const namespace = zcu.namespacePtr(decl.src_namespace);1217 const target = &file_scope.mod.resolved_target.result;
1214 const target = namespace.fileScope(zcu).mod.resolved_target.result;
1215 var code_gen: CodeGen = .{1218 var code_gen: CodeGen = .{
1216 .gpa = gpa,1219 .gpa = gpa,
1217 .pt = pt,1220 .pt = pt,
1218 .air = air,1221 .air = air,
1219 .liveness = liveness,1222 .liveness = liveness,
1220 .code = code,1223 .code = code,
1221 .decl_index = func.owner_decl,1224 .owner_nav = func.owner_nav,
1222 .decl = decl,1225 .src_loc = src_loc,
1223 .err_msg = undefined,1226 .err_msg = undefined,
1224 .locals = .{},1227 .locals = .{},
1225 .target = target,1228 .target = target,
1226 .bin_file = bin_file.cast(link.File.Wasm).?,1229 .bin_file = bin_file.cast(.wasm).?,
1227 .debug_output = debug_output,1230 .debug_output = debug_output,
1228 .func_index = func_index,1231 .func_index = func_index,
1229 };1232 };
...@@ -1241,12 +1244,13 @@ fn genFunc(func: *CodeGen) InnerError!void {...@@ -1241,12 +1244,13 @@ fn genFunc(func: *CodeGen) InnerError!void {
1241 const pt = func.pt;1244 const pt = func.pt;
1242 const mod = pt.zcu;1245 const mod = pt.zcu;
1243 const ip = &mod.intern_pool;1246 const ip = &mod.intern_pool;
1244 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;1247 const fn_ty = mod.navValue(func.owner_nav).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);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.*);
1246 defer func_type.deinit(func.gpa);1250 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);
1250 defer cc_result.deinit(func.gpa);1254 defer cc_result.deinit(func.gpa);
12511255
1252 func.args = cc_result.args;1256 func.args = cc_result.args;
...@@ -1324,7 +1328,7 @@ fn genFunc(func: *CodeGen) InnerError!void {...@@ -1324,7 +1328,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
1324 .bin_file = func.bin_file,1328 .bin_file = func.bin_file,
1325 .code = func.code,1329 .code = func.code,
1326 .locals = func.locals.items,1330 .locals = func.locals.items,
1327 .decl_index = func.decl_index,1331 .owner_nav = func.owner_nav,
1328 .dbg_output = func.debug_output,1332 .dbg_output = func.debug_output,
1329 .prev_di_line = 0,1333 .prev_di_line = 0,
1330 .prev_di_column = 0,1334 .prev_di_column = 0,
...@@ -1367,7 +1371,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1367,7 +1371,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
13671371
1368 // Check if we store the result as a pointer to the stack rather than1372 // Check if we store the result as a pointer to the stack rather than
1369 // by value1373 // 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.*)) {
1371 // the sret arg will be passed as first argument, therefore we1375 // the sret arg will be passed as first argument, therefore we
1372 // set the `return_value` before allocating locals for regular args.1376 // set the `return_value` before allocating locals for regular args.
1373 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };1377 result.return_value = .{ .local = .{ .value = func.local_index, .references = 1 } };
...@@ -1401,9 +1405,9 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV...@@ -1401,9 +1405,9 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV
1401 return result;1405 return result;
1402}1406}
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 {
1405 switch (cc) {1409 switch (cc) {
1406 .Unspecified, .Inline => return isByRef(return_type, pt),1410 .Unspecified, .Inline => return isByRef(return_type, pt, target),
1407 .C => {1411 .C => {
1408 const ty_classes = abi.classifyType(return_type, pt);1412 const ty_classes = abi.classifyType(return_type, pt);
1409 if (ty_classes[0] == .indirect) return true;1413 if (ty_classes[0] == .indirect) return true;
...@@ -1711,10 +1715,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {...@@ -1711,10 +1715,9 @@ fn arch(func: *const CodeGen) std.Target.Cpu.Arch {
17111715
1712/// For a given `Type`, will return true when the type will be passed1716/// For a given `Type`, will return true when the type will be passed
1713/// by reference, rather than by value1717/// 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 {
1715 const mod = pt.zcu;1719 const mod = pt.zcu;
1716 const ip = &mod.intern_pool;1720 const ip = &mod.intern_pool;
1717 const target = mod.getTarget();
1718 switch (ty.zigTypeTag(mod)) {1721 switch (ty.zigTypeTag(mod)) {
1719 .Type,1722 .Type,
1720 .ComptimeInt,1723 .ComptimeInt,
...@@ -1746,11 +1749,11 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {...@@ -1746,11 +1749,11 @@ fn isByRef(ty: Type, pt: Zcu.PerThread) bool {
1746 },1749 },
1747 .Struct => {1750 .Struct => {
1748 if (mod.typeToPackedStruct(ty)) |packed_struct| {1751 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);
1750 }1753 }
1751 return ty.hasRuntimeBitsIgnoreComptime(pt);1754 return ty.hasRuntimeBitsIgnoreComptime(pt);
1752 },1755 },
1753 .Vector => return determineSimdStoreStrategy(ty, pt) == .unrolled,1756 .Vector => return determineSimdStoreStrategy(ty, pt, target) == .unrolled,
1754 .Int => return ty.intInfo(mod).bits > 64,1757 .Int => return ty.intInfo(mod).bits > 64,
1755 .Enum => return ty.intInfo(mod).bits > 64,1758 .Enum => return ty.intInfo(mod).bits > 64,
1756 .Float => return ty.floatBits(target) > 64,1759 .Float => return ty.floatBits(target) > 64,
...@@ -1784,11 +1787,10 @@ const SimdStoreStrategy = enum {...@@ -1784,11 +1787,10 @@ const SimdStoreStrategy = enum {
1784/// This means when a given type is 128 bits and either the simd128 or relaxed-simd1787/// This means when a given type is 128 bits and either the simd128 or relaxed-simd
1785/// features are enabled, the function will return `.direct`. This would allow to store1788/// features are enabled, the function will return `.direct`. This would allow to store
1786/// it using a instruction, rather than an unrolled version.1789/// 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 {
1788 std.debug.assert(ty.zigTypeTag(pt.zcu) == .Vector);1791 std.debug.assert(ty.zigTypeTag(pt.zcu) == .Vector);
1789 if (ty.bitSize(pt) != 128) return .unrolled;1792 if (ty.bitSize(pt) != 128) return .unrolled;
1790 const hasFeature = std.Target.wasm.featureSetHas;1793 const hasFeature = std.Target.wasm.featureSetHas;
1791 const target = pt.zcu.getTarget();
1792 const features = target.cpu.features;1794 const features = target.cpu.features;
1793 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {1795 if (hasFeature(features, .relaxed_simd) or hasFeature(features, .simd128)) {
1794 return .direct;1796 return .direct;
...@@ -2091,7 +2093,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2091,7 +2093,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2091 const mod = pt.zcu;2093 const mod = pt.zcu;
2092 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;2094 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
2093 const operand = try func.resolveInst(un_op);2095 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)).?;
2095 const ret_ty = Type.fromInterned(fn_info.return_type);2097 const ret_ty = Type.fromInterned(fn_info.return_type);
20962098
2097 // result must be stored in the stack and we return a pointer2099 // 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 {...@@ -2108,7 +2110,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2108 .op = .load,2110 .op = .load,
2109 .width = @as(u8, @intCast(scalar_type.abiSize(pt) * 8)),2111 .width = @as(u8, @intCast(scalar_type.abiSize(pt) * 8)),
2110 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,2112 .signedness = if (scalar_type.isSignedInt(mod)) .signed else .unsigned,
2111 .valtype1 = typeToValtype(scalar_type, pt),2113 .valtype1 = typeToValtype(scalar_type, pt, func.target.*),
2112 });2114 });
2113 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{2115 try func.addMemArg(Mir.Inst.Tag.fromOpcode(opcode), .{
2114 .offset = operand.offset(),2116 .offset = operand.offset(),
...@@ -2140,8 +2142,8 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2140,8 +2142,8 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2140 break :result try func.allocStack(Type.usize); // create pointer to void2142 break :result try func.allocStack(Type.usize); // create pointer to void
2141 }2143 }
21422144
2143 const fn_info = mod.typeToFunc(func.decl.typeOf(mod)).?;2145 const fn_info = mod.typeToFunc(mod.navValue(func.owner_nav).typeOf(mod)).?;
2144 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt)) {2146 if (firstParamSRet(fn_info.cc, Type.fromInterned(fn_info.return_type), pt, func.target.*)) {
2145 break :result func.return_value;2147 break :result func.return_value;
2146 }2148 }
21472149
...@@ -2158,12 +2160,12 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2158,12 +2160,12 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2158 const operand = try func.resolveInst(un_op);2160 const operand = try func.resolveInst(un_op);
2159 const ret_ty = func.typeOf(un_op).childType(mod);2161 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)).?;
2162 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {2164 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
2163 if (ret_ty.isError(mod)) {2165 if (ret_ty.isError(mod)) {
2164 try func.addImm32(0);2166 try func.addImm32(0);
2165 }2167 }
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.*)) {
2167 // leave on the stack2169 // leave on the stack
2168 _ = try func.load(operand, ret_ty, 0);2170 _ = try func.load(operand, ret_ty, 0);
2169 }2171 }
...@@ -2190,34 +2192,43 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2190,34 +2192,43 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2190 };2192 };
2191 const ret_ty = fn_ty.fnReturnType(mod);2193 const ret_ty = fn_ty.fnReturnType(mod);
2192 const fn_info = mod.typeToFunc(fn_ty).?;2194 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: {
2196 const func_val = (try func.air.value(pl_op.operand, pt)) orelse break :blk null;2198 const func_val = (try func.air.value(pl_op.operand, pt)) orelse break :blk null;
21972199
2198 if (func_val.getFunction(mod)) |function| {2200 switch (ip.indexToKey(func_val.toIntern())) {
2199 _ = try func.bin_file.getOrCreateAtomForDecl(pt, function.owner_decl);2201 .func => |function| {
2200 break :blk function.owner_decl;2202 _ = try func.bin_file.getOrCreateAtomForNav(pt, function.owner_nav);
2201 } else if (func_val.getExternFunc(mod)) |extern_func| {2203 break :blk function.owner_nav;
2202 const ext_decl = mod.declPtr(extern_func.decl);2204 },
2203 const ext_info = mod.typeToFunc(ext_decl.typeOf(mod)).?;2205 .@"extern" => |@"extern"| {
2204 var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types.get(ip), Type.fromInterned(ext_info.return_type), pt);2206 const ext_nav = ip.getNav(@"extern".owner_nav);
2205 defer func_type.deinit(func.gpa);2207 const ext_info = mod.typeToFunc(Type.fromInterned(@"extern".ty)).?;
2206 const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, extern_func.decl);2208 var func_type = try genFunctype(
2207 const atom = func.bin_file.getAtomPtr(atom_index);2209 func.gpa,
2208 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);2210 ext_info.cc,
2209 try func.bin_file.addOrUpdateImport(2211 ext_info.param_types.get(ip),
2210 ext_decl.name.toSlice(&mod.intern_pool),2212 Type.fromInterned(ext_info.return_type),
2211 atom.sym_index,2213 pt,
2212 ext_decl.getOwnedExternFunc(mod).?.lib_name.toSlice(&mod.intern_pool),2214 func.target.*,
2213 type_index,2215 );
2214 );2216 defer func_type.deinit(func.gpa);
2215 break :blk extern_func.decl;2217 const atom_index = try func.bin_file.getOrCreateAtomForNav(pt, @"extern".owner_nav);
2216 } else switch (mod.intern_pool.indexToKey(func_val.ip_index)) {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 },
2217 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {2228 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
2218 .decl => |decl| {2229 .nav => |nav| {
2219 _ = try func.bin_file.getOrCreateAtomForDecl(pt, decl);2230 _ = try func.bin_file.getOrCreateAtomForNav(pt, nav);
2220 break :blk decl;2231 break :blk nav;
2221 },2232 },
2222 else => {},2233 else => {},
2223 },2234 },
...@@ -2242,7 +2253,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2242,7 +2253,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2242 }2253 }
22432254
2244 if (callee) |direct| {2255 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;
2246 try func.addLabel(.call, @intFromEnum(func.bin_file.getAtom(atom_index).sym_index));2257 try func.addLabel(.call, @intFromEnum(func.bin_file.getAtom(atom_index).sym_index));
2247 } else {2258 } else {
2248 // in this case we call a function pointer2259 // in this case we call a function pointer
...@@ -2251,7 +2262,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -2251,7 +2262,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2251 const operand = try func.resolveInst(pl_op.operand);2262 const operand = try func.resolveInst(pl_op.operand);
2252 try func.emitWValue(operand);2263 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.*);
2255 defer fn_type.deinit(func.gpa);2266 defer fn_type.deinit(func.gpa);
22562267
2257 const fn_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, fn_type);2268 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...@@ -2315,7 +2326,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
2315 // load the value, and then shift+or the rhs into the result location.2326 // load the value, and then shift+or the rhs into the result location.
2316 const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);2327 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.*)) {
2319 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});2330 return func.fail("TODO: airStore for pointers to bitfields with backing type larger than 64bits", .{});
2320 }2331 }
23212332
...@@ -2381,11 +2392,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2381,11 +2392,11 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2381 const len = @as(u32, @intCast(abi_size));2392 const len = @as(u32, @intCast(abi_size));
2382 return func.memcpy(lhs, rhs, .{ .imm32 = len });2393 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2383 },2394 },
2384 .Struct, .Array, .Union => if (isByRef(ty, pt)) {2395 .Struct, .Array, .Union => if (isByRef(ty, pt, func.target.*)) {
2385 const len = @as(u32, @intCast(abi_size));2396 const len = @as(u32, @intCast(abi_size));
2386 return func.memcpy(lhs, rhs, .{ .imm32 = len });2397 return func.memcpy(lhs, rhs, .{ .imm32 = len });
2387 },2398 },
2388 .Vector => switch (determineSimdStoreStrategy(ty, pt)) {2399 .Vector => switch (determineSimdStoreStrategy(ty, pt, func.target.*)) {
2389 .unrolled => {2400 .unrolled => {
2390 const len: u32 = @intCast(abi_size);2401 const len: u32 = @intCast(abi_size);
2391 return func.memcpy(lhs, rhs, .{ .imm32 = len });2402 return func.memcpy(lhs, rhs, .{ .imm32 = len });
...@@ -2443,7 +2454,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE...@@ -2443,7 +2454,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
2443 // into lhs, so we calculate that and emit that instead2454 // into lhs, so we calculate that and emit that instead
2444 try func.lowerToStack(rhs);2455 try func.lowerToStack(rhs);
24452456
2446 const valtype = typeToValtype(ty, pt);2457 const valtype = typeToValtype(ty, pt, func.target.*);
2447 const opcode = buildOpcode(.{2458 const opcode = buildOpcode(.{
2448 .valtype1 = valtype,2459 .valtype1 = valtype,
2449 .width = @as(u8, @intCast(abi_size * 8)),2460 .width = @as(u8, @intCast(abi_size * 8)),
...@@ -2472,7 +2483,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2472,7 +2483,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2472 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{ty_op.operand});2483 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{ty_op.operand});
24732484
2474 const result = result: {2485 const result = result: {
2475 if (isByRef(ty, pt)) {2486 if (isByRef(ty, pt, func.target.*)) {
2476 const new_local = try func.allocStack(ty);2487 const new_local = try func.allocStack(ty);
2477 try func.store(new_local, operand, ty, 0);2488 try func.store(new_local, operand, ty, 0);
2478 break :result new_local;2489 break :result new_local;
...@@ -2522,7 +2533,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu...@@ -2522,7 +2533,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25222533
2523 const abi_size: u8 = @intCast(ty.abiSize(pt));2534 const abi_size: u8 = @intCast(ty.abiSize(pt));
2524 const opcode = buildOpcode(.{2535 const opcode = buildOpcode(.{
2525 .valtype1 = typeToValtype(ty, pt),2536 .valtype1 = typeToValtype(ty, pt, func.target.*),
2526 .width = abi_size * 8,2537 .width = abi_size * 8,
2527 .op = .load,2538 .op = .load,
2528 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,2539 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
...@@ -2544,7 +2555,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2544,7 +2555,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2544 const mod = pt.zcu;2555 const mod = pt.zcu;
2545 const arg_index = func.arg_index;2556 const arg_index = func.arg_index;
2546 const arg = func.args[arg_index];2557 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;
2548 const arg_ty = func.typeOfIndex(inst);2559 const arg_ty = func.typeOfIndex(inst);
2549 if (cc == .C) {2560 if (cc == .C) {
2550 const arg_classes = abi.classifyType(arg_ty, pt);2561 const arg_classes = abi.classifyType(arg_ty, pt);
...@@ -2577,7 +2588,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2577,7 +2588,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2577 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;2588 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
2578 if (name_nts != .none) {2589 if (name_nts != .none) {
2579 const name = func.air.nullTerminatedString(@intFromEnum(name_nts));2590 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, .{
2581 .wasm_local = arg.local.value,2592 .wasm_local = arg.local.value,
2582 });2593 });
2583 }2594 }
...@@ -2631,7 +2642,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2631,7 +2642,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
2631 return func.floatOp(float_op, ty, &.{ lhs, rhs });2642 return func.floatOp(float_op, ty, &.{ lhs, rhs });
2632 }2643 }
26332644
2634 if (isByRef(ty, pt)) {2645 if (isByRef(ty, pt, func.target.*)) {
2635 if (ty.zigTypeTag(mod) == .Int) {2646 if (ty.zigTypeTag(mod) == .Int) {
2636 return func.binOpBigInt(lhs, rhs, ty, op);2647 return func.binOpBigInt(lhs, rhs, ty, op);
2637 } else {2648 } else {
...@@ -2644,7 +2655,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!...@@ -2644,7 +2655,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26442655
2645 const opcode: wasm.Opcode = buildOpcode(.{2656 const opcode: wasm.Opcode = buildOpcode(.{
2646 .op = op,2657 .op = op,
2647 .valtype1 = typeToValtype(ty, pt),2658 .valtype1 = typeToValtype(ty, pt, func.target.*),
2648 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,2659 .signedness = if (ty.isSignedInt(mod)) .signed else .unsigned,
2649 });2660 });
2650 try func.emitWValue(lhs);2661 try func.emitWValue(lhs);
...@@ -2896,7 +2907,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In...@@ -2896,7 +2907,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
2896 return func.fail("TODO: Implement floatOps for vectors", .{});2907 return func.fail("TODO: Implement floatOps for vectors", .{});
2897 }2908 }
28982909
2899 const float_bits = ty.floatBits(func.target);2910 const float_bits = ty.floatBits(func.target.*);
29002911
2901 if (float_op == .neg) {2912 if (float_op == .neg) {
2902 return func.floatNeg(ty, args[0]);2913 return func.floatNeg(ty, args[0]);
...@@ -2907,7 +2918,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In...@@ -2907,7 +2918,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
2907 for (args) |operand| {2918 for (args) |operand| {
2908 try func.emitWValue(operand);2919 try func.emitWValue(operand);
2909 }2920 }
2910 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, pt) });2921 const opcode = buildOpcode(.{ .op = op, .valtype1 = typeToValtype(ty, pt, func.target.*) });
2911 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));2922 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
2912 return .stack;2923 return .stack;
2913 }2924 }
...@@ -2955,7 +2966,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In...@@ -2955,7 +2966,7 @@ fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) In
29552966
2956/// NOTE: The result value remains on top of the stack.2967/// NOTE: The result value remains on top of the stack.
2957fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue {2968fn 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.*);
2959 switch (float_bits) {2970 switch (float_bits) {
2960 16 => {2971 16 => {
2961 try func.emitWValue(arg);2972 try func.emitWValue(arg);
...@@ -3115,8 +3126,8 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr...@@ -3115,8 +3126,8 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
3115 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;3126 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
3116 const offset: u64 = prev_offset + ptr.byte_offset;3127 const offset: u64 = prev_offset + ptr.byte_offset;
3117 return switch (ptr.base_addr) {3128 return switch (ptr.base_addr) {
3118 .decl => |decl| return func.lowerDeclRefValue(decl, @intCast(offset)),3129 .nav => |nav| return func.lowerNavRef(nav, @intCast(offset)),
3119 .anon_decl => |ad| return func.lowerAnonDeclRef(ad, @intCast(offset)),3130 .uav => |uav| return func.lowerUavRef(uav, @intCast(offset)),
3120 .int => return func.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),3131 .int => return func.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
3121 .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}),3132 .eu_payload => return func.fail("Wasm TODO: lower error union payload pointer", .{}),
3122 .opt_payload => |opt_ptr| return func.lowerPtr(opt_ptr, offset),3133 .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...@@ -3128,7 +3139,7 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
3128 assert(base_ty.isSlice(zcu));3139 assert(base_ty.isSlice(zcu));
3129 break :off switch (field.index) {3140 break :off switch (field.index) {
3130 Value.slice_ptr_index => 0,3141 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),
3132 else => unreachable,3143 else => unreachable,
3133 };3144 };
3134 },3145 },
...@@ -3160,32 +3171,29 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr...@@ -3160,32 +3171,29 @@ fn lowerPtr(func: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerEr
3160 };3171 };
3161}3172}
31623173
3163fn lowerAnonDeclRef(3174fn lowerUavRef(
3164 func: *CodeGen,3175 func: *CodeGen,
3165 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,3176 uav: InternPool.Key.Ptr.BaseAddr.Uav,
3166 offset: u32,3177 offset: u32,
3167) InnerError!WValue {3178) InnerError!WValue {
3168 const pt = func.pt;3179 const pt = func.pt;
3169 const mod = pt.zcu;3180 const mod = pt.zcu;
3170 const decl_val = anon_decl.val;3181 const ty = Type.fromInterned(mod.intern_pool.typeOf(uav.val));
3171 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
31723182
3173 const is_fn_body = ty.zigTypeTag(mod) == .Fn;3183 const is_fn_body = ty.zigTypeTag(mod) == .Fn;
3174 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) {3184 if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) {
3175 return .{ .imm32 = 0xaaaaaaaa };3185 return .{ .imm32 = 0xaaaaaaaa };
3176 }3186 }
31773187
3178 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;3188 const decl_align = mod.intern_pool.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
3179 const res = try func.bin_file.lowerAnonDecl(pt, decl_val, decl_align, func.decl.navSrcLoc(mod));3189 const res = try func.bin_file.lowerUav(pt, uav.val, decl_align, func.src_loc);
3180 switch (res) {3190 const target_sym_index = switch (res) {
3181 .ok => {},3191 .mcv => |mcv| mcv.load_symbol,
3182 .fail => |em| {3192 .fail => |err_msg| {
3183 func.err_msg = em;3193 func.err_msg = err_msg;
3184 return error.CodegenFail;3194 return error.CodegenFail;
3185 },3195 },
3186 }3196 };
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);
3189 if (is_fn_body) {3197 if (is_fn_body) {
3190 return .{ .function_index = target_sym_index };3198 return .{ .function_index = target_sym_index };
3191 } else if (offset == 0) {3199 } else if (offset == 0) {
...@@ -3193,32 +3201,29 @@ fn lowerAnonDeclRef(...@@ -3193,32 +3201,29 @@ fn lowerAnonDeclRef(
3193 } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };3201 } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
3194}3202}
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 {
3197 const pt = func.pt;3205 const pt = func.pt;
3198 const mod = pt.zcu;3206 const mod = pt.zcu;
3207 const ip = &mod.intern_pool;
31993208
3200 const decl = mod.declPtr(decl_index);
3201 // check if decl is an alias to a function, in which case we3209 // check if decl is an alias to a function, in which case we
3202 // want to lower the actual decl, rather than the alias itself.3210 // want to lower the actual decl, rather than the alias itself.
3203 if (decl.val.getFunction(mod)) |func_val| {3211 const owner_nav = switch (ip.indexToKey(mod.navValue(nav_index).toIntern())) {
3204 if (func_val.owner_decl != decl_index) {3212 .func => |function| function.owner_nav,
3205 return func.lowerDeclRefValue(func_val.owner_decl, offset);3213 .variable => |variable| variable.owner_nav,
3206 }3214 .@"extern" => |@"extern"| @"extern".owner_nav,
3207 } else if (decl.val.getExternFunc(mod)) |func_val| {3215 else => nav_index,
3208 if (func_val.decl != decl_index) {3216 };
3209 return func.lowerDeclRefValue(func_val.decl, offset);3217 const nav_ty = ip.getNav(owner_nav).typeOf(ip);
3210 }3218 if (!ip.isFunctionType(nav_ty) and !Type.fromInterned(nav_ty).hasRuntimeBitsIgnoreComptime(pt)) {
3211 }
3212 const decl_ty = decl.typeOf(mod);
3213 if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
3214 return .{ .imm32 = 0xaaaaaaaa };3219 return .{ .imm32 = 0xaaaaaaaa };
3215 }3220 }
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);
3218 const atom = func.bin_file.getAtom(atom_index);3223 const atom = func.bin_file.getAtom(atom_index);
32193224
3220 const target_sym_index = @intFromEnum(atom.sym_index);3225 const target_sym_index = @intFromEnum(atom.sym_index);
3221 if (decl_ty.zigTypeTag(mod) == .Fn) {3226 if (ip.isFunctionType(nav_ty)) {
3222 return .{ .function_index = target_sym_index };3227 return .{ .function_index = target_sym_index };
3223 } else if (offset == 0) {3228 } else if (offset == 0) {
3224 return .{ .memory = target_sym_index };3229 return .{ .memory = target_sym_index };
...@@ -3229,7 +3234,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u...@@ -3229,7 +3234,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
3229fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {3234fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3230 const pt = func.pt;3235 const pt = func.pt;
3231 const mod = pt.zcu;3236 const mod = pt.zcu;
3232 assert(!isByRef(ty, pt));3237 assert(!isByRef(ty, pt, func.target.*));
3233 const ip = &mod.intern_pool;3238 const ip = &mod.intern_pool;
3234 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);3239 if (val.isUndefDeep(mod)) return func.emitUndefined(ty);
32353240
...@@ -3268,7 +3273,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3268,7 +3273,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3268 } },3273 } },
3269 },3274 },
3270 .variable,3275 .variable,
3271 .extern_func,3276 .@"extern",
3272 .func,3277 .func,
3273 .enum_literal,3278 .enum_literal,
3274 .empty_enum_value,3279 .empty_enum_value,
...@@ -3325,16 +3330,12 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3325,16 +3330,12 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3325 .f64 => |f64_val| return .{ .float64 = f64_val },3330 .f64 => |f64_val| return .{ .float64 = f64_val },
3326 else => unreachable,3331 else => unreachable,
3327 },3332 },
3328 .slice => |slice| {3333 .slice => switch (try func.bin_file.lowerUav(pt, val.toIntern(), .none, func.src_loc)) {
3329 var ptr = ip.indexToKey(slice.ptr).ptr;3334 .mcv => |mcv| return .{ .memory = mcv.load_symbol },
3330 const owner_decl = while (true) switch (ptr.base_addr) {3335 .fail => |err_msg| {
3331 .decl => |decl| break decl,3336 func.err_msg = err_msg;
3332 .int, .anon_decl => return func.fail("Wasm TODO: lower slice where ptr is not owned by decl", .{}),3337 return error.CodegenFail;
3333 .opt_payload, .eu_payload => |base| ptr = ip.indexToKey(base).ptr,3338 },
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) };
3338 },3339 },
3339 .ptr => return func.lowerPtr(val.toIntern(), 0),3340 .ptr => return func.lowerPtr(val.toIntern(), 0),
3340 .opt => if (ty.optionalReprIsPayload(mod)) {3341 .opt => if (ty.optionalReprIsPayload(mod)) {
...@@ -3350,7 +3351,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3350,7 +3351,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3350 .aggregate => switch (ip.indexToKey(ty.ip_index)) {3351 .aggregate => switch (ip.indexToKey(ty.ip_index)) {
3351 .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),3352 .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),
3352 .vector_type => {3353 .vector_type => {
3353 assert(determineSimdStoreStrategy(ty, pt) == .direct);3354 assert(determineSimdStoreStrategy(ty, pt, func.target.*) == .direct);
3354 var buf: [16]u8 = undefined;3355 var buf: [16]u8 = undefined;
3355 val.writeToMemory(ty, pt, &buf) catch unreachable;3356 val.writeToMemory(ty, pt, &buf) catch unreachable;
3356 return func.storeSimdImmd(buf);3357 return func.storeSimdImmd(buf);
...@@ -3405,7 +3406,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3405,7 +3406,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3405 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },3406 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3406 else => unreachable,3407 else => unreachable,
3407 },3408 },
3408 .Float => switch (ty.floatBits(func.target)) {3409 .Float => switch (ty.floatBits(func.target.*)) {
3409 16 => return .{ .imm32 = 0xaaaaaaaa },3410 16 => return .{ .imm32 = 0xaaaaaaaa },
3410 32 => return .{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },3411 32 => return .{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },
3411 64 => return .{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },3412 64 => return .{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
...@@ -3480,11 +3481,11 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3480,11 +3481,11 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
34803481
3481fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {3482fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
3482 const pt = func.pt;3483 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
3485 // if wasm_block_ty is non-empty, we create a register to store the temporary value3486 // if wasm_block_ty is non-empty, we create a register to store the temporary value
3486 const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {3487 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;
3488 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten3489 break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
3489 } else .none;3490 } else .none;
34903491
...@@ -3608,7 +3609,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO...@@ -3608,7 +3609,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
3608 }3609 }
3609 } else if (ty.isAnyFloat()) {3610 } else if (ty.isAnyFloat()) {
3610 return func.cmpFloat(ty, lhs, rhs, op);3611 return func.cmpFloat(ty, lhs, rhs, op);
3611 } else if (isByRef(ty, pt)) {3612 } else if (isByRef(ty, pt, func.target.*)) {
3612 return func.cmpBigInt(lhs, rhs, ty, op);3613 return func.cmpBigInt(lhs, rhs, ty, op);
3613 }3614 }
36143615
...@@ -3626,7 +3627,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO...@@ -3626,7 +3627,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
3626 try func.lowerToStack(rhs);3627 try func.lowerToStack(rhs);
36273628
3628 const opcode: wasm.Opcode = buildOpcode(.{3629 const opcode: wasm.Opcode = buildOpcode(.{
3629 .valtype1 = typeToValtype(ty, pt),3630 .valtype1 = typeToValtype(ty, pt, func.target.*),
3630 .op = switch (op) {3631 .op = switch (op) {
3631 .lt => .lt,3632 .lt => .lt,
3632 .lte => .le,3633 .lte => .le,
...@@ -3645,7 +3646,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO...@@ -3645,7 +3646,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
3645/// Compares two floats.3646/// Compares two floats.
3646/// NOTE: Leaves the result of the comparison on top of the stack.3647/// NOTE: Leaves the result of the comparison on top of the stack.
3647fn cmpFloat(func: *CodeGen, ty: Type, lhs: WValue, rhs: WValue, cmp_op: std.math.CompareOperator) InnerError!WValue {3648fn 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
3650 const op: Op = switch (cmp_op) {3651 const op: Op = switch (cmp_op) {
3651 .lt => .lt,3652 .lt => .lt,
...@@ -3829,7 +3830,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3829,7 +3830,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3829 break :result try func.bitcast(wanted_ty, given_ty, operand);3830 break :result try func.bitcast(wanted_ty, given_ty, operand);
3830 }3831 }
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.*)) {
3833 const loaded_memory = try func.load(operand, wanted_ty, 0);3834 const loaded_memory = try func.load(operand, wanted_ty, 0);
3834 if (needs_wrapping) {3835 if (needs_wrapping) {
3835 break :result try func.wrapOperand(loaded_memory, wanted_ty);3836 break :result try func.wrapOperand(loaded_memory, wanted_ty);
...@@ -3837,7 +3838,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3837,7 +3838,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3837 break :result loaded_memory;3838 break :result loaded_memory;
3838 }3839 }
3839 }3840 }
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.*)) {
3841 const stack_memory = try func.allocStack(wanted_ty);3842 const stack_memory = try func.allocStack(wanted_ty);
3842 try func.store(stack_memory, operand, given_ty, 0);3843 try func.store(stack_memory, operand, given_ty, 0);
3843 if (needs_wrapping) {3844 if (needs_wrapping) {
...@@ -3867,8 +3868,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn...@@ -3867,8 +3868,8 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
38673868
3868 const opcode = buildOpcode(.{3869 const opcode = buildOpcode(.{
3869 .op = .reinterpret,3870 .op = .reinterpret,
3870 .valtype1 = typeToValtype(wanted_ty, pt),3871 .valtype1 = typeToValtype(wanted_ty, pt, func.target.*),
3871 .valtype2 = typeToValtype(given_ty, pt),3872 .valtype2 = typeToValtype(given_ty, pt, func.target.*),
3872 });3873 });
3873 try func.emitWValue(operand);3874 try func.emitWValue(operand);
3874 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));3875 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
...@@ -3990,8 +3991,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3990,8 +3991,8 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3990 break :result try func.trunc(shifted_value, field_ty, backing_ty);3991 break :result try func.trunc(shifted_value, field_ty, backing_ty);
3991 },3992 },
3992 .Union => result: {3993 .Union => result: {
3993 if (isByRef(struct_ty, pt)) {3994 if (isByRef(struct_ty, pt, func.target.*)) {
3994 if (!isByRef(field_ty, pt)) {3995 if (!isByRef(field_ty, pt, func.target.*)) {
3995 break :result try func.load(operand, field_ty, 0);3996 break :result try func.load(operand, field_ty, 0);
3996 } else {3997 } else {
3997 const new_stack_val = try func.allocStack(field_ty);3998 const new_stack_val = try func.allocStack(field_ty);
...@@ -4017,7 +4018,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4017,7 +4018,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4017 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, pt)) orelse {4018 const offset = std.math.cast(u32, struct_ty.structFieldOffset(field_index, pt)) orelse {
4018 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)});4019 return func.fail("Field type '{}' too big to fit into stack frame", .{field_ty.fmt(pt)});
4019 };4020 };
4020 if (isByRef(field_ty, pt)) {4021 if (isByRef(field_ty, pt, func.target.*)) {
4021 switch (operand) {4022 switch (operand) {
4022 .stack_offset => |stack_offset| {4023 .stack_offset => |stack_offset| {
4023 break :result .{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };4024 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 {...@@ -4163,7 +4164,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4163 const val = try func.lowerConstant(case.values[0].value, target_ty);4164 const val = try func.lowerConstant(case.values[0].value, target_ty);
4164 try func.emitWValue(val);4165 try func.emitWValue(val);
4165 const opcode = buildOpcode(.{4166 const opcode = buildOpcode(.{
4166 .valtype1 = typeToValtype(target_ty, pt),4167 .valtype1 = typeToValtype(target_ty, pt, func.target.*),
4167 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.4168 .op = .ne, // not equal, because we want to jump out of this block if it does not match the condition.
4168 .signedness = signedness,4169 .signedness = signedness,
4169 });4170 });
...@@ -4177,7 +4178,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4177,7 +4178,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4177 const val = try func.lowerConstant(value.value, target_ty);4178 const val = try func.lowerConstant(value.value, target_ty);
4178 try func.emitWValue(val);4179 try func.emitWValue(val);
4179 const opcode = buildOpcode(.{4180 const opcode = buildOpcode(.{
4180 .valtype1 = typeToValtype(target_ty, pt),4181 .valtype1 = typeToValtype(target_ty, pt, func.target.*),
4181 .op = .eq,4182 .op = .eq,
4182 .signedness = signedness,4183 .signedness = signedness,
4183 });4184 });
...@@ -4265,7 +4266,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo...@@ -4265,7 +4266,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
4265 }4266 }
42664267
4267 const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));4268 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.*)) {
4269 break :result try func.buildPointerOffset(operand, pl_offset, .new);4270 break :result try func.buildPointerOffset(operand, pl_offset, .new);
4270 }4271 }
42714272
...@@ -4492,7 +4493,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4492,7 +4493,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4492 const operand = try func.resolveInst(ty_op.operand);4493 const operand = try func.resolveInst(ty_op.operand);
4493 if (opt_ty.optionalReprIsPayload(mod)) break :result func.reuseOperand(ty_op.operand, operand);4494 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.*)) {
4496 break :result try func.buildPointerOffset(operand, 0, .new);4497 break :result try func.buildPointerOffset(operand, 0, .new);
4497 }4498 }
44984499
...@@ -4626,7 +4627,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4626,7 +4627,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4626 try func.addTag(.i32_mul);4627 try func.addTag(.i32_mul);
4627 try func.addTag(.i32_add);4628 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.*))
4630 .stack4631 .stack
4631 else4632 else
4632 try func.load(.stack, elem_ty, 0);4633 try func.load(.stack, elem_ty, 0);
...@@ -4784,7 +4785,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4784,7 +4785,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4784 try func.addTag(.i32_mul);4785 try func.addTag(.i32_mul);
4785 try func.addTag(.i32_add);4786 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.*))
4788 .stack4789 .stack
4789 else4790 else
4790 try func.load(.stack, elem_ty, 0);4791 try func.load(.stack, elem_ty, 0);
...@@ -4835,7 +4836,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -4835,7 +4836,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4835 else => ptr_ty.childType(mod),4836 else => ptr_ty.childType(mod),
4836 };4837 };
48374838
4838 const valtype = typeToValtype(Type.usize, pt);4839 const valtype = typeToValtype(Type.usize, pt, func.target.*);
4839 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });4840 const mul_opcode = buildOpcode(.{ .valtype1 = valtype, .op = .mul });
4840 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });4841 const bin_opcode = buildOpcode(.{ .valtype1 = valtype, .op = op });
48414842
...@@ -4982,7 +4983,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4982,7 +4983,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4982 const elem_ty = array_ty.childType(mod);4983 const elem_ty = array_ty.childType(mod);
4983 const elem_size = elem_ty.abiSize(pt);4984 const elem_size = elem_ty.abiSize(pt);
49844985
4985 if (isByRef(array_ty, pt)) {4986 if (isByRef(array_ty, pt, func.target.*)) {
4986 try func.lowerToStack(array);4987 try func.lowerToStack(array);
4987 try func.emitWValue(index);4988 try func.emitWValue(index);
4988 try func.addImm32(@intCast(elem_size));4989 try func.addImm32(@intCast(elem_size));
...@@ -5025,7 +5026,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5025,7 +5026,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5025 }5026 }
5026 }5027 }
50275028
5028 const elem_result = if (isByRef(elem_ty, pt))5029 const elem_result = if (isByRef(elem_ty, pt, func.target.*))
5029 .stack5030 .stack
5030 else5031 else
5031 try func.load(.stack, elem_ty, 0);5032 try func.load(.stack, elem_ty, 0);
...@@ -5040,7 +5041,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5040,7 +5041,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50405041
5041 const operand = try func.resolveInst(ty_op.operand);5042 const operand = try func.resolveInst(ty_op.operand);
5042 const op_ty = func.typeOf(ty_op.operand);5043 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
5045 const dest_ty = func.typeOfIndex(inst);5046 const dest_ty = func.typeOfIndex(inst);
5046 const dest_info = dest_ty.intInfo(mod);5047 const dest_info = dest_ty.intInfo(mod);
...@@ -5069,8 +5070,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5069,8 +5070,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5069 try func.emitWValue(operand);5070 try func.emitWValue(operand);
5070 const op = buildOpcode(.{5071 const op = buildOpcode(.{
5071 .op = .trunc,5072 .op = .trunc,
5072 .valtype1 = typeToValtype(dest_ty, pt),5073 .valtype1 = typeToValtype(dest_ty, pt, func.target.*),
5073 .valtype2 = typeToValtype(op_ty, pt),5074 .valtype2 = typeToValtype(op_ty, pt, func.target.*),
5074 .signedness = dest_info.signedness,5075 .signedness = dest_info.signedness,
5075 });5076 });
5076 try func.addTag(Mir.Inst.Tag.fromOpcode(op));5077 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
...@@ -5088,7 +5089,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5088,7 +5089,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5088 const op_info = op_ty.intInfo(mod);5089 const op_info = op_ty.intInfo(mod);
50895090
5090 const dest_ty = func.typeOfIndex(inst);5091 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
5093 if (op_info.bits > 128) {5094 if (op_info.bits > 128) {
5094 return func.fail("TODO: floatFromInt for integers/floats with bitsize {d} bits", .{op_info.bits});5095 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 {...@@ -5114,8 +5115,8 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5114 try func.emitWValue(operand);5115 try func.emitWValue(operand);
5115 const op = buildOpcode(.{5116 const op = buildOpcode(.{
5116 .op = .convert,5117 .op = .convert,
5117 .valtype1 = typeToValtype(dest_ty, pt),5118 .valtype1 = typeToValtype(dest_ty, pt, func.target.*),
5118 .valtype2 = typeToValtype(op_ty, pt),5119 .valtype2 = typeToValtype(op_ty, pt, func.target.*),
5119 .signedness = op_info.signedness,5120 .signedness = op_info.signedness,
5120 });5121 });
5121 try func.addTag(Mir.Inst.Tag.fromOpcode(op));5122 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
...@@ -5131,7 +5132,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5131,7 +5132,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5131 const ty = func.typeOfIndex(inst);5132 const ty = func.typeOfIndex(inst);
5132 const elem_ty = ty.childType(mod);5133 const elem_ty = ty.childType(mod);
51335134
5134 if (determineSimdStoreStrategy(ty, pt) == .direct) blk: {5135 if (determineSimdStoreStrategy(ty, pt, func.target.*) == .direct) blk: {
5135 switch (operand) {5136 switch (operand) {
5136 // when the operand lives in the linear memory section, we can directly5137 // when the operand lives in the linear memory section, we can directly
5137 // load and splat the value at once. Meaning we do not first have to load5138 // 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 {...@@ -5215,7 +5216,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5215 const elem_size = child_ty.abiSize(pt);5216 const elem_size = child_ty.abiSize(pt);
52165217
5217 // TODO: One of them could be by ref; handle in loop5218 // 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.*)) {
5219 const result = try func.allocStack(inst_ty);5220 const result = try func.allocStack(inst_ty);
52205221
5221 for (0..mask_len) |index| {5222 for (0..mask_len) |index| {
...@@ -5291,7 +5292,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5291,7 +5292,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5291 // When the element type is by reference, we must copy the entire5292 // When the element type is by reference, we must copy the entire
5292 // value. It is therefore safer to move the offset pointer and store5293 // value. It is therefore safer to move the offset pointer and store
5293 // each value individually, instead of using store offsets.5294 // each value individually, instead of using store offsets.
5294 if (isByRef(elem_ty, pt)) {5295 if (isByRef(elem_ty, pt, func.target.*)) {
5295 // copy stack pointer into a temporary local, which is5296 // copy stack pointer into a temporary local, which is
5296 // moved for each element to store each value in the right position.5297 // moved for each element to store each value in the right position.
5297 const offset = try func.buildPointerOffset(result, 0, .new);5298 const offset = try func.buildPointerOffset(result, 0, .new);
...@@ -5321,7 +5322,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5321,7 +5322,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5321 },5322 },
5322 .Struct => switch (result_ty.containerLayout(mod)) {5323 .Struct => switch (result_ty.containerLayout(mod)) {
5323 .@"packed" => {5324 .@"packed" => {
5324 if (isByRef(result_ty, pt)) {5325 if (isByRef(result_ty, pt, func.target.*)) {
5325 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});5326 return func.fail("TODO: airAggregateInit for packed structs larger than 64 bits", .{});
5326 }5327 }
5327 const packed_struct = mod.typeToPackedStruct(result_ty).?;5328 const packed_struct = mod.typeToPackedStruct(result_ty).?;
...@@ -5424,15 +5425,15 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5424,15 +5425,15 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5424 if (layout.tag_size == 0) {5425 if (layout.tag_size == 0) {
5425 break :result .none;5426 break :result .none;
5426 }5427 }
5427 assert(!isByRef(union_ty, pt));5428 assert(!isByRef(union_ty, pt, func.target.*));
5428 break :result tag_int;5429 break :result tag_int;
5429 }5430 }
54305431
5431 if (isByRef(union_ty, pt)) {5432 if (isByRef(union_ty, pt, func.target.*)) {
5432 const result_ptr = try func.allocStack(union_ty);5433 const result_ptr = try func.allocStack(union_ty);
5433 const payload = try func.resolveInst(extra.init);5434 const payload = try func.resolveInst(extra.init);
5434 if (layout.tag_align.compare(.gte, layout.payload_align)) {5435 if (layout.tag_align.compare(.gte, layout.payload_align)) {
5435 if (isByRef(field_ty, pt)) {5436 if (isByRef(field_ty, pt, func.target.*)) {
5436 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);5437 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
5437 try func.store(payload_ptr, payload, field_ty, 0);5438 try func.store(payload_ptr, payload, field_ty, 0);
5438 } else {5439 } else {
...@@ -5513,7 +5514,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:...@@ -5513,7 +5514,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
55135514
5514 _ = try func.load(lhs, payload_ty, 0);5515 _ = try func.load(lhs, payload_ty, 0);
5515 _ = try func.load(rhs, payload_ty, 0);5516 _ = 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.*) });
5517 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));5518 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
5518 try func.addLabel(.br_if, 0);5519 try func.addLabel(.br_if, 0);
55195520
...@@ -5630,8 +5631,8 @@ fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5630,8 +5631,8 @@ fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5630/// Extends a float from a given `Type` to a larger wanted `Type`5631/// Extends a float from a given `Type` to a larger wanted `Type`
5631/// NOTE: Leaves the result on the stack5632/// NOTE: Leaves the result on the stack
5632fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {5633fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
5633 const given_bits = given.floatBits(func.target);5634 const given_bits = given.floatBits(func.target.*);
5634 const wanted_bits = wanted.floatBits(func.target);5635 const wanted_bits = wanted.floatBits(func.target.*);
56355636
5636 if (wanted_bits == 64 and given_bits == 32) {5637 if (wanted_bits == 64 and given_bits == 32) {
5637 try func.emitWValue(operand);5638 try func.emitWValue(operand);
...@@ -5674,8 +5675,8 @@ fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5674,8 +5675,8 @@ fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5674/// Truncates a float from a given `Type` to its wanted `Type`5675/// Truncates a float from a given `Type` to its wanted `Type`
5675/// NOTE: The result value remains on the stack5676/// NOTE: The result value remains on the stack
5676fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {5677fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
5677 const given_bits = given.floatBits(func.target);5678 const given_bits = given.floatBits(func.target.*);
5678 const wanted_bits = wanted.floatBits(func.target);5679 const wanted_bits = wanted.floatBits(func.target.*);
56795680
5680 if (wanted_bits == 32 and given_bits == 64) {5681 if (wanted_bits == 32 and given_bits == 64) {
5681 try func.emitWValue(operand);5682 try func.emitWValue(operand);
...@@ -6247,7 +6248,6 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6247,7 +6248,6 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
6247 assert(op == .max or op == .min);6248 assert(op == .max or op == .min);
6248 const pt = func.pt;6249 const pt = func.pt;
6249 const mod = pt.zcu;6250 const mod = pt.zcu;
6250 const target = mod.getTarget();
6251 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;6251 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
62526252
6253 const ty = func.typeOfIndex(inst);6253 const ty = func.typeOfIndex(inst);
...@@ -6264,7 +6264,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {...@@ -6264,7 +6264,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
62646264
6265 if (ty.zigTypeTag(mod) == .Float) {6265 if (ty.zigTypeTag(mod) == .Float) {
6266 var fn_name_buf: [64]u8 = undefined;6266 var fn_name_buf: [64]u8 = undefined;
6267 const float_bits = ty.floatBits(target);6267 const float_bits = ty.floatBits(func.target.*);
6268 const fn_name = std.fmt.bufPrint(&fn_name_buf, "{s}f{s}{s}", .{6268 const fn_name = std.fmt.bufPrint(&fn_name_buf, "{s}f{s}{s}", .{
6269 target_util.libcFloatPrefix(float_bits),6269 target_util.libcFloatPrefix(float_bits),
6270 @tagName(op),6270 @tagName(op),
...@@ -6300,7 +6300,7 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6300,7 +6300,7 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6300 const lhs = try func.resolveInst(bin_op.lhs);6300 const lhs = try func.resolveInst(bin_op.lhs);
6301 const rhs = try func.resolveInst(bin_op.rhs);6301 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: {
6304 const rhs_ext = try func.fpext(rhs, ty, Type.f32);6304 const rhs_ext = try func.fpext(rhs, ty, Type.f32);
6305 const lhs_ext = try func.fpext(lhs, ty, Type.f32);6305 const lhs_ext = try func.fpext(lhs, ty, Type.f32);
6306 const addend_ext = try func.fpext(addend, ty, Type.f32);6306 const addend_ext = try func.fpext(addend, ty, Type.f32);
...@@ -6457,8 +6457,6 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6457,8 +6457,6 @@ fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6457fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {6457fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void {
6458 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});6458 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
64596459
6460 const pt = func.pt;
6461 const mod = pt.zcu;
6462 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6460 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6463 const ty = func.typeOf(pl_op.operand);6461 const ty = func.typeOf(pl_op.operand);
6464 const operand = try func.resolveInst(pl_op.operand);6462 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...@@ -6468,14 +6466,14 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
6468 const name = func.air.nullTerminatedString(pl_op.payload);6466 const name = func.air.nullTerminatedString(pl_op.payload);
6469 log.debug(" var name = ({s})", .{name});6467 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) {
6472 .local => |local| .{ .wasm_local = local.value },6470 .local => |local| .{ .wasm_local = local.value },
6473 else => blk: {6471 else => blk: {
6474 log.debug("TODO generate debug info for {}", .{operand});6472 log.debug("TODO generate debug info for {}", .{operand});
6475 break :blk .nop;6473 break :blk .nop;
6476 },6474 },
6477 };6475 };
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
6480 return func.finishAir(inst, .none, &.{});6478 return func.finishAir(inst, .none, &.{});
6481}6479}
...@@ -6552,7 +6550,7 @@ fn lowerTry(...@@ -6552,7 +6550,7 @@ fn lowerTry(
6552 }6550 }
65536551
6554 const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt));6552 const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
6555 if (isByRef(pl_ty, pt)) {6553 if (isByRef(pl_ty, pt, func.target.*)) {
6556 return buildPointerOffset(func, err_union, pl_offset, .new);6554 return buildPointerOffset(func, err_union, pl_offset, .new);
6557 }6555 }
6558 const payload = try func.load(err_union, pl_ty, pl_offset);6556 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 {...@@ -6712,7 +6710,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6712 _ = try func.wrapOperand(.stack, ty);6710 _ = try func.wrapOperand(.stack, ty);
6713 }6711 }
6714 } else {6712 } else {
6715 const float_bits = ty.floatBits(func.target);6713 const float_bits = ty.floatBits(func.target.*);
6716 if (float_bits > 64) {6714 if (float_bits > 64) {
6717 return func.fail("TODO: `@divFloor` for floats with bitsize: {d}", .{float_bits});6715 return func.fail("TODO: `@divFloor` for floats with bitsize: {d}", .{float_bits});
6718 }6716 }
...@@ -7126,12 +7124,12 @@ fn callIntrinsic(...@@ -7126,12 +7124,12 @@ fn callIntrinsic(
7126 // Always pass over C-ABI7124 // Always pass over C-ABI
7127 const pt = func.pt;7125 const pt = func.pt;
7128 const mod = pt.zcu;7126 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.*);
7130 defer func_type.deinit(func.gpa);7128 defer func_type.deinit(func.gpa);
7131 const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type);7129 const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type);
7132 try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index);7130 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.*);
7135 // if we want return as first param, we allocate a pointer to stack,7133 // if we want return as first param, we allocate a pointer to stack,
7136 // and emit it as our first argument7134 // and emit it as our first argument
7137 const sret = if (want_sret_param) blk: {7135 const sret = if (want_sret_param) blk: {
...@@ -7181,14 +7179,12 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7181,14 +7179,12 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7181 const pt = func.pt;7179 const pt = func.pt;
7182 const mod = pt.zcu;7180 const mod = pt.zcu;
7183 const ip = &mod.intern_pool;7181 const ip = &mod.intern_pool;
7184 const enum_decl_index = enum_ty.getOwnerDecl(mod);
71857182
7186 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);7183 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
7187 defer arena_allocator.deinit();7184 defer arena_allocator.deinit();
7188 const arena = arena_allocator.allocator();7185 const arena = arena_allocator.allocator();
71897186
7190 const decl = mod.declPtr(enum_decl_index);7187 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{ip.loadEnumType(enum_ty.toIntern()).name.fmt(ip)});
7191 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{decl.fqn.fmt(ip)});
71927188
7193 // check if we already generated code for this.7189 // check if we already generated code for this.
7194 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {7190 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {
...@@ -7232,11 +7228,13 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7232,11 +7228,13 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7232 .ty = name_ty.toIntern(),7228 .ty = name_ty.toIntern(),
7233 .storage = .{ .bytes = tag_name.toString() },7229 .storage = .{ .bytes = tag_name.toString() },
7234 } });7230 } });
7235 const tag_sym_index = try func.bin_file.lowerUnnamedConst(7231 const tag_sym_index = switch (try func.bin_file.lowerUav(pt, name_val, .none, func.src_loc)) {
7236 pt,7232 .mcv => |mcv| mcv.load_symbol,
7237 Value.fromInterned(name_val),7233 .fail => |err_msg| {
7238 enum_decl_index,7234 func.err_msg = err_msg;
7239 );7235 return error.CodegenFail;
7236 },
7237 };
72407238
7241 // block for this if case7239 // block for this if case
7242 try writer.writeByte(std.wasm.opcode(.block));7240 try writer.writeByte(std.wasm.opcode(.block));
...@@ -7333,7 +7331,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7333,7 +7331,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7333 try writer.writeByte(std.wasm.opcode(.end));7331 try writer.writeByte(std.wasm.opcode(.end));
73347332
7335 const slice_ty = Type.slice_const_u8_sentinel_0;7333 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.*);
7337 const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);7335 const sym_index = try func.bin_file.createFunction(func_name, func_type, &body_list, &relocs);
7338 return @intFromEnum(sym_index);7336 return @intFromEnum(sym_index);
7339}7337}
...@@ -7477,7 +7475,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7477,7 +7475,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7477 break :val ptr_val;7475 break :val ptr_val;
7478 };7476 };
74797477
7480 const result = if (isByRef(result_ty, pt)) val: {7478 const result = if (isByRef(result_ty, pt, func.target.*)) val: {
7481 try func.emitWValue(cmp_result);7479 try func.emitWValue(cmp_result);
7482 try func.addImm32(~@as(u32, 0));7480 try func.addImm32(~@as(u32, 0));
7483 try func.addTag(.i32_xor);7481 try func.addTag(.i32_xor);
...@@ -7706,8 +7704,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7706,8 +7704,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7706 // Only when the atomic feature is enabled, and we're not building7704 // Only when the atomic feature is enabled, and we're not building
7707 // for a single-threaded build, can we emit the `fence` instruction.7705 // for a single-threaded build, can we emit the `fence` instruction.
7708 // In all other cases, we emit no instructions for a fence.7706 // In all other cases, we emit no instructions for a fence.
7709 const func_namespace = zcu.namespacePtr(func.decl.src_namespace);7707 const single_threaded = zcu.navFileScope(func.owner_nav).mod.single_threaded;
7710 const single_threaded = func_namespace.fileScope(zcu).mod.single_threaded;
7711 if (func.useAtomicFeature() and !single_threaded) {7708 if (func.useAtomicFeature() and !single_threaded) {
7712 try func.addAtomicTag(.atomic_fence);7709 try func.addAtomicTag(.atomic_fence);
7713 }7710 }
src/arch/wasm/Emit.zig+7-7
...@@ -22,7 +22,7 @@ code: *std.ArrayList(u8),...@@ -22,7 +22,7 @@ code: *std.ArrayList(u8),
22/// List of allocated locals.22/// List of allocated locals.
23locals: []const u8,23locals: []const u8,
24/// The declaration that code is being generated for.24/// The declaration that code is being generated for.
25decl_index: InternPool.DeclIndex,25owner_nav: InternPool.Nav.Index,
2626
27// Debug information27// Debug information
28/// Holds the debug information for this emission28/// Holds the debug information for this emission
...@@ -257,7 +257,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {...@@ -257,7 +257,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
257 const comp = emit.bin_file.base.comp;257 const comp = emit.bin_file.base.comp;
258 const zcu = comp.module.?;258 const zcu = comp.module.?;
259 const gpa = comp.gpa;259 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);
261 return error.EmitFail;261 return error.EmitFail;
262}262}
263263
...@@ -310,7 +310,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {...@@ -310,7 +310,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
310 const global_offset = emit.offset();310 const global_offset = emit.offset();
311 try emit.code.appendSlice(&buf);311 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;
314 const atom = emit.bin_file.getAtomPtr(atom_index);314 const atom = emit.bin_file.getAtomPtr(atom_index);
315 try atom.relocs.append(gpa, .{315 try atom.relocs.append(gpa, .{
316 .index = label,316 .index = label,
...@@ -370,7 +370,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -370,7 +370,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
370 try emit.code.appendSlice(&buf);370 try emit.code.appendSlice(&buf);
371371
372 if (label != 0) {372 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;
374 const atom = emit.bin_file.getAtomPtr(atom_index);374 const atom = emit.bin_file.getAtomPtr(atom_index);
375 try atom.relocs.append(gpa, .{375 try atom.relocs.append(gpa, .{
376 .offset = call_offset,376 .offset = call_offset,
...@@ -390,7 +390,7 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -390,7 +390,7 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
390 leb128.writeUnsignedFixed(5, &buf, type_index);390 leb128.writeUnsignedFixed(5, &buf, type_index);
391 try emit.code.appendSlice(&buf);391 try emit.code.appendSlice(&buf);
392 if (type_index != 0) {392 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;
394 const atom = emit.bin_file.getAtomPtr(atom_index);394 const atom = emit.bin_file.getAtomPtr(atom_index);
395 try atom.relocs.append(emit.bin_file.base.comp.gpa, .{395 try atom.relocs.append(emit.bin_file.base.comp.gpa, .{
396 .offset = call_offset,396 .offset = call_offset,
...@@ -412,7 +412,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -412,7 +412,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
412 try emit.code.appendSlice(&buf);412 try emit.code.appendSlice(&buf);
413413
414 if (symbol_index != 0) {414 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;
416 const atom = emit.bin_file.getAtomPtr(atom_index);416 const atom = emit.bin_file.getAtomPtr(atom_index);
417 try atom.relocs.append(gpa, .{417 try atom.relocs.append(gpa, .{
418 .offset = index_offset,418 .offset = index_offset,
...@@ -443,7 +443,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -443,7 +443,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
443 }443 }
444444
445 if (mem.pointer != 0) {445 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;
447 const atom = emit.bin_file.getAtomPtr(atom_index);447 const atom = emit.bin_file.getAtomPtr(atom_index);
448 try atom.relocs.append(gpa, .{448 try atom.relocs.append(gpa, .{
449 .offset = mem_offset,449 .offset = mem_offset,
src/arch/x86_64/CodeGen.zig+84-109
...@@ -116,48 +116,36 @@ const RegisterOffset = struct { reg: Register, off: i32 = 0 };...@@ -116,48 +116,36 @@ const RegisterOffset = struct { reg: Register, off: i32 = 0 };
116const SymbolOffset = struct { sym: u32, off: i32 = 0 };116const SymbolOffset = struct { sym: u32, off: i32 = 0 };
117117
118const Owner = union(enum) {118const Owner = union(enum) {
119 func_index: InternPool.Index,119 nav_index: InternPool.Nav.Index,
120 lazy_sym: link.File.LazySymbol,120 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
129 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {122 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {
130 const pt = ctx.pt;123 const pt = ctx.pt;
131 switch (owner) {124 switch (owner) {
132 .func_index => |func_index| {125 .nav_index => |nav_index| if (ctx.bin_file.cast(.elf)) |elf_file| {
133 const decl_index = ctx.pt.zcu.funcOwnerDeclIndex(func_index);126 return elf_file.zigObjectPtr().?.getOrCreateMetadataForNav(elf_file, nav_index);
134 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {127 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
135 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);128 return macho_file.getZigObject().?.getOrCreateMetadataForNav(macho_file, nav_index);
136 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {129 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
137 return macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index);130 const atom = try coff_file.getOrCreateAtomForNav(nav_index);
138 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {131 return coff_file.getAtom(atom).getSymbolIndex().?;
139 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);132 } else if (ctx.bin_file.cast(.plan9)) |p9_file| {
140 return coff_file.getAtom(atom).getSymbolIndex().?;133 return p9_file.seeNav(pt, nav_index);
141 } else if (ctx.bin_file.cast(link.File.Plan9)) |p9_file| {134 } else unreachable,
142 return p9_file.seeDecl(decl_index);135 .lazy_sym => |lazy_sym| if (ctx.bin_file.cast(.elf)) |elf_file| {
143 } else unreachable;136 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
144 },137 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
145 .lazy_sym => |lazy_sym| {138 } else if (ctx.bin_file.cast(.macho)) |macho_file| {
146 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {139 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
147 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|140 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
148 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});141 } else if (ctx.bin_file.cast(.coff)) |coff_file| {
149 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {142 const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
150 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|143 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
151 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});144 return coff_file.getAtom(atom).getSymbolIndex().?;
152 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {145 } else if (ctx.bin_file.cast(.plan9)) |p9_file| {
153 const atom = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|146 return p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
154 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});147 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
155 return coff_file.getAtom(atom).getSymbolIndex().?;148 } else unreachable,
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 },
161 }149 }
162 }150 }
163};151};
...@@ -803,14 +791,12 @@ pub fn generate(...@@ -803,14 +791,12 @@ pub fn generate(
803 debug_output: DebugInfoOutput,791 debug_output: DebugInfoOutput,
804) CodeGenError!Result {792) CodeGenError!Result {
805 const zcu = pt.zcu;793 const zcu = pt.zcu;
806 const gpa = zcu.gpa;
807 const comp = zcu.comp;794 const comp = zcu.comp;
795 const gpa = zcu.gpa;
796 const ip = &zcu.intern_pool;
808 const func = zcu.funcInfo(func_index);797 const func = zcu.funcInfo(func_index);
809 const fn_owner_decl = zcu.declPtr(func.owner_decl);798 const fn_type = Type.fromInterned(func.ty);
810 assert(fn_owner_decl.has_tv);799 const mod = zcu.navFileScope(func.owner_nav).mod;
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;
814800
815 var function: Self = .{801 var function: Self = .{
816 .gpa = gpa,802 .gpa = gpa,
...@@ -821,7 +807,7 @@ pub fn generate(...@@ -821,7 +807,7 @@ pub fn generate(
821 .mod = mod,807 .mod = mod,
822 .bin_file = bin_file,808 .bin_file = bin_file,
823 .debug_output = debug_output,809 .debug_output = debug_output,
824 .owner = .{ .func_index = func_index },810 .owner = .{ .nav_index = func.owner_nav },
825 .inline_func = func_index,811 .inline_func = func_index,
826 .err_msg = null,812 .err_msg = null,
827 .args = undefined, // populated after `resolveCallingConventionValues`813 .args = undefined, // populated after `resolveCallingConventionValues`
...@@ -847,9 +833,7 @@ pub fn generate(...@@ -847,9 +833,7 @@ pub fn generate(
847 function.mir_extra.deinit(gpa);833 function.mir_extra.deinit(gpa);
848 }834 }
849835
850 wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)});836 wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)});
851
852 const ip = &zcu.intern_pool;
853837
854 try function.frame_allocs.resize(gpa, FrameIndex.named_count);838 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
855 function.frame_allocs.set(839 function.frame_allocs.set(
...@@ -1067,22 +1051,22 @@ pub fn generateLazy(...@@ -1067,22 +1051,22 @@ pub fn generateLazy(
1067 }1051 }
1068}1052}
10691053
1070const FormatDeclData = struct {1054const FormatNavData = struct {
1071 zcu: *Zcu,1055 ip: *const InternPool,
1072 decl_index: InternPool.DeclIndex,1056 nav_index: InternPool.Nav.Index,
1073};1057};
1074fn formatDecl(1058fn formatNav(
1075 data: FormatDeclData,1059 data: FormatNavData,
1076 comptime _: []const u8,1060 comptime _: []const u8,
1077 _: std.fmt.FormatOptions,1061 _: std.fmt.FormatOptions,
1078 writer: anytype,1062 writer: anytype,
1079) @TypeOf(writer).Error!void {1063) @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)});
1081}1065}
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) {
1083 return .{ .data = .{1067 return .{ .data = .{
1084 .zcu = self.pt.zcu,1068 .ip = ip,
1085 .decl_index = decl_index,1069 .nav_index = nav_index,
1086 } };1070 } };
1087}1071}
10881072
...@@ -2230,9 +2214,9 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -2230,9 +2214,9 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2230 const pt = self.pt;2214 const pt = self.pt;
2231 const mod = pt.zcu;2215 const mod = pt.zcu;
2232 const ip = &mod.intern_pool;2216 const ip = &mod.intern_pool;
2233 switch (lazy_sym.ty.zigTypeTag(mod)) {2217 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(mod)) {
2234 .Enum => {2218 .Enum => {
2235 const enum_ty = lazy_sym.ty;2219 const enum_ty = Type.fromInterned(lazy_sym.ty);
2236 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});2220 wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)});
22372221
2238 const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*);2222 const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*);
...@@ -2249,7 +2233,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -2249,7 +2233,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2249 const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);2233 const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
2250 const data_lock = self.register_manager.lockRegAssumeUnused(data_reg);2234 const data_lock = self.register_manager.lockRegAssumeUnused(data_reg);
2251 defer self.register_manager.unlockReg(data_lock);2235 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
2254 var data_off: i32 = 0;2238 var data_off: i32 = 0;
2255 const tag_names = enum_ty.enumFields(mod);2239 const tag_names = enum_ty.enumFields(mod);
...@@ -2288,7 +2272,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -2288,7 +2272,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2288 },2272 },
2289 else => return self.fail(2273 else => return self.fail(
2290 "TODO implement {s} for {}",2274 "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) },
2292 ),2276 ),
2293 }2277 }
2294}2278}
...@@ -11932,11 +11916,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -11932,11 +11916,9 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
11932}11916}
1193311917
11934fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {11918fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
11935 const pt = self.pt;
11936 const mod = pt.zcu;
11937 switch (self.debug_output) {11919 switch (self.debug_output) {
11938 .dwarf => |dw| {11920 .dwarf => |dw| {
11939 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {11921 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (mcv) {
11940 .register => |reg| .{ .register = reg.dwarfNum() },11922 .register => |reg| .{ .register = reg.dwarfNum() },
11941 .register_pair => |regs| .{ .register_pair = .{11923 .register_pair => |regs| .{ .register_pair = .{
11942 regs[0].dwarfNum(), regs[1].dwarfNum(),11924 regs[0].dwarfNum(), regs[1].dwarfNum(),
...@@ -11955,7 +11937,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {...@@ -11955,7 +11937,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
11955 // TODO: this might need adjusting like the linkers do.11937 // TODO: this might need adjusting like the linkers do.
11956 // Instead of flattening the owner and passing Decl.Index here we may11938 // Instead of flattening the owner and passing Decl.Index here we may
11957 // want to special case LazySymbol in DWARF linker too.11939 // 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);
11959 },11941 },
11960 .plan9 => {},11942 .plan9 => {},
11961 .none => {},11943 .none => {},
...@@ -11969,8 +11951,6 @@ fn genVarDbgInfo(...@@ -11969,8 +11951,6 @@ fn genVarDbgInfo(
11969 mcv: MCValue,11951 mcv: MCValue,
11970 name: [:0]const u8,11952 name: [:0]const u8,
11971) !void {11953) !void {
11972 const pt = self.pt;
11973 const mod = pt.zcu;
11974 const is_ptr = switch (tag) {11954 const is_ptr = switch (tag) {
11975 .dbg_var_ptr => true,11955 .dbg_var_ptr => true,
11976 .dbg_var_val => false,11956 .dbg_var_val => false,
...@@ -11979,7 +11959,7 @@ fn genVarDbgInfo(...@@ -11979,7 +11959,7 @@ fn genVarDbgInfo(
1197911959
11980 switch (self.debug_output) {11960 switch (self.debug_output) {
11981 .dwarf => |dw| {11961 .dwarf => |dw| {
11982 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {11962 const loc: link.File.Dwarf.NavState.DbgInfoLoc = switch (mcv) {
11983 .register => |reg| .{ .register = reg.dwarfNum() },11963 .register => |reg| .{ .register = reg.dwarfNum() },
11984 // TODO use a frame index11964 // TODO use a frame index
11985 .load_frame, .lea_frame => return,11965 .load_frame, .lea_frame => return,
...@@ -12007,7 +11987,7 @@ fn genVarDbgInfo(...@@ -12007,7 +11987,7 @@ fn genVarDbgInfo(
12007 // TODO: this might need adjusting like the linkers do.11987 // TODO: this might need adjusting like the linkers do.
12008 // Instead of flattening the owner and passing Decl.Index here we may11988 // Instead of flattening the owner and passing Decl.Index here we may
12009 // want to special case LazySymbol in DWARF linker too.11989 // 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);
12011 },11991 },
12012 .plan9 => {},11992 .plan9 => {},
12013 .none => {},11993 .none => {},
...@@ -12090,14 +12070,15 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12090,14 +12070,15 @@ fn genCall(self: *Self, info: union(enum) {
12090 },12070 },
12091}, arg_types: []const Type, args: []const MCValue) !MCValue {12071}, arg_types: []const Type, args: []const MCValue) !MCValue {
12092 const pt = self.pt;12072 const pt = self.pt;
12093 const mod = pt.zcu;12073 const zcu = pt.zcu;
12074 const ip = &zcu.intern_pool;
1209412075
12095 const fn_ty = switch (info) {12076 const fn_ty = switch (info) {
12096 .air => |callee| fn_info: {12077 .air => |callee| fn_info: {
12097 const callee_ty = self.typeOf(callee);12078 const callee_ty = self.typeOf(callee);
12098 break :fn_info switch (callee_ty.zigTypeTag(mod)) {12079 break :fn_info switch (callee_ty.zigTypeTag(zcu)) {
12099 .Fn => callee_ty,12080 .Fn => callee_ty,
12100 .Pointer => callee_ty.childType(mod),12081 .Pointer => callee_ty.childType(zcu),
12101 else => unreachable,12082 else => unreachable,
12102 };12083 };
12103 },12084 },
...@@ -12107,7 +12088,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12107,7 +12088,7 @@ fn genCall(self: *Self, info: union(enum) {
12107 .cc = .C,12088 .cc = .C,
12108 }),12089 }),
12109 };12090 };
12110 const fn_info = mod.typeToFunc(fn_ty).?;12091 const fn_info = zcu.typeToFunc(fn_ty).?;
12111 const resolved_cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);12092 const resolved_cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);
1211212093
12113 const ExpectedContents = extern struct {12094 const ExpectedContents = extern struct {
...@@ -12225,7 +12206,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12225,7 +12206,7 @@ fn genCall(self: *Self, info: union(enum) {
12225 try self.asmRegisterImmediate(12206 try self.asmRegisterImmediate(
12226 .{ ._, .cmp },12207 .{ ._, .cmp },
12227 index_reg.to32(),12208 index_reg.to32(),
12228 Immediate.u(arg_ty.vectorLen(mod)),12209 Immediate.u(arg_ty.vectorLen(zcu)),
12229 );12210 );
12230 _ = try self.asmJccReloc(.b, loop);12211 _ = try self.asmJccReloc(.b, loop);
1223112212
...@@ -12317,18 +12298,18 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12317,18 +12298,18 @@ fn genCall(self: *Self, info: union(enum) {
12317 // on linking.12298 // on linking.
12318 switch (info) {12299 switch (info) {
12319 .air => |callee| if (try self.air.value(callee, pt)) |func_value| {12300 .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);
12321 switch (switch (func_key) {12302 switch (switch (func_key) {
12322 else => func_key,12303 else => func_key,
12323 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {12304 .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()),
12325 else => func_key,12306 else => func_key,
12326 } else func_key,12307 } else func_key,
12327 }) {12308 }) {
12328 .func => |func| {12309 .func => |func| {
12329 if (self.bin_file.cast(link.File.Elf)) |elf_file| {12310 if (self.bin_file.cast(.elf)) |elf_file| {
12330 const zo = elf_file.zigObjectPtr().?;12311 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);
12332 if (self.mod.pic) {12313 if (self.mod.pic) {
12333 const callee_reg: Register = switch (resolved_cc) {12314 const callee_reg: Register = switch (resolved_cc) {
12334 .SysV => callee: {12315 .SysV => callee: {
...@@ -12356,14 +12337,14 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12356,14 +12337,14 @@ fn genCall(self: *Self, info: union(enum) {
12356 } },12337 } },
12357 .mod = .{ .rm = .{ .size = .qword } },12338 .mod = .{ .rm = .{ .size = .qword } },
12358 });12339 });
12359 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {12340 } else if (self.bin_file.cast(.coff)) |coff_file| {
12360 const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);12341 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
12361 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;12342 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
12362 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{});12343 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{});
12363 try self.asmRegister(.{ ._, .call }, .rax);12344 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| {
12365 const zo = macho_file.getZigObject().?;12346 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);
12367 const sym = zo.symbols.items[sym_index];12348 const sym = zo.symbols.items[sym_index];
12368 try self.genSetReg(12349 try self.genSetReg(
12369 .rax,12350 .rax,
...@@ -12372,8 +12353,8 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12372,8 +12353,8 @@ fn genCall(self: *Self, info: union(enum) {
12372 .{},12353 .{},
12373 );12354 );
12374 try self.asmRegister(.{ ._, .call }, .rax);12355 try self.asmRegister(.{ ._, .call }, .rax);
12375 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {12356 } else if (self.bin_file.cast(.plan9)) |p9| {
12376 const atom_index = try p9.seeDecl(func.owner_decl);12357 const atom_index = try p9.seeNav(pt, func.owner_nav);
12377 const atom = p9.getAtom(atom_index);12358 const atom = p9.getAtom(atom_index);
12378 try self.asmMemory(.{ ._, .call }, .{12359 try self.asmMemory(.{ ._, .call }, .{
12379 .base = .{ .reg = .ds },12360 .base = .{ .reg = .ds },
...@@ -12384,16 +12365,15 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12384,16 +12365,15 @@ fn genCall(self: *Self, info: union(enum) {
12384 });12365 });
12385 } else unreachable;12366 } else unreachable;
12386 },12367 },
12387 .extern_func => |extern_func| {12368 .@"extern" => |@"extern"| try self.genExternSymbolRef(
12388 const owner_decl = mod.declPtr(extern_func.decl);12369 .call,
12389 const lib_name = extern_func.lib_name.toSlice(&mod.intern_pool);12370 @"extern".lib_name.toSlice(ip),
12390 const decl_name = owner_decl.name.toSlice(&mod.intern_pool);12371 @"extern".name.toSlice(ip),
12391 try self.genExternSymbolRef(.call, lib_name, decl_name);12372 ),
12392 },
12393 else => return self.fail("TODO implement calling bitcasted functions", .{}),12373 else => return self.fail("TODO implement calling bitcasted functions", .{}),
12394 }12374 }
12395 } else {12375 } else {
12396 assert(self.typeOf(callee).zigTypeTag(mod) == .Pointer);12376 assert(self.typeOf(callee).zigTypeTag(zcu) == .Pointer);
12397 try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }, .{});12377 try self.genSetReg(.rax, Type.usize, .{ .air_ref = callee }, .{});
12398 try self.asmRegister(.{ ._, .call }, .rax);12378 try self.asmRegister(.{ ._, .call }, .rax);
12399 },12379 },
...@@ -12919,13 +12899,13 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {...@@ -12919,13 +12899,13 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
1291912899
12920fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {12900fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
12921 const pt = self.pt;12901 const pt = self.pt;
12922 const mod = pt.zcu;
12923 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;12902 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1292412903
12925 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);12904 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
12926 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);12905 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
12927 defer self.register_manager.unlockReg(addr_lock);12906 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
12930 try self.spillEflagsIfOccupied();12910 try self.spillEflagsIfOccupied();
1293112911
...@@ -15273,7 +15253,7 @@ fn genExternSymbolRef(...@@ -15273,7 +15253,7 @@ fn genExternSymbolRef(
15273 callee: []const u8,15253 callee: []const u8,
15274) InnerError!void {15254) InnerError!void {
15275 const atom_index = try self.owner.getSymbolIndex(self);15255 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| {
15277 _ = try self.addInst(.{15257 _ = try self.addInst(.{
15278 .tag = tag,15258 .tag = tag,
15279 .ops = .extern_fn_reloc,15259 .ops = .extern_fn_reloc,
...@@ -15282,7 +15262,7 @@ fn genExternSymbolRef(...@@ -15282,7 +15262,7 @@ fn genExternSymbolRef(
15282 .sym_index = try elf_file.getGlobalSymbol(callee, lib),15262 .sym_index = try elf_file.getGlobalSymbol(callee, lib),
15283 } },15263 } },
15284 });15264 });
15285 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {15265 } else if (self.bin_file.cast(.coff)) |coff_file| {
15286 const global_index = try coff_file.getGlobalSymbol(callee, lib);15266 const global_index = try coff_file.getGlobalSymbol(callee, lib);
15287 _ = try self.addInst(.{15267 _ = try self.addInst(.{
15288 .tag = .mov,15268 .tag = .mov,
...@@ -15300,7 +15280,7 @@ fn genExternSymbolRef(...@@ -15300,7 +15280,7 @@ fn genExternSymbolRef(
15300 .call => try self.asmRegister(.{ ._, .call }, .rax),15280 .call => try self.asmRegister(.{ ._, .call }, .rax),
15301 else => unreachable,15281 else => unreachable,
15302 }15282 }
15303 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {15283 } else if (self.bin_file.cast(.macho)) |macho_file| {
15304 _ = try self.addInst(.{15284 _ = try self.addInst(.{
15305 .tag = .call,15285 .tag = .call,
15306 .ops = .extern_fn_reloc,15286 .ops = .extern_fn_reloc,
...@@ -15319,7 +15299,7 @@ fn genLazySymbolRef(...@@ -15319,7 +15299,7 @@ fn genLazySymbolRef(
15319 lazy_sym: link.File.LazySymbol,15299 lazy_sym: link.File.LazySymbol,
15320) InnerError!void {15300) InnerError!void {
15321 const pt = self.pt;15301 const pt = self.pt;
15322 if (self.bin_file.cast(link.File.Elf)) |elf_file| {15302 if (self.bin_file.cast(.elf)) |elf_file| {
15323 const zo = elf_file.zigObjectPtr().?;15303 const zo = elf_file.zigObjectPtr().?;
15324 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|15304 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
15325 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15305 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
...@@ -15355,7 +15335,7 @@ fn genLazySymbolRef(...@@ -15355,7 +15335,7 @@ fn genLazySymbolRef(
15355 else => unreachable,15335 else => unreachable,
15356 }15336 }
15357 }15337 }
15358 } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| {15338 } else if (self.bin_file.cast(.plan9)) |p9_file| {
15359 const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|15339 const atom_index = p9_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
15360 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15340 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15361 var atom = p9_file.getAtom(atom_index);15341 var atom = p9_file.getAtom(atom_index);
...@@ -15382,7 +15362,7 @@ fn genLazySymbolRef(...@@ -15382,7 +15362,7 @@ fn genLazySymbolRef(
15382 ),15362 ),
15383 else => unreachable,15363 else => unreachable,
15384 }15364 }
15385 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {15365 } else if (self.bin_file.cast(.coff)) |coff_file| {
15386 const atom_index = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|15366 const atom_index = coff_file.getOrCreateAtomForLazySymbol(pt, lazy_sym) catch |err|
15387 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15367 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15388 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;15368 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
...@@ -15396,7 +15376,7 @@ fn genLazySymbolRef(...@@ -15396,7 +15376,7 @@ fn genLazySymbolRef(
15396 .call => try self.asmRegister(.{ ._, .call }, reg),15376 .call => try self.asmRegister(.{ ._, .call }, reg),
15397 else => unreachable,15377 else => unreachable,
15398 }15378 }
15399 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {15379 } else if (self.bin_file.cast(.macho)) |macho_file| {
15400 const zo = macho_file.getZigObject().?;15380 const zo = macho_file.getZigObject().?;
15401 const sym_index = zo.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|15381 const sym_index = zo.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
15402 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15382 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
...@@ -16361,7 +16341,6 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {...@@ -16361,7 +16341,6 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
1636116341
16362fn airTagName(self: *Self, inst: Air.Inst.Index) !void {16342fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
16363 const pt = self.pt;16343 const pt = self.pt;
16364 const mod = pt.zcu;
16365 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;16344 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
16366 const inst_ty = self.typeOfIndex(inst);16345 const inst_ty = self.typeOfIndex(inst);
16367 const enum_ty = self.typeOf(un_op);16346 const enum_ty = self.typeOf(un_op);
...@@ -16393,18 +16372,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16393,18 +16372,13 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
16393 const operand = try self.resolveInst(un_op);16372 const operand = try self.resolveInst(un_op);
16394 try self.genSetReg(param_regs[1], enum_ty, operand, .{});16373 try self.genSetReg(param_regs[1], enum_ty, operand, .{});
1639516374
16396 try self.genLazySymbolRef(16375 const enum_lazy_sym: link.File.LazySymbol = .{ .kind = .code, .ty = enum_ty.toIntern() };
16397 .call,16376 try self.genLazySymbolRef(.call, .rax, enum_lazy_sym);
16398 .rax,
16399 link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(mod), mod),
16400 );
1640116377
16402 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });16378 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
16403}16379}
1640416380
16405fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {16381fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16406 const pt = self.pt;
16407 const mod = pt.zcu;
16408 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;16382 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1640916383
16410 const err_ty = self.typeOf(un_op);16384 const err_ty = self.typeOf(un_op);
...@@ -16416,7 +16390,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16416,7 +16390,8 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16416 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);16390 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
16417 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);16391 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
16418 defer self.register_manager.unlockReg(addr_lock);16392 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
16421 const start_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);16396 const start_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
16422 const start_lock = self.register_manager.lockRegAssumeUnused(start_reg);16397 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...@@ -18808,7 +18783,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
1880818783
18809fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {18784fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
18810 const pt = self.pt;18785 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.*)) {
18812 .mcv => |mcv| switch (mcv) {18787 .mcv => |mcv| switch (mcv) {
18813 .none => .none,18788 .none => .none,
18814 .undef => .undef,18789 .undef => .undef,
src/arch/x86_64/Emit.zig+11-11
...@@ -40,7 +40,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -40,7 +40,7 @@ pub fn emitMir(emit: *Emit) Error!void {
40 .offset = end_offset - 4,40 .offset = end_offset - 4,
41 .length = @intCast(end_offset - start_offset),41 .length = @intCast(end_offset - start_offset),
42 }),42 }),
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| {
44 // Add relocation to the decl.44 // Add relocation to the decl.
45 const zo = elf_file.zigObjectPtr().?;45 const zo = elf_file.zigObjectPtr().?;
46 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;46 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
...@@ -50,7 +50,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -50,7 +50,7 @@ pub fn emitMir(emit: *Emit) Error!void {
50 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,50 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
51 .r_addend = -4,51 .r_addend = -4,
52 });52 });
53 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {53 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
54 // Add relocation to the decl.54 // Add relocation to the decl.
55 const zo = macho_file.getZigObject().?;55 const zo = macho_file.getZigObject().?;
56 const atom = zo.symbols.items[symbol.atom_index].getAtom(macho_file).?;56 const atom = zo.symbols.items[symbol.atom_index].getAtom(macho_file).?;
...@@ -67,7 +67,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -67,7 +67,7 @@ pub fn emitMir(emit: *Emit) Error!void {
67 .symbolnum = @intCast(symbol.sym_index),67 .symbolnum = @intCast(symbol.sym_index),
68 },68 },
69 });69 });
70 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {70 } else if (emit.lower.bin_file.cast(.coff)) |coff_file| {
71 // Add relocation to the decl.71 // Add relocation to the decl.
72 const atom_index = coff_file.getAtomIndexForSymbol(72 const atom_index = coff_file.getAtomIndexForSymbol(
73 .{ .sym_index = symbol.atom_index, .file = null },73 .{ .sym_index = symbol.atom_index, .file = null },
...@@ -88,7 +88,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -88,7 +88,7 @@ pub fn emitMir(emit: *Emit) Error!void {
88 @tagName(emit.lower.bin_file.tag),88 @tagName(emit.lower.bin_file.tag),
89 }),89 }),
90 .linker_tlsld => |data| {90 .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).?;
92 const zo = elf_file.zigObjectPtr().?;92 const zo = elf_file.zigObjectPtr().?;
93 const atom = zo.symbol(data.atom_index).atom(elf_file).?;93 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
94 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);94 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
...@@ -99,7 +99,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -99,7 +99,7 @@ pub fn emitMir(emit: *Emit) Error!void {
99 });99 });
100 },100 },
101 .linker_dtpoff => |data| {101 .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).?;
103 const zo = elf_file.zigObjectPtr().?;103 const zo = elf_file.zigObjectPtr().?;
104 const atom = zo.symbol(data.atom_index).atom(elf_file).?;104 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
105 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);105 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
...@@ -109,7 +109,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -109,7 +109,7 @@ pub fn emitMir(emit: *Emit) Error!void {
109 .r_addend = 0,109 .r_addend = 0,
110 });110 });
111 },111 },
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| {
113 const is_obj_or_static_lib = switch (emit.lower.output_mode) {113 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
114 .Exe => false,114 .Exe => false,
115 .Obj => true,115 .Obj => true,
...@@ -157,7 +157,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -157,7 +157,7 @@ pub fn emitMir(emit: *Emit) Error!void {
157 });157 });
158 }158 }
159 }159 }
160 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {160 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
161 const is_obj_or_static_lib = switch (emit.lower.output_mode) {161 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
162 .Exe => false,162 .Exe => false,
163 .Obj => true,163 .Obj => true,
...@@ -196,11 +196,11 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -196,11 +196,11 @@ pub fn emitMir(emit: *Emit) Error!void {
196 .linker_got,196 .linker_got,
197 .linker_direct,197 .linker_direct,
198 .linker_import,198 .linker_import,
199 => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {199 => |symbol| if (emit.lower.bin_file.cast(.elf)) |_| {
200 unreachable;200 unreachable;
201 } else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {201 } else if (emit.lower.bin_file.cast(.macho)) |_| {
202 unreachable;202 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| {
204 const atom_index = coff_file.getAtomIndexForSymbol(.{204 const atom_index = coff_file.getAtomIndexForSymbol(.{
205 .sym_index = symbol.atom_index,205 .sym_index = symbol.atom_index,
206 .file = null,206 .file = null,
...@@ -222,7 +222,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -222,7 +222,7 @@ pub fn emitMir(emit: *Emit) Error!void {
222 .pcrel = true,222 .pcrel = true,
223 .length = 2,223 .length = 2,
224 });224 });
225 } else if (emit.lower.bin_file.cast(link.File.Plan9)) |p9_file| {225 } else if (emit.lower.bin_file.cast(.plan9)) |p9_file| {
226 const atom_index = symbol.atom_index;226 const atom_index = symbol.atom_index;
227 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_direct227 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
228 .target = symbol.sym_index, // we set sym_index to just be the atom index228 .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)...@@ -348,7 +348,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
348 assert(mem_op.sib.disp == 0);348 assert(mem_op.sib.disp == 0);
349 assert(mem_op.sib.scale_index.scale == 0);349 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| {
352 const zo = elf_file.zigObjectPtr().?;352 const zo = elf_file.zigObjectPtr().?;
353 const elf_sym = zo.symbol(sym.sym_index);353 const elf_sym = zo.symbol(sym.sym_index);
354354
...@@ -424,7 +424,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)...@@ -424,7 +424,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
424 },424 },
425 else => unreachable,425 else => unreachable,
426 };426 };
427 } else if (lower.bin_file.cast(link.File.MachO)) |macho_file| {427 } else if (lower.bin_file.cast(.macho)) |macho_file| {
428 const zo = macho_file.getZigObject().?;428 const zo = macho_file.getZigObject().?;
429 const macho_sym = zo.symbols.items[sym.sym_index];429 const macho_sym = zo.symbols.items[sym.sym_index];
430430
src/codegen.zig+71-132
...@@ -17,7 +17,7 @@ const ErrorMsg = Zcu.ErrorMsg;...@@ -17,7 +17,7 @@ const ErrorMsg = Zcu.ErrorMsg;
17const InternPool = @import("InternPool.zig");17const InternPool = @import("InternPool.zig");
18const Liveness = @import("Liveness.zig");18const Liveness = @import("Liveness.zig");
19const Zcu = @import("Zcu.zig");19const Zcu = @import("Zcu.zig");
20const Target = std.Target;20
21const Type = @import("Type.zig");21const Type = @import("Type.zig");
22const Value = @import("Value.zig");22const Value = @import("Value.zig");
23const Zir = std.zig.Zir;23const Zir = std.zig.Zir;
...@@ -26,7 +26,7 @@ const dev = @import("dev.zig");...@@ -26,7 +26,7 @@ const dev = @import("dev.zig");
2626
27pub const Result = union(enum) {27pub const Result = union(enum) {
28 /// The `code` parameter passed to `generateSymbol` has the value ok.28 /// The `code` parameter passed to `generateSymbol` has the value ok.
29 ok: void,29 ok,
3030
31 /// There was a codegen error.31 /// There was a codegen error.
32 fail: *ErrorMsg,32 fail: *ErrorMsg,
...@@ -39,7 +39,7 @@ pub const CodeGenError = error{...@@ -39,7 +39,7 @@ pub const CodeGenError = error{
39};39};
4040
41pub const DebugInfoOutput = union(enum) {41pub const DebugInfoOutput = union(enum) {
42 dwarf: *link.File.Dwarf.DeclState,42 dwarf: *link.File.Dwarf.NavState,
43 plan9: *link.File.Plan9.DebugInfoOutput,43 plan9: *link.File.Plan9.DebugInfoOutput,
44 none,44 none,
45};45};
...@@ -73,9 +73,7 @@ pub fn generateFunction(...@@ -73,9 +73,7 @@ pub fn generateFunction(
73) CodeGenError!Result {73) CodeGenError!Result {
74 const zcu = pt.zcu;74 const zcu = pt.zcu;
75 const func = zcu.funcInfo(func_index);75 const func = zcu.funcInfo(func_index);
76 const decl = zcu.declPtr(func.owner_decl);76 const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result;
77 const namespace = zcu.namespacePtr(decl.src_namespace);
78 const target = namespace.fileScope(zcu).mod.resolved_target.result;
79 switch (target_util.zigBackend(target, false)) {77 switch (target_util.zigBackend(target, false)) {
80 else => unreachable,78 else => unreachable,
81 inline .stage2_aarch64,79 inline .stage2_aarch64,
...@@ -100,10 +98,8 @@ pub fn generateLazyFunction(...@@ -100,10 +98,8 @@ pub fn generateLazyFunction(
100 debug_output: DebugInfoOutput,98 debug_output: DebugInfoOutput,
101) CodeGenError!Result {99) CodeGenError!Result {
102 const zcu = pt.zcu;100 const zcu = pt.zcu;
103 const decl_index = lazy_sym.ty.getOwnerDecl(zcu);101 const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(&zcu.intern_pool).file;
104 const decl = zcu.declPtr(decl_index);102 const target = zcu.fileByIndex(file).mod.resolved_target.result;
105 const namespace = zcu.namespacePtr(decl.src_namespace);
106 const target = namespace.fileScope(zcu).mod.resolved_target.result;
107 switch (target_util.zigBackend(target, false)) {103 switch (target_util.zigBackend(target, false)) {
108 else => unreachable,104 else => unreachable,
109 inline .stage2_x86_64,105 inline .stage2_x86_64,
...@@ -115,7 +111,7 @@ pub fn generateLazyFunction(...@@ -115,7 +111,7 @@ pub fn generateLazyFunction(
115 }111 }
116}112}
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 {
119 _ = target;115 _ = target;
120 const bits = @typeInfo(F).Float.bits;116 const bits = @typeInfo(F).Float.bits;
121 const Int = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = bits } });117 const Int = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = bits } });
...@@ -147,7 +143,7 @@ pub fn generateLazySymbol(...@@ -147,7 +143,7 @@ pub fn generateLazySymbol(
147143
148 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{144 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
149 @tagName(lazy_sym.kind),145 @tagName(lazy_sym.kind),
150 lazy_sym.ty.fmt(pt),146 Type.fromInterned(lazy_sym.ty).fmt(pt),
151 });147 });
152148
153 if (lazy_sym.kind == .code) {149 if (lazy_sym.kind == .code) {
...@@ -155,7 +151,7 @@ pub fn generateLazySymbol(...@@ -155,7 +151,7 @@ pub fn generateLazySymbol(
155 return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, code, debug_output);151 return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, code, debug_output);
156 }152 }
157153
158 if (lazy_sym.ty.isAnyError(pt.zcu)) {154 if (lazy_sym.ty == .anyerror_type) {
159 alignment.* = .@"4";155 alignment.* = .@"4";
160 const err_names = ip.global_error_set.getNamesFromMainThread();156 const err_names = ip.global_error_set.getNamesFromMainThread();
161 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);157 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);
...@@ -171,9 +167,10 @@ pub fn generateLazySymbol(...@@ -171,9 +167,10 @@ pub fn generateLazySymbol(
171 }167 }
172 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);168 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);
173 return Result.ok;169 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) {
175 alignment.* = .@"1";171 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);
177 for (0..tag_names.len) |tag_index| {174 for (0..tag_names.len) |tag_index| {
178 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);175 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
179 try code.ensureUnusedCapacity(tag_name.len + 1);176 try code.ensureUnusedCapacity(tag_name.len + 1);
...@@ -185,7 +182,7 @@ pub fn generateLazySymbol(...@@ -185,7 +182,7 @@ pub fn generateLazySymbol(
185 gpa,182 gpa,
186 src_loc,183 src_loc,
187 "TODO implement generateLazySymbol for {s} {}",184 "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) },
189 ) };186 ) };
190}187}
191188
...@@ -251,7 +248,7 @@ pub fn generateSymbol(...@@ -251,7 +248,7 @@ pub fn generateSymbol(
251 }),248 }),
252 },249 },
253 .variable,250 .variable,
254 .extern_func,251 .@"extern",
255 .func,252 .func,
256 .enum_literal,253 .enum_literal,
257 .empty_enum_value,254 .empty_enum_value,
...@@ -651,8 +648,8 @@ fn lowerPtr(...@@ -651,8 +648,8 @@ fn lowerPtr(
651 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;648 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
652 const offset: u64 = prev_offset + ptr.byte_offset;649 const offset: u64 = prev_offset + ptr.byte_offset;
653 return switch (ptr.base_addr) {650 return switch (ptr.base_addr) {
654 .decl => |decl| try lowerDeclRef(bin_file, pt, src_loc, decl, code, debug_output, reloc_info, offset),651 .nav => |nav| try lowerNavRef(bin_file, pt, src_loc, nav, code, debug_output, reloc_info, offset),
655 .anon_decl => |ad| try lowerAnonDeclRef(bin_file, pt, src_loc, ad, code, debug_output, reloc_info, offset),652 .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, code, debug_output, reloc_info, offset),
656 .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, debug_output, reloc_info),653 .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, debug_output, reloc_info),
657 .eu_payload => |eu_ptr| try lowerPtr(654 .eu_payload => |eu_ptr| try lowerPtr(
658 bin_file,655 bin_file,
...@@ -705,11 +702,11 @@ const RelocInfo = struct {...@@ -705,11 +702,11 @@ const RelocInfo = struct {
705 parent_atom_index: u32,702 parent_atom_index: u32,
706};703};
707704
708fn lowerAnonDeclRef(705fn lowerUavRef(
709 lf: *link.File,706 lf: *link.File,
710 pt: Zcu.PerThread,707 pt: Zcu.PerThread,
711 src_loc: Zcu.LazySrcLoc,708 src_loc: Zcu.LazySrcLoc,
712 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,709 uav: InternPool.Key.Ptr.BaseAddr.Uav,
713 code: *std.ArrayList(u8),710 code: *std.ArrayList(u8),
714 debug_output: DebugInfoOutput,711 debug_output: DebugInfoOutput,
715 reloc_info: RelocInfo,712 reloc_info: RelocInfo,
...@@ -720,23 +717,23 @@ fn lowerAnonDeclRef(...@@ -720,23 +717,23 @@ fn lowerAnonDeclRef(
720 const target = lf.comp.root_mod.resolved_target.result;717 const target = lf.comp.root_mod.resolved_target.result;
721718
722 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);719 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
723 const decl_val = anon_decl.val;720 const uav_val = uav.val;
724 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));721 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));
725 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(pt)});722 log.debug("lowerUavRef: ty = {}", .{uav_ty.fmt(pt)});
726 const is_fn_body = decl_ty.zigTypeTag(pt.zcu) == .Fn;723 const is_fn_body = uav_ty.zigTypeTag(pt.zcu) == .Fn;
727 if (!is_fn_body and !decl_ty.hasRuntimeBits(pt)) {724 if (!is_fn_body and !uav_ty.hasRuntimeBits(pt)) {
728 try code.appendNTimes(0xaa, ptr_width_bytes);725 try code.appendNTimes(0xaa, ptr_width_bytes);
729 return Result.ok;726 return Result.ok;
730 }727 }
731728
732 const decl_align = ip.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;729 const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
733 const res = try lf.lowerAnonDecl(pt, decl_val, decl_align, src_loc);730 const res = try lf.lowerUav(pt, uav_val, uav_align, src_loc);
734 switch (res) {731 switch (res) {
735 .ok => {},732 .mcv => {},
736 .fail => |em| return .{ .fail = em },733 .fail => |em| return .{ .fail = em },
737 }734 }
738735
739 const vaddr = try lf.getAnonDeclVAddr(decl_val, .{736 const vaddr = try lf.getUavVAddr(uav_val, .{
740 .parent_atom_index = reloc_info.parent_atom_index,737 .parent_atom_index = reloc_info.parent_atom_index,
741 .offset = code.items.len,738 .offset = code.items.len,
742 .addend = @intCast(offset),739 .addend = @intCast(offset),
...@@ -752,11 +749,11 @@ fn lowerAnonDeclRef(...@@ -752,11 +749,11 @@ fn lowerAnonDeclRef(
752 return Result.ok;749 return Result.ok;
753}750}
754751
755fn lowerDeclRef(752fn lowerNavRef(
756 lf: *link.File,753 lf: *link.File,
757 pt: Zcu.PerThread,754 pt: Zcu.PerThread,
758 src_loc: Zcu.LazySrcLoc,755 src_loc: Zcu.LazySrcLoc,
759 decl_index: InternPool.DeclIndex,756 nav_index: InternPool.Nav.Index,
760 code: *std.ArrayList(u8),757 code: *std.ArrayList(u8),
761 debug_output: DebugInfoOutput,758 debug_output: DebugInfoOutput,
762 reloc_info: RelocInfo,759 reloc_info: RelocInfo,
...@@ -765,18 +762,18 @@ fn lowerDeclRef(...@@ -765,18 +762,18 @@ fn lowerDeclRef(
765 _ = src_loc;762 _ = src_loc;
766 _ = debug_output;763 _ = debug_output;
767 const zcu = pt.zcu;764 const zcu = pt.zcu;
768 const decl = zcu.declPtr(decl_index);765 const ip = &zcu.intern_pool;
769 const namespace = zcu.namespacePtr(decl.src_namespace);766 const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
770 const target = namespace.fileScope(zcu).mod.resolved_target.result;
771767
772 const ptr_width = target.ptrBitWidth();768 const ptr_width = target.ptrBitWidth();
773 const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn;769 const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
774 if (!is_fn_body and !decl.typeOf(zcu).hasRuntimeBits(pt)) {770 const is_fn_body = nav_ty.zigTypeTag(zcu) == .Fn;
771 if (!is_fn_body and !nav_ty.hasRuntimeBits(pt)) {
775 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));772 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));
776 return Result.ok;773 return Result.ok;
777 }774 }
778775
779 const vaddr = try lf.getDeclVAddr(pt, decl_index, .{776 const vaddr = try lf.getNavVAddr(pt, nav_index, .{
780 .parent_atom_index = reloc_info.parent_atom_index,777 .parent_atom_index = reloc_info.parent_atom_index,
781 .offset = code.items.len,778 .offset = code.items.len,
782 .addend = @intCast(offset),779 .addend = @intCast(offset),
...@@ -848,34 +845,21 @@ pub const GenResult = union(enum) {...@@ -848,34 +845,21 @@ pub const GenResult = union(enum) {
848 }845 }
849};846};
850847
851fn genDeclRef(848fn genNavRef(
852 lf: *link.File,849 lf: *link.File,
853 pt: Zcu.PerThread,850 pt: Zcu.PerThread,
854 src_loc: Zcu.LazySrcLoc,851 src_loc: Zcu.LazySrcLoc,
855 val: Value,852 val: Value,
856 ptr_decl_index: InternPool.DeclIndex,853 ref_nav_index: InternPool.Nav.Index,
854 target: std.Target,
857) CodeGenError!GenResult {855) CodeGenError!GenResult {
858 const zcu = pt.zcu;856 const zcu = pt.zcu;
859 const ip = &zcu.intern_pool;857 const ip = &zcu.intern_pool;
860 const ty = val.typeOf(zcu);858 const ty = val.typeOf(zcu);
861 log.debug("genDeclRef: val = {}", .{val.fmtValue(pt)});859 log.debug("genNavRef: 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);
876860
877 if (!decl.typeOf(zcu).isFnOrHasRuntimeBitsIgnoreComptime(pt)) {861 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
878 const imm: u64 = switch (ptr_bytes) {862 const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
879 1 => 0xaa,863 1 => 0xaa,
880 2 => 0xaaaa,864 2 => 0xaaaa,
881 4 => 0xaaaaaaaa,865 4 => 0xaaaaaaaa,
...@@ -900,96 +884,56 @@ fn genDeclRef(...@@ -900,96 +884,56 @@ fn genDeclRef(
900 }884 }
901 }885 }
902886
903 const decl_namespace = zcu.namespacePtr(decl.src_namespace);887 const nav_index, const is_extern, const lib_name, const is_threadlocal = switch (ip.indexToKey(zcu.navValue(ref_nav_index).toIntern())) {
904 const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded;888 .func => |func| .{ func.owner_nav, false, .none, false },
905 const is_threadlocal = val.isPtrToThreadLocal(zcu) and !single_threaded;889 .variable => |variable| .{ variable.owner_nav, false, variable.lib_name, variable.is_threadlocal },
906 const is_extern = decl.isExtern(zcu);890 .@"extern" => |@"extern"| .{ @"extern".owner_nav, true, @"extern".lib_name, @"extern".is_threadlocal },
907891 else => .{ ref_nav_index, false, .none, false },
908 if (lf.cast(link.File.Elf)) |elf_file| {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| {
909 const zo = elf_file.zigObjectPtr().?;896 const zo = elf_file.zigObjectPtr().?;
910 if (is_extern) {897 if (is_extern) {
911 const name = decl.name.toSlice(ip);
912 // TODO audit this898 // TODO audit this
913 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;899 const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
914 const sym_index = try elf_file.getGlobalSymbol(name, lib_name);
915 zo.symbol(sym_index).flags.needs_got = true;900 zo.symbol(sym_index).flags.needs_got = true;
916 return GenResult.mcv(.{ .load_symbol = sym_index });901 return GenResult.mcv(.{ .load_symbol = sym_index });
917 }902 }
918 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, decl_index);903 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);
919 if (is_threadlocal) {904 if (!single_threaded and is_threadlocal) {
920 return GenResult.mcv(.{ .load_tlv = sym_index });905 return GenResult.mcv(.{ .load_tlv = sym_index });
921 }906 }
922 return GenResult.mcv(.{ .load_symbol = sym_index });907 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| {
924 const zo = macho_file.getZigObject().?;909 const zo = macho_file.getZigObject().?;
925 if (is_extern) {910 if (is_extern) {
926 const name = decl.name.toSlice(ip);911 const sym_index = try macho_file.getGlobalSymbol(name.toSlice(ip), lib_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);
929 zo.symbols.items[sym_index].setSectionFlags(.{ .needs_got = true });912 zo.symbols.items[sym_index].setSectionFlags(.{ .needs_got = true });
930 return GenResult.mcv(.{ .load_symbol = sym_index });913 return GenResult.mcv(.{ .load_symbol = sym_index });
931 }914 }
932 const sym_index = try zo.getOrCreateMetadataForDecl(macho_file, decl_index);915 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
933 const sym = zo.symbols.items[sym_index];916 const sym = zo.symbols.items[sym_index];
934 if (is_threadlocal) {917 if (!single_threaded and is_threadlocal) {
935 return GenResult.mcv(.{ .load_tlv = sym.nlist_idx });918 return GenResult.mcv(.{ .load_tlv = sym.nlist_idx });
936 }919 }
937 return GenResult.mcv(.{ .load_symbol = sym.nlist_idx });920 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| {
939 if (is_extern) {922 if (is_extern) {
940 const name = decl.name.toSlice(ip);
941 // TODO audit this923 // TODO audit this
942 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;924 const global_index = try coff_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
943 const global_index = try coff_file.getGlobalSymbol(name, lib_name);
944 try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT925 try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT
945 return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index });926 return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index });
946 }927 }
947 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);928 const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
948 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;929 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
949 return GenResult.mcv(.{ .load_got = sym_index });930 return GenResult.mcv(.{ .load_got = sym_index });
950 } else if (lf.cast(link.File.Plan9)) |p9| {931 } else if (lf.cast(.plan9)) |p9| {
951 const atom_index = try p9.seeDecl(decl_index);932 const atom_index = try p9.seeNav(pt, nav_index);
952 const atom = p9.getAtom(atom_index);933 const atom = p9.getAtom(atom_index);
953 return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) });934 return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) });
954 } else {935 } else {
955 return GenResult.fail(gpa, src_loc, "TODO genDeclRef for target {}", .{target});936 return GenResult.fail(gpa, src_loc, "TODO genNavRef 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", .{}),
993 }937 }
994}938}
995939
...@@ -998,7 +942,7 @@ pub fn genTypedValue(...@@ -998,7 +942,7 @@ pub fn genTypedValue(
998 pt: Zcu.PerThread,942 pt: Zcu.PerThread,
999 src_loc: Zcu.LazySrcLoc,943 src_loc: Zcu.LazySrcLoc,
1000 val: Value,944 val: Value,
1001 owner_decl_index: InternPool.DeclIndex,945 target: std.Target,
1002) CodeGenError!GenResult {946) CodeGenError!GenResult {
1003 const zcu = pt.zcu;947 const zcu = pt.zcu;
1004 const ip = &zcu.intern_pool;948 const ip = &zcu.intern_pool;
...@@ -1010,14 +954,9 @@ pub fn genTypedValue(...@@ -1010,14 +954,9 @@ pub fn genTypedValue(
1010 return GenResult.mcv(.undef);954 return GenResult.mcv(.undef);
1011 }955 }
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
1018 if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) {957 if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) {
1019 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {958 .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),
1021 else => {},960 else => {},
1022 },961 },
1023 else => {},962 else => {},
...@@ -1042,7 +981,7 @@ pub fn genTypedValue(...@@ -1042,7 +981,7 @@ pub fn genTypedValue(
1042 },981 },
1043 .Int => {982 .Int => {
1044 const info = ty.intInfo(zcu);983 const info = ty.intInfo(zcu);
1045 if (info.bits <= ptr_bits) {984 if (info.bits <= target.ptrBitWidth()) {
1046 const unsigned: u64 = switch (info.signedness) {985 const unsigned: u64 = switch (info.signedness) {
1047 .signed => @bitCast(val.toSignedInt(pt)),986 .signed => @bitCast(val.toSignedInt(pt)),
1048 .unsigned => val.toUnsignedInt(pt),987 .unsigned => val.toUnsignedInt(pt),
...@@ -1060,7 +999,7 @@ pub fn genTypedValue(...@@ -1060,7 +999,7 @@ pub fn genTypedValue(
1060 pt,999 pt,
1061 src_loc,1000 src_loc,
1062 val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),1001 val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),
1063 owner_decl_index,1002 target,
1064 );1003 );
1065 } else if (ty.abiSize(pt) == 1) {1004 } else if (ty.abiSize(pt) == 1) {
1066 return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) });1005 return GenResult.mcv(.{ .immediate = @intFromBool(!val.isNull(zcu)) });
...@@ -1073,7 +1012,7 @@ pub fn genTypedValue(...@@ -1073,7 +1012,7 @@ pub fn genTypedValue(
1073 pt,1012 pt,
1074 src_loc,1013 src_loc,
1075 Value.fromInterned(enum_tag.int),1014 Value.fromInterned(enum_tag.int),
1076 owner_decl_index,1015 target,
1077 );1016 );
1078 },1017 },
1079 .ErrorSet => {1018 .ErrorSet => {
...@@ -1096,14 +1035,14 @@ pub fn genTypedValue(...@@ -1096,14 +1035,14 @@ pub fn genTypedValue(
1096 .ty = err_type.toIntern(),1035 .ty = err_type.toIntern(),
1097 .name = err_name,1036 .name = err_name,
1098 } })),1037 } })),
1099 owner_decl_index,1038 target,
1100 ),1039 ),
1101 .payload => return genTypedValue(1040 .payload => return genTypedValue(
1102 lf,1041 lf,
1103 pt,1042 pt,
1104 src_loc,1043 src_loc,
1105 try pt.intValue(err_int_ty, 0),1044 try pt.intValue(err_int_ty, 0),
1106 owner_decl_index,1045 target,
1107 ),1046 ),
1108 }1047 }
1109 }1048 }
...@@ -1121,7 +1060,7 @@ pub fn genTypedValue(...@@ -1121,7 +1060,7 @@ pub fn genTypedValue(
1121 else => {},1060 else => {},
1122 }1061 }
11231062
1124 return genUnnamedConst(lf, pt, src_loc, val, owner_decl_index);1063 return lf.lowerUav(pt, val.toIntern(), .none, src_loc);
1125}1064}
11261065
1127pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {1066pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 {
src/codegen/c.zig+251-229
...@@ -38,8 +38,8 @@ pub const CValue = union(enum) {...@@ -38,8 +38,8 @@ pub const CValue = union(enum) {
38 /// Index into a tuple's fields38 /// Index into a tuple's fields
39 field: usize,39 field: usize,
40 /// By-value40 /// By-value
41 decl: InternPool.DeclIndex,41 nav: InternPool.Nav.Index,
42 decl_ref: InternPool.DeclIndex,42 nav_ref: InternPool.Nav.Index,
43 /// An undefined value (cannot be dereferenced)43 /// An undefined value (cannot be dereferenced)
44 undef: Type,44 undef: Type,
45 /// Rendered as an identifier (using fmtIdent)45 /// Rendered as an identifier (using fmtIdent)
...@@ -58,19 +58,12 @@ const BlockData = struct {...@@ -58,19 +58,12 @@ const BlockData = struct {
58pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);58pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);
5959
60pub const LazyFnKey = union(enum) {60pub const LazyFnKey = union(enum) {
61 tag_name: InternPool.DeclIndex,61 tag_name: InternPool.Index,
62 never_tail: InternPool.DeclIndex,62 never_tail: InternPool.Nav.Index,
63 never_inline: InternPool.DeclIndex,63 never_inline: InternPool.Nav.Index,
64};64};
65pub const LazyFnValue = struct {65pub const LazyFnValue = struct {
66 fn_name: CType.Pool.String,66 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 };
74};67};
75pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue);68pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue);
7669
...@@ -498,10 +491,11 @@ pub const Function = struct {...@@ -498,10 +491,11 @@ pub const Function = struct {
498 return f.object.dg.fmtIntLiteral(val, .Other);491 return f.object.dg.fmtIntLiteral(val, .Other);
499 }492 }
500493
501 fn getLazyFnName(f: *Function, key: LazyFnKey, data: LazyFnValue.Data) ![]const u8 {494 fn getLazyFnName(f: *Function, key: LazyFnKey) ![]const u8 {
502 const gpa = f.object.dg.gpa;495 const gpa = f.object.dg.gpa;
503 const pt = f.object.dg.pt;496 const pt = f.object.dg.pt;
504 const zcu = pt.zcu;497 const zcu = pt.zcu;
498 const ip = &zcu.intern_pool;
505 const ctype_pool = &f.object.dg.ctype_pool;499 const ctype_pool = &f.object.dg.ctype_pool;
506500
507 const gop = try f.lazy_fns.getOrPut(gpa, key);501 const gop = try f.lazy_fns.getOrPut(gpa, key);
...@@ -511,19 +505,19 @@ pub const Function = struct {...@@ -511,19 +505,19 @@ pub const Function = struct {
511 gop.value_ptr.* = .{505 gop.value_ptr.* = .{
512 .fn_name = switch (key) {506 .fn_name = switch (key) {
513 .tag_name,507 .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 }),
514 .never_tail,513 .never_tail,
515 .never_inline,514 .never_inline,
516 => |owner_decl| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{515 => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{
517 @tagName(key),516 @tagName(key),
518 fmtIdent(zcu.declPtr(owner_decl).name.toSlice(&zcu.intern_pool)),517 fmtIdent(ip.getNav(owner_nav).name.toSlice(ip)),
519 @intFromEnum(owner_decl),518 @intFromEnum(owner_nav),
520 }),519 }),
521 },520 },
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 },
527 };521 };
528 }522 }
529 return gop.value_ptr.fn_name.toSlice(ctype_pool).?;523 return gop.value_ptr.fn_name.toSlice(ctype_pool).?;
...@@ -618,12 +612,12 @@ pub const DeclGen = struct {...@@ -618,12 +612,12 @@ pub const DeclGen = struct {
618 scratch: std.ArrayListUnmanaged(u32),612 scratch: std.ArrayListUnmanaged(u32),
619 /// Keeps track of anonymous decls that need to be rendered before this613 /// Keeps track of anonymous decls that need to be rendered before this
620 /// (named) Decl in the output C code.614 /// (named) Decl in the output C code.
621 anon_decl_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.DeclBlock),615 uav_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, C.AvBlock),
622 aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),616 aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
623617
624 pub const Pass = union(enum) {618 pub const Pass = union(enum) {
625 decl: InternPool.DeclIndex,619 nav: InternPool.Nav.Index,
626 anon: InternPool.Index,620 uav: InternPool.Index,
627 flush,621 flush,
628 };622 };
629623
...@@ -634,39 +628,37 @@ pub const DeclGen = struct {...@@ -634,39 +628,37 @@ pub const DeclGen = struct {
634 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {628 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
635 @setCold(true);629 @setCold(true);
636 const zcu = dg.pt.zcu;630 const zcu = dg.pt.zcu;
637 const decl_index = dg.pass.decl;631 const src_loc = zcu.navSrcLoc(dg.pass.nav);
638 const decl = zcu.declPtr(decl_index);
639 const src_loc = decl.navSrcLoc(zcu);
640 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);632 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
641 return error.AnalysisFail;633 return error.AnalysisFail;
642 }634 }
643635
644 fn renderAnonDeclValue(636 fn renderUav(
645 dg: *DeclGen,637 dg: *DeclGen,
646 writer: anytype,638 writer: anytype,
647 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,639 uav: InternPool.Key.Ptr.BaseAddr.Uav,
648 location: ValueRenderLocation,640 location: ValueRenderLocation,
649 ) error{ OutOfMemory, AnalysisFail }!void {641 ) error{ OutOfMemory, AnalysisFail }!void {
650 const pt = dg.pt;642 const pt = dg.pt;
651 const zcu = pt.zcu;643 const zcu = pt.zcu;
652 const ip = &zcu.intern_pool;644 const ip = &zcu.intern_pool;
653 const ctype_pool = &dg.ctype_pool;645 const ctype_pool = &dg.ctype_pool;
654 const decl_val = Value.fromInterned(anon_decl.val);646 const uav_val = Value.fromInterned(uav.val);
655 const decl_ty = decl_val.typeOf(zcu);647 const uav_ty = uav_val.typeOf(zcu);
656648
657 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.649 // 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);650 const ptr_ty = Type.fromInterned(uav.orig_ty);
659 if (ptr_ty.isPtrAtRuntime(zcu) and !decl_ty.isFnOrHasRuntimeBits(pt)) {651 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(pt)) {
660 return dg.writeCValue(writer, .{ .undef = ptr_ty });652 return dg.writeCValue(writer, .{ .undef = ptr_ty });
661 }653 }
662654
663 // Chase function values in order to be able to reference the original function.655 // Chase function values in order to be able to reference the original function.
664 if (decl_val.getFunction(zcu)) |func|656 switch (ip.indexToKey(uav.val)) {
665 return dg.renderDeclValue(writer, func.owner_decl, location);657 .variable => unreachable,
666 if (decl_val.getExternFunc(zcu)) |extern_func|658 .func => |func| return dg.renderNav(writer, func.owner_nav, location),
667 return dg.renderDeclValue(writer, extern_func.decl, location);659 .@"extern" => |@"extern"| return dg.renderNav(writer, @"extern".owner_nav, location),
668660 else => {},
669 assert(decl_val.getVariable(zcu) == null);661 }
670662
671 // We shouldn't cast C function pointers as this is UB (when you call663 // We shouldn't cast C function pointers as this is UB (when you call
672 // them). The analysis until now should ensure that the C function664 // them). The analysis until now should ensure that the C function
...@@ -674,22 +666,22 @@ pub const DeclGen = struct {...@@ -674,22 +666,22 @@ pub const DeclGen = struct {
674 // somewhere and we should let the C compiler tell us about it.666 // somewhere and we should let the C compiler tell us about it.
675 const ptr_ctype = try dg.ctypeFromType(ptr_ty, .complete);667 const ptr_ctype = try dg.ctypeFromType(ptr_ty, .complete);
676 const elem_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;668 const elem_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
677 const decl_ctype = try dg.ctypeFromType(decl_ty, .complete);669 const uav_ctype = try dg.ctypeFromType(uav_ty, .complete);
678 const need_cast = !elem_ctype.eql(decl_ctype) and670 const need_cast = !elem_ctype.eql(uav_ctype) and
679 (elem_ctype.info(ctype_pool) != .function or decl_ctype.info(ctype_pool) != .function);671 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
680 if (need_cast) {672 if (need_cast) {
681 try writer.writeAll("((");673 try writer.writeAll("((");
682 try dg.renderCType(writer, ptr_ctype);674 try dg.renderCType(writer, ptr_ctype);
683 try writer.writeByte(')');675 try writer.writeByte(')');
684 }676 }
685 try writer.writeByte('&');677 try writer.writeByte('&');
686 try renderAnonDeclName(writer, decl_val);678 try renderUavName(writer, uav_val);
687 if (need_cast) try writer.writeByte(')');679 if (need_cast) try writer.writeByte(')');
688680
689 // Indicate that the anon decl should be rendered to the output so that681 // Indicate that the anon decl should be rendered to the output so that
690 // our reference above is not undefined.682 // our reference above is not undefined.
691 const ptr_type = ip.indexToKey(anon_decl.orig_ty).ptr_type;683 const ptr_type = ip.indexToKey(uav.orig_ty).ptr_type;
692 const gop = try dg.anon_decl_deps.getOrPut(dg.gpa, anon_decl.val);684 const gop = try dg.uav_deps.getOrPut(dg.gpa, uav.val);
693 if (!gop.found_existing) gop.value_ptr.* = .{};685 if (!gop.found_existing) gop.value_ptr.* = .{};
694686
695 // Only insert an alignment entry if the alignment is greater than ABI687 // Only insert an alignment entry if the alignment is greater than ABI
...@@ -698,7 +690,7 @@ pub const DeclGen = struct {...@@ -698,7 +690,7 @@ pub const DeclGen = struct {
698 if (explicit_alignment != .none) {690 if (explicit_alignment != .none) {
699 const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(pt);691 const abi_alignment = Type.fromInterned(ptr_type.child).abiAlignment(pt);
700 if (explicit_alignment.order(abi_alignment).compare(.gt)) {692 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);
702 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)694 aligned_gop.value_ptr.* = if (aligned_gop.found_existing)
703 aligned_gop.value_ptr.maxStrict(explicit_alignment)695 aligned_gop.value_ptr.maxStrict(explicit_alignment)
704 else696 else
...@@ -707,47 +699,49 @@ pub const DeclGen = struct {...@@ -707,47 +699,49 @@ pub const DeclGen = struct {
707 }699 }
708 }700 }
709701
710 fn renderDeclValue(702 fn renderNav(
711 dg: *DeclGen,703 dg: *DeclGen,
712 writer: anytype,704 writer: anytype,
713 decl_index: InternPool.DeclIndex,705 nav_index: InternPool.Nav.Index,
714 location: ValueRenderLocation,706 location: ValueRenderLocation,
715 ) error{ OutOfMemory, AnalysisFail }!void {707 ) error{ OutOfMemory, AnalysisFail }!void {
708 _ = location;
716 const pt = dg.pt;709 const pt = dg.pt;
717 const zcu = pt.zcu;710 const zcu = pt.zcu;
711 const ip = &zcu.intern_pool;
718 const ctype_pool = &dg.ctype_pool;712 const ctype_pool = &dg.ctype_pool;
719 const decl = zcu.declPtr(decl_index);713
720 assert(decl.has_tv);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
722 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.722 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
723 const decl_ty = decl.typeOf(zcu);723 const nav_ty = Type.fromInterned(ip.getNav(owner_nav).typeOf(ip));
724 const ptr_ty = try decl.declPtrType(pt);724 const ptr_ty = try pt.navPtrType(owner_nav);
725 if (!decl_ty.isFnOrHasRuntimeBits(pt)) {725 if (!nav_ty.isFnOrHasRuntimeBits(pt)) {
726 return dg.writeCValue(writer, .{ .undef = ptr_ty });726 return dg.writeCValue(writer, .{ .undef = ptr_ty });
727 }727 }
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
735 // We shouldn't cast C function pointers as this is UB (when you call729 // We shouldn't cast C function pointers as this is UB (when you call
736 // them). The analysis until now should ensure that the C function730 // them). The analysis until now should ensure that the C function
737 // pointers are compatible. If they are not, then there is a bug731 // pointers are compatible. If they are not, then there is a bug
738 // somewhere and we should let the C compiler tell us about it.732 // somewhere and we should let the C compiler tell us about it.
739 const ctype = try dg.ctypeFromType(ptr_ty, .complete);733 const ctype = try dg.ctypeFromType(ptr_ty, .complete);
740 const elem_ctype = ctype.info(ctype_pool).pointer.elem_ctype;734 const elem_ctype = ctype.info(ctype_pool).pointer.elem_ctype;
741 const decl_ctype = try dg.ctypeFromType(decl_ty, .complete);735 const nav_ctype = try dg.ctypeFromType(nav_ty, .complete);
742 const need_cast = !elem_ctype.eql(decl_ctype) and736 const need_cast = !elem_ctype.eql(nav_ctype) and
743 (elem_ctype.info(ctype_pool) != .function or decl_ctype.info(ctype_pool) != .function);737 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
744 if (need_cast) {738 if (need_cast) {
745 try writer.writeAll("((");739 try writer.writeAll("((");
746 try dg.renderCType(writer, ctype);740 try dg.renderCType(writer, ctype);
747 try writer.writeByte(')');741 try writer.writeByte(')');
748 }742 }
749 try writer.writeByte('&');743 try writer.writeByte('&');
750 try dg.renderDeclName(writer, decl_index);744 try dg.renderNavName(writer, owner_nav);
751 if (need_cast) try writer.writeByte(')');745 if (need_cast) try writer.writeByte(')');
752 }746 }
753747
...@@ -769,8 +763,8 @@ pub const DeclGen = struct {...@@ -769,8 +763,8 @@ pub const DeclGen = struct {
769 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});763 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});
770 },764 },
771765
772 .decl_ptr => |decl| try dg.renderDeclValue(writer, decl, location),766 .nav_ptr => |nav| try dg.renderNav(writer, nav, location),
773 .anon_decl_ptr => |ad| try dg.renderAnonDeclValue(writer, ad, location),767 .uav_ptr => |uav| try dg.renderUav(writer, uav, location),
774768
775 inline .eu_payload_ptr, .opt_payload_ptr => |info| {769 inline .eu_payload_ptr, .opt_payload_ptr => |info| {
776 try writer.writeAll("&(");770 try writer.writeAll("&(");
...@@ -918,7 +912,7 @@ pub const DeclGen = struct {...@@ -918,7 +912,7 @@ pub const DeclGen = struct {
918 .true => try writer.writeAll("true"),912 .true => try writer.writeAll("true"),
919 },913 },
920 .variable,914 .variable,
921 .extern_func,915 .@"extern",
922 .func,916 .func,
923 .enum_literal,917 .enum_literal,
924 .empty_enum_value,918 .empty_enum_value,
...@@ -1743,7 +1737,7 @@ pub const DeclGen = struct {...@@ -1743,7 +1737,7 @@ pub const DeclGen = struct {
1743 .undef,1737 .undef,
1744 .simple_value,1738 .simple_value,
1745 .variable,1739 .variable,
1746 .extern_func,1740 .@"extern",
1747 .func,1741 .func,
1748 .int,1742 .int,
1749 .err,1743 .err,
...@@ -1758,7 +1752,7 @@ pub const DeclGen = struct {...@@ -1758,7 +1752,7 @@ pub const DeclGen = struct {
1758 .aggregate,1752 .aggregate,
1759 .un,1753 .un,
1760 .memoized_call,1754 .memoized_call,
1761 => unreachable,1755 => unreachable, // values, not types
1762 },1756 },
1763 }1757 }
1764 }1758 }
...@@ -1770,7 +1764,7 @@ pub const DeclGen = struct {...@@ -1770,7 +1764,7 @@ pub const DeclGen = struct {
1770 fn_align: InternPool.Alignment,1764 fn_align: InternPool.Alignment,
1771 kind: CType.Kind,1765 kind: CType.Kind,
1772 name: union(enum) {1766 name: union(enum) {
1773 decl: InternPool.DeclIndex,1767 nav: InternPool.Nav.Index,
1774 fmt_ctype_pool_string: std.fmt.Formatter(formatCTypePoolString),1768 fmt_ctype_pool_string: std.fmt.Formatter(formatCTypePoolString),
1775 @"export": struct {1769 @"export": struct {
1776 main_name: InternPool.NullTerminatedString,1770 main_name: InternPool.NullTerminatedString,
...@@ -1805,7 +1799,7 @@ pub const DeclGen = struct {...@@ -1805,7 +1799,7 @@ pub const DeclGen = struct {
18051799
1806 try w.print("{}", .{trailing});1800 try w.print("{}", .{trailing});
1807 switch (name) {1801 switch (name) {
1808 .decl => |decl_index| try dg.renderDeclName(w, decl_index),1802 .nav => |nav| try dg.renderNavName(w, nav),
1809 .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}),1803 .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}),
1810 .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),1804 .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),
1811 }1805 }
...@@ -1828,7 +1822,7 @@ pub const DeclGen = struct {...@@ -1828,7 +1822,7 @@ pub const DeclGen = struct {
1828 .forward => {1822 .forward => {
1829 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});1823 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});
1830 switch (name) {1824 switch (name) {
1831 .decl, .fmt_ctype_pool_string => {},1825 .nav, .fmt_ctype_pool_string => {},
1832 .@"export" => |@"export"| {1826 .@"export" => |@"export"| {
1833 const extern_name = @"export".extern_name.toSlice(ip);1827 const extern_name = @"export".extern_name.toSlice(ip);
1834 const is_mangled = isMangledIdent(extern_name, true);1828 const is_mangled = isMangledIdent(extern_name, true);
...@@ -2069,8 +2063,8 @@ pub const DeclGen = struct {...@@ -2069,8 +2063,8 @@ pub const DeclGen = struct {
2069 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {2063 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {
2070 switch (c_value) {2064 switch (c_value) {
2071 .new_local, .local => |i| try w.print("t{d}", .{i}),2065 .new_local, .local => |i| try w.print("t{d}", .{i}),
2072 .constant => |val| try renderAnonDeclName(w, val),2066 .constant => |uav| try renderUavName(w, uav),
2073 .decl => |decl| try dg.renderDeclName(w, decl),2067 .nav => |nav| try dg.renderNavName(w, nav),
2074 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),2068 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
2075 else => unreachable,2069 else => unreachable,
2076 }2070 }
...@@ -2079,13 +2073,13 @@ pub const DeclGen = struct {...@@ -2079,13 +2073,13 @@ pub const DeclGen = struct {
2079 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {2073 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {
2080 switch (c_value) {2074 switch (c_value) {
2081 .none, .new_local, .local, .local_ref => unreachable,2075 .none, .new_local, .local, .local_ref => unreachable,
2082 .constant => |val| try renderAnonDeclName(w, val),2076 .constant => |uav| try renderUavName(w, uav),
2083 .arg, .arg_array => unreachable,2077 .arg, .arg_array => unreachable,
2084 .field => |i| try w.print("f{d}", .{i}),2078 .field => |i| try w.print("f{d}", .{i}),
2085 .decl => |decl| try dg.renderDeclName(w, decl),2079 .nav => |nav| try dg.renderNavName(w, nav),
2086 .decl_ref => |decl| {2080 .nav_ref => |nav| {
2087 try w.writeByte('&');2081 try w.writeByte('&');
2088 try dg.renderDeclName(w, decl);2082 try dg.renderNavName(w, nav);
2089 },2083 },
2090 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),2084 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),
2091 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),2085 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
...@@ -2111,12 +2105,12 @@ pub const DeclGen = struct {...@@ -2111,12 +2105,12 @@ pub const DeclGen = struct {
2111 .ctype_pool_string,2105 .ctype_pool_string,
2112 => unreachable,2106 => unreachable,
2113 .field => |i| try w.print("f{d}", .{i}),2107 .field => |i| try w.print("f{d}", .{i}),
2114 .decl => |decl| {2108 .nav => |nav| {
2115 try w.writeAll("(*");2109 try w.writeAll("(*");
2116 try dg.renderDeclName(w, decl);2110 try dg.renderNavName(w, nav);
2117 try w.writeByte(')');2111 try w.writeByte(')');
2118 },2112 },
2119 .decl_ref => |decl| try dg.renderDeclName(w, decl),2113 .nav_ref => |nav| try dg.renderNavName(w, nav),
2120 .undef => unreachable,2114 .undef => unreachable,
2121 .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}),2115 .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}),
2122 .payload_identifier => |ident| try w.print("(*{ }.{ })", .{2116 .payload_identifier => |ident| try w.print("(*{ }.{ })", .{
...@@ -2150,11 +2144,11 @@ pub const DeclGen = struct {...@@ -2150,11 +2144,11 @@ pub const DeclGen = struct {
2150 .arg_array,2144 .arg_array,
2151 .ctype_pool_string,2145 .ctype_pool_string,
2152 => unreachable,2146 => unreachable,
2153 .decl, .identifier, .payload_identifier => {2147 .nav, .identifier, .payload_identifier => {
2154 try dg.writeCValue(writer, c_value);2148 try dg.writeCValue(writer, c_value);
2155 try writer.writeAll("->");2149 try writer.writeAll("->");
2156 },2150 },
2157 .decl_ref => {2151 .nav_ref => {
2158 try dg.writeCValueDeref(writer, c_value);2152 try dg.writeCValueDeref(writer, c_value);
2159 try writer.writeByte('.');2153 try writer.writeByte('.');
2160 },2154 },
...@@ -2164,46 +2158,53 @@ pub const DeclGen = struct {...@@ -2164,46 +2158,53 @@ pub const DeclGen = struct {
21642158
2165 fn renderFwdDecl(2159 fn renderFwdDecl(
2166 dg: *DeclGen,2160 dg: *DeclGen,
2167 decl_index: InternPool.DeclIndex,2161 nav_index: InternPool.Nav.Index,
2168 variable: InternPool.Key.Variable,2162 flags: struct {
2163 is_extern: bool,
2164 is_const: bool,
2165 is_threadlocal: bool,
2166 is_weak_linkage: bool,
2167 },
2169 ) !void {2168 ) !void {
2170 const zcu = dg.pt.zcu;2169 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);
2172 const fwd = dg.fwdDeclWriter();2172 const fwd = dg.fwdDeclWriter();
2173 try fwd.writeAll(if (variable.is_extern) "zig_extern " else "static ");2173 try fwd.writeAll(if (flags.is_extern) "zig_extern " else "static ");
2174 if (variable.is_weak_linkage) try fwd.writeAll("zig_weak_linkage ");2174 if (flags.is_weak_linkage) try fwd.writeAll("zig_weak_linkage ");
2175 if (variable.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal ");2175 if (flags.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal ");
2176 try dg.renderTypeAndName(2176 try dg.renderTypeAndName(
2177 fwd,2177 fwd,
2178 decl.typeOf(zcu),2178 Type.fromInterned(nav.typeOf(ip)),
2179 .{ .decl = decl_index },2179 .{ .nav = nav_index },
2180 CQualifiers.init(.{ .@"const" = variable.is_const }),2180 CQualifiers.init(.{ .@"const" = flags.is_const }),
2181 decl.alignment,2181 nav.status.resolved.alignment,
2182 .complete,2182 .complete,
2183 );2183 );
2184 try fwd.writeAll(";\n");2184 try fwd.writeAll(";\n");
2185 }2185 }
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 {
2188 const zcu = dg.pt.zcu;2188 const zcu = dg.pt.zcu;
2189 const ip = &zcu.intern_pool;2189 const ip = &zcu.intern_pool;
2190 const decl = zcu.declPtr(decl_index);2190 switch (ip.indexToKey(zcu.navValue(nav_index).toIntern())) {
21912191 .@"extern" => |@"extern"| try writer.print("{ }", .{
2192 if (decl.getExternDecl(zcu).unwrap()) |extern_decl_index| try writer.print("{ }", .{2192 fmtIdent(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
2193 fmtIdent(zcu.declPtr(extern_decl_index).name.toSlice(ip)),2193 }),
2194 }) else {2194 else => {
2195 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),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.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);2197 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
2198 try writer.print("{}__{d}", .{2198 try writer.print("{}__{d}", .{
2199 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),2199 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
2200 @intFromEnum(decl_index),2200 @intFromEnum(nav_index),
2201 });2201 });
2202 },
2202 }2203 }
2203 }2204 }
22042205
2205 fn renderAnonDeclName(writer: anytype, anon_decl_val: Value) !void {2206 fn renderUavName(writer: anytype, uav: Value) !void {
2206 try writer.print("__anon_{d}", .{@intFromEnum(anon_decl_val.toIntern())});2207 try writer.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
2207 }2208 }
22082209
2209 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {2210 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
...@@ -2301,12 +2302,13 @@ fn renderFwdDeclTypeName(...@@ -2301,12 +2302,13 @@ fn renderFwdDeclTypeName(
2301 fwd_decl: CType.Info.FwdDecl,2302 fwd_decl: CType.Info.FwdDecl,
2302 attributes: []const u8,2303 attributes: []const u8,
2303) !void {2304) !void {
2305 const ip = &zcu.intern_pool;
2304 try w.print("{s} {s}", .{ @tagName(fwd_decl.tag), attributes });2306 try w.print("{s} {s}", .{ @tagName(fwd_decl.tag), attributes });
2305 switch (fwd_decl.name) {2307 switch (fwd_decl.name) {
2306 .anon => try w.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),2308 .anon => try w.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),
2307 .owner_decl => |owner_decl| try w.print("{}__{d}", .{2309 .index => |index| try w.print("{}__{d}", .{
2308 fmtIdent(zcu.declPtr(owner_decl).name.toSlice(&zcu.intern_pool)),2310 fmtIdent(Type.fromInterned(index).containerTypeName(ip).toSlice(&zcu.intern_pool)),
2309 @intFromEnum(owner_decl),2311 @intFromEnum(index),
2310 }),2312 }),
2311 }2313 }
2312}2314}
...@@ -2340,11 +2342,11 @@ fn renderTypePrefix(...@@ -2340,11 +2342,11 @@ fn renderTypePrefix(
2340 },2342 },
23412343
2342 .aligned => switch (pass) {2344 .aligned => switch (pass) {
2343 .decl => |decl_index| try w.print("decl__{d}_{d}", .{2345 .nav => |nav| try w.print("nav__{d}_{d}", .{
2344 @intFromEnum(decl_index), @intFromEnum(ctype.index),2346 @intFromEnum(nav), @intFromEnum(ctype.index),
2345 }),2347 }),
2346 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{2348 .uav => |uav| try w.print("uav__{d}_{d}", .{
2347 @intFromEnum(anon_decl), @intFromEnum(ctype.index),2349 @intFromEnum(uav), @intFromEnum(ctype.index),
2348 }),2350 }),
2349 .flush => try renderAlignedTypeName(w, ctype),2351 .flush => try renderAlignedTypeName(w, ctype),
2350 },2352 },
...@@ -2370,15 +2372,15 @@ fn renderTypePrefix(...@@ -2370,15 +2372,15 @@ fn renderTypePrefix(
23702372
2371 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {2373 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2372 .anon => switch (pass) {2374 .anon => switch (pass) {
2373 .decl => |decl_index| try w.print("decl__{d}_{d}", .{2375 .nav => |nav| try w.print("nav__{d}_{d}", .{
2374 @intFromEnum(decl_index), @intFromEnum(ctype.index),2376 @intFromEnum(nav), @intFromEnum(ctype.index),
2375 }),2377 }),
2376 .anon => |anon_decl| try w.print("anon__{d}_{d}", .{2378 .uav => |uav| try w.print("uav__{d}_{d}", .{
2377 @intFromEnum(anon_decl), @intFromEnum(ctype.index),2379 @intFromEnum(uav), @intFromEnum(ctype.index),
2378 }),2380 }),
2379 .flush => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),2381 .flush => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2380 },2382 },
2381 .owner_decl => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),2383 .index => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2382 },2384 },
23832385
2384 .aggregate => |aggregate_info| switch (aggregate_info.name) {2386 .aggregate => |aggregate_info| switch (aggregate_info.name) {
...@@ -2557,7 +2559,7 @@ pub fn genTypeDecl(...@@ -2557,7 +2559,7 @@ pub fn genTypeDecl(
2557 try writer.writeAll(";\n");2559 try writer.writeAll(";\n");
2558 }2560 }
2559 switch (pass) {2561 switch (pass) {
2560 .decl, .anon => {2562 .nav, .uav => {
2561 try writer.writeAll("typedef ");2563 try writer.writeAll("typedef ");
2562 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2564 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
2563 try writer.writeByte(' ');2565 try writer.writeByte(' ');
...@@ -2569,7 +2571,7 @@ pub fn genTypeDecl(...@@ -2569,7 +2571,7 @@ pub fn genTypeDecl(
2569 },2571 },
2570 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {2572 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2571 .anon => switch (pass) {2573 .anon => switch (pass) {
2572 .decl, .anon => {2574 .nav, .uav => {
2573 try writer.writeAll("typedef ");2575 try writer.writeAll("typedef ");
2574 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2576 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
2575 try writer.writeByte(' ');2577 try writer.writeByte(' ');
...@@ -2578,13 +2580,14 @@ pub fn genTypeDecl(...@@ -2578,13 +2580,14 @@ pub fn genTypeDecl(
2578 },2580 },
2579 .flush => {},2581 .flush => {},
2580 },2582 },
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);
2582 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2586 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
2583 try writer.writeByte(';');2587 try writer.writeByte(';');
2584 const owner_decl = zcu.declPtr(owner_decl_index);2588 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file;
2585 const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod;2589 if (!zcu.fileByIndex(file_scope).mod.strip) try writer.print(" /* {} */", .{
2586 if (!owner_mod.strip) try writer.print(" /* {} */", .{2590 ty.containerTypeName(ip).fmt(ip),
2587 owner_decl.fqn.fmt(&zcu.intern_pool),
2588 });2591 });
2589 try writer.writeByte('\n');2592 try writer.writeByte('\n');
2590 },2593 },
...@@ -2709,9 +2712,8 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn...@@ -2709,9 +2712,8 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2709 const key = lazy_fn.key_ptr.*;2712 const key = lazy_fn.key_ptr.*;
2710 const val = lazy_fn.value_ptr;2713 const val = lazy_fn.value_ptr;
2711 switch (key) {2714 switch (key) {
2712 .tag_name => {2715 .tag_name => |enum_ty_ip| {
2713 const enum_ty = val.data.tag_name;2716 const enum_ty = Type.fromInterned(enum_ty_ip);
2714
2715 const name_slice_ty = Type.slice_const_u8_sentinel_0;2717 const name_slice_ty = Type.slice_const_u8_sentinel_0;
27162718
2717 try w.writeAll("static ");2719 try w.writeAll("static ");
...@@ -2756,25 +2758,25 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn...@@ -2756,25 +2758,25 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2756 _ = try airBreakpoint(w);2758 _ = try airBreakpoint(w);
2757 try w.writeAll("}\n");2759 try w.writeAll("}\n");
2758 },2760 },
2759 .never_tail, .never_inline => |fn_decl_index| {2761 .never_tail, .never_inline => |fn_nav_index| {
2760 const fn_decl = zcu.declPtr(fn_decl_index);2762 const fn_val = zcu.navValue(fn_nav_index);
2761 const fn_ctype = try o.dg.ctypeFromType(fn_decl.typeOf(zcu), .complete);2763 const fn_ctype = try o.dg.ctypeFromType(fn_val.typeOf(zcu), .complete);
2762 const fn_info = fn_ctype.info(ctype_pool).function;2764 const fn_info = fn_ctype.info(ctype_pool).function;
2763 const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool);2765 const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool);
27642766
2765 const fwd = o.dg.fwdDeclWriter();2767 const fwd = o.dg.fwdDeclWriter();
2766 try fwd.print("static zig_{s} ", .{@tagName(key)});2768 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, .{
2768 .fmt_ctype_pool_string = fn_name,2770 .fmt_ctype_pool_string = fn_name,
2769 });2771 });
2770 try fwd.writeAll(";\n");2772 try fwd.writeAll(";\n");
27712773
2772 try w.print("zig_{s} ", .{@tagName(key)});2774 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, .{
2774 .fmt_ctype_pool_string = fn_name,2776 .fmt_ctype_pool_string = fn_name,
2775 });2777 });
2776 try w.writeAll(" {\n return ");2778 try w.writeAll(" {\n return ");
2777 try o.dg.renderDeclName(w, fn_decl_index);2779 try o.dg.renderNavName(w, fn_nav_index);
2778 try w.writeByte('(');2780 try w.writeByte('(');
2779 for (0..fn_info.param_ctypes.len) |arg| {2781 for (0..fn_info.param_ctypes.len) |arg| {
2780 if (arg > 0) try w.writeAll(", ");2782 if (arg > 0) try w.writeAll(", ");
...@@ -2791,9 +2793,11 @@ pub fn genFunc(f: *Function) !void {...@@ -2791,9 +2793,11 @@ pub fn genFunc(f: *Function) !void {
27912793
2792 const o = &f.object;2794 const o = &f.object;
2793 const zcu = o.dg.pt.zcu;2795 const zcu = o.dg.pt.zcu;
2796 const ip = &zcu.intern_pool;
2794 const gpa = o.dg.gpa;2797 const gpa = o.dg.gpa;
2795 const decl_index = o.dg.pass.decl;2798 const nav_index = o.dg.pass.nav;
2796 const decl = zcu.declPtr(decl_index);2799 const nav_val = zcu.navValue(nav_index);
2800 const nav = ip.getNav(nav_index);
27972801
2798 o.code_header = std.ArrayList(u8).init(gpa);2802 o.code_header = std.ArrayList(u8).init(gpa);
2799 defer o.code_header.deinit();2803 defer o.code_header.deinit();
...@@ -2802,21 +2806,21 @@ pub fn genFunc(f: *Function) !void {...@@ -2802,21 +2806,21 @@ pub fn genFunc(f: *Function) !void {
2802 try fwd.writeAll("static ");2806 try fwd.writeAll("static ");
2803 try o.dg.renderFunctionSignature(2807 try o.dg.renderFunctionSignature(
2804 fwd,2808 fwd,
2805 decl.val,2809 nav_val,
2806 decl.alignment,2810 nav.status.resolved.alignment,
2807 .forward,2811 .forward,
2808 .{ .decl = decl_index },2812 .{ .nav = nav_index },
2809 );2813 );
2810 try fwd.writeAll(";\n");2814 try fwd.writeAll(";\n");
28112815
2812 if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s|2816 if (nav.status.resolved.@"linksection".toSlice(ip)) |s|
2813 try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)});2817 try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)});
2814 try o.dg.renderFunctionSignature(2818 try o.dg.renderFunctionSignature(
2815 o.writer(),2819 o.writer(),
2816 decl.val,2820 nav_val,
2817 .none,2821 .none,
2818 .complete,2822 .complete,
2819 .{ .decl = decl_index },2823 .{ .nav = nav_index },
2820 );2824 );
2821 try o.writer().writeByte(' ');2825 try o.writer().writeByte(' ');
28222826
...@@ -2883,44 +2887,66 @@ pub fn genDecl(o: *Object) !void {...@@ -2883,44 +2887,66 @@ pub fn genDecl(o: *Object) !void {
28832887
2884 const pt = o.dg.pt;2888 const pt = o.dg.pt;
2885 const zcu = pt.zcu;2889 const zcu = pt.zcu;
2886 const decl_index = o.dg.pass.decl;2890 const ip = &zcu.intern_pool;
2887 const decl = zcu.declPtr(decl_index);2891 const nav = ip.getNav(o.dg.pass.nav);
2888 const decl_ty = decl.typeOf(zcu);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;2904 const fwd = o.dg.fwdDeclWriter();
2891 if (decl.val.getExternFunc(zcu)) |_| {2905 try fwd.writeAll("zig_extern ");
2892 const fwd = o.dg.fwdDeclWriter();2906 try o.dg.renderFunctionSignature(
2893 try fwd.writeAll("zig_extern ");2907 fwd,
2894 try o.dg.renderFunctionSignature(2908 Value.fromInterned(nav.status.resolved.val),
2895 fwd,2909 nav.status.resolved.alignment,
2896 decl.val,2910 .forward,
2897 decl.alignment,2911 .{ .@"export" = .{
2898 .forward,2912 .main_name = nav.name,
2899 .{ .@"export" = .{2913 .extern_name = nav.name,
2900 .main_name = decl.name,2914 } },
2901 .extern_name = decl.name,2915 );
2902 } },2916 try fwd.writeAll(";\n");
2903 );2917 },
2904 try fwd.writeAll(";\n");2918 .variable => |variable| {
2905 } else if (decl.val.getVariable(zcu)) |variable| {2919 try o.dg.renderFwdDecl(o.dg.pass.nav, .{
2906 try o.dg.renderFwdDecl(decl_index, variable);2920 .is_extern = false,
29072921 .is_const = false,
2908 if (variable.is_extern) return;2922 .is_threadlocal = variable.is_threadlocal,
29092923 .is_weak_linkage = variable.is_weak_linkage,
2910 const w = o.writer();2924 });
2911 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");2925 const w = o.writer();
2912 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");2926 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2913 if (decl.@"linksection".toSlice(&zcu.intern_pool)) |s|2927 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");
2914 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});2928 if (nav.status.resolved.@"linksection".toSlice(&zcu.intern_pool)) |s|
2915 const decl_c_value = .{ .decl = decl_index };2929 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
2916 try o.dg.renderTypeAndName(w, decl_ty, decl_c_value, .{}, decl.alignment, .complete);2930 try o.dg.renderTypeAndName(
2917 try w.writeAll(" = ");2931 w,
2918 try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);2932 nav_ty,
2919 try w.writeByte(';');2933 .{ .nav = o.dg.pass.nav },
2920 try o.indent_writer.insertNewline();2934 .{},
2921 } else {2935 nav.status.resolved.alignment,
2922 const decl_c_value = .{ .decl = decl_index };2936 .complete,
2923 try genDeclValue(o, decl.val, decl_c_value, decl.alignment, decl.@"linksection");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 ),
2924 }2950 }
2925}2951}
29262952
...@@ -2956,31 +2982,34 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -2956,31 +2982,34 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
2956 const main_name = zcu.all_exports.items[export_indices[0]].opts.name;2982 const main_name = zcu.all_exports.items[export_indices[0]].opts.name;
2957 try fwd.writeAll("#define ");2983 try fwd.writeAll("#define ");
2958 switch (exported) {2984 switch (exported) {
2959 .decl_index => |decl_index| try dg.renderDeclName(fwd, decl_index),2985 .nav => |nav| try dg.renderNavName(fwd, nav),
2960 .value => |value| try DeclGen.renderAnonDeclName(fwd, Value.fromInterned(value)),2986 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),
2961 }2987 }
2962 try fwd.writeByte(' ');2988 try fwd.writeByte(' ');
2963 try fwd.print("{ }", .{fmtIdent(main_name.toSlice(ip))});2989 try fwd.print("{ }", .{fmtIdent(main_name.toSlice(ip))});
2964 try fwd.writeByte('\n');2990 try fwd.writeByte('\n');
29652991
2966 const is_const = switch (ip.indexToKey(exported.getValue(zcu).toIntern())) {2992 const exported_val = exported.getValue(zcu);
2967 .func, .extern_func => return for (export_indices) |export_index| {2993 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {
2968 const @"export" = &zcu.all_exports.items[export_index];2994 const @"export" = &zcu.all_exports.items[export_index];
2969 try fwd.writeAll("zig_extern ");2995 try fwd.writeAll("zig_extern ");
2970 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");2996 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");
2971 try dg.renderFunctionSignature(2997 try dg.renderFunctionSignature(
2972 fwd,2998 fwd,
2973 exported.getValue(zcu),2999 exported.getValue(zcu),
2974 exported.getAlign(zcu),3000 exported.getAlign(zcu),
2975 .forward,3001 .forward,
2976 .{ .@"export" = .{3002 .{ .@"export" = .{
2977 .main_name = main_name,3003 .main_name = main_name,
2978 .extern_name = @"export".opts.name,3004 .extern_name = @"export".opts.name,
2979 } },3005 } },
2980 );3006 );
2981 try fwd.writeAll(";\n");3007 try fwd.writeAll(";\n");
2982 },3008 };
2983 .variable => |variable| variable.is_const,3009 const is_const = switch (ip.indexToKey(exported_val.toIntern())) {
3010 .func => unreachable,
3011 .@"extern" => |@"extern"| @"extern".is_const,
3012 .variable => false,
2984 else => true,3013 else => true,
2985 };3014 };
2986 for (export_indices) |export_index| {3015 for (export_indices) |export_index| {
...@@ -4474,24 +4503,19 @@ fn airCall(...@@ -4474,24 +4503,19 @@ fn airCall(
44744503
4475 callee: {4504 callee: {
4476 known: {4505 known: {
4477 const fn_decl = fn_decl: {4506 const callee_val = (try f.air.value(pl_op.operand, pt)) orelse break :known;
4478 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())) {
4479 break :fn_decl switch (zcu.intern_pool.indexToKey(callee_val.toIntern())) {4508 .@"extern" => |@"extern"| @"extern".owner_nav,
4480 .extern_func => |extern_func| extern_func.decl,4509 .func => |func| func.owner_nav,
4481 .func => |func| func.owner_decl,4510 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
4482 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {4511 .nav => |nav| nav,
4483 .decl => |decl| decl,
4484 else => break :known,
4485 } else break :known,
4486 else => break :known,4512 else => break :known,
4487 };4513 } else break :known,
4514 else => break :known,
4488 };4515 };
4489 switch (modifier) {4516 switch (modifier) {
4490 .auto, .always_tail => try f.object.dg.renderDeclName(writer, fn_decl),4517 .auto, .always_tail => try f.object.dg.renderNavName(writer, fn_nav),
4491 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(4518 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
4492 @unionInit(LazyFnKey, @tagName(m), fn_decl),
4493 @unionInit(LazyFnValue.Data, @tagName(m), {}),
4494 )),
4495 else => unreachable,4519 else => unreachable,
4496 }4520 }
4497 break :callee;4521 break :callee;
...@@ -4554,11 +4578,12 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4554,11 +4578,12 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4554fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {4578fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4555 const pt = f.object.dg.pt;4579 const pt = f.object.dg.pt;
4556 const zcu = pt.zcu;4580 const zcu = pt.zcu;
4581 const ip = &zcu.intern_pool;
4557 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4582 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4558 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4583 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);
4560 const writer = f.object.writer();4585 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)});
4562 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));4587 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
4563}4588}
45644589
...@@ -5059,7 +5084,7 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool...@@ -5059,7 +5084,7 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
5059 else => switch (value) {5084 else => switch (value) {
5060 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {5085 .constant => |val| switch (dg.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
5061 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {5086 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
5062 .decl => false,5087 .nav => false,
5063 else => true,5088 else => true,
5064 } else true,5089 } else true,
5065 else => true,5090 else => true,
...@@ -6841,8 +6866,6 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6841,8 +6866,6 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
6841}6866}
68426867
6843fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {6868fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6844 const pt = f.object.dg.pt;
6845 const zcu = pt.zcu;
6846 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6869 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
68476870
6848 const inst_ty = f.typeOfIndex(inst);6871 const inst_ty = f.typeOfIndex(inst);
...@@ -6854,7 +6877,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6854,7 +6877,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6854 const local = try f.allocLocal(inst, inst_ty);6877 const local = try f.allocLocal(inst, inst_ty);
6855 try f.writeCValue(writer, local, .Other);6878 try f.writeCValue(writer, local, .Other);
6856 try writer.print(" = {s}(", .{6879 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() }),
6858 });6881 });
6859 try f.writeCValue(writer, operand, .Other);6882 try f.writeCValue(writer, operand, .Other);
6860 try writer.writeAll(");\n");6883 try writer.writeAll(");\n");
...@@ -7390,18 +7413,17 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7390,18 +7413,17 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7390 const pt = f.object.dg.pt;7413 const pt = f.object.dg.pt;
7391 const zcu = pt.zcu;7414 const zcu = pt.zcu;
7392 const inst_ty = f.typeOfIndex(inst);7415 const inst_ty = f.typeOfIndex(inst);
7393 const decl_index = f.object.dg.pass.decl;7416 const function_ty = zcu.navValue(f.object.dg.pass.nav).typeOf(zcu);
7394 const decl = zcu.declPtr(decl_index);7417 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;
7395 const function_ctype = try f.ctypeFromType(decl.typeOf(zcu), .complete);7418 assert(function_info.varargs);
7396 const params_len = function_ctype.info(&f.object.dg.ctype_pool).function.param_ctypes.len;
73977419
7398 const writer = f.object.writer();7420 const writer = f.object.writer();
7399 const local = try f.allocLocal(inst, inst_ty);7421 const local = try f.allocLocal(inst, inst_ty);
7400 try writer.writeAll("va_start(*(va_list *)&");7422 try writer.writeAll("va_start(*(va_list *)&");
7401 try f.writeCValue(writer, local, .Other);7423 try f.writeCValue(writer, local, .Other);
7402 if (params_len > 0) {7424 if (function_info.param_ctypes.len > 0) {
7403 try writer.writeAll(", ");7425 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);
7405 }7427 }
7406 try writer.writeAll(");\n");7428 try writer.writeAll(");\n");
7407 return local;7429 return local;
...@@ -7941,7 +7963,7 @@ const Materialize = struct {...@@ -7941,7 +7963,7 @@ const Materialize = struct {
79417963
7942 pub fn start(f: *Function, inst: Air.Inst.Index, ty: Type, value: CValue) !Materialize {7964 pub fn start(f: *Function, inst: Air.Inst.Index, ty: Type, value: CValue) !Materialize {
7943 return .{ .local = switch (value) {7965 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),
7945 .new_local => |local| .{ .local = local },7967 .new_local => |local| .{ .local = local },
7946 else => value,7968 else => value,
7947 } };7969 } };
src/codegen/c/Type.zig+36-37
...@@ -449,18 +449,18 @@ pub fn info(ctype: CType, pool: *const Pool) Info {...@@ -449,18 +449,18 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
449 },449 },
450 .fwd_decl_struct => return .{ .fwd_decl = .{450 .fwd_decl_struct => return .{ .fwd_decl = .{
451 .tag = .@"struct",451 .tag = .@"struct",
452 .name = .{ .owner_decl = @enumFromInt(item.data) },452 .name = .{ .index = @enumFromInt(item.data) },
453 } },453 } },
454 .fwd_decl_union => return .{ .fwd_decl = .{454 .fwd_decl_union => return .{ .fwd_decl = .{
455 .tag = .@"union",455 .tag = .@"union",
456 .name = .{ .owner_decl = @enumFromInt(item.data) },456 .name = .{ .index = @enumFromInt(item.data) },
457 } },457 } },
458 .aggregate_struct_anon => {458 .aggregate_struct_anon => {
459 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);459 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);
460 return .{ .aggregate = .{460 return .{ .aggregate = .{
461 .tag = .@"struct",461 .tag = .@"struct",
462 .name = .{ .anon = .{462 .name = .{ .anon = .{
463 .owner_decl = extra_trail.extra.owner_decl,463 .index = extra_trail.extra.index,
464 .id = extra_trail.extra.id,464 .id = extra_trail.extra.id,
465 } },465 } },
466 .fields = .{466 .fields = .{
...@@ -474,7 +474,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {...@@ -474,7 +474,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
474 return .{ .aggregate = .{474 return .{ .aggregate = .{
475 .tag = .@"union",475 .tag = .@"union",
476 .name = .{ .anon = .{476 .name = .{ .anon = .{
477 .owner_decl = extra_trail.extra.owner_decl,477 .index = extra_trail.extra.index,
478 .id = extra_trail.extra.id,478 .id = extra_trail.extra.id,
479 } },479 } },
480 .fields = .{480 .fields = .{
...@@ -489,7 +489,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {...@@ -489,7 +489,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
489 .tag = .@"struct",489 .tag = .@"struct",
490 .@"packed" = true,490 .@"packed" = true,
491 .name = .{ .anon = .{491 .name = .{ .anon = .{
492 .owner_decl = extra_trail.extra.owner_decl,492 .index = extra_trail.extra.index,
493 .id = extra_trail.extra.id,493 .id = extra_trail.extra.id,
494 } },494 } },
495 .fields = .{495 .fields = .{
...@@ -504,7 +504,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {...@@ -504,7 +504,7 @@ pub fn info(ctype: CType, pool: *const Pool) Info {
504 .tag = .@"union",504 .tag = .@"union",
505 .@"packed" = true,505 .@"packed" = true,
506 .name = .{ .anon = .{506 .name = .{ .anon = .{
507 .owner_decl = extra_trail.extra.owner_decl,507 .index = extra_trail.extra.index,
508 .id = extra_trail.extra.id,508 .id = extra_trail.extra.id,
509 } },509 } },
510 .fields = .{510 .fields = .{
...@@ -834,7 +834,7 @@ pub const Info = union(enum) {...@@ -834,7 +834,7 @@ pub const Info = union(enum) {
834 tag: AggregateTag,834 tag: AggregateTag,
835 name: union(enum) {835 name: union(enum) {
836 anon: Field.Slice,836 anon: Field.Slice,
837 owner_decl: DeclIndex,837 index: InternPool.Index,
838 },838 },
839 };839 };
840840
...@@ -843,7 +843,7 @@ pub const Info = union(enum) {...@@ -843,7 +843,7 @@ pub const Info = union(enum) {
843 @"packed": bool = false,843 @"packed": bool = false,
844 name: union(enum) {844 name: union(enum) {
845 anon: struct {845 anon: struct {
846 owner_decl: DeclIndex,846 index: InternPool.Index,
847 id: u32,847 id: u32,
848 },848 },
849 fwd_decl: CType,849 fwd_decl: CType,
...@@ -885,14 +885,14 @@ pub const Info = union(enum) {...@@ -885,14 +885,14 @@ pub const Info = union(enum) {
885 rhs_pool,885 rhs_pool,
886 pool_adapter,886 pool_adapter,
887 ),887 ),
888 .owner_decl => |lhs_owner_decl| rhs_info.fwd_decl.name == .owner_decl and888 .index => |lhs_index| rhs_info.fwd_decl.name == .index and
889 lhs_owner_decl == rhs_info.fwd_decl.name.owner_decl,889 lhs_index == rhs_info.fwd_decl.name.index,
890 },890 },
891 .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and891 .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and
892 lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and892 lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and
893 switch (lhs_aggregate_info.name) {893 switch (lhs_aggregate_info.name) {
894 .anon => |lhs_anon| rhs_info.aggregate.name == .anon and894 .anon => |lhs_anon| rhs_info.aggregate.name == .anon and
895 lhs_anon.owner_decl == rhs_info.aggregate.name.anon.owner_decl and895 lhs_anon.index == rhs_info.aggregate.name.anon.index and
896 lhs_anon.id == rhs_info.aggregate.name.anon.id,896 lhs_anon.id == rhs_info.aggregate.name.anon.id,
897 .fwd_decl => |lhs_fwd_decl| rhs_info.aggregate.name == .fwd_decl and897 .fwd_decl => |lhs_fwd_decl| rhs_info.aggregate.name == .fwd_decl and
898 pool_adapter.eql(lhs_fwd_decl, rhs_info.aggregate.name.fwd_decl),898 pool_adapter.eql(lhs_fwd_decl, rhs_info.aggregate.name.fwd_decl),
...@@ -1105,7 +1105,7 @@ pub const Pool = struct {...@@ -1105,7 +1105,7 @@ pub const Pool = struct {
1105 tag: Info.AggregateTag,1105 tag: Info.AggregateTag,
1106 name: union(enum) {1106 name: union(enum) {
1107 anon: []const Info.Field,1107 anon: []const Info.Field,
1108 owner_decl: DeclIndex,1108 index: InternPool.Index,
1109 },1109 },
1110 },1110 },
1111 ) !CType {1111 ) !CType {
...@@ -1145,13 +1145,13 @@ pub const Pool = struct {...@@ -1145,13 +1145,13 @@ pub const Pool = struct {
1145 .@"enum" => unreachable,1145 .@"enum" => unreachable,
1146 }, extra_index);1146 }, extra_index);
1147 },1147 },
1148 .owner_decl => |owner_decl| {1148 .index => |index| {
1149 hasher.update(owner_decl);1149 hasher.update(index);
1150 return pool.tagData(allocator, hasher, switch (fwd_decl_info.tag) {1150 return pool.tagData(allocator, hasher, switch (fwd_decl_info.tag) {
1151 .@"struct" => .fwd_decl_struct,1151 .@"struct" => .fwd_decl_struct,
1152 .@"union" => .fwd_decl_union,1152 .@"union" => .fwd_decl_union,
1153 .@"enum" => unreachable,1153 .@"enum" => unreachable,
1154 }, @intFromEnum(owner_decl));1154 }, @intFromEnum(index));
1155 },1155 },
1156 }1156 }
1157 }1157 }
...@@ -1164,7 +1164,7 @@ pub const Pool = struct {...@@ -1164,7 +1164,7 @@ pub const Pool = struct {
1164 @"packed": bool = false,1164 @"packed": bool = false,
1165 name: union(enum) {1165 name: union(enum) {
1166 anon: struct {1166 anon: struct {
1167 owner_decl: DeclIndex,1167 index: InternPool.Index,
1168 id: u32,1168 id: u32,
1169 },1169 },
1170 fwd_decl: CType,1170 fwd_decl: CType,
...@@ -1176,7 +1176,7 @@ pub const Pool = struct {...@@ -1176,7 +1176,7 @@ pub const Pool = struct {
1176 switch (aggregate_info.name) {1176 switch (aggregate_info.name) {
1177 .anon => |anon| {1177 .anon => |anon| {
1178 const extra: AggregateAnon = .{1178 const extra: AggregateAnon = .{
1179 .owner_decl = anon.owner_decl,1179 .index = anon.index,
1180 .id = anon.id,1180 .id = anon.id,
1181 .fields_len = @intCast(aggregate_info.fields.len),1181 .fields_len = @intCast(aggregate_info.fields.len),
1182 };1182 };
...@@ -1683,7 +1683,7 @@ pub const Pool = struct {...@@ -1683,7 +1683,7 @@ pub const Pool = struct {
1683 .auto, .@"extern" => {1683 .auto, .@"extern" => {
1684 const fwd_decl = try pool.getFwdDecl(allocator, .{1684 const fwd_decl = try pool.getFwdDecl(allocator, .{
1685 .tag = .@"struct",1685 .tag = .@"struct",
1686 .name = .{ .owner_decl = loaded_struct.decl.unwrap().? },1686 .name = .{ .index = ip_index },
1687 });1687 });
1688 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))1688 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))
1689 fwd_decl1689 fwd_decl
...@@ -1822,7 +1822,7 @@ pub const Pool = struct {...@@ -1822,7 +1822,7 @@ pub const Pool = struct {
1822 const has_tag = loaded_union.hasTag(ip);1822 const has_tag = loaded_union.hasTag(ip);
1823 const fwd_decl = try pool.getFwdDecl(allocator, .{1823 const fwd_decl = try pool.getFwdDecl(allocator, .{
1824 .tag = if (has_tag) .@"struct" else .@"union",1824 .tag = if (has_tag) .@"struct" else .@"union",
1825 .name = .{ .owner_decl = loaded_union.decl },1825 .name = .{ .index = ip_index },
1826 });1826 });
1827 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))1827 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(pt))
1828 fwd_decl1828 fwd_decl
...@@ -1837,7 +1837,7 @@ pub const Pool = struct {...@@ -1837,7 +1837,7 @@ pub const Pool = struct {
1837 );1837 );
1838 var hasher = Hasher.init;1838 var hasher = Hasher.init;
1839 var tag: Pool.Tag = .aggregate_union;1839 var tag: Pool.Tag = .aggregate_union;
1840 var payload_align: Alignment = .@"1";1840 var payload_align: InternPool.Alignment = .@"1";
1841 for (0..loaded_union.field_types.len) |field_index| {1841 for (0..loaded_union.field_types.len) |field_index| {
1842 const field_type = Type.fromInterned(1842 const field_type = Type.fromInterned(
1843 loaded_union.field_types.get(ip)[field_index],1843 loaded_union.field_types.get(ip)[field_index],
...@@ -1915,7 +1915,7 @@ pub const Pool = struct {...@@ -1915,7 +1915,7 @@ pub const Pool = struct {
1915 &hasher,1915 &hasher,
1916 AggregateAnon,1916 AggregateAnon,
1917 .{1917 .{
1918 .owner_decl = loaded_union.decl,1918 .index = ip_index,
1919 .id = 0,1919 .id = 0,
1920 .fields_len = fields_len,1920 .fields_len = fields_len,
1921 },1921 },
...@@ -2017,7 +2017,7 @@ pub const Pool = struct {...@@ -2017,7 +2017,7 @@ pub const Pool = struct {
2017 .undef,2017 .undef,
2018 .simple_value,2018 .simple_value,
2019 .variable,2019 .variable,
2020 .extern_func,2020 .@"extern",
2021 .func,2021 .func,
2022 .int,2022 .int,
2023 .err,2023 .err,
...@@ -2032,7 +2032,7 @@ pub const Pool = struct {...@@ -2032,7 +2032,7 @@ pub const Pool = struct {
2032 .aggregate,2032 .aggregate,
2033 .un,2033 .un,
2034 .memoized_call,2034 .memoized_call,
2035 => unreachable,2035 => unreachable, // values, not types
2036 },2036 },
2037 }2037 }
2038 }2038 }
...@@ -2123,9 +2123,9 @@ pub const Pool = struct {...@@ -2123,9 +2123,9 @@ pub const Pool = struct {
2123 });2123 });
2124 }2124 }
2125 },2125 },
2126 .owner_decl => |owner_decl| pool.items.appendAssumeCapacity(.{2126 .index => |index| pool.items.appendAssumeCapacity(.{
2127 .tag = tag,2127 .tag = tag,
2128 .data = @intFromEnum(owner_decl),2128 .data = @intFromEnum(index),
2129 }),2129 }),
2130 },2130 },
2131 .aggregate => |aggregate_info| {2131 .aggregate => |aggregate_info| {
...@@ -2133,7 +2133,7 @@ pub const Pool = struct {...@@ -2133,7 +2133,7 @@ pub const Pool = struct {
2133 .tag = tag,2133 .tag = tag,
2134 .data = switch (aggregate_info.name) {2134 .data = switch (aggregate_info.name) {
2135 .anon => |anon| try pool.addExtra(allocator, AggregateAnon, .{2135 .anon => |anon| try pool.addExtra(allocator, AggregateAnon, .{
2136 .owner_decl = anon.owner_decl,2136 .index = anon.index,
2137 .id = anon.id,2137 .id = anon.id,
2138 .fields_len = aggregate_info.fields.len,2138 .fields_len = aggregate_info.fields.len,
2139 }, aggregate_info.fields.len * @typeInfo(Field).Struct.fields.len),2139 }, aggregate_info.fields.len * @typeInfo(Field).Struct.fields.len),
...@@ -2221,7 +2221,7 @@ pub const Pool = struct {...@@ -2221,7 +2221,7 @@ pub const Pool = struct {
2221 Pool.Tag => @compileError("pass tag to final"),2221 Pool.Tag => @compileError("pass tag to final"),
2222 CType, CType.Index => @compileError("hash ctype.hash(pool) instead"),2222 CType, CType.Index => @compileError("hash ctype.hash(pool) instead"),
2223 String, String.Index => @compileError("hash string.slice(pool) instead"),2223 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)),
2225 []const u8 => hasher.impl.update(data),2225 []const u8 => hasher.impl.update(data),
2226 else => @compileError("unhandled type: " ++ @typeName(@TypeOf(data))),2226 else => @compileError("unhandled type: " ++ @typeName(@TypeOf(data))),
2227 }2227 }
...@@ -2426,7 +2426,7 @@ pub const Pool = struct {...@@ -2426,7 +2426,7 @@ pub const Pool = struct {
2426 };2426 };
24272427
2428 const AggregateAnon = struct {2428 const AggregateAnon = struct {
2429 owner_decl: DeclIndex,2429 index: InternPool.Index,
2430 id: u32,2430 id: u32,
2431 fields_len: u32,2431 fields_len: u32,
2432 };2432 };
...@@ -2467,7 +2467,7 @@ pub const Pool = struct {...@@ -2467,7 +2467,7 @@ pub const Pool = struct {
2467 const value = @field(extra, field.name);2467 const value = @field(extra, field.name);
2468 array.appendAssumeCapacity(switch (field.type) {2468 array.appendAssumeCapacity(switch (field.type) {
2469 u32 => value,2469 u32 => value,
2470 CType.Index, String.Index, DeclIndex => @intFromEnum(value),2470 CType.Index, String.Index, InternPool.Index => @intFromEnum(value),
2471 Aligned.Flags => @bitCast(value),2471 Aligned.Flags => @bitCast(value),
2472 else => @compileError("bad field type: " ++ field.name ++ ": " ++2472 else => @compileError("bad field type: " ++ field.name ++ ": " ++
2473 @typeName(field.type)),2473 @typeName(field.type)),
...@@ -2530,7 +2530,7 @@ pub const Pool = struct {...@@ -2530,7 +2530,7 @@ pub const Pool = struct {
2530 inline for (fields, pool.extra.items[extra_index..][0..fields.len]) |field, value|2530 inline for (fields, pool.extra.items[extra_index..][0..fields.len]) |field, value|
2531 @field(extra, field.name) = switch (field.type) {2531 @field(extra, field.name) = switch (field.type) {
2532 u32 => value,2532 u32 => value,
2533 CType.Index, String.Index, DeclIndex => @enumFromInt(value),2533 CType.Index, String.Index, InternPool.Index => @enumFromInt(value),
2534 Aligned.Flags => @bitCast(value),2534 Aligned.Flags => @bitCast(value),
2535 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),2535 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
2536 };2536 };
...@@ -2546,8 +2546,8 @@ pub const Pool = struct {...@@ -2546,8 +2546,8 @@ pub const Pool = struct {
2546};2546};
25472547
2548pub const AlignAs = packed struct {2548pub const AlignAs = packed struct {
2549 @"align": Alignment,2549 @"align": InternPool.Alignment,
2550 abi: Alignment,2550 abi: InternPool.Alignment,
25512551
2552 pub fn fromAlignment(alignas: AlignAs) AlignAs {2552 pub fn fromAlignment(alignas: AlignAs) AlignAs {
2553 assert(alignas.abi != .none);2553 assert(alignas.abi != .none);
...@@ -2556,14 +2556,14 @@ pub const AlignAs = packed struct {...@@ -2556,14 +2556,14 @@ pub const AlignAs = packed struct {
2556 .abi = alignas.abi,2556 .abi = alignas.abi,
2557 };2557 };
2558 }2558 }
2559 pub fn fromAbiAlignment(abi: Alignment) AlignAs {2559 pub fn fromAbiAlignment(abi: InternPool.Alignment) AlignAs {
2560 assert(abi != .none);2560 assert(abi != .none);
2561 return .{ .@"align" = abi, .abi = abi };2561 return .{ .@"align" = abi, .abi = abi };
2562 }2562 }
2563 pub fn fromByteUnits(@"align": u64, abi: u64) AlignAs {2563 pub fn fromByteUnits(@"align": u64, abi: u64) AlignAs {
2564 return fromAlignment(.{2564 return fromAlignment(.{
2565 .@"align" = Alignment.fromByteUnits(@"align"),2565 .@"align" = InternPool.Alignment.fromByteUnits(@"align"),
2566 .abi = Alignment.fromNonzeroByteUnits(abi),2566 .abi = InternPool.Alignment.fromNonzeroByteUnits(abi),
2567 });2567 });
2568 }2568 }
25692569
...@@ -2578,11 +2578,10 @@ pub const AlignAs = packed struct {...@@ -2578,11 +2578,10 @@ pub const AlignAs = packed struct {
2578 }2578 }
2579};2579};
25802580
2581const Alignment = @import("../../InternPool.zig").Alignment;
2582const assert = std.debug.assert;2581const assert = std.debug.assert;
2583const CType = @This();2582const CType = @This();
2583const InternPool = @import("../../InternPool.zig");
2584const Module = @import("../../Package/Module.zig");2584const Module = @import("../../Package/Module.zig");
2585const std = @import("std");2585const std = @import("std");
2586const Type = @import("../../Type.zig");2586const Type = @import("../../Type.zig");
2587const Zcu = @import("../../Zcu.zig");2587const Zcu = @import("../../Zcu.zig");
2588const DeclIndex = @import("../../InternPool.zig").DeclIndex;
src/codegen/llvm.zig+410-440
...@@ -776,7 +776,7 @@ pub const Object = struct {...@@ -776,7 +776,7 @@ pub const Object = struct {
776 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),776 debug_enums: std.ArrayListUnmanaged(Builder.Metadata),
777 debug_globals: std.ArrayListUnmanaged(Builder.Metadata),777 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),
780 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),780 debug_type_map: std.AutoHashMapUnmanaged(Type, Builder.Metadata),
781781
782 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),782 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
...@@ -790,11 +790,13 @@ pub const Object = struct {...@@ -790,11 +790,13 @@ pub const Object = struct {
790 /// version of the name and incorrectly get function not found in the llvm module.790 /// version of the name and incorrectly get function not found in the llvm module.
791 /// * it works for functions not all globals.791 /// * it works for functions not all globals.
792 /// Therefore, this table keeps track of the mapping.792 /// 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),
794 /// Same deal as `decl_map` but for anonymous declarations, which are always global constants.794 /// 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),795 uav_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.796 /// Maps enum types to their corresponding LLVM functions for implementing the `tag_name` instruction.
797 named_enum_map: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Builder.Function.Index),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),
798 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of800 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
799 /// the compiler.801 /// the compiler.
800 /// TODO when InternPool garbage collection is implemented, this map needs802 /// TODO when InternPool garbage collection is implemented, this map needs
...@@ -963,8 +965,9 @@ pub const Object = struct {...@@ -963,8 +965,9 @@ pub const Object = struct {
963 .debug_type_map = .{},965 .debug_type_map = .{},
964 .debug_unresolved_namespace_scopes = .{},966 .debug_unresolved_namespace_scopes = .{},
965 .target = target,967 .target = target,
966 .decl_map = .{},968 .nav_map = .{},
967 .anon_decl_map = .{},969 .uav_map = .{},
970 .enum_tag_name_map = .{},
968 .named_enum_map = .{},971 .named_enum_map = .{},
969 .type_map = .{},972 .type_map = .{},
970 .error_name_table = .none,973 .error_name_table = .none,
...@@ -981,8 +984,9 @@ pub const Object = struct {...@@ -981,8 +984,9 @@ pub const Object = struct {
981 self.debug_file_map.deinit(gpa);984 self.debug_file_map.deinit(gpa);
982 self.debug_type_map.deinit(gpa);985 self.debug_type_map.deinit(gpa);
983 self.debug_unresolved_namespace_scopes.deinit(gpa);986 self.debug_unresolved_namespace_scopes.deinit(gpa);
984 self.decl_map.deinit(gpa);987 self.nav_map.deinit(gpa);
985 self.anon_decl_map.deinit(gpa);988 self.uav_map.deinit(gpa);
989 self.enum_tag_name_map.deinit(gpa);
986 self.named_enum_map.deinit(gpa);990 self.named_enum_map.deinit(gpa);
987 self.type_map.deinit(gpa);991 self.type_map.deinit(gpa);
988 self.builder.deinit();992 self.builder.deinit();
...@@ -1108,7 +1112,7 @@ pub const Object = struct {...@@ -1108,7 +1112,7 @@ pub const Object = struct {
1108 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];1112 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
11091113
1110 const namespace = zcu.namespacePtr(namespace_index);1114 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
1113 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);1117 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1114 }1118 }
...@@ -1328,24 +1332,22 @@ pub const Object = struct {...@@ -1328,24 +1332,22 @@ pub const Object = struct {
1328 assert(std.meta.eql(pt, o.pt));1332 assert(std.meta.eql(pt, o.pt));
1329 const zcu = pt.zcu;1333 const zcu = pt.zcu;
1330 const comp = zcu.comp;1334 const comp = zcu.comp;
1335 const ip = &zcu.intern_pool;
1331 const func = zcu.funcInfo(func_index);1336 const func = zcu.funcInfo(func_index);
1332 const decl_index = func.owner_decl;1337 const nav = ip.getNav(func.owner_nav);
1333 const decl = zcu.declPtr(decl_index);1338 const file_scope = zcu.navFileScopeIndex(func.owner_nav);
1334 const namespace = zcu.namespacePtr(decl.src_namespace);1339 const owner_mod = zcu.fileByIndex(file_scope).mod;
1335 const file_scope = namespace.fileScope(zcu);1340 const fn_ty = Type.fromInterned(func.ty);
1336 const owner_mod = file_scope.mod;1341 const fn_info = zcu.typeToFunc(fn_ty).?;
1337 const fn_info = zcu.typeToFunc(decl.typeOf(zcu)).?;
1338 const target = owner_mod.resolved_target.result;1342 const target = owner_mod.resolved_target.result;
1339 const ip = &zcu.intern_pool;
13401343
1341 var dg: DeclGen = .{1344 var ng: NavGen = .{
1342 .object = o,1345 .object = o,
1343 .decl_index = decl_index,1346 .nav_index = func.owner_nav,
1344 .decl = decl,
1345 .err_msg = null,1347 .err_msg = null,
1346 };1348 };
13471349
1348 const function_index = try o.resolveLlvmFunction(decl_index);1350 const function_index = try o.resolveLlvmFunction(func.owner_nav);
13491351
1350 var attributes = try function_index.ptrConst(&o.builder).attributes.toWip(&o.builder);1352 var attributes = try function_index.ptrConst(&o.builder).attributes.toWip(&o.builder);
1351 defer attributes.deinit(&o.builder);1353 defer attributes.deinit(&o.builder);
...@@ -1409,7 +1411,7 @@ pub const Object = struct {...@@ -1409,7 +1411,7 @@ pub const Object = struct {
1409 } }, &o.builder);1411 } }, &o.builder);
1410 }1412 }
14111413
1412 if (decl.@"linksection".toSlice(ip)) |section|1414 if (nav.status.resolved.@"linksection".toSlice(ip)) |section|
1413 function_index.setSection(try o.builder.string(section), &o.builder);1415 function_index.setSection(try o.builder.string(section), &o.builder);
14141416
1415 var deinit_wip = true;1417 var deinit_wip = true;
...@@ -1422,7 +1424,7 @@ pub const Object = struct {...@@ -1422,7 +1424,7 @@ pub const Object = struct {
14221424
1423 var llvm_arg_i: u32 = 0;1425 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`.
1426 const sret = firstParamSRet(fn_info, pt, target);1428 const sret = firstParamSRet(fn_info, pt, target);
1427 const ret_ptr: Builder.Value = if (sret) param: {1429 const ret_ptr: Builder.Value = if (sret) param: {
1428 const param = wip.arg(llvm_arg_i);1430 const param = wip.arg(llvm_arg_i);
...@@ -1622,13 +1624,13 @@ pub const Object = struct {...@@ -1622,13 +1624,13 @@ pub const Object = struct {
1622 const file, const subprogram = if (!wip.strip) debug_info: {1624 const file, const subprogram = if (!wip.strip) debug_info: {
1623 const file = try o.getDebugFile(file_scope);1625 const file = try o.getDebugFile(file_scope);
16241626
1625 const line_number = decl.navSrcLine(zcu) + 1;1627 const line_number = zcu.navSrcLine(func.owner_nav) + 1;
1626 const is_internal_linkage = decl.val.getExternFunc(zcu) == null;1628 const is_internal_linkage = ip.indexToKey(nav.status.resolved.val) != .@"extern";
1627 const debug_decl_type = try o.lowerDebugType(decl.typeOf(zcu));1629 const debug_decl_type = try o.lowerDebugType(fn_ty);
16281630
1629 const subprogram = try o.builder.debugSubprogram(1631 const subprogram = try o.builder.debugSubprogram(
1630 file,1632 file,
1631 try o.builder.metadataString(decl.name.toSlice(ip)),1633 try o.builder.metadataString(nav.name.toSlice(ip)),
1632 try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)),1634 try o.builder.metadataStringFromStrtabString(function_index.name(&o.builder)),
1633 line_number,1635 line_number,
1634 line_number + func.lbrace_line,1636 line_number + func.lbrace_line,
...@@ -1654,7 +1656,7 @@ pub const Object = struct {...@@ -1654,7 +1656,7 @@ pub const Object = struct {
1654 .gpa = gpa,1656 .gpa = gpa,
1655 .air = air,1657 .air = air,
1656 .liveness = liveness,1658 .liveness = liveness,
1657 .dg = &dg,1659 .ng = &ng,
1658 .wip = wip,1660 .wip = wip,
1659 .is_naked = fn_info.cc == .Naked,1661 .is_naked = fn_info.cc == .Naked,
1660 .ret_ptr = ret_ptr,1662 .ret_ptr = ret_ptr,
...@@ -1665,7 +1667,7 @@ pub const Object = struct {...@@ -1665,7 +1667,7 @@ pub const Object = struct {
1665 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,1667 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
1666 .file = file,1668 .file = file,
1667 .scope = subprogram,1669 .scope = subprogram,
1668 .base_line = dg.decl.navSrcLine(zcu),1670 .base_line = zcu.navSrcLine(func.owner_nav),
1669 .prev_dbg_line = 0,1671 .prev_dbg_line = 0,
1670 .prev_dbg_column = 0,1672 .prev_dbg_column = 0,
1671 .err_ret_trace = err_ret_trace,1673 .err_ret_trace = err_ret_trace,
...@@ -1675,9 +1677,8 @@ pub const Object = struct {...@@ -1675,9 +1677,8 @@ pub const Object = struct {
16751677
1676 fg.genBody(air.getMainBody()) catch |err| switch (err) {1678 fg.genBody(air.getMainBody()) catch |err| switch (err) {
1677 error.CodegenFail => {1679 error.CodegenFail => {
1678 decl.analysis = .codegen_failure;1680 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, ng.err_msg.?);
1679 try zcu.failed_analysis.put(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?);1681 ng.err_msg = null;
1680 dg.err_msg = null;
1681 return;1682 return;
1682 },1683 },
1683 else => |e| return e,1684 else => |e| return e,
...@@ -1686,20 +1687,17 @@ pub const Object = struct {...@@ -1686,20 +1687,17 @@ pub const Object = struct {
1686 try fg.wip.finish();1687 try fg.wip.finish();
1687 }1688 }
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 {
1690 assert(std.meta.eql(pt, self.pt));1691 assert(std.meta.eql(pt, self.pt));
1691 const decl = pt.zcu.declPtr(decl_index);1692 var ng: NavGen = .{
1692 var dg: DeclGen = .{
1693 .object = self,1693 .object = self,
1694 .decl = decl,1694 .nav_index = nav_index,
1695 .decl_index = decl_index,
1696 .err_msg = null,1695 .err_msg = null,
1697 };1696 };
1698 dg.genDecl() catch |err| switch (err) {1697 ng.genDecl() catch |err| switch (err) {
1699 error.CodegenFail => {1698 error.CodegenFail => {
1700 decl.analysis = .codegen_failure;1699 try pt.zcu.failed_codegen.put(pt.zcu.gpa, nav_index, ng.err_msg.?);
1701 try pt.zcu.failed_analysis.put(pt.zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), dg.err_msg.?);1700 ng.err_msg = null;
1702 dg.err_msg = null;
1703 return;1701 return;
1704 },1702 },
1705 else => |e| return e,1703 else => |e| return e,
...@@ -1714,19 +1712,18 @@ pub const Object = struct {...@@ -1714,19 +1712,18 @@ pub const Object = struct {
1714 ) link.File.UpdateExportsError!void {1712 ) link.File.UpdateExportsError!void {
1715 assert(std.meta.eql(pt, self.pt));1713 assert(std.meta.eql(pt, self.pt));
1716 const zcu = pt.zcu;1714 const zcu = pt.zcu;
1717 const decl_index = switch (exported) {1715 const nav_index = switch (exported) {
1718 .decl_index => |i| i,1716 .nav => |nav| nav,
1719 .value => |val| return updateExportedValue(self, zcu, val, export_indices),1717 .uav => |uav| return updateExportedValue(self, zcu, uav, export_indices),
1720 };1718 };
1721 const ip = &zcu.intern_pool;1719 const ip = &zcu.intern_pool;
1722 const global_index = self.decl_map.get(decl_index).?;1720 const global_index = self.nav_map.get(nav_index).?;
1723 const decl = zcu.declPtr(decl_index);
1724 const comp = zcu.comp;1721 const comp = zcu.comp;
17251722
1726 if (export_indices.len != 0) {1723 if (export_indices.len != 0) {
1727 return updateExportedGlobal(self, zcu, global_index, export_indices);1724 return updateExportedGlobal(self, zcu, global_index, export_indices);
1728 } else {1725 } 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));
1730 try global_index.rename(fqn, &self.builder);1727 try global_index.rename(fqn, &self.builder);
1731 global_index.setLinkage(.internal, &self.builder);1728 global_index.setLinkage(.internal, &self.builder);
1732 if (comp.config.dll_export_fns)1729 if (comp.config.dll_export_fns)
...@@ -1745,7 +1742,7 @@ pub const Object = struct {...@@ -1745,7 +1742,7 @@ pub const Object = struct {
1745 const ip = &mod.intern_pool;1742 const ip = &mod.intern_pool;
1746 const main_exp_name = try o.builder.strtabString(mod.all_exports.items[export_indices[0]].opts.name.toSlice(ip));1743 const main_exp_name = try o.builder.strtabString(mod.all_exports.items[export_indices[0]].opts.name.toSlice(ip));
1747 const global_index = i: {1744 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);
1749 if (gop.found_existing) {1746 if (gop.found_existing) {
1750 const global_index = gop.value_ptr.*;1747 const global_index = gop.value_ptr.*;
1751 try global_index.rename(main_exp_name, &o.builder);1748 try global_index.rename(main_exp_name, &o.builder);
...@@ -1868,11 +1865,12 @@ pub const Object = struct {...@@ -1868,11 +1865,12 @@ pub const Object = struct {
1868 global.delete(&self.builder);1865 global.delete(&self.builder);
1869 }1866 }
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 {
1872 const gpa = o.gpa;1869 const gpa = o.gpa;
1873 const gop = try o.debug_file_map.getOrPut(gpa, file);1870 const gop = try o.debug_file_map.getOrPut(gpa, file_index);
1874 errdefer assert(o.debug_file_map.remove(file));1871 errdefer assert(o.debug_file_map.remove(file_index));
1875 if (gop.found_existing) return gop.value_ptr.*;1872 if (gop.found_existing) return gop.value_ptr.*;
1873 const file = o.pt.zcu.fileByIndex(file_index);
1876 gop.value_ptr.* = try o.builder.debugFile(1874 gop.value_ptr.* = try o.builder.debugFile(
1877 try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)),1875 try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)),
1878 dir_path: {1876 dir_path: {
...@@ -1930,17 +1928,13 @@ pub const Object = struct {...@@ -1930,17 +1928,13 @@ pub const Object = struct {
1930 return debug_int_type;1928 return debug_int_type;
1931 },1929 },
1932 .Enum => {1930 .Enum => {
1933 const owner_decl_index = ty.getOwnerDecl(zcu);
1934 const owner_decl = zcu.declPtr(owner_decl_index);
1935
1936 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {1931 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
1937 const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);1932 const debug_enum_type = try o.makeEmptyNamespaceDebugType(ty);
1938 try o.debug_type_map.put(gpa, ty, debug_enum_type);1933 try o.debug_type_map.put(gpa, ty, debug_enum_type);
1939 return debug_enum_type;1934 return debug_enum_type;
1940 }1935 }
19411936
1942 const enum_type = ip.loadEnumType(ty.toIntern());1937 const enum_type = ip.loadEnumType(ty.toIntern());
1943
1944 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);1938 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
1945 defer gpa.free(enumerators);1939 defer gpa.free(enumerators);
19461940
...@@ -1963,9 +1957,11 @@ pub const Object = struct {...@@ -1963,9 +1957,11 @@ pub const Object = struct {
1963 );1957 );
1964 }1958 }
19651959
1966 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);1960 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file);
1967 const file = try o.getDebugFile(file_scope);1961 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
1968 const scope = try o.namespaceToDebugScope(owner_decl.src_namespace);1962 try o.namespaceToDebugScope(parent_namespace)
1963 else
1964 file;
19691965
1970 const name = try o.allocTypeName(ty);1966 const name = try o.allocTypeName(ty);
1971 defer gpa.free(name);1967 defer gpa.free(name);
...@@ -1974,7 +1970,7 @@ pub const Object = struct {...@@ -1974,7 +1970,7 @@ pub const Object = struct {
1974 try o.builder.metadataString(name),1970 try o.builder.metadataString(name),
1975 file,1971 file,
1976 scope,1972 scope,
1977 owner_decl.typeSrcLine(zcu) + 1, // Line1973 ty.typeDeclSrcLine(zcu).? + 1, // Line
1978 try o.lowerDebugType(int_ty),1974 try o.lowerDebugType(int_ty),
1979 ty.abiSize(pt) * 8,1975 ty.abiSize(pt) * 8,
1980 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,1976 (ty.abiAlignment(pt).toByteUnits() orelse 0) * 8,
...@@ -2138,14 +2134,18 @@ pub const Object = struct {...@@ -2138,14 +2134,18 @@ pub const Object = struct {
21382134
2139 const name = try o.allocTypeName(ty);2135 const name = try o.allocTypeName(ty);
2140 defer gpa.free(name);2136 defer gpa.free(name);
2141 const owner_decl_index = ty.getOwnerDecl(zcu);2137
2142 const owner_decl = zcu.declPtr(owner_decl_index);2138 const file = try o.getDebugFile(ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFull(ip).file);
2143 const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu);2139 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2140 try o.namespaceToDebugScope(parent_namespace)
2141 else
2142 file;
2143
2144 const debug_opaque_type = try o.builder.debugStructType(2144 const debug_opaque_type = try o.builder.debugStructType(
2145 try o.builder.metadataString(name),2145 try o.builder.metadataString(name),
2146 try o.getDebugFile(file_scope),2146 file,
2147 try o.namespaceToDebugScope(owner_decl.src_namespace),2147 scope,
2148 owner_decl.typeSrcLine(zcu) + 1, // Line2148 ty.typeDeclSrcLine(zcu).? + 1, // Line
2149 .none, // Underlying type2149 .none, // Underlying type
2150 0, // Size2150 0, // Size
2151 0, // Align2151 0, // Align
...@@ -2460,8 +2460,7 @@ pub const Object = struct {...@@ -2460,8 +2460,7 @@ pub const Object = struct {
2460 // into. Therefore we can satisfy this by making an empty namespace,2460 // into. Therefore we can satisfy this by making an empty namespace,
2461 // rather than changing the frontend to unnecessarily resolve the2461 // rather than changing the frontend to unnecessarily resolve the
2462 // struct field types.2462 // struct field types.
2463 const owner_decl_index = ty.getOwnerDecl(zcu);2463 const debug_struct_type = try o.makeEmptyNamespaceDebugType(ty);
2464 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2465 try o.debug_type_map.put(gpa, ty, debug_struct_type);2464 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2466 return debug_struct_type;2465 return debug_struct_type;
2467 }2466 }
...@@ -2470,8 +2469,7 @@ pub const Object = struct {...@@ -2470,8 +2469,7 @@ pub const Object = struct {
2470 }2469 }
24712470
2472 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {2471 if (!ty.hasRuntimeBitsIgnoreComptime(pt)) {
2473 const owner_decl_index = ty.getOwnerDecl(zcu);2472 const debug_struct_type = try o.makeEmptyNamespaceDebugType(ty);
2474 const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
2475 try o.debug_type_map.put(gpa, ty, debug_struct_type);2473 try o.debug_type_map.put(gpa, ty, debug_struct_type);
2476 return debug_struct_type;2474 return debug_struct_type;
2477 }2475 }
...@@ -2536,8 +2534,6 @@ pub const Object = struct {...@@ -2536,8 +2534,6 @@ pub const Object = struct {
2536 return debug_struct_type;2534 return debug_struct_type;
2537 },2535 },
2538 .Union => {2536 .Union => {
2539 const owner_decl_index = ty.getOwnerDecl(zcu);
2540
2541 const name = try o.allocTypeName(ty);2537 const name = try o.allocTypeName(ty);
2542 defer gpa.free(name);2538 defer gpa.free(name);
25432539
...@@ -2546,7 +2542,7 @@ pub const Object = struct {...@@ -2546,7 +2542,7 @@ pub const Object = struct {
2546 !ty.hasRuntimeBitsIgnoreComptime(pt) or2542 !ty.hasRuntimeBitsIgnoreComptime(pt) or
2547 !union_type.haveLayout(ip))2543 !union_type.haveLayout(ip))
2548 {2544 {
2549 const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);2545 const debug_union_type = try o.makeEmptyNamespaceDebugType(ty);
2550 try o.debug_type_map.put(gpa, ty, debug_union_type);2546 try o.debug_type_map.put(gpa, ty, debug_union_type);
2551 return debug_union_type;2547 return debug_union_type;
2552 }2548 }
...@@ -2762,8 +2758,7 @@ pub const Object = struct {...@@ -2762,8 +2758,7 @@ pub const Object = struct {
2762 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {2758 fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
2763 const zcu = o.pt.zcu;2759 const zcu = o.pt.zcu;
2764 const namespace = zcu.namespacePtr(namespace_index);2760 const namespace = zcu.namespacePtr(namespace_index);
2765 const file_scope = namespace.fileScope(zcu);2761 if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope);
2766 if (namespace.parent == .none) return try o.getDebugFile(file_scope);
27672762
2768 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);2763 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);
27692764
...@@ -2772,15 +2767,19 @@ pub const Object = struct {...@@ -2772,15 +2767,19 @@ pub const Object = struct {
2772 return gop.value_ptr.*;2767 return gop.value_ptr.*;
2773 }2768 }
27742769
2775 fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata {2770 fn makeEmptyNamespaceDebugType(o: *Object, ty: Type) !Builder.Metadata {
2776 const zcu = o.pt.zcu;2771 const zcu = o.pt.zcu;
2777 const decl = zcu.declPtr(decl_index);2772 const ip = &zcu.intern_pool;
2778 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);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;
2779 return o.builder.debugStructType(2778 return o.builder.debugStructType(
2780 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)), // TODO use fully qualified name2779 try o.builder.metadataString(ty.containerTypeName(ip).toSlice(ip)), // TODO use fully qualified name
2781 try o.getDebugFile(file_scope),2780 file,
2782 try o.namespaceToDebugScope(decl.src_namespace),2781 scope,
2783 decl.typeSrcLine(zcu) + 1,2782 ty.typeDeclSrcLine(zcu).? + 1,
2784 .none,2783 .none,
2785 0,2784 0,
2786 0,2785 0,
...@@ -2791,25 +2790,24 @@ pub const Object = struct {...@@ -2791,25 +2790,24 @@ pub const Object = struct {
2791 fn getStackTraceType(o: *Object) Allocator.Error!Type {2790 fn getStackTraceType(o: *Object) Allocator.Error!Type {
2792 const pt = o.pt;2791 const pt = o.pt;
2793 const zcu = pt.zcu;2792 const zcu = pt.zcu;
2793 const ip = &zcu.intern_pool;
27942794
2795 const std_mod = zcu.std_mod;2795 const std_mod = zcu.std_mod;
2796 const std_file_imported = pt.importPkg(std_mod) catch unreachable;2796 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);2798 const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
2799 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);2799 const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
2800 const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace);2800 const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu));
2801 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = 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);
2804 // buffer is only used for int_type, `builtin` is a struct.2804 // buffer is only used for int_type, `builtin` is a struct.
2805 const builtin_ty = zcu.declPtr(builtin_decl).val.toType();2805 const builtin_ty = zcu.navValue(builtin_nav).toType();
2806 const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?;2806 const builtin_namespace = zcu.namespacePtr(builtin_ty.getNamespaceIndex(zcu));
2807 const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Zcu.DeclAdapter{ .zcu = zcu }).?;2807 const stack_trace_nav = builtin_namespace.pub_decls.getKeyAdapted(stack_trace_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?;
2808 const stack_trace_decl = zcu.declPtr(stack_trace_decl_index);
28092808
2810 // Sema should have ensured that StackTrace was analyzed.2809 // Sema should have ensured that StackTrace was analyzed.
2811 assert(stack_trace_decl.has_tv);2810 return zcu.navValue(stack_trace_nav).toType();
2812 return stack_trace_decl.val.toType();
2813 }2811 }
28142812
2815 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {2813 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
...@@ -2824,29 +2822,33 @@ pub const Object = struct {...@@ -2824,29 +2822,33 @@ pub const Object = struct {
2824 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.2822 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
2825 fn resolveLlvmFunction(2823 fn resolveLlvmFunction(
2826 o: *Object,2824 o: *Object,
2827 decl_index: InternPool.DeclIndex,2825 nav_index: InternPool.Nav.Index,
2828 ) Allocator.Error!Builder.Function.Index {2826 ) Allocator.Error!Builder.Function.Index {
2829 const pt = o.pt;2827 const pt = o.pt;
2830 const zcu = pt.zcu;2828 const zcu = pt.zcu;
2831 const ip = &zcu.intern_pool;2829 const ip = &zcu.intern_pool;
2832 const gpa = o.gpa;2830 const gpa = o.gpa;
2833 const decl = zcu.declPtr(decl_index);2831 const nav = ip.getNav(nav_index);
2834 const namespace = zcu.namespacePtr(decl.src_namespace);2832 const owner_mod = zcu.navFileScope(nav_index).mod;
2835 const owner_mod = namespace.fileScope(zcu).mod;2833 const resolved = nav.status.resolved;
2836 const zig_fn_type = decl.typeOf(zcu);2834 const val = Value.fromInterned(resolved.val);
2837 const gop = try o.decl_map.getOrPut(gpa, decl_index);2835 const ty = val.typeOf(zcu);
2836 const gop = try o.nav_map.getOrPut(gpa, nav_index);
2838 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;2837 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
28392838
2840 assert(decl.has_tv);2839 const fn_info = zcu.typeToFunc(ty).?;
2841 const fn_info = zcu.typeToFunc(zig_fn_type).?;
2842 const target = owner_mod.resolved_target.result;2840 const target = owner_mod.resolved_target.result;
2843 const sret = firstParamSRet(fn_info, pt, target);2841 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 };
2846 const function_index = try o.builder.addFunction(2848 const function_index = try o.builder.addFunction(
2847 try o.lowerType(zig_fn_type),2849 try o.lowerType(ty),
2848 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),2850 try o.builder.strtabString((if (is_extern) nav.name else nav.fqn).toSlice(ip)),
2849 toLlvmAddressSpace(decl.@"addrspace", target),2851 toLlvmAddressSpace(resolved.@"addrspace", target),
2850 );2852 );
2851 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;2853 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
28522854
...@@ -2860,12 +2862,12 @@ pub const Object = struct {...@@ -2860,12 +2862,12 @@ pub const Object = struct {
2860 if (target.isWasm()) {2862 if (target.isWasm()) {
2861 try attributes.addFnAttr(.{ .string = .{2863 try attributes.addFnAttr(.{ .string = .{
2862 .kind = try o.builder.string("wasm-import-name"),2864 .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)),
2864 } }, &o.builder);2866 } }, &o.builder);
2865 if (decl.getOwnedExternFunc(zcu).?.lib_name.toSlice(ip)) |lib_name| {2867 if (lib_name.toSlice(ip)) |lib_name_slice| {
2866 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{2868 if (!std.mem.eql(u8, lib_name_slice, "c")) try attributes.addFnAttr(.{ .string = .{
2867 .kind = try o.builder.string("wasm-import-module"),2869 .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),
2869 } }, &o.builder);2871 } }, &o.builder);
2870 }2872 }
2871 }2873 }
...@@ -2901,8 +2903,8 @@ pub const Object = struct {...@@ -2901,8 +2903,8 @@ pub const Object = struct {
2901 else => function_index.setCallConv(toLlvmCallConv(fn_info.cc, target), &o.builder),2903 else => function_index.setCallConv(toLlvmCallConv(fn_info.cc, target), &o.builder),
2902 }2904 }
29032905
2904 if (decl.alignment != .none)2906 if (resolved.alignment != .none)
2905 function_index.setAlignment(decl.alignment.toLlvm(), &o.builder);2907 function_index.setAlignment(resolved.alignment.toLlvm(), &o.builder);
29062908
2907 // Function attributes that are independent of analysis results of the function body.2909 // Function attributes that are independent of analysis results of the function body.
2908 try o.addCommonFnAttributes(&attributes, owner_mod);2910 try o.addCommonFnAttributes(&attributes, owner_mod);
...@@ -3006,15 +3008,15 @@ pub const Object = struct {...@@ -3006,15 +3008,15 @@ pub const Object = struct {
3006 }3008 }
3007 }3009 }
30083010
3009 fn resolveGlobalAnonDecl(3011 fn resolveGlobalUav(
3010 o: *Object,3012 o: *Object,
3011 decl_val: InternPool.Index,3013 uav: InternPool.Index,
3012 llvm_addr_space: Builder.AddrSpace,3014 llvm_addr_space: Builder.AddrSpace,
3013 alignment: InternPool.Alignment,3015 alignment: InternPool.Alignment,
3014 ) Error!Builder.Variable.Index {3016 ) Error!Builder.Variable.Index {
3015 assert(alignment != .none);3017 assert(alignment != .none);
3016 // TODO: Add address space to the anon_decl_map3018 // 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);
3018 if (gop.found_existing) {3020 if (gop.found_existing) {
3019 // Keep the greater of the two alignments.3021 // Keep the greater of the two alignments.
3020 const variable_index = gop.value_ptr.ptr(&o.builder).kind.variable;3022 const variable_index = gop.value_ptr.ptr(&o.builder).kind.variable;
...@@ -3023,19 +3025,19 @@ pub const Object = struct {...@@ -3023,19 +3025,19 @@ pub const Object = struct {
3023 variable_index.setAlignment(max_alignment.toLlvm(), &o.builder);3025 variable_index.setAlignment(max_alignment.toLlvm(), &o.builder);
3024 return variable_index;3026 return variable_index;
3025 }3027 }
3026 errdefer assert(o.anon_decl_map.remove(decl_val));3028 errdefer assert(o.uav_map.remove(uav));
30273029
3028 const mod = o.pt.zcu;3030 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
3031 const variable_index = try o.builder.addVariable(3033 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)}),
3033 try o.lowerType(Type.fromInterned(decl_ty)),3035 try o.lowerType(Type.fromInterned(decl_ty)),
3034 llvm_addr_space,3036 llvm_addr_space,
3035 );3037 );
3036 gop.value_ptr.* = variable_index.ptrConst(&o.builder).global;3038 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);
3039 variable_index.setLinkage(.internal, &o.builder);3041 variable_index.setLinkage(.internal, &o.builder);
3040 variable_index.setMutability(.constant, &o.builder);3042 variable_index.setMutability(.constant, &o.builder);
3041 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);3043 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
...@@ -3043,24 +3045,29 @@ pub const Object = struct {...@@ -3043,24 +3045,29 @@ pub const Object = struct {
3043 return variable_index;3045 return variable_index;
3044 }3046 }
30453047
3046 fn resolveGlobalDecl(3048 fn resolveGlobalNav(
3047 o: *Object,3049 o: *Object,
3048 decl_index: InternPool.DeclIndex,3050 nav_index: InternPool.Nav.Index,
3049 ) Allocator.Error!Builder.Variable.Index {3051 ) 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);
3051 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable;3053 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
3054 const pt = o.pt;3056 const pt = o.pt;
3055 const zcu = pt.zcu;3057 const zcu = pt.zcu;
3056 const ip = &zcu.intern_pool;3058 const ip = &zcu.intern_pool;
3057 const decl = zcu.declPtr(decl_index);3059 const nav = ip.getNav(nav_index);
3058 const is_extern = decl.isExtern(zcu);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
3060 const variable_index = try o.builder.addVariable(3067 const variable_index = try o.builder.addVariable(
3061 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),3068 try o.builder.strtabString((if (is_extern) nav.name else nav.fqn).toSlice(ip)),
3062 try o.lowerType(decl.typeOf(zcu)),3069 try o.lowerType(Type.fromInterned(nav.typeOf(ip))),
3063 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),3070 toLlvmGlobalAddressSpace(resolved.@"addrspace", zcu.getTarget()),
3064 );3071 );
3065 gop.value_ptr.* = variable_index.ptrConst(&o.builder).global;3072 gop.value_ptr.* = variable_index.ptrConst(&o.builder).global;
30663073
...@@ -3068,15 +3075,9 @@ pub const Object = struct {...@@ -3068,15 +3075,9 @@ pub const Object = struct {
3068 if (is_extern) {3075 if (is_extern) {
3069 variable_index.setLinkage(.external, &o.builder);3076 variable_index.setLinkage(.external, &o.builder);
3070 variable_index.setUnnamedAddr(.default, &o.builder);3077 variable_index.setUnnamedAddr(.default, &o.builder);
3071 if (decl.val.getVariable(zcu)) |decl_var| {3078 if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded)
3072 const decl_namespace = zcu.namespacePtr(decl.src_namespace);3079 variable_index.setThreadLocal(.generaldynamic, &o.builder);
3073 const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded;3080 if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder);
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 }
3080 } else {3081 } else {
3081 variable_index.setLinkage(.internal, &o.builder);3082 variable_index.setLinkage(.internal, &o.builder);
3082 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);3083 variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
...@@ -3286,8 +3287,6 @@ pub const Object = struct {...@@ -3286,8 +3287,6 @@ pub const Object = struct {
3286 return int_ty;3287 return int_ty;
3287 }3288 }
32883289
3289 const decl = mod.declPtr(struct_type.decl.unwrap().?);
3290
3291 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};3290 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
3292 defer llvm_field_types.deinit(o.gpa);3291 defer llvm_field_types.deinit(o.gpa);
3293 // Although we can estimate how much capacity to add, these cannot be3292 // Although we can estimate how much capacity to add, these cannot be
...@@ -3351,7 +3350,7 @@ pub const Object = struct {...@@ -3351,7 +3350,7 @@ pub const Object = struct {
3351 );3350 );
3352 }3351 }
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)));
3355 try o.type_map.put(o.gpa, t.toIntern(), ty);3354 try o.type_map.put(o.gpa, t.toIntern(), ty);
33563355
3357 o.builder.namedTypeSetBody(3356 o.builder.namedTypeSetBody(
...@@ -3440,8 +3439,6 @@ pub const Object = struct {...@@ -3440,8 +3439,6 @@ pub const Object = struct {
3440 return enum_tag_ty;3439 return enum_tag_ty;
3441 }3440 }
34423441
3443 const decl = mod.declPtr(union_obj.decl);
3444
3445 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);3442 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
3446 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);3443 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
34473444
...@@ -3460,7 +3457,7 @@ pub const Object = struct {...@@ -3460,7 +3457,7 @@ pub const Object = struct {
3460 };3457 };
34613458
3462 if (layout.tag_size == 0) {3459 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)));
3464 try o.type_map.put(o.gpa, t.toIntern(), ty);3461 try o.type_map.put(o.gpa, t.toIntern(), ty);
34653462
3466 o.builder.namedTypeSetBody(3463 o.builder.namedTypeSetBody(
...@@ -3488,7 +3485,7 @@ pub const Object = struct {...@@ -3488,7 +3485,7 @@ pub const Object = struct {
3488 llvm_fields_len += 1;3485 llvm_fields_len += 1;
3489 }3486 }
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)));
3492 try o.type_map.put(o.gpa, t.toIntern(), ty);3489 try o.type_map.put(o.gpa, t.toIntern(), ty);
34933490
3494 o.builder.namedTypeSetBody(3491 o.builder.namedTypeSetBody(
...@@ -3500,8 +3497,7 @@ pub const Object = struct {...@@ -3500,8 +3497,7 @@ pub const Object = struct {
3500 .opaque_type => {3497 .opaque_type => {
3501 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());3498 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
3502 if (!gop.found_existing) {3499 if (!gop.found_existing) {
3503 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);3500 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
3504 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3505 }3501 }
3506 return gop.value_ptr.*;3502 return gop.value_ptr.*;
3507 },3503 },
...@@ -3512,7 +3508,7 @@ pub const Object = struct {...@@ -3512,7 +3508,7 @@ pub const Object = struct {
3512 .undef,3508 .undef,
3513 .simple_value,3509 .simple_value,
3514 .variable,3510 .variable,
3515 .extern_func,3511 .@"extern",
3516 .func,3512 .func,
3517 .int,3513 .int,
3518 .err,3514 .err,
...@@ -3632,15 +3628,13 @@ pub const Object = struct {...@@ -3632,15 +3628,13 @@ pub const Object = struct {
36323628
3633 const ty = Type.fromInterned(val_key.typeOf());3629 const ty = Type.fromInterned(val_key.typeOf());
3634 switch (val_key) {3630 switch (val_key) {
3635 .extern_func => |extern_func| {3631 .@"extern" => |@"extern"| {
3636 const fn_decl_index = extern_func.decl;3632 const function_index = try o.resolveLlvmFunction(@"extern".owner_nav);
3637 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3638 const ptr = function_index.ptrConst(&o.builder).global.toConst();3633 const ptr = function_index.ptrConst(&o.builder).global.toConst();
3639 return o.builder.convConst(ptr, llvm_int_ty);3634 return o.builder.convConst(ptr, llvm_int_ty);
3640 },3635 },
3641 .func => |func| {3636 .func => |func| {
3642 const fn_decl_index = func.owner_decl;3637 const function_index = try o.resolveLlvmFunction(func.owner_nav);
3643 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3644 const ptr = function_index.ptrConst(&o.builder).global.toConst();3638 const ptr = function_index.ptrConst(&o.builder).global.toConst();
3645 return o.builder.convConst(ptr, llvm_int_ty);3639 return o.builder.convConst(ptr, llvm_int_ty);
3646 },3640 },
...@@ -3783,14 +3777,12 @@ pub const Object = struct {...@@ -3783,14 +3777,12 @@ pub const Object = struct {
3783 .enum_literal,3777 .enum_literal,
3784 .empty_enum_value,3778 .empty_enum_value,
3785 => unreachable, // non-runtime values3779 => unreachable, // non-runtime values
3786 .extern_func => |extern_func| {3780 .@"extern" => |@"extern"| {
3787 const fn_decl_index = extern_func.decl;3781 const function_index = try o.resolveLlvmFunction(@"extern".owner_nav);
3788 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3789 return function_index.ptrConst(&o.builder).global.toConst();3782 return function_index.ptrConst(&o.builder).global.toConst();
3790 },3783 },
3791 .func => |func| {3784 .func => |func| {
3792 const fn_decl_index = func.owner_decl;3785 const function_index = try o.resolveLlvmFunction(func.owner_nav);
3793 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3794 return function_index.ptrConst(&o.builder).global.toConst();3786 return function_index.ptrConst(&o.builder).global.toConst();
3795 },3787 },
3796 .int => {3788 .int => {
...@@ -4284,14 +4276,14 @@ pub const Object = struct {...@@ -4284,14 +4276,14 @@ pub const Object = struct {
4284 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;4276 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
4285 const offset: u64 = prev_offset + ptr.byte_offset;4277 const offset: u64 = prev_offset + ptr.byte_offset;
4286 return switch (ptr.base_addr) {4278 return switch (ptr.base_addr) {
4287 .decl => |decl| {4279 .nav => |nav| {
4288 const base_ptr = try o.lowerDeclRefValue(decl);4280 const base_ptr = try o.lowerNavRefValue(nav);
4289 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{4281 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{
4290 try o.builder.intConst(.i64, offset),4282 try o.builder.intConst(.i64, offset),
4291 });4283 });
4292 },4284 },
4293 .anon_decl => |ad| {4285 .uav => |uav| {
4294 const base_ptr = try o.lowerAnonDeclRef(ad);4286 const base_ptr = try o.lowerUavRef(uav);
4295 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{4287 return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{
4296 try o.builder.intConst(.i64, offset),4288 try o.builder.intConst(.i64, offset),
4297 });4289 });
...@@ -4332,39 +4324,37 @@ pub const Object = struct {...@@ -4332,39 +4324,37 @@ pub const Object = struct {
4332 };4324 };
4333 }4325 }
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.
4336 /// Maybe the logic could be unified.4328 /// Maybe the logic could be unified.
4337 fn lowerAnonDeclRef(4329 fn lowerUavRef(
4338 o: *Object,4330 o: *Object,
4339 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,4331 uav: InternPool.Key.Ptr.BaseAddr.Uav,
4340 ) Error!Builder.Constant {4332 ) Error!Builder.Constant {
4341 const pt = o.pt;4333 const pt = o.pt;
4342 const mod = pt.zcu;4334 const mod = pt.zcu;
4343 const ip = &mod.intern_pool;4335 const ip = &mod.intern_pool;
4344 const decl_val = anon_decl.val;4336 const uav_val = uav.val;
4345 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));4337 const uav_ty = Type.fromInterned(ip.typeOf(uav_val));
4346 const target = mod.getTarget();4338 const target = mod.getTarget();
43474339
4348 if (Value.fromInterned(decl_val).getFunction(mod)) |func| {4340 switch (ip.indexToKey(uav_val)) {
4349 _ = func;4341 .func => @panic("TODO"),
4350 @panic("TODO");4342 .@"extern" => @panic("TODO"),
4351 } else if (Value.fromInterned(decl_val).getExternFunc(mod)) |func| {4343 else => {},
4352 _ = func;
4353 @panic("TODO");
4354 }4344 }
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;4348 const is_fn_body = uav_ty.zigTypeTag(mod) == .Fn;
4359 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or4349 if ((!is_fn_body and !uav_ty.hasRuntimeBits(pt)) or
4360 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);4350 (is_fn_body and mod.typeToFunc(uav_ty).?.is_generic)) return o.lowerPtrToVoid(ptr_ty);
43614351
4362 if (is_fn_body)4352 if (is_fn_body)
4363 @panic("TODO");4353 @panic("TODO");
43644354
4365 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);4355 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(mod), target);
4366 const alignment = ptr_ty.ptrAlignment(pt);4356 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
4369 const llvm_val = try o.builder.convConst(4359 const llvm_val = try o.builder.convConst(
4370 llvm_global.toConst(),4360 llvm_global.toConst(),
...@@ -4374,44 +4364,41 @@ pub const Object = struct {...@@ -4374,44 +4364,41 @@ pub const Object = struct {
4374 return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));4364 return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));
4375 }4365 }
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 {
4378 const pt = o.pt;4368 const pt = o.pt;
4379 const mod = pt.zcu;4369 const zcu = pt.zcu;
4370 const ip = &zcu.intern_pool;
43804371
4381 // In the case of something like:4372 // In the case of something like:
4382 // fn foo() void {}4373 // fn foo() void {}
4383 // const bar = foo;4374 // const bar = foo;
4384 // ... &bar;4375 // ... &bar;
4385 // `bar` is just an alias and we actually want to lower a reference to `foo`.4376 // `bar` is just an alias and we actually want to lower a reference to `foo`.
4386 const decl = mod.declPtr(decl_index);4377 const owner_nav_index = switch (ip.indexToKey(zcu.navValue(nav_index).toIntern())) {
4387 if (decl.val.getFunction(mod)) |func| {4378 .func => |func| func.owner_nav,
4388 if (func.owner_decl != decl_index) {4379 .@"extern" => |@"extern"| @"extern".owner_nav,
4389 return o.lowerDeclRefValue(func.owner_decl);4380 else => nav_index,
4390 }4381 };
4391 } else if (decl.val.getExternFunc(mod)) |func| {4382 const owner_nav = ip.getNav(owner_nav_index);
4392 if (func.decl != decl_index) {
4393 return o.lowerDeclRefValue(func.decl);
4394 }
4395 }
43964383
4397 const decl_ty = decl.typeOf(mod);4384 const nav_ty = Type.fromInterned(owner_nav.typeOf(ip));
4398 const ptr_ty = try decl.declPtrType(pt);4385 const ptr_ty = try pt.navPtrType(owner_nav_index);
43994386
4400 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;4387 const is_fn_body = nav_ty.zigTypeTag(zcu) == .Fn;
4401 if ((!is_fn_body and !decl_ty.hasRuntimeBits(pt)) or4388 if ((!is_fn_body and !nav_ty.hasRuntimeBits(pt)) or
4402 (is_fn_body and mod.typeToFunc(decl_ty).?.is_generic))4389 (is_fn_body and zcu.typeToFunc(nav_ty).?.is_generic))
4403 {4390 {
4404 return o.lowerPtrToVoid(ptr_ty);4391 return o.lowerPtrToVoid(ptr_ty);
4405 }4392 }
44064393
4407 const llvm_global = if (is_fn_body)4394 const llvm_global = if (is_fn_body)
4408 (try o.resolveLlvmFunction(decl_index)).ptrConst(&o.builder).global4395 (try o.resolveLlvmFunction(owner_nav_index)).ptrConst(&o.builder).global
4409 else4396 else
4410 (try o.resolveGlobalDecl(decl_index)).ptrConst(&o.builder).global;4397 (try o.resolveGlobalNav(owner_nav_index)).ptrConst(&o.builder).global;
44114398
4412 const llvm_val = try o.builder.convConst(4399 const llvm_val = try o.builder.convConst(
4413 llvm_global.toConst(),4400 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())),
4415 );4402 );
44164403
4417 return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));4404 return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));
...@@ -4553,18 +4540,16 @@ pub const Object = struct {...@@ -4553,18 +4540,16 @@ pub const Object = struct {
4553 const ip = &zcu.intern_pool;4540 const ip = &zcu.intern_pool;
4554 const enum_type = ip.loadEnumType(enum_ty.toIntern());4541 const enum_type = ip.loadEnumType(enum_ty.toIntern());
45554542
4556 // TODO: detect when the type changes and re-emit this function.4543 const gop = try o.enum_tag_name_map.getOrPut(o.gpa, enum_ty.toIntern());
4557 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
4558 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;4544 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
4561 const usize_ty = try o.lowerType(Type.usize);4547 const usize_ty = try o.lowerType(Type.usize);
4562 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);4548 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4563 const decl = zcu.declPtr(enum_type.decl);
4564 const target = zcu.root_mod.resolved_target.result;4549 const target = zcu.root_mod.resolved_target.result;
4565 const function_index = try o.builder.addFunction(4550 const function_index = try o.builder.addFunction(
4566 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),4551 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)}),
4568 toLlvmAddressSpace(.generic, target),4553 toLlvmAddressSpace(.generic, target),
4569 );4554 );
45704555
...@@ -4624,86 +4609,73 @@ pub const Object = struct {...@@ -4624,86 +4609,73 @@ pub const Object = struct {
4624 }4609 }
4625};4610};
46264611
4627pub const DeclGen = struct {4612pub const NavGen = struct {
4628 object: *Object,4613 object: *Object,
4629 decl: *Zcu.Decl,4614 nav_index: InternPool.Nav.Index,
4630 decl_index: InternPool.DeclIndex,
4631 err_msg: ?*Zcu.ErrorMsg,4615 err_msg: ?*Zcu.ErrorMsg,
46324616
4633 fn ownerModule(dg: DeclGen) *Package.Module {4617 fn ownerModule(ng: NavGen) *Package.Module {
4634 const o = dg.object;4618 return ng.object.pt.zcu.navFileScope(ng.nav_index).mod;
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;
4639 }4619 }
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 {
4642 @setCold(true);4622 @setCold(true);
4643 assert(dg.err_msg == null);4623 assert(ng.err_msg == null);
4644 const o = dg.object;4624 const o = ng.object;
4645 const gpa = o.gpa;4625 const gpa = o.gpa;
4646 const src_loc = dg.decl.navSrcLoc(o.pt.zcu);4626 const src_loc = o.pt.zcu.navSrcLoc(ng.nav_index);
4647 dg.err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);4627 ng.err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
4648 return error.CodegenFail;4628 return error.CodegenFail;
4649 }4629 }
46504630
4651 fn genDecl(dg: *DeclGen) !void {4631 fn genDecl(ng: *NavGen) !void {
4652 const o = dg.object;4632 const o = ng.object;
4653 const pt = o.pt;4633 const pt = o.pt;
4654 const zcu = pt.zcu;4634 const zcu = pt.zcu;
4655 const ip = &zcu.intern_pool;4635 const ip = &zcu.intern_pool;
4656 const decl = dg.decl;4636 const nav_index = ng.nav_index;
4657 const decl_index = dg.decl_index;4637 const nav = ip.getNav(nav_index);
4658 assert(decl.has_tv);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| {4647 if (is_extern and ip.isFunctionType(ty.toIntern())) {
4661 _ = try o.resolveLlvmFunction(extern_func.decl);4648 _ = try o.resolveLlvmFunction(owner_nav);
4662 } else {4649 } else {
4663 const variable_index = try o.resolveGlobalDecl(decl_index);4650 const variable_index = try o.resolveGlobalNav(nav_index);
4664 variable_index.setAlignment(4651 variable_index.setAlignment(pt.navAlignment(nav_index).toLlvm(), &o.builder);
4665 decl.getAlignment(pt).toLlvm(),4652 if (resolved.@"linksection".toSlice(ip)) |section|
4666 &o.builder,
4667 );
4668 if (decl.@"linksection".toSlice(ip)) |section|
4669 variable_index.setSection(try o.builder.string(section), &o.builder);4653 variable_index.setSection(try o.builder.string(section), &o.builder);
4670 assert(decl.has_tv);4654 if (is_const) variable_index.setMutability(.constant, &o.builder);
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 };
4675 try variable_index.setInitializer(switch (init_val) {4655 try variable_index.setInitializer(switch (init_val) {
4676 .none => .no_init,4656 .none => .no_init,
4677 else => try o.lowerValue(init_val),4657 else => try o.lowerValue(init_val),
4678 }, &o.builder);4658 }, &o.builder);
46794659
4680 if (decl.val.getVariable(zcu)) |decl_var| {4660 const file_scope = zcu.navFileScopeIndex(nav_index);
4681 const decl_namespace = zcu.namespacePtr(decl.src_namespace);4661 const mod = zcu.fileByIndex(file_scope).mod;
4682 const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded;4662 if (is_threadlocal and !mod.single_threaded)
4683 variable_index.setThreadLocal(4663 variable_index.setThreadLocal(.generaldynamic, &o.builder);
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;
46904664
4691 const namespace = zcu.namespacePtr(decl.src_namespace);4665 const line_number = zcu.navSrcLine(nav_index) + 1;
4692 const file_scope = namespace.fileScope(zcu);
4693 const owner_mod = file_scope.mod;
46944666
4695 if (!owner_mod.strip) {4667 if (!mod.strip) {
4696 const debug_file = try o.getDebugFile(file_scope);4668 const debug_file = try o.getDebugFile(file_scope);
46974669
4698 const debug_global_var = try o.builder.debugGlobalVar(4670 const debug_global_var = try o.builder.debugGlobalVar(
4699 try o.builder.metadataString(decl.name.toSlice(ip)), // Name4671 try o.builder.metadataString(nav.name.toSlice(ip)), // Name
4700 try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name4672 try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name
4701 debug_file, // File4673 debug_file, // File
4702 debug_file, // Scope4674 debug_file, // Scope
4703 line_number,4675 line_number,
4704 try o.lowerDebugType(decl.typeOf(zcu)),4676 try o.lowerDebugType(ty),
4705 variable_index,4677 variable_index,
4706 .{ .local = !decl.isExtern(zcu) },4678 .{ .local = !is_extern },
4707 );4679 );
47084680
4709 const debug_expression = try o.builder.debugExpression(&.{});4681 const debug_expression = try o.builder.debugExpression(&.{});
...@@ -4718,18 +4690,18 @@ pub const DeclGen = struct {...@@ -4718,18 +4690,18 @@ pub const DeclGen = struct {
4718 }4690 }
4719 }4691 }
47204692
4721 if (decl.isExtern(zcu)) {4693 if (is_extern) {
4722 const global_index = o.decl_map.get(decl_index).?;4694 const global_index = o.nav_map.get(nav_index).?;
47234695
4724 const decl_name = decl_name: {4696 const decl_name = decl_name: {
4725 if (zcu.getTarget().isWasm() and decl.typeOf(zcu).zigTypeTag(zcu) == .Fn) {4697 if (zcu.getTarget().isWasm() and ty.zigTypeTag(zcu) == .Fn) {
4726 if (decl.getOwnedExternFunc(zcu).?.lib_name.toSlice(ip)) |lib_name| {4698 if (lib_name.toSlice(ip)) |lib_name_slice| {
4727 if (!std.mem.eql(u8, lib_name, "c")) {4699 if (!std.mem.eql(u8, lib_name_slice, "c")) {
4728 break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ decl.name.fmt(ip), lib_name });4700 break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ nav.name.fmt(ip), lib_name_slice });
4729 }4701 }
4730 }4702 }
4731 }4703 }
4732 break :decl_name try o.builder.strtabString(decl.name.toSlice(ip));4704 break :decl_name try o.builder.strtabString(nav.name.toSlice(ip));
4733 };4705 };
47344706
4735 if (o.builder.getGlobal(decl_name)) |other_global| {4707 if (o.builder.getGlobal(decl_name)) |other_global| {
...@@ -4746,16 +4718,14 @@ pub const DeclGen = struct {...@@ -4746,16 +4718,14 @@ pub const DeclGen = struct {
4746 if (zcu.comp.config.dll_export_fns)4718 if (zcu.comp.config.dll_export_fns)
4747 global_index.setDllStorageClass(.default, &o.builder);4719 global_index.setDllStorageClass(.default, &o.builder);
47484720
4749 if (decl.val.getVariable(zcu)) |decl_var| {4721 if (is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder);
4750 if (decl_var.is_weak_linkage) global_index.setLinkage(.extern_weak, &o.builder);
4751 }
4752 }4722 }
4753 }4723 }
4754};4724};
47554725
4756pub const FuncGen = struct {4726pub const FuncGen = struct {
4757 gpa: Allocator,4727 gpa: Allocator,
4758 dg: *DeclGen,4728 ng: *NavGen,
4759 air: Air,4729 air: Air,
4760 liveness: Liveness,4730 liveness: Liveness,
4761 wip: Builder.WipFunction,4731 wip: Builder.WipFunction,
...@@ -4815,7 +4785,7 @@ pub const FuncGen = struct {...@@ -4815,7 +4785,7 @@ pub const FuncGen = struct {
48154785
4816 fn todo(self: *FuncGen, comptime format: []const u8, args: anytype) Error {4786 fn todo(self: *FuncGen, comptime format: []const u8, args: anytype) Error {
4817 @setCold(true);4787 @setCold(true);
4818 return self.dg.todo(format, args);4788 return self.ng.todo(format, args);
4819 }4789 }
48204790
4821 fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !Builder.Value {4791 fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !Builder.Value {
...@@ -4823,13 +4793,13 @@ pub const FuncGen = struct {...@@ -4823,13 +4793,13 @@ pub const FuncGen = struct {
4823 const gop = try self.func_inst_table.getOrPut(gpa, inst);4793 const gop = try self.func_inst_table.getOrPut(gpa, inst);
4824 if (gop.found_existing) return gop.value_ptr.*;4794 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)).?);
4827 gop.value_ptr.* = llvm_val.toValue();4797 gop.value_ptr.* = llvm_val.toValue();
4828 return llvm_val.toValue();4798 return llvm_val.toValue();
4829 }4799 }
48304800
4831 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {4801 fn resolveValue(self: *FuncGen, val: Value) Error!Builder.Constant {
4832 const o = self.dg.object;4802 const o = self.ng.object;
4833 const pt = o.pt;4803 const pt = o.pt;
4834 const ty = val.typeOf(pt.zcu);4804 const ty = val.typeOf(pt.zcu);
4835 const llvm_val = try o.lowerValue(val.toIntern());4805 const llvm_val = try o.lowerValue(val.toIntern());
...@@ -4855,7 +4825,7 @@ pub const FuncGen = struct {...@@ -4855,7 +4825,7 @@ pub const FuncGen = struct {
4855 }4825 }
48564826
4857 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {4827 fn resolveNullOptUsize(self: *FuncGen) Error!Builder.Constant {
4858 const o = self.dg.object;4828 const o = self.ng.object;
4859 const pt = o.pt;4829 const pt = o.pt;
4860 if (o.null_opt_usize == .no_init) {4830 if (o.null_opt_usize == .no_init) {
4861 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try pt.intern(.{ .opt = .{4831 o.null_opt_usize = try self.resolveValue(Value.fromInterned(try pt.intern(.{ .opt = .{
...@@ -4867,7 +4837,7 @@ pub const FuncGen = struct {...@@ -4867,7 +4837,7 @@ pub const FuncGen = struct {
4867 }4837 }
48684838
4869 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {4839 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
4870 const o = self.dg.object;4840 const o = self.ng.object;
4871 const mod = o.pt.zcu;4841 const mod = o.pt.zcu;
4872 const ip = &mod.intern_pool;4842 const ip = &mod.intern_pool;
4873 const air_tags = self.air.instructions.items(.tag);4843 const air_tags = self.air.instructions.items(.tag);
...@@ -5132,20 +5102,19 @@ pub const FuncGen = struct {...@@ -5132,20 +5102,19 @@ pub const FuncGen = struct {
5132 defer self.scope = old_scope;5102 defer self.scope = old_scope;
51335103
5134 if (maybe_inline_func) |inline_func| {5104 if (maybe_inline_func) |inline_func| {
5135 const o = self.dg.object;5105 const o = self.ng.object;
5136 const pt = o.pt;5106 const pt = o.pt;
5137 const zcu = pt.zcu;5107 const zcu = pt.zcu;
5108 const ip = &zcu.intern_pool;
51385109
5139 const func = zcu.funcInfo(inline_func);5110 const func = zcu.funcInfo(inline_func);
5140 const decl_index = func.owner_decl;5111 const nav = ip.getNav(func.owner_nav);
5141 const decl = zcu.declPtr(decl_index);5112 const file_scope = zcu.navFileScopeIndex(func.owner_nav);
5142 const namespace = zcu.namespacePtr(decl.src_namespace);5113 const mod = zcu.fileByIndex(file_scope).mod;
5143 const file_scope = namespace.fileScope(zcu);
5144 const owner_mod = file_scope.mod;
51455114
5146 self.file = try o.getDebugFile(file_scope);5115 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;
5149 self.inlined = self.wip.debug_location;5118 self.inlined = self.wip.debug_location;
51505119
5151 const fn_ty = try pt.funcType(.{5120 const fn_ty = try pt.funcType(.{
...@@ -5155,15 +5124,15 @@ pub const FuncGen = struct {...@@ -5155,15 +5124,15 @@ pub const FuncGen = struct {
51555124
5156 self.scope = try o.builder.debugSubprogram(5125 self.scope = try o.builder.debugSubprogram(
5157 self.file,5126 self.file,
5158 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),5127 try o.builder.metadataString(nav.name.toSlice(&zcu.intern_pool)),
5159 try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),5128 try o.builder.metadataString(nav.fqn.toSlice(&zcu.intern_pool)),
5160 line_number,5129 line_number,
5161 line_number + func.lbrace_line,5130 line_number + func.lbrace_line,
5162 try o.lowerDebugType(fn_ty),5131 try o.lowerDebugType(fn_ty),
5163 .{5132 .{
5164 .di_flags = .{ .StaticMember = true },5133 .di_flags = .{ .StaticMember = true },
5165 .sp_flags = .{5134 .sp_flags = .{
5166 .Optimized = owner_mod.optimize_mode != .Debug,5135 .Optimized = mod.optimize_mode != .Debug,
5167 .Definition = true,5136 .Definition = true,
5168 .LocalToUnit = true, // TODO: we can't know this at this point, since the function could be exported later!5137 .LocalToUnit = true, // TODO: we can't know this at this point, since the function could be exported later!
5169 },5138 },
...@@ -5171,7 +5140,7 @@ pub const FuncGen = struct {...@@ -5171,7 +5140,7 @@ pub const FuncGen = struct {
5171 o.debug_compile_unit,5140 o.debug_compile_unit,
5172 );5141 );
51735142
5174 self.base_line = decl.navSrcLine(zcu);5143 self.base_line = zcu.navSrcLine(func.owner_nav);
5175 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);5144 const inlined_at_location = try self.wip.debug_location.toMetadata(&o.builder);
5176 self.wip.debug_location = .{5145 self.wip.debug_location = .{
5177 .location = .{5146 .location = .{
...@@ -5183,7 +5152,7 @@ pub const FuncGen = struct {...@@ -5183,7 +5152,7 @@ pub const FuncGen = struct {
5183 };5152 };
5184 }5153 }
51855154
5186 self.scope = try self.dg.object.builder.debugLexicalBlock(5155 self.scope = try self.ng.object.builder.debugLexicalBlock(
5187 self.scope,5156 self.scope,
5188 self.file,5157 self.file,
5189 self.prev_dbg_line,5158 self.prev_dbg_line,
...@@ -5214,7 +5183,7 @@ pub const FuncGen = struct {...@@ -5214,7 +5183,7 @@ pub const FuncGen = struct {
5214 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5183 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
5215 const extra = self.air.extraData(Air.Call, pl_op.payload);5184 const extra = self.air.extraData(Air.Call, pl_op.payload);
5216 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);5185 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;
5218 const pt = o.pt;5187 const pt = o.pt;
5219 const mod = pt.zcu;5188 const mod = pt.zcu;
5220 const ip = &mod.intern_pool;5189 const ip = &mod.intern_pool;
...@@ -5515,14 +5484,15 @@ pub const FuncGen = struct {...@@ -5515,14 +5484,15 @@ pub const FuncGen = struct {
5515 }5484 }
55165485
5517 fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {5486 fn buildSimplePanic(fg: *FuncGen, panic_id: Zcu.PanicId) !void {
5518 const o = fg.dg.object;5487 const o = fg.ng.object;
5519 const mod = o.pt.zcu;5488 const zcu = o.pt.zcu;
5520 const msg_decl_index = mod.panic_messages[@intFromEnum(panic_id)].unwrap().?;5489 const ip = &zcu.intern_pool;
5521 const msg_decl = mod.declPtr(msg_decl_index);5490 const msg_nav_index = zcu.panic_messages[@intFromEnum(panic_id)].unwrap().?;
5522 const msg_len = msg_decl.typeOf(mod).childType(mod).arrayLen(mod);5491 const msg_nav = ip.getNav(msg_nav_index);
5523 const msg_ptr = try o.lowerValue(msg_decl.val.toIntern());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);
5524 const null_opt_addr_global = try fg.resolveNullOptUsize();5494 const null_opt_addr_global = try fg.resolveNullOptUsize();
5525 const target = mod.getTarget();5495 const target = zcu.getTarget();
5526 const llvm_usize = try o.lowerType(Type.usize);5496 const llvm_usize = try o.lowerType(Type.usize);
5527 // example:5497 // example:
5528 // call fastcc void @test2.panic(5498 // call fastcc void @test2.panic(
...@@ -5531,10 +5501,10 @@ pub const FuncGen = struct {...@@ -5531,10 +5501,10 @@ pub const FuncGen = struct {
5531 // ptr null, ; stack trace5501 // ptr null, ; stack trace
5532 // ptr @2, ; addr (null ?usize)5502 // ptr @2, ; addr (null ?usize)
5533 // )5503 // )
5534 const panic_func = mod.funcInfo(mod.panic_func_index);5504 const panic_func = zcu.funcInfo(zcu.panic_func_index);
5535 const panic_decl = mod.declPtr(panic_func.owner_decl);5505 const panic_nav = ip.getNav(panic_func.owner_nav);
5536 const fn_info = mod.typeToFunc(panic_decl.typeOf(mod)).?;5506 const fn_info = zcu.typeToFunc(Type.fromInterned(panic_nav.typeOf(ip))).?;
5537 const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl);5507 const panic_global = try o.resolveLlvmFunction(panic_func.owner_nav);
5538 _ = try fg.wip.call(5508 _ = try fg.wip.call(
5539 .normal,5509 .normal,
5540 toLlvmCallConv(fn_info.cc, target),5510 toLlvmCallConv(fn_info.cc, target),
...@@ -5553,9 +5523,10 @@ pub const FuncGen = struct {...@@ -5553,9 +5523,10 @@ pub const FuncGen = struct {
5553 }5523 }
55545524
5555 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {5525 fn airRet(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
5556 const o = self.dg.object;5526 const o = self.ng.object;
5557 const pt = o.pt;5527 const pt = o.pt;
5558 const mod = pt.zcu;5528 const mod = pt.zcu;
5529 const ip = &mod.intern_pool;
5559 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5530 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5560 const ret_ty = self.typeOf(un_op);5531 const ret_ty = self.typeOf(un_op);
55615532
...@@ -5581,7 +5552,7 @@ pub const FuncGen = struct {...@@ -5581,7 +5552,7 @@ pub const FuncGen = struct {
5581 len,5552 len,
5582 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,5553 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
5583 );5554 );
5584 const owner_mod = self.dg.ownerModule();5555 const owner_mod = self.ng.ownerModule();
5585 if (owner_mod.valgrind) {5556 if (owner_mod.valgrind) {
5586 try self.valgrindMarkUndef(self.ret_ptr, len);5557 try self.valgrindMarkUndef(self.ret_ptr, len);
5587 }5558 }
...@@ -5602,7 +5573,7 @@ pub const FuncGen = struct {...@@ -5602,7 +5573,7 @@ pub const FuncGen = struct {
5602 _ = try self.wip.retVoid();5573 _ = try self.wip.retVoid();
5603 return .none;5574 return .none;
5604 }5575 }
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))).?;
5606 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {5577 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5607 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5578 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5608 // Functions with an empty error set are emitted with an error code5579 // Functions with an empty error set are emitted with an error code
...@@ -5631,7 +5602,7 @@ pub const FuncGen = struct {...@@ -5631,7 +5602,7 @@ pub const FuncGen = struct {
5631 len,5602 len,
5632 .normal,5603 .normal,
5633 );5604 );
5634 const owner_mod = self.dg.ownerModule();5605 const owner_mod = self.ng.ownerModule();
5635 if (owner_mod.valgrind) {5606 if (owner_mod.valgrind) {
5636 try self.valgrindMarkUndef(rp, len);5607 try self.valgrindMarkUndef(rp, len);
5637 }5608 }
...@@ -5659,13 +5630,14 @@ pub const FuncGen = struct {...@@ -5659,13 +5630,14 @@ pub const FuncGen = struct {
5659 }5630 }
56605631
5661 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5632 fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5662 const o = self.dg.object;5633 const o = self.ng.object;
5663 const pt = o.pt;5634 const pt = o.pt;
5664 const mod = pt.zcu;5635 const mod = pt.zcu;
5636 const ip = &mod.intern_pool;
5665 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5637 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5666 const ptr_ty = self.typeOf(un_op);5638 const ptr_ty = self.typeOf(un_op);
5667 const ret_ty = ptr_ty.childType(mod);5639 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))).?;
5669 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {5641 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5670 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5642 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5671 // Functions with an empty error set are emitted with an error code5643 // Functions with an empty error set are emitted with an error code
...@@ -5689,7 +5661,7 @@ pub const FuncGen = struct {...@@ -5689,7 +5661,7 @@ pub const FuncGen = struct {
5689 }5661 }
56905662
5691 fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5663 fn airCVaArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5692 const o = self.dg.object;5664 const o = self.ng.object;
5693 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5665 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5694 const list = try self.resolveInst(ty_op.operand);5666 const list = try self.resolveInst(ty_op.operand);
5695 const arg_ty = ty_op.ty.toType();5667 const arg_ty = ty_op.ty.toType();
...@@ -5699,7 +5671,7 @@ pub const FuncGen = struct {...@@ -5699,7 +5671,7 @@ pub const FuncGen = struct {
5699 }5671 }
57005672
5701 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5673 fn airCVaCopy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5702 const o = self.dg.object;5674 const o = self.ng.object;
5703 const pt = o.pt;5675 const pt = o.pt;
5704 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5676 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5705 const src_list = try self.resolveInst(ty_op.operand);5677 const src_list = try self.resolveInst(ty_op.operand);
...@@ -5725,7 +5697,7 @@ pub const FuncGen = struct {...@@ -5725,7 +5697,7 @@ pub const FuncGen = struct {
5725 }5697 }
57265698
5727 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5699 fn airCVaStart(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5728 const o = self.dg.object;5700 const o = self.ng.object;
5729 const pt = o.pt;5701 const pt = o.pt;
5730 const va_list_ty = self.typeOfIndex(inst);5702 const va_list_ty = self.typeOfIndex(inst);
5731 const llvm_va_list_ty = try o.lowerType(va_list_ty);5703 const llvm_va_list_ty = try o.lowerType(va_list_ty);
...@@ -5767,7 +5739,7 @@ pub const FuncGen = struct {...@@ -5767,7 +5739,7 @@ pub const FuncGen = struct {
5767 }5739 }
57685740
5769 fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5741 fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5770 const o = self.dg.object;5742 const o = self.ng.object;
5771 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5743 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5772 const operand = try self.resolveInst(un_op);5744 const operand = try self.resolveInst(un_op);
5773 const llvm_fn = try o.getCmpLtErrorsLenFunction();5745 const llvm_fn = try o.getCmpLtErrorsLenFunction();
...@@ -5790,7 +5762,7 @@ pub const FuncGen = struct {...@@ -5790,7 +5762,7 @@ pub const FuncGen = struct {
5790 lhs: Builder.Value,5762 lhs: Builder.Value,
5791 rhs: Builder.Value,5763 rhs: Builder.Value,
5792 ) Allocator.Error!Builder.Value {5764 ) Allocator.Error!Builder.Value {
5793 const o = self.dg.object;5765 const o = self.ng.object;
5794 const pt = o.pt;5766 const pt = o.pt;
5795 const mod = pt.zcu;5767 const mod = pt.zcu;
5796 const scalar_ty = operand_ty.scalarType(mod);5768 const scalar_ty = operand_ty.scalarType(mod);
...@@ -5897,7 +5869,7 @@ pub const FuncGen = struct {...@@ -5897,7 +5869,7 @@ pub const FuncGen = struct {
5897 maybe_inline_func: ?InternPool.Index,5869 maybe_inline_func: ?InternPool.Index,
5898 body: []const Air.Inst.Index,5870 body: []const Air.Inst.Index,
5899 ) !Builder.Value {5871 ) !Builder.Value {
5900 const o = self.dg.object;5872 const o = self.ng.object;
5901 const pt = o.pt;5873 const pt = o.pt;
5902 const mod = pt.zcu;5874 const mod = pt.zcu;
5903 const inst_ty = self.typeOfIndex(inst);5875 const inst_ty = self.typeOfIndex(inst);
...@@ -5948,7 +5920,7 @@ pub const FuncGen = struct {...@@ -5948,7 +5920,7 @@ pub const FuncGen = struct {
5948 }5920 }
59495921
5950 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5922 fn airBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
5951 const o = self.dg.object;5923 const o = self.ng.object;
5952 const pt = o.pt;5924 const pt = o.pt;
5953 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;5925 const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
5954 const block = self.blocks.get(branch.block_inst).?;5926 const block = self.blocks.get(branch.block_inst).?;
...@@ -5988,7 +5960,7 @@ pub const FuncGen = struct {...@@ -5988,7 +5960,7 @@ pub const FuncGen = struct {
5988 }5960 }
59895961
5990 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {5962 fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
5991 const o = self.dg.object;5963 const o = self.ng.object;
5992 const pt = o.pt;5964 const pt = o.pt;
5993 const inst = body_tail[0];5965 const inst = body_tail[0];
5994 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5966 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -6003,7 +5975,7 @@ pub const FuncGen = struct {...@@ -6003,7 +5975,7 @@ pub const FuncGen = struct {
6003 }5975 }
60045976
6005 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {5977 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6006 const o = self.dg.object;5978 const o = self.ng.object;
6007 const mod = o.pt.zcu;5979 const mod = o.pt.zcu;
6008 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5980 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6009 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);5981 const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
...@@ -6023,7 +5995,7 @@ pub const FuncGen = struct {...@@ -6023,7 +5995,7 @@ pub const FuncGen = struct {
6023 can_elide_load: bool,5995 can_elide_load: bool,
6024 is_unused: bool,5996 is_unused: bool,
6025 ) !Builder.Value {5997 ) !Builder.Value {
6026 const o = fg.dg.object;5998 const o = fg.ng.object;
6027 const pt = o.pt;5999 const pt = o.pt;
6028 const mod = pt.zcu;6000 const mod = pt.zcu;
6029 const payload_ty = err_union_ty.errorUnionPayload(mod);6001 const payload_ty = err_union_ty.errorUnionPayload(mod);
...@@ -6088,7 +6060,7 @@ pub const FuncGen = struct {...@@ -6088,7 +6060,7 @@ pub const FuncGen = struct {
6088 }6060 }
60896061
6090 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6062 fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6091 const o = self.dg.object;6063 const o = self.ng.object;
6092 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6064 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6093 const cond = try self.resolveInst(pl_op.operand);6065 const cond = try self.resolveInst(pl_op.operand);
6094 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);6066 const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
...@@ -6152,7 +6124,7 @@ pub const FuncGen = struct {...@@ -6152,7 +6124,7 @@ pub const FuncGen = struct {
6152 }6124 }
61536125
6154 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6126 fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6155 const o = self.dg.object;6127 const o = self.ng.object;
6156 const mod = o.pt.zcu;6128 const mod = o.pt.zcu;
6157 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6129 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6158 const loop = self.air.extraData(Air.Block, ty_pl.payload);6130 const loop = self.air.extraData(Air.Block, ty_pl.payload);
...@@ -6176,7 +6148,7 @@ pub const FuncGen = struct {...@@ -6176,7 +6148,7 @@ pub const FuncGen = struct {
6176 }6148 }
61776149
6178 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6150 fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6179 const o = self.dg.object;6151 const o = self.ng.object;
6180 const pt = o.pt;6152 const pt = o.pt;
6181 const mod = pt.zcu;6153 const mod = pt.zcu;
6182 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6154 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -6195,7 +6167,7 @@ pub const FuncGen = struct {...@@ -6195,7 +6167,7 @@ pub const FuncGen = struct {
6195 }6167 }
61966168
6197 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6169 fn airFloatFromInt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6198 const o = self.dg.object;6170 const o = self.ng.object;
6199 const pt = o.pt;6171 const pt = o.pt;
6200 const mod = pt.zcu;6172 const mod = pt.zcu;
6201 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6173 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -6280,7 +6252,7 @@ pub const FuncGen = struct {...@@ -6280,7 +6252,7 @@ pub const FuncGen = struct {
6280 ) !Builder.Value {6252 ) !Builder.Value {
6281 _ = fast;6253 _ = fast;
62826254
6283 const o = self.dg.object;6255 const o = self.ng.object;
6284 const pt = o.pt;6256 const pt = o.pt;
6285 const mod = pt.zcu;6257 const mod = pt.zcu;
6286 const target = mod.getTarget();6258 const target = mod.getTarget();
...@@ -6342,13 +6314,13 @@ pub const FuncGen = struct {...@@ -6342,13 +6314,13 @@ pub const FuncGen = struct {
6342 }6314 }
63436315
6344 fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {6316 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;
6346 const mod = o.pt.zcu;6318 const mod = o.pt.zcu;
6347 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;6319 return if (ty.isSlice(mod)) fg.wip.extractValue(ptr, &.{0}, "") else ptr;
6348 }6320 }
63496321
6350 fn sliceOrArrayLenInBytes(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value {6322 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;
6352 const pt = o.pt;6324 const pt = o.pt;
6353 const mod = pt.zcu;6325 const mod = pt.zcu;
6354 const llvm_usize = try o.lowerType(Type.usize);6326 const llvm_usize = try o.lowerType(Type.usize);
...@@ -6378,7 +6350,7 @@ pub const FuncGen = struct {...@@ -6378,7 +6350,7 @@ pub const FuncGen = struct {
6378 }6350 }
63796351
6380 fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !Builder.Value {6352 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;
6382 const mod = o.pt.zcu;6354 const mod = o.pt.zcu;
6383 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6355 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6384 const slice_ptr = try self.resolveInst(ty_op.operand);6356 const slice_ptr = try self.resolveInst(ty_op.operand);
...@@ -6389,7 +6361,7 @@ pub const FuncGen = struct {...@@ -6389,7 +6361,7 @@ pub const FuncGen = struct {
6389 }6361 }
63906362
6391 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6363 fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6392 const o = self.dg.object;6364 const o = self.ng.object;
6393 const pt = o.pt;6365 const pt = o.pt;
6394 const mod = pt.zcu;6366 const mod = pt.zcu;
6395 const inst = body_tail[0];6367 const inst = body_tail[0];
...@@ -6413,7 +6385,7 @@ pub const FuncGen = struct {...@@ -6413,7 +6385,7 @@ pub const FuncGen = struct {
6413 }6385 }
64146386
6415 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6387 fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6416 const o = self.dg.object;6388 const o = self.ng.object;
6417 const mod = o.pt.zcu;6389 const mod = o.pt.zcu;
6418 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6390 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6419 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;6391 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -6427,7 +6399,7 @@ pub const FuncGen = struct {...@@ -6427,7 +6399,7 @@ pub const FuncGen = struct {
6427 }6399 }
64286400
6429 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6401 fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6430 const o = self.dg.object;6402 const o = self.ng.object;
6431 const pt = o.pt;6403 const pt = o.pt;
6432 const mod = pt.zcu;6404 const mod = pt.zcu;
6433 const inst = body_tail[0];6405 const inst = body_tail[0];
...@@ -6460,7 +6432,7 @@ pub const FuncGen = struct {...@@ -6460,7 +6432,7 @@ pub const FuncGen = struct {
6460 }6432 }
64616433
6462 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6434 fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6463 const o = self.dg.object;6435 const o = self.ng.object;
6464 const pt = o.pt;6436 const pt = o.pt;
6465 const mod = pt.zcu;6437 const mod = pt.zcu;
6466 const inst = body_tail[0];6438 const inst = body_tail[0];
...@@ -6486,7 +6458,7 @@ pub const FuncGen = struct {...@@ -6486,7 +6458,7 @@ pub const FuncGen = struct {
6486 }6458 }
64876459
6488 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6460 fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6489 const o = self.dg.object;6461 const o = self.ng.object;
6490 const pt = o.pt;6462 const pt = o.pt;
6491 const mod = pt.zcu;6463 const mod = pt.zcu;
6492 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6464 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -6529,7 +6501,7 @@ pub const FuncGen = struct {...@@ -6529,7 +6501,7 @@ pub const FuncGen = struct {
6529 }6501 }
65306502
6531 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {6503 fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
6532 const o = self.dg.object;6504 const o = self.ng.object;
6533 const pt = o.pt;6505 const pt = o.pt;
6534 const mod = pt.zcu;6506 const mod = pt.zcu;
6535 const inst = body_tail[0];6507 const inst = body_tail[0];
...@@ -6635,7 +6607,7 @@ pub const FuncGen = struct {...@@ -6635,7 +6607,7 @@ pub const FuncGen = struct {
6635 }6607 }
66366608
6637 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6609 fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6638 const o = self.dg.object;6610 const o = self.ng.object;
6639 const pt = o.pt;6611 const pt = o.pt;
6640 const mod = pt.zcu;6612 const mod = pt.zcu;
6641 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6613 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -6697,7 +6669,7 @@ pub const FuncGen = struct {...@@ -6697,7 +6669,7 @@ pub const FuncGen = struct {
6697 }6669 }
66986670
6699 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6671 fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6700 const o = self.dg.object;6672 const o = self.ng.object;
6701 const mod = o.pt.zcu;6673 const mod = o.pt.zcu;
6702 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6674 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6703 const operand = try self.resolveInst(pl_op.operand);6675 const operand = try self.resolveInst(pl_op.operand);
...@@ -6729,7 +6701,7 @@ pub const FuncGen = struct {...@@ -6729,7 +6701,7 @@ pub const FuncGen = struct {
6729 }6701 }
67306702
6731 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {6703 fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
6732 const o = self.dg.object;6704 const o = self.ng.object;
6733 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6705 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6734 const operand = try self.resolveInst(pl_op.operand);6706 const operand = try self.resolveInst(pl_op.operand);
6735 const operand_ty = self.typeOf(pl_op.operand);6707 const operand_ty = self.typeOf(pl_op.operand);
...@@ -6746,7 +6718,7 @@ pub const FuncGen = struct {...@@ -6746,7 +6718,7 @@ pub const FuncGen = struct {
6746 );6718 );
67476719
6748 const pt = o.pt;6720 const pt = o.pt;
6749 const owner_mod = self.dg.ownerModule();6721 const owner_mod = self.ng.ownerModule();
6750 if (isByRef(operand_ty, pt)) {6722 if (isByRef(operand_ty, pt)) {
6751 _ = try self.wip.callIntrinsic(6723 _ = try self.wip.callIntrinsic(
6752 .normal,6724 .normal,
...@@ -6800,7 +6772,7 @@ pub const FuncGen = struct {...@@ -6800,7 +6772,7 @@ pub const FuncGen = struct {
6800 // We don't have such an assembler implemented yet though. For now,6772 // We don't have such an assembler implemented yet though. For now,
6801 // this implementation feeds the inline assembly code directly to LLVM.6773 // this implementation feeds the inline assembly code directly to LLVM.
68026774
6803 const o = self.dg.object;6775 const o = self.ng.object;
6804 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6776 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6805 const extra = self.air.extraData(Air.Asm, ty_pl.payload);6777 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
6806 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;6778 const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
...@@ -7181,7 +7153,7 @@ pub const FuncGen = struct {...@@ -7181,7 +7153,7 @@ pub const FuncGen = struct {
7181 operand_is_ptr: bool,7153 operand_is_ptr: bool,
7182 cond: Builder.IntegerCondition,7154 cond: Builder.IntegerCondition,
7183 ) !Builder.Value {7155 ) !Builder.Value {
7184 const o = self.dg.object;7156 const o = self.ng.object;
7185 const pt = o.pt;7157 const pt = o.pt;
7186 const mod = pt.zcu;7158 const mod = pt.zcu;
7187 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7159 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
...@@ -7226,7 +7198,7 @@ pub const FuncGen = struct {...@@ -7226,7 +7198,7 @@ pub const FuncGen = struct {
7226 cond: Builder.IntegerCondition,7198 cond: Builder.IntegerCondition,
7227 operand_is_ptr: bool,7199 operand_is_ptr: bool,
7228 ) !Builder.Value {7200 ) !Builder.Value {
7229 const o = self.dg.object;7201 const o = self.ng.object;
7230 const pt = o.pt;7202 const pt = o.pt;
7231 const mod = pt.zcu;7203 const mod = pt.zcu;
7232 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7204 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
...@@ -7266,7 +7238,7 @@ pub const FuncGen = struct {...@@ -7266,7 +7238,7 @@ pub const FuncGen = struct {
7266 }7238 }
72677239
7268 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7240 fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7269 const o = self.dg.object;7241 const o = self.ng.object;
7270 const pt = o.pt;7242 const pt = o.pt;
7271 const mod = pt.zcu;7243 const mod = pt.zcu;
7272 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7244 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -7288,7 +7260,7 @@ pub const FuncGen = struct {...@@ -7288,7 +7260,7 @@ pub const FuncGen = struct {
7288 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7260 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7289 comptime assert(optional_layout_version == 3);7261 comptime assert(optional_layout_version == 3);
72907262
7291 const o = self.dg.object;7263 const o = self.ng.object;
7292 const pt = o.pt;7264 const pt = o.pt;
7293 const mod = pt.zcu;7265 const mod = pt.zcu;
7294 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7266 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -7320,7 +7292,7 @@ pub const FuncGen = struct {...@@ -7320,7 +7292,7 @@ pub const FuncGen = struct {
7320 }7292 }
73217293
7322 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7294 fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7323 const o = self.dg.object;7295 const o = self.ng.object;
7324 const pt = o.pt;7296 const pt = o.pt;
7325 const mod = pt.zcu;7297 const mod = pt.zcu;
7326 const inst = body_tail[0];7298 const inst = body_tail[0];
...@@ -7345,7 +7317,7 @@ pub const FuncGen = struct {...@@ -7345,7 +7317,7 @@ pub const FuncGen = struct {
7345 body_tail: []const Air.Inst.Index,7317 body_tail: []const Air.Inst.Index,
7346 operand_is_ptr: bool,7318 operand_is_ptr: bool,
7347 ) !Builder.Value {7319 ) !Builder.Value {
7348 const o = self.dg.object;7320 const o = self.ng.object;
7349 const pt = o.pt;7321 const pt = o.pt;
7350 const mod = pt.zcu;7322 const mod = pt.zcu;
7351 const inst = body_tail[0];7323 const inst = body_tail[0];
...@@ -7381,7 +7353,7 @@ pub const FuncGen = struct {...@@ -7381,7 +7353,7 @@ pub const FuncGen = struct {
7381 inst: Air.Inst.Index,7353 inst: Air.Inst.Index,
7382 operand_is_ptr: bool,7354 operand_is_ptr: bool,
7383 ) !Builder.Value {7355 ) !Builder.Value {
7384 const o = self.dg.object;7356 const o = self.ng.object;
7385 const pt = o.pt;7357 const pt = o.pt;
7386 const mod = pt.zcu;7358 const mod = pt.zcu;
7387 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7359 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -7415,7 +7387,7 @@ pub const FuncGen = struct {...@@ -7415,7 +7387,7 @@ pub const FuncGen = struct {
7415 }7387 }
74167388
7417 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7389 fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7418 const o = self.dg.object;7390 const o = self.ng.object;
7419 const pt = o.pt;7391 const pt = o.pt;
7420 const mod = pt.zcu;7392 const mod = pt.zcu;
7421 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7393 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -7456,7 +7428,7 @@ pub const FuncGen = struct {...@@ -7456,7 +7428,7 @@ pub const FuncGen = struct {
7456 }7428 }
74577429
7458 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7430 fn airSaveErrReturnTraceIndex(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7459 const o = self.dg.object;7431 const o = self.ng.object;
7460 const pt = o.pt;7432 const pt = o.pt;
7461 const mod = pt.zcu;7433 const mod = pt.zcu;
74627434
...@@ -7502,7 +7474,7 @@ pub const FuncGen = struct {...@@ -7502,7 +7474,7 @@ pub const FuncGen = struct {
7502 }7474 }
75037475
7504 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7476 fn airWrapOptional(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7505 const o = self.dg.object;7477 const o = self.ng.object;
7506 const pt = o.pt;7478 const pt = o.pt;
7507 const mod = pt.zcu;7479 const mod = pt.zcu;
7508 const inst = body_tail[0];7480 const inst = body_tail[0];
...@@ -7536,7 +7508,7 @@ pub const FuncGen = struct {...@@ -7536,7 +7508,7 @@ pub const FuncGen = struct {
7536 }7508 }
75377509
7538 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7510 fn airWrapErrUnionPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7539 const o = self.dg.object;7511 const o = self.ng.object;
7540 const pt = o.pt;7512 const pt = o.pt;
7541 const inst = body_tail[0];7513 const inst = body_tail[0];
7542 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;7514 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -7577,7 +7549,7 @@ pub const FuncGen = struct {...@@ -7577,7 +7549,7 @@ pub const FuncGen = struct {
7577 }7549 }
75787550
7579 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {7551 fn airWrapErrUnionErr(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
7580 const o = self.dg.object;7552 const o = self.ng.object;
7581 const pt = o.pt;7553 const pt = o.pt;
7582 const mod = pt.zcu;7554 const mod = pt.zcu;
7583 const inst = body_tail[0];7555 const inst = body_tail[0];
...@@ -7618,7 +7590,7 @@ pub const FuncGen = struct {...@@ -7618,7 +7590,7 @@ pub const FuncGen = struct {
7618 }7590 }
76197591
7620 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7592 fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7621 const o = self.dg.object;7593 const o = self.ng.object;
7622 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7594 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
7623 const index = pl_op.payload;7595 const index = pl_op.payload;
7624 const llvm_usize = try o.lowerType(Type.usize);7596 const llvm_usize = try o.lowerType(Type.usize);
...@@ -7628,7 +7600,7 @@ pub const FuncGen = struct {...@@ -7628,7 +7600,7 @@ pub const FuncGen = struct {
7628 }7600 }
76297601
7630 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7602 fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7631 const o = self.dg.object;7603 const o = self.ng.object;
7632 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7604 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
7633 const index = pl_op.payload;7605 const index = pl_op.payload;
7634 const llvm_isize = try o.lowerType(Type.isize);7606 const llvm_isize = try o.lowerType(Type.isize);
...@@ -7638,7 +7610,7 @@ pub const FuncGen = struct {...@@ -7638,7 +7610,7 @@ pub const FuncGen = struct {
7638 }7610 }
76397611
7640 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7612 fn airVectorStoreElem(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7641 const o = self.dg.object;7613 const o = self.ng.object;
7642 const pt = o.pt;7614 const pt = o.pt;
7643 const mod = pt.zcu;7615 const mod = pt.zcu;
7644 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;7616 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
...@@ -7661,7 +7633,7 @@ pub const FuncGen = struct {...@@ -7661,7 +7633,7 @@ pub const FuncGen = struct {
7661 }7633 }
76627634
7663 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7635 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7664 const o = self.dg.object;7636 const o = self.ng.object;
7665 const mod = o.pt.zcu;7637 const mod = o.pt.zcu;
7666 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7638 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7667 const lhs = try self.resolveInst(bin_op.lhs);7639 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7681,7 +7653,7 @@ pub const FuncGen = struct {...@@ -7681,7 +7653,7 @@ pub const FuncGen = struct {
7681 }7653 }
76827654
7683 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7655 fn airMax(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7684 const o = self.dg.object;7656 const o = self.ng.object;
7685 const mod = o.pt.zcu;7657 const mod = o.pt.zcu;
7686 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7658 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7687 const lhs = try self.resolveInst(bin_op.lhs);7659 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7701,7 +7673,7 @@ pub const FuncGen = struct {...@@ -7701,7 +7673,7 @@ pub const FuncGen = struct {
7701 }7673 }
77027674
7703 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7675 fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7704 const o = self.dg.object;7676 const o = self.ng.object;
7705 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7677 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
7706 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;7678 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
7707 const ptr = try self.resolveInst(bin_op.lhs);7679 const ptr = try self.resolveInst(bin_op.lhs);
...@@ -7711,7 +7683,7 @@ pub const FuncGen = struct {...@@ -7711,7 +7683,7 @@ pub const FuncGen = struct {
7711 }7683 }
77127684
7713 fn airAdd(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7685 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;
7715 const mod = o.pt.zcu;7687 const mod = o.pt.zcu;
7716 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7688 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7717 const lhs = try self.resolveInst(bin_op.lhs);7689 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7729,7 +7701,7 @@ pub const FuncGen = struct {...@@ -7729,7 +7701,7 @@ pub const FuncGen = struct {
7729 signed_intrinsic: Builder.Intrinsic,7701 signed_intrinsic: Builder.Intrinsic,
7730 unsigned_intrinsic: Builder.Intrinsic,7702 unsigned_intrinsic: Builder.Intrinsic,
7731 ) !Builder.Value {7703 ) !Builder.Value {
7732 const o = fg.dg.object;7704 const o = fg.ng.object;
7733 const mod = o.pt.zcu;7705 const mod = o.pt.zcu;
77347706
7735 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7707 const bin_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -7777,7 +7749,7 @@ pub const FuncGen = struct {...@@ -7777,7 +7749,7 @@ pub const FuncGen = struct {
7777 }7749 }
77787750
7779 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7751 fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7780 const o = self.dg.object;7752 const o = self.ng.object;
7781 const mod = o.pt.zcu;7753 const mod = o.pt.zcu;
7782 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7754 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7783 const lhs = try self.resolveInst(bin_op.lhs);7755 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7797,7 +7769,7 @@ pub const FuncGen = struct {...@@ -7797,7 +7769,7 @@ pub const FuncGen = struct {
7797 }7769 }
77987770
7799 fn airSub(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7771 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;
7801 const mod = o.pt.zcu;7773 const mod = o.pt.zcu;
7802 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7774 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7803 const lhs = try self.resolveInst(bin_op.lhs);7775 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7818,7 +7790,7 @@ pub const FuncGen = struct {...@@ -7818,7 +7790,7 @@ pub const FuncGen = struct {
7818 }7790 }
78197791
7820 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7792 fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7821 const o = self.dg.object;7793 const o = self.ng.object;
7822 const mod = o.pt.zcu;7794 const mod = o.pt.zcu;
7823 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7795 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7824 const lhs = try self.resolveInst(bin_op.lhs);7796 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7838,7 +7810,7 @@ pub const FuncGen = struct {...@@ -7838,7 +7810,7 @@ pub const FuncGen = struct {
7838 }7810 }
78397811
7840 fn airMul(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7812 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;
7842 const mod = o.pt.zcu;7814 const mod = o.pt.zcu;
7843 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7815 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7844 const lhs = try self.resolveInst(bin_op.lhs);7816 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7859,7 +7831,7 @@ pub const FuncGen = struct {...@@ -7859,7 +7831,7 @@ pub const FuncGen = struct {
7859 }7831 }
78607832
7861 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7833 fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
7862 const o = self.dg.object;7834 const o = self.ng.object;
7863 const mod = o.pt.zcu;7835 const mod = o.pt.zcu;
7864 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7836 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7865 const lhs = try self.resolveInst(bin_op.lhs);7837 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7888,7 +7860,7 @@ pub const FuncGen = struct {...@@ -7888,7 +7860,7 @@ pub const FuncGen = struct {
7888 }7860 }
78897861
7890 fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7862 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;
7892 const mod = o.pt.zcu;7864 const mod = o.pt.zcu;
7893 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7865 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7894 const lhs = try self.resolveInst(bin_op.lhs);7866 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7904,7 +7876,7 @@ pub const FuncGen = struct {...@@ -7904,7 +7876,7 @@ pub const FuncGen = struct {
7904 }7876 }
79057877
7906 fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7878 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;
7908 const mod = o.pt.zcu;7880 const mod = o.pt.zcu;
7909 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7881 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7910 const lhs = try self.resolveInst(bin_op.lhs);7882 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7936,7 +7908,7 @@ pub const FuncGen = struct {...@@ -7936,7 +7908,7 @@ pub const FuncGen = struct {
7936 }7908 }
79377909
7938 fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7910 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;
7940 const mod = o.pt.zcu;7912 const mod = o.pt.zcu;
7941 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7913 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7942 const lhs = try self.resolveInst(bin_op.lhs);7914 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7954,7 +7926,7 @@ pub const FuncGen = struct {...@@ -7954,7 +7926,7 @@ pub const FuncGen = struct {
7954 }7926 }
79557927
7956 fn airRem(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7928 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;
7958 const mod = o.pt.zcu;7930 const mod = o.pt.zcu;
7959 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7931 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7960 const lhs = try self.resolveInst(bin_op.lhs);7932 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -7971,7 +7943,7 @@ pub const FuncGen = struct {...@@ -7971,7 +7943,7 @@ pub const FuncGen = struct {
7971 }7943 }
79727944
7973 fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {7945 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;
7975 const mod = o.pt.zcu;7947 const mod = o.pt.zcu;
7976 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;7948 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
7977 const lhs = try self.resolveInst(bin_op.lhs);7949 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8007,7 +7979,7 @@ pub const FuncGen = struct {...@@ -8007,7 +7979,7 @@ pub const FuncGen = struct {
8007 }7979 }
80087980
8009 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {7981 fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8010 const o = self.dg.object;7982 const o = self.ng.object;
8011 const mod = o.pt.zcu;7983 const mod = o.pt.zcu;
8012 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;7984 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8013 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;7985 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -8029,7 +8001,7 @@ pub const FuncGen = struct {...@@ -8029,7 +8001,7 @@ pub const FuncGen = struct {
8029 }8001 }
80308002
8031 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8003 fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8032 const o = self.dg.object;8004 const o = self.ng.object;
8033 const mod = o.pt.zcu;8005 const mod = o.pt.zcu;
8034 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8006 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
8035 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;8007 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -8057,7 +8029,7 @@ pub const FuncGen = struct {...@@ -8057,7 +8029,7 @@ pub const FuncGen = struct {
8057 signed_intrinsic: Builder.Intrinsic,8029 signed_intrinsic: Builder.Intrinsic,
8058 unsigned_intrinsic: Builder.Intrinsic,8030 unsigned_intrinsic: Builder.Intrinsic,
8059 ) !Builder.Value {8031 ) !Builder.Value {
8060 const o = self.dg.object;8032 const o = self.ng.object;
8061 const pt = o.pt;8033 const pt = o.pt;
8062 const mod = pt.zcu;8034 const mod = pt.zcu;
8063 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8035 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -8111,7 +8083,7 @@ pub const FuncGen = struct {...@@ -8111,7 +8083,7 @@ pub const FuncGen = struct {
8111 result_vector: Builder.Value,8083 result_vector: Builder.Value,
8112 vector_len: usize,8084 vector_len: usize,
8113 ) !Builder.Value {8085 ) !Builder.Value {
8114 const o = self.dg.object;8086 const o = self.ng.object;
8115 assert(args_vectors.len <= 3);8087 assert(args_vectors.len <= 3);
81168088
8117 var i: usize = 0;8089 var i: usize = 0;
...@@ -8143,7 +8115,7 @@ pub const FuncGen = struct {...@@ -8143,7 +8115,7 @@ pub const FuncGen = struct {
8143 param_types: []const Builder.Type,8115 param_types: []const Builder.Type,
8144 return_type: Builder.Type,8116 return_type: Builder.Type,
8145 ) Allocator.Error!Builder.Function.Index {8117 ) Allocator.Error!Builder.Function.Index {
8146 const o = self.dg.object;8118 const o = self.ng.object;
8147 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {8119 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
8148 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,8120 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
8149 .function => |function| function,8121 .function => |function| function,
...@@ -8165,7 +8137,7 @@ pub const FuncGen = struct {...@@ -8165,7 +8137,7 @@ pub const FuncGen = struct {
8165 ty: Type,8137 ty: Type,
8166 params: [2]Builder.Value,8138 params: [2]Builder.Value,
8167 ) !Builder.Value {8139 ) !Builder.Value {
8168 const o = self.dg.object;8140 const o = self.ng.object;
8169 const mod = o.pt.zcu;8141 const mod = o.pt.zcu;
8170 const target = mod.getTarget();8142 const target = mod.getTarget();
8171 const scalar_ty = ty.scalarType(mod);8143 const scalar_ty = ty.scalarType(mod);
...@@ -8271,7 +8243,7 @@ pub const FuncGen = struct {...@@ -8271,7 +8243,7 @@ pub const FuncGen = struct {
8271 comptime params_len: usize,8243 comptime params_len: usize,
8272 params: [params_len]Builder.Value,8244 params: [params_len]Builder.Value,
8273 ) !Builder.Value {8245 ) !Builder.Value {
8274 const o = self.dg.object;8246 const o = self.ng.object;
8275 const mod = o.pt.zcu;8247 const mod = o.pt.zcu;
8276 const target = mod.getTarget();8248 const target = mod.getTarget();
8277 const scalar_ty = ty.scalarType(mod);8249 const scalar_ty = ty.scalarType(mod);
...@@ -8412,7 +8384,7 @@ pub const FuncGen = struct {...@@ -8412,7 +8384,7 @@ pub const FuncGen = struct {
8412 }8384 }
84138385
8414 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8386 fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8415 const o = self.dg.object;8387 const o = self.ng.object;
8416 const pt = o.pt;8388 const pt = o.pt;
8417 const mod = pt.zcu;8389 const mod = pt.zcu;
8418 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;8390 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -8483,7 +8455,7 @@ pub const FuncGen = struct {...@@ -8483,7 +8455,7 @@ pub const FuncGen = struct {
8483 }8455 }
84848456
8485 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8457 fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8486 const o = self.dg.object;8458 const o = self.ng.object;
8487 const mod = o.pt.zcu;8459 const mod = o.pt.zcu;
8488 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8460 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
84898461
...@@ -8501,7 +8473,7 @@ pub const FuncGen = struct {...@@ -8501,7 +8473,7 @@ pub const FuncGen = struct {
8501 }8473 }
85028474
8503 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8475 fn airShl(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8504 const o = self.dg.object;8476 const o = self.ng.object;
8505 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8477 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85068478
8507 const lhs = try self.resolveInst(bin_op.lhs);8479 const lhs = try self.resolveInst(bin_op.lhs);
...@@ -8514,7 +8486,7 @@ pub const FuncGen = struct {...@@ -8514,7 +8486,7 @@ pub const FuncGen = struct {
8514 }8486 }
85158487
8516 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8488 fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8517 const o = self.dg.object;8489 const o = self.ng.object;
8518 const pt = o.pt;8490 const pt = o.pt;
8519 const mod = pt.zcu;8491 const mod = pt.zcu;
8520 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8492 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -8557,7 +8529,7 @@ pub const FuncGen = struct {...@@ -8557,7 +8529,7 @@ pub const FuncGen = struct {
8557 }8529 }
85588530
8559 fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !Builder.Value {8531 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;
8561 const mod = o.pt.zcu;8533 const mod = o.pt.zcu;
8562 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8534 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
85638535
...@@ -8576,7 +8548,7 @@ pub const FuncGen = struct {...@@ -8576,7 +8548,7 @@ pub const FuncGen = struct {
8576 }8548 }
85778549
8578 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8550 fn airAbs(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8579 const o = self.dg.object;8551 const o = self.ng.object;
8580 const mod = o.pt.zcu;8552 const mod = o.pt.zcu;
8581 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8553 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8582 const operand = try self.resolveInst(ty_op.operand);8554 const operand = try self.resolveInst(ty_op.operand);
...@@ -8598,7 +8570,7 @@ pub const FuncGen = struct {...@@ -8598,7 +8570,7 @@ pub const FuncGen = struct {
8598 }8570 }
85998571
8600 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8572 fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8601 const o = self.dg.object;8573 const o = self.ng.object;
8602 const mod = o.pt.zcu;8574 const mod = o.pt.zcu;
8603 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8575 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8604 const dest_ty = self.typeOfIndex(inst);8576 const dest_ty = self.typeOfIndex(inst);
...@@ -8614,7 +8586,7 @@ pub const FuncGen = struct {...@@ -8614,7 +8586,7 @@ pub const FuncGen = struct {
8614 }8586 }
86158587
8616 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8588 fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8617 const o = self.dg.object;8589 const o = self.ng.object;
8618 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8590 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8619 const operand = try self.resolveInst(ty_op.operand);8591 const operand = try self.resolveInst(ty_op.operand);
8620 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));8592 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
...@@ -8622,7 +8594,7 @@ pub const FuncGen = struct {...@@ -8622,7 +8594,7 @@ pub const FuncGen = struct {
8622 }8594 }
86238595
8624 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8596 fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8625 const o = self.dg.object;8597 const o = self.ng.object;
8626 const mod = o.pt.zcu;8598 const mod = o.pt.zcu;
8627 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8599 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8628 const operand = try self.resolveInst(ty_op.operand);8600 const operand = try self.resolveInst(ty_op.operand);
...@@ -8656,7 +8628,7 @@ pub const FuncGen = struct {...@@ -8656,7 +8628,7 @@ pub const FuncGen = struct {
8656 }8628 }
86578629
8658 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8630 fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8659 const o = self.dg.object;8631 const o = self.ng.object;
8660 const mod = o.pt.zcu;8632 const mod = o.pt.zcu;
8661 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;8633 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
8662 const operand = try self.resolveInst(ty_op.operand);8634 const operand = try self.resolveInst(ty_op.operand);
...@@ -8696,7 +8668,7 @@ pub const FuncGen = struct {...@@ -8696,7 +8668,7 @@ pub const FuncGen = struct {
8696 }8668 }
86978669
8698 fn airIntFromPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8670 fn airIntFromPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8699 const o = self.dg.object;8671 const o = self.ng.object;
8700 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;8672 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
8701 const operand = try self.resolveInst(un_op);8673 const operand = try self.resolveInst(un_op);
8702 const ptr_ty = self.typeOf(un_op);8674 const ptr_ty = self.typeOf(un_op);
...@@ -8714,7 +8686,7 @@ pub const FuncGen = struct {...@@ -8714,7 +8686,7 @@ pub const FuncGen = struct {
8714 }8686 }
87158687
8716 fn bitCast(self: *FuncGen, operand: Builder.Value, operand_ty: Type, inst_ty: Type) !Builder.Value {8688 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;
8718 const pt = o.pt;8690 const pt = o.pt;
8719 const mod = pt.zcu;8691 const mod = pt.zcu;
8720 const operand_is_ref = isByRef(operand_ty, pt);8692 const operand_is_ref = isByRef(operand_ty, pt);
...@@ -8739,7 +8711,7 @@ pub const FuncGen = struct {...@@ -8739,7 +8711,7 @@ pub const FuncGen = struct {
8739 if (operand_ty.zigTypeTag(mod) == .Vector and inst_ty.zigTypeTag(mod) == .Array) {8711 if (operand_ty.zigTypeTag(mod) == .Vector and inst_ty.zigTypeTag(mod) == .Array) {
8740 const elem_ty = operand_ty.childType(mod);8712 const elem_ty = operand_ty.childType(mod);
8741 if (!result_is_ref) {8713 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", .{});
8743 }8715 }
8744 const alignment = inst_ty.abiAlignment(pt).toLlvm();8716 const alignment = inst_ty.abiAlignment(pt).toLlvm();
8745 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);8717 const array_ptr = try self.buildAllocaWorkaround(inst_ty, alignment);
...@@ -8766,7 +8738,7 @@ pub const FuncGen = struct {...@@ -8766,7 +8738,7 @@ pub const FuncGen = struct {
8766 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {8738 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {
8767 const elem_ty = operand_ty.childType(mod);8739 const elem_ty = operand_ty.childType(mod);
8768 const llvm_vector_ty = try o.lowerType(inst_ty);8740 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
8771 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;8743 const bitcast_ok = elem_ty.bitSize(pt) == elem_ty.abiSize(pt) * 8;
8772 if (bitcast_ok) {8744 if (bitcast_ok) {
...@@ -8831,9 +8803,9 @@ pub const FuncGen = struct {...@@ -8831,9 +8803,9 @@ pub const FuncGen = struct {
8831 }8803 }
88328804
8833 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8805 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8834 const o = self.dg.object;8806 const o = self.ng.object;
8835 const pt = o.pt;8807 const pt = o.pt;
8836 const mod = pt.zcu;8808 const zcu = pt.zcu;
8837 const arg_val = self.args[self.arg_index];8809 const arg_val = self.args[self.arg_index];
8838 self.arg_index += 1;8810 self.arg_index += 1;
88398811
...@@ -8846,9 +8818,8 @@ pub const FuncGen = struct {...@@ -8846,9 +8818,8 @@ pub const FuncGen = struct {
8846 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;8818 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
8847 if (name == .none) return arg_val;8819 if (name == .none) return arg_val;
88488820
8849 const func_index = self.dg.decl.getOwnedFunctionIndex();8821 const func = zcu.funcInfo(zcu.navValue(self.ng.nav_index).toIntern());
8850 const func = mod.funcInfo(func_index);8822 const lbrace_line = zcu.navSrcLine(func.owner_nav) + func.lbrace_line + 1;
8851 const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;
8852 const lbrace_col = func.lbrace_column + 1;8823 const lbrace_col = func.lbrace_column + 1;
88538824
8854 const debug_parameter = try o.builder.debugParameter(8825 const debug_parameter = try o.builder.debugParameter(
...@@ -8870,7 +8841,7 @@ pub const FuncGen = struct {...@@ -8870,7 +8841,7 @@ pub const FuncGen = struct {
8870 },8841 },
8871 };8842 };
88728843
8873 const owner_mod = self.dg.ownerModule();8844 const mod = self.ng.ownerModule();
8874 if (isByRef(inst_ty, pt)) {8845 if (isByRef(inst_ty, pt)) {
8875 _ = try self.wip.callIntrinsic(8846 _ = try self.wip.callIntrinsic(
8876 .normal,8847 .normal,
...@@ -8884,7 +8855,7 @@ pub const FuncGen = struct {...@@ -8884,7 +8855,7 @@ pub const FuncGen = struct {
8884 },8855 },
8885 "",8856 "",
8886 );8857 );
8887 } else if (owner_mod.optimize_mode == .Debug) {8858 } else if (mod.optimize_mode == .Debug) {
8888 const alignment = inst_ty.abiAlignment(pt).toLlvm();8859 const alignment = inst_ty.abiAlignment(pt).toLlvm();
8889 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);8860 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
8890 _ = try self.wip.store(.normal, arg_val, alloca, alignment);8861 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
...@@ -8920,7 +8891,7 @@ pub const FuncGen = struct {...@@ -8920,7 +8891,7 @@ pub const FuncGen = struct {
8920 }8891 }
89218892
8922 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8893 fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8923 const o = self.dg.object;8894 const o = self.ng.object;
8924 const pt = o.pt;8895 const pt = o.pt;
8925 const mod = pt.zcu;8896 const mod = pt.zcu;
8926 const ptr_ty = self.typeOfIndex(inst);8897 const ptr_ty = self.typeOfIndex(inst);
...@@ -8934,7 +8905,7 @@ pub const FuncGen = struct {...@@ -8934,7 +8905,7 @@ pub const FuncGen = struct {
8934 }8905 }
89358906
8936 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8907 fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8937 const o = self.dg.object;8908 const o = self.ng.object;
8938 const pt = o.pt;8909 const pt = o.pt;
8939 const mod = pt.zcu;8910 const mod = pt.zcu;
8940 const ptr_ty = self.typeOfIndex(inst);8911 const ptr_ty = self.typeOfIndex(inst);
...@@ -8954,7 +8925,7 @@ pub const FuncGen = struct {...@@ -8954,7 +8925,7 @@ pub const FuncGen = struct {
8954 llvm_ty: Builder.Type,8925 llvm_ty: Builder.Type,
8955 alignment: Builder.Alignment,8926 alignment: Builder.Alignment,
8956 ) Allocator.Error!Builder.Value {8927 ) Allocator.Error!Builder.Value {
8957 const target = self.dg.object.pt.zcu.getTarget();8928 const target = self.ng.object.pt.zcu.getTarget();
8958 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);8929 return buildAllocaInner(&self.wip, llvm_ty, alignment, target);
8959 }8930 }
89608931
...@@ -8964,12 +8935,12 @@ pub const FuncGen = struct {...@@ -8964,12 +8935,12 @@ pub const FuncGen = struct {
8964 ty: Type,8935 ty: Type,
8965 alignment: Builder.Alignment,8936 alignment: Builder.Alignment,
8966 ) Allocator.Error!Builder.Value {8937 ) Allocator.Error!Builder.Value {
8967 const o = self.dg.object;8938 const o = self.ng.object;
8968 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment);8939 return self.buildAlloca(try o.builder.arrayType(ty.abiSize(o.pt), .i8), alignment);
8969 }8940 }
89708941
8971 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {8942 fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
8972 const o = self.dg.object;8943 const o = self.ng.object;
8973 const pt = o.pt;8944 const pt = o.pt;
8974 const mod = pt.zcu;8945 const mod = pt.zcu;
8975 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;8946 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -8979,7 +8950,7 @@ pub const FuncGen = struct {...@@ -8979,7 +8950,7 @@ pub const FuncGen = struct {
89798950
8980 const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false;8951 const val_is_undef = if (try self.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(mod) else false;
8981 if (val_is_undef) {8952 if (val_is_undef) {
8982 const owner_mod = self.dg.ownerModule();8953 const owner_mod = self.ng.ownerModule();
89838954
8984 // Even if safety is disabled, we still emit a memset to undefined since it conveys8955 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8985 // extra information to LLVM, and LLVM will optimize it out. Safety makes the difference8956 // extra information to LLVM, and LLVM will optimize it out. Safety makes the difference
...@@ -9029,7 +9000,7 @@ pub const FuncGen = struct {...@@ -9029,7 +9000,7 @@ pub const FuncGen = struct {
9029 ///9000 ///
9030 /// The first instruction of `body_tail` is the one whose copy we want to elide.9001 /// The first instruction of `body_tail` is the one whose copy we want to elide.
9031 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {9002 fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool {
9032 const o = fg.dg.object;9003 const o = fg.ng.object;
9033 const mod = o.pt.zcu;9004 const mod = o.pt.zcu;
9034 const ip = &mod.intern_pool;9005 const ip = &mod.intern_pool;
9035 for (body_tail[1..]) |body_inst| {9006 for (body_tail[1..]) |body_inst| {
...@@ -9045,7 +9016,7 @@ pub const FuncGen = struct {...@@ -9045,7 +9016,7 @@ pub const FuncGen = struct {
9045 }9016 }
90469017
9047 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {9018 fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value {
9048 const o = fg.dg.object;9019 const o = fg.ng.object;
9049 const pt = o.pt;9020 const pt = o.pt;
9050 const mod = pt.zcu;9021 const mod = pt.zcu;
9051 const inst = body_tail[0];9022 const inst = body_tail[0];
...@@ -9077,7 +9048,7 @@ pub const FuncGen = struct {...@@ -9077,7 +9048,7 @@ pub const FuncGen = struct {
90779048
9078 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9049 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9079 _ = inst;9050 _ = inst;
9080 const o = self.dg.object;9051 const o = self.ng.object;
9081 const llvm_usize = try o.lowerType(Type.usize);9052 const llvm_usize = try o.lowerType(Type.usize);
9082 if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) {9053 if (!target_util.supportsReturnAddress(o.pt.zcu.getTarget())) {
9083 // https://github.com/ziglang/zig/issues/119469054 // https://github.com/ziglang/zig/issues/11946
...@@ -9089,7 +9060,7 @@ pub const FuncGen = struct {...@@ -9089,7 +9060,7 @@ pub const FuncGen = struct {
90899060
9090 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9061 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9091 _ = inst;9062 _ = inst;
9092 const o = self.dg.object;9063 const o = self.ng.object;
9093 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");9064 const result = try self.wip.callIntrinsic(.normal, .none, .frameaddress, &.{.ptr}, &.{.@"0"}, "");
9094 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");9065 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");
9095 }9066 }
...@@ -9106,7 +9077,7 @@ pub const FuncGen = struct {...@@ -9106,7 +9077,7 @@ pub const FuncGen = struct {
9106 inst: Air.Inst.Index,9077 inst: Air.Inst.Index,
9107 kind: Builder.Function.Instruction.CmpXchg.Kind,9078 kind: Builder.Function.Instruction.CmpXchg.Kind,
9108 ) !Builder.Value {9079 ) !Builder.Value {
9109 const o = self.dg.object;9080 const o = self.ng.object;
9110 const pt = o.pt;9081 const pt = o.pt;
9111 const mod = pt.zcu;9082 const mod = pt.zcu;
9112 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;9083 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -9157,7 +9128,7 @@ pub const FuncGen = struct {...@@ -9157,7 +9128,7 @@ pub const FuncGen = struct {
9157 }9128 }
91589129
9159 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9130 fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9160 const o = self.dg.object;9131 const o = self.ng.object;
9161 const pt = o.pt;9132 const pt = o.pt;
9162 const mod = pt.zcu;9133 const mod = pt.zcu;
9163 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;9134 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
...@@ -9221,7 +9192,7 @@ pub const FuncGen = struct {...@@ -9221,7 +9192,7 @@ pub const FuncGen = struct {
9221 }9192 }
92229193
9223 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9194 fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9224 const o = self.dg.object;9195 const o = self.ng.object;
9225 const pt = o.pt;9196 const pt = o.pt;
9226 const mod = pt.zcu;9197 const mod = pt.zcu;
9227 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;9198 const atomic_load = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
...@@ -9269,7 +9240,7 @@ pub const FuncGen = struct {...@@ -9269,7 +9240,7 @@ pub const FuncGen = struct {
9269 inst: Air.Inst.Index,9240 inst: Air.Inst.Index,
9270 ordering: Builder.AtomicOrdering,9241 ordering: Builder.AtomicOrdering,
9271 ) !Builder.Value {9242 ) !Builder.Value {
9272 const o = self.dg.object;9243 const o = self.ng.object;
9273 const pt = o.pt;9244 const pt = o.pt;
9274 const mod = pt.zcu;9245 const mod = pt.zcu;
9275 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9246 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -9294,7 +9265,7 @@ pub const FuncGen = struct {...@@ -9294,7 +9265,7 @@ pub const FuncGen = struct {
9294 }9265 }
92959266
9296 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {9267 fn airMemset(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !Builder.Value {
9297 const o = self.dg.object;9268 const o = self.ng.object;
9298 const pt = o.pt;9269 const pt = o.pt;
9299 const mod = pt.zcu;9270 const mod = pt.zcu;
9300 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9271 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -9329,7 +9300,7 @@ pub const FuncGen = struct {...@@ -9329,7 +9300,7 @@ pub const FuncGen = struct {
9329 } else {9300 } else {
9330 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);9301 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
9331 }9302 }
9332 const owner_mod = self.dg.ownerModule();9303 const owner_mod = self.ng.ownerModule();
9333 if (safety and owner_mod.valgrind) {9304 if (safety and owner_mod.valgrind) {
9334 try self.valgrindMarkUndef(dest_ptr, len);9305 try self.valgrindMarkUndef(dest_ptr, len);
9335 }9306 }
...@@ -9435,7 +9406,7 @@ pub const FuncGen = struct {...@@ -9435,7 +9406,7 @@ pub const FuncGen = struct {
9435 dest_ptr_align: Builder.Alignment,9406 dest_ptr_align: Builder.Alignment,
9436 access_kind: Builder.MemoryAccessKind,9407 access_kind: Builder.MemoryAccessKind,
9437 ) !void {9408 ) !void {
9438 const o = self.dg.object;9409 const o = self.ng.object;
9439 const usize_zero = try o.builder.intValue(try o.lowerType(Type.usize), 0);9410 const usize_zero = try o.builder.intValue(try o.lowerType(Type.usize), 0);
9440 const cond = try self.cmp(.normal, .neq, Type.usize, len, usize_zero);9411 const cond = try self.cmp(.normal, .neq, Type.usize, len, usize_zero);
9441 const memset_block = try self.wip.block(1, "MemsetTrapSkip");9412 const memset_block = try self.wip.block(1, "MemsetTrapSkip");
...@@ -9448,7 +9419,7 @@ pub const FuncGen = struct {...@@ -9448,7 +9419,7 @@ pub const FuncGen = struct {
9448 }9419 }
94499420
9450 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9421 fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9451 const o = self.dg.object;9422 const o = self.ng.object;
9452 const pt = o.pt;9423 const pt = o.pt;
9453 const mod = pt.zcu;9424 const mod = pt.zcu;
9454 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9425 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -9502,7 +9473,7 @@ pub const FuncGen = struct {...@@ -9502,7 +9473,7 @@ pub const FuncGen = struct {
9502 }9473 }
95039474
9504 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9475 fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9505 const o = self.dg.object;9476 const o = self.ng.object;
9506 const pt = o.pt;9477 const pt = o.pt;
9507 const mod = pt.zcu;9478 const mod = pt.zcu;
9508 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;9479 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
...@@ -9524,7 +9495,7 @@ pub const FuncGen = struct {...@@ -9524,7 +9495,7 @@ pub const FuncGen = struct {
9524 }9495 }
95259496
9526 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9497 fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9527 const o = self.dg.object;9498 const o = self.ng.object;
9528 const pt = o.pt;9499 const pt = o.pt;
9529 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9500 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9530 const un_ty = self.typeOf(ty_op.operand);9501 const un_ty = self.typeOf(ty_op.operand);
...@@ -9563,7 +9534,7 @@ pub const FuncGen = struct {...@@ -9563,7 +9534,7 @@ pub const FuncGen = struct {
9563 }9534 }
95649535
9565 fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {9536 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;
9567 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9538 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9568 const inst_ty = self.typeOfIndex(inst);9539 const inst_ty = self.typeOfIndex(inst);
9569 const operand_ty = self.typeOf(ty_op.operand);9540 const operand_ty = self.typeOf(ty_op.operand);
...@@ -9581,7 +9552,7 @@ pub const FuncGen = struct {...@@ -9581,7 +9552,7 @@ pub const FuncGen = struct {
9581 }9552 }
95829553
9583 fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, intrinsic: Builder.Intrinsic) !Builder.Value {9554 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;
9585 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9556 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9586 const inst_ty = self.typeOfIndex(inst);9557 const inst_ty = self.typeOfIndex(inst);
9587 const operand_ty = self.typeOf(ty_op.operand);9558 const operand_ty = self.typeOf(ty_op.operand);
...@@ -9599,7 +9570,7 @@ pub const FuncGen = struct {...@@ -9599,7 +9570,7 @@ pub const FuncGen = struct {
9599 }9570 }
96009571
9601 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9572 fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9602 const o = self.dg.object;9573 const o = self.ng.object;
9603 const mod = o.pt.zcu;9574 const mod = o.pt.zcu;
9604 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9575 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9605 const operand_ty = self.typeOf(ty_op.operand);9576 const operand_ty = self.typeOf(ty_op.operand);
...@@ -9633,7 +9604,7 @@ pub const FuncGen = struct {...@@ -9633,7 +9604,7 @@ pub const FuncGen = struct {
9633 }9604 }
96349605
9635 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9606 fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9636 const o = self.dg.object;9607 const o = self.ng.object;
9637 const mod = o.pt.zcu;9608 const mod = o.pt.zcu;
9638 const ip = &mod.intern_pool;9609 const ip = &mod.intern_pool;
9639 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9610 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -9665,7 +9636,7 @@ pub const FuncGen = struct {...@@ -9665,7 +9636,7 @@ pub const FuncGen = struct {
9665 }9636 }
96669637
9667 fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9638 fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9668 const o = self.dg.object;9639 const o = self.ng.object;
9669 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;9640 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
9670 const operand = try self.resolveInst(un_op);9641 const operand = try self.resolveInst(un_op);
9671 const enum_ty = self.typeOf(un_op);9642 const enum_ty = self.typeOf(un_op);
...@@ -9683,22 +9654,21 @@ pub const FuncGen = struct {...@@ -9683,22 +9654,21 @@ pub const FuncGen = struct {
9683 }9654 }
96849655
9685 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {9656 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9686 const o = self.dg.object;9657 const o = self.ng.object;
9687 const pt = o.pt;9658 const pt = o.pt;
9688 const zcu = pt.zcu;9659 const zcu = pt.zcu;
9689 const ip = &zcu.intern_pool;9660 const ip = &zcu.intern_pool;
9690 const enum_type = ip.loadEnumType(enum_ty.toIntern());9661 const enum_type = ip.loadEnumType(enum_ty.toIntern());
96919662
9692 // TODO: detect when the type changes and re-emit this function.9663 // 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());
9694 if (gop.found_existing) return gop.value_ptr.*;9665 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);
9698 const target = zcu.root_mod.resolved_target.result;9668 const target = zcu.root_mod.resolved_target.result;
9699 const function_index = try o.builder.addFunction(9669 const function_index = try o.builder.addFunction(
9700 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),9670 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)}),
9702 toLlvmAddressSpace(.generic, target),9672 toLlvmAddressSpace(.generic, target),
9703 );9673 );
97049674
...@@ -9741,7 +9711,7 @@ pub const FuncGen = struct {...@@ -9741,7 +9711,7 @@ pub const FuncGen = struct {
9741 }9711 }
97429712
9743 fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9713 fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9744 const o = self.dg.object;9714 const o = self.ng.object;
9745 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;9715 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
9746 const operand = try self.resolveInst(un_op);9716 const operand = try self.resolveInst(un_op);
9747 const enum_ty = self.typeOf(un_op);9717 const enum_ty = self.typeOf(un_op);
...@@ -9759,7 +9729,7 @@ pub const FuncGen = struct {...@@ -9759,7 +9729,7 @@ pub const FuncGen = struct {
9759 }9729 }
97609730
9761 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9731 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9762 const o = self.dg.object;9732 const o = self.ng.object;
9763 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;9733 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
9764 const operand = try self.resolveInst(un_op);9734 const operand = try self.resolveInst(un_op);
9765 const slice_ty = self.typeOfIndex(inst);9735 const slice_ty = self.typeOfIndex(inst);
...@@ -9774,7 +9744,7 @@ pub const FuncGen = struct {...@@ -9774,7 +9744,7 @@ pub const FuncGen = struct {
9774 }9744 }
97759745
9776 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9746 fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9777 const o = self.dg.object;9747 const o = self.ng.object;
9778 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;9748 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
9779 const scalar = try self.resolveInst(ty_op.operand);9749 const scalar = try self.resolveInst(ty_op.operand);
9780 const vector_ty = self.typeOfIndex(inst);9750 const vector_ty = self.typeOfIndex(inst);
...@@ -9792,7 +9762,7 @@ pub const FuncGen = struct {...@@ -9792,7 +9762,7 @@ pub const FuncGen = struct {
9792 }9762 }
97939763
9794 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9764 fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9795 const o = self.dg.object;9765 const o = self.ng.object;
9796 const pt = o.pt;9766 const pt = o.pt;
9797 const mod = pt.zcu;9767 const mod = pt.zcu;
9798 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;9768 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -9848,7 +9818,7 @@ pub const FuncGen = struct {...@@ -9848,7 +9818,7 @@ pub const FuncGen = struct {
9848 vector_len: usize,9818 vector_len: usize,
9849 accum_init: Builder.Value,9819 accum_init: Builder.Value,
9850 ) !Builder.Value {9820 ) !Builder.Value {
9851 const o = self.dg.object;9821 const o = self.ng.object;
9852 const usize_ty = try o.lowerType(Type.usize);9822 const usize_ty = try o.lowerType(Type.usize);
9853 const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len);9823 const llvm_vector_len = try o.builder.intValue(usize_ty, vector_len);
9854 const llvm_result_ty = accum_init.typeOfWip(&self.wip);9824 const llvm_result_ty = accum_init.typeOfWip(&self.wip);
...@@ -9902,7 +9872,7 @@ pub const FuncGen = struct {...@@ -9902,7 +9872,7 @@ pub const FuncGen = struct {
9902 }9872 }
99039873
9904 fn airReduce(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) !Builder.Value {9874 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;
9906 const mod = o.pt.zcu;9876 const mod = o.pt.zcu;
9907 const target = mod.getTarget();9877 const target = mod.getTarget();
99089878
...@@ -10012,7 +9982,7 @@ pub const FuncGen = struct {...@@ -10012,7 +9982,7 @@ pub const FuncGen = struct {
10012 }9982 }
100139983
10014 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9984 fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10015 const o = self.dg.object;9985 const o = self.ng.object;
10016 const pt = o.pt;9986 const pt = o.pt;
10017 const mod = pt.zcu;9987 const mod = pt.zcu;
10018 const ip = &mod.intern_pool;9988 const ip = &mod.intern_pool;
...@@ -10133,7 +10103,7 @@ pub const FuncGen = struct {...@@ -10133,7 +10103,7 @@ pub const FuncGen = struct {
10133 }10103 }
1013410104
10135 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10105 fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10136 const o = self.dg.object;10106 const o = self.ng.object;
10137 const pt = o.pt;10107 const pt = o.pt;
10138 const mod = pt.zcu;10108 const mod = pt.zcu;
10139 const ip = &mod.intern_pool;10109 const ip = &mod.intern_pool;
...@@ -10256,7 +10226,7 @@ pub const FuncGen = struct {...@@ -10256,7 +10226,7 @@ pub const FuncGen = struct {
10256 }10226 }
1025710227
10258 fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10228 fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10259 const o = self.dg.object;10229 const o = self.ng.object;
10260 const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;10230 const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
1026110231
10262 comptime assert(@intFromEnum(std.builtin.PrefetchOptions.Rw.read) == 0);10232 comptime assert(@intFromEnum(std.builtin.PrefetchOptions.Rw.read) == 0);
...@@ -10306,7 +10276,7 @@ pub const FuncGen = struct {...@@ -10306,7 +10276,7 @@ pub const FuncGen = struct {
10306 }10276 }
1030710277
10308 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10278 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10309 const o = self.dg.object;10279 const o = self.ng.object;
10310 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;10280 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
10311 const inst_ty = self.typeOfIndex(inst);10281 const inst_ty = self.typeOfIndex(inst);
10312 const operand = try self.resolveInst(ty_op.operand);10282 const operand = try self.resolveInst(ty_op.operand);
...@@ -10324,12 +10294,12 @@ pub const FuncGen = struct {...@@ -10324,12 +10294,12 @@ pub const FuncGen = struct {
10324 0 => @field(Builder.Intrinsic, basename ++ ".x"),10294 0 => @field(Builder.Intrinsic, basename ++ ".x"),
10325 1 => @field(Builder.Intrinsic, basename ++ ".y"),10295 1 => @field(Builder.Intrinsic, basename ++ ".y"),
10326 2 => @field(Builder.Intrinsic, basename ++ ".z"),10296 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),
10328 }, &.{}, &.{}, "");10298 }, &.{}, &.{}, "");
10329 }10299 }
1033010300
10331 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10301 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10332 const o = self.dg.object;10302 const o = self.ng.object;
10333 const target = o.pt.zcu.getTarget();10303 const target = o.pt.zcu.getTarget();
10334 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10304 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1033510305
...@@ -10339,7 +10309,7 @@ pub const FuncGen = struct {...@@ -10339,7 +10309,7 @@ pub const FuncGen = struct {
10339 }10309 }
1034010310
10341 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10311 fn airWorkGroupSize(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10342 const o = self.dg.object;10312 const o = self.ng.object;
10343 const target = o.pt.zcu.getTarget();10313 const target = o.pt.zcu.getTarget();
10344 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10314 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1034510315
...@@ -10362,7 +10332,7 @@ pub const FuncGen = struct {...@@ -10362,7 +10332,7 @@ pub const FuncGen = struct {
10362 }10332 }
1036310333
10364 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10334 fn airWorkGroupId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
10365 const o = self.dg.object;10335 const o = self.ng.object;
10366 const target = o.pt.zcu.getTarget();10336 const target = o.pt.zcu.getTarget();
10367 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures10337 assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures
1036810338
...@@ -10372,7 +10342,7 @@ pub const FuncGen = struct {...@@ -10372,7 +10342,7 @@ pub const FuncGen = struct {
10372 }10342 }
1037310343
10374 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {10344 fn getErrorNameTable(self: *FuncGen) Allocator.Error!Builder.Variable.Index {
10375 const o = self.dg.object;10345 const o = self.ng.object;
10376 const pt = o.pt;10346 const pt = o.pt;
1037710347
10378 const table = o.error_name_table;10348 const table = o.error_name_table;
...@@ -10401,7 +10371,7 @@ pub const FuncGen = struct {...@@ -10401,7 +10371,7 @@ pub const FuncGen = struct {
10401 opt_handle: Builder.Value,10371 opt_handle: Builder.Value,
10402 is_by_ref: bool,10372 is_by_ref: bool,
10403 ) Allocator.Error!Builder.Value {10373 ) Allocator.Error!Builder.Value {
10404 const o = self.dg.object;10374 const o = self.ng.object;
10405 const field = b: {10375 const field = b: {
10406 if (is_by_ref) {10376 if (is_by_ref) {
10407 const field_ptr = try self.wip.gepStruct(opt_llvm_ty, opt_handle, 1, "");10377 const field_ptr = try self.wip.gepStruct(opt_llvm_ty, opt_handle, 1, "");
...@@ -10422,7 +10392,7 @@ pub const FuncGen = struct {...@@ -10422,7 +10392,7 @@ pub const FuncGen = struct {
10422 opt_ty: Type,10392 opt_ty: Type,
10423 can_elide_load: bool,10393 can_elide_load: bool,
10424 ) !Builder.Value {10394 ) !Builder.Value {
10425 const o = fg.dg.object;10395 const o = fg.ng.object;
10426 const pt = o.pt;10396 const pt = o.pt;
10427 const mod = pt.zcu;10397 const mod = pt.zcu;
10428 const payload_ty = opt_ty.optionalChild(mod);10398 const payload_ty = opt_ty.optionalChild(mod);
...@@ -10451,7 +10421,7 @@ pub const FuncGen = struct {...@@ -10451,7 +10421,7 @@ pub const FuncGen = struct {
10451 payload: Builder.Value,10421 payload: Builder.Value,
10452 non_null_bit: Builder.Value,10422 non_null_bit: Builder.Value,
10453 ) !Builder.Value {10423 ) !Builder.Value {
10454 const o = self.dg.object;10424 const o = self.ng.object;
10455 const pt = o.pt;10425 const pt = o.pt;
10456 const optional_llvm_ty = try o.lowerType(optional_ty);10426 const optional_llvm_ty = try o.lowerType(optional_ty);
10457 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");10427 const non_null_field = try self.wip.cast(.zext, non_null_bit, .i8, "");
...@@ -10483,7 +10453,7 @@ pub const FuncGen = struct {...@@ -10483,7 +10453,7 @@ pub const FuncGen = struct {
10483 struct_ptr_ty: Type,10453 struct_ptr_ty: Type,
10484 field_index: u32,10454 field_index: u32,
10485 ) !Builder.Value {10455 ) !Builder.Value {
10486 const o = self.dg.object;10456 const o = self.ng.object;
10487 const pt = o.pt;10457 const pt = o.pt;
10488 const mod = pt.zcu;10458 const mod = pt.zcu;
10489 const struct_ty = struct_ptr_ty.childType(mod);10459 const struct_ty = struct_ptr_ty.childType(mod);
...@@ -10552,7 +10522,7 @@ pub const FuncGen = struct {...@@ -10552,7 +10522,7 @@ pub const FuncGen = struct {
10552 // "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. "10522 // "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. "
10553 // => so load the byte aligned value and trunc the unwanted bits.10523 // => so load the byte aligned value and trunc the unwanted bits.
1055410524
10555 const o = fg.dg.object;10525 const o = fg.ng.object;
10556 const pt = o.pt;10526 const pt = o.pt;
10557 const mod = pt.zcu;10527 const mod = pt.zcu;
10558 const payload_llvm_ty = try o.lowerType(payload_ty);10528 const payload_llvm_ty = try o.lowerType(payload_ty);
...@@ -10599,7 +10569,7 @@ pub const FuncGen = struct {...@@ -10599,7 +10569,7 @@ pub const FuncGen = struct {
10599 ptr_alignment: Builder.Alignment,10569 ptr_alignment: Builder.Alignment,
10600 access_kind: Builder.MemoryAccessKind,10570 access_kind: Builder.MemoryAccessKind,
10601 ) !Builder.Value {10571 ) !Builder.Value {
10602 const o = fg.dg.object;10572 const o = fg.ng.object;
10603 const pt = o.pt;10573 const pt = o.pt;
10604 //const pointee_llvm_ty = try o.lowerType(pointee_type);10574 //const pointee_llvm_ty = try o.lowerType(pointee_type);
10605 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(pt)).toLlvm();10575 const result_align = InternPool.Alignment.fromLlvm(ptr_alignment).max(pointee_type.abiAlignment(pt)).toLlvm();
...@@ -10620,7 +10590,7 @@ pub const FuncGen = struct {...@@ -10620,7 +10590,7 @@ pub const FuncGen = struct {
10620 /// alloca and copies the value into it, then returns the alloca instruction.10590 /// alloca and copies the value into it, then returns the alloca instruction.
10621 /// For isByRef=false types, it creates a load instruction and returns it.10591 /// For isByRef=false types, it creates a load instruction and returns it.
10622 fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {10592 fn load(self: *FuncGen, ptr: Builder.Value, ptr_ty: Type) !Builder.Value {
10623 const o = self.dg.object;10593 const o = self.ng.object;
10624 const pt = o.pt;10594 const pt = o.pt;
10625 const mod = pt.zcu;10595 const mod = pt.zcu;
10626 const info = ptr_ty.ptrInfo(mod);10596 const info = ptr_ty.ptrInfo(mod);
...@@ -10693,7 +10663,7 @@ pub const FuncGen = struct {...@@ -10693,7 +10663,7 @@ pub const FuncGen = struct {
10693 elem: Builder.Value,10663 elem: Builder.Value,
10694 ordering: Builder.AtomicOrdering,10664 ordering: Builder.AtomicOrdering,
10695 ) !void {10665 ) !void {
10696 const o = self.dg.object;10666 const o = self.ng.object;
10697 const pt = o.pt;10667 const pt = o.pt;
10698 const mod = pt.zcu;10668 const mod = pt.zcu;
10699 const info = ptr_ty.ptrInfo(mod);10669 const info = ptr_ty.ptrInfo(mod);
...@@ -10784,7 +10754,7 @@ pub const FuncGen = struct {...@@ -10784,7 +10754,7 @@ pub const FuncGen = struct {
1078410754
10785 fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {10755 fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {
10786 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;10756 const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
10787 const o = fg.dg.object;10757 const o = fg.ng.object;
10788 const usize_ty = try o.lowerType(Type.usize);10758 const usize_ty = try o.lowerType(Type.usize);
10789 const zero = try o.builder.intValue(usize_ty, 0);10759 const zero = try o.builder.intValue(usize_ty, 0);
10790 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);10760 const req = try o.builder.intValue(usize_ty, VG_USERREQ__MAKE_MEM_UNDEFINED);
...@@ -10802,7 +10772,7 @@ pub const FuncGen = struct {...@@ -10802,7 +10772,7 @@ pub const FuncGen = struct {
10802 a4: Builder.Value,10772 a4: Builder.Value,
10803 a5: Builder.Value,10773 a5: Builder.Value,
10804 ) Allocator.Error!Builder.Value {10774 ) Allocator.Error!Builder.Value {
10805 const o = fg.dg.object;10775 const o = fg.ng.object;
10806 const pt = o.pt;10776 const pt = o.pt;
10807 const mod = pt.zcu;10777 const mod = pt.zcu;
10808 const target = mod.getTarget();10778 const target = mod.getTarget();
...@@ -10869,13 +10839,13 @@ pub const FuncGen = struct {...@@ -10869,13 +10839,13 @@ pub const FuncGen = struct {
10869 }10839 }
1087010840
10871 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {10841 fn typeOf(fg: *FuncGen, inst: Air.Inst.Ref) Type {
10872 const o = fg.dg.object;10842 const o = fg.ng.object;
10873 const mod = o.pt.zcu;10843 const mod = o.pt.zcu;
10874 return fg.air.typeOf(inst, &mod.intern_pool);10844 return fg.air.typeOf(inst, &mod.intern_pool);
10875 }10845 }
1087610846
10877 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {10847 fn typeOfIndex(fg: *FuncGen, inst: Air.Inst.Index) Type {
10878 const o = fg.dg.object;10848 const o = fg.ng.object;
10879 const mod = o.pt.zcu;10849 const mod = o.pt.zcu;
10880 return fg.air.typeOfIndex(inst, &mod.intern_pool);10850 return fg.air.typeOfIndex(inst, &mod.intern_pool);
10881 }10851 }
src/codegen/spirv.zig+287-299
...@@ -31,9 +31,9 @@ const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);...@@ -31,9 +31,9 @@ const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);
3131
32pub const zig_call_abi_ver = 3;32pub 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);
35const PtrTypeMap = std.AutoHashMapUnmanaged(35const PtrTypeMap = std.AutoHashMapUnmanaged(
36 struct { InternPool.Index, StorageClass, DeclGen.Repr },36 struct { InternPool.Index, StorageClass, NavGen.Repr },
37 struct { ty_id: IdRef, fwd_emitted: bool },37 struct { ty_id: IdRef, fwd_emitted: bool },
38);38);
3939
...@@ -142,7 +142,7 @@ const ControlFlow = union(enum) {...@@ -142,7 +142,7 @@ const ControlFlow = union(enum) {
142};142};
143143
144/// This structure holds information that is relevant to the entire compilation,144/// This structure holds information that is relevant to the entire compilation,
145/// in contrast to `DeclGen`, which only holds relevant information about a145/// in contrast to `NavGen`, which only holds relevant information about a
146/// single decl.146/// single decl.
147pub const Object = struct {147pub const Object = struct {
148 /// A general-purpose allocator that can be used for any allocation for this Object.148 /// A general-purpose allocator that can be used for any allocation for this Object.
...@@ -153,10 +153,10 @@ pub const Object = struct {...@@ -153,10 +153,10 @@ pub const Object = struct {
153153
154 /// The Zig module that this object file is generated for.154 /// The Zig module that this object file is generated for.
155 /// A map of Zig decl indices to SPIR-V decl indices.155 /// 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
158 /// A map of Zig InternPool indices for anonymous decls to SPIR-V decl indices.158 /// 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
161 /// A map that maps AIR intern pool indices to SPIR-V result-ids.161 /// A map that maps AIR intern pool indices to SPIR-V result-ids.
162 intern_map: InternMap = .{},162 intern_map: InternMap = .{},
...@@ -178,31 +178,29 @@ pub const Object = struct {...@@ -178,31 +178,29 @@ pub const Object = struct {
178178
179 pub fn deinit(self: *Object) void {179 pub fn deinit(self: *Object) void {
180 self.spv.deinit();180 self.spv.deinit();
181 self.decl_link.deinit(self.gpa);181 self.nav_link.deinit(self.gpa);
182 self.anon_decl_link.deinit(self.gpa);182 self.uav_link.deinit(self.gpa);
183 self.intern_map.deinit(self.gpa);183 self.intern_map.deinit(self.gpa);
184 self.ptr_types.deinit(self.gpa);184 self.ptr_types.deinit(self.gpa);
185 }185 }
186186
187 fn genDecl(187 fn genNav(
188 self: *Object,188 self: *Object,
189 pt: Zcu.PerThread,189 pt: Zcu.PerThread,
190 decl_index: InternPool.DeclIndex,190 nav_index: InternPool.Nav.Index,
191 air: Air,191 air: Air,
192 liveness: Liveness,192 liveness: Liveness,
193 ) !void {193 ) !void {
194 const zcu = pt.zcu;194 const zcu = pt.zcu;
195 const gpa = zcu.gpa;195 const gpa = zcu.gpa;
196 const decl = zcu.declPtr(decl_index);196 const structured_cfg = zcu.navFileScope(nav_index).mod.structured_cfg;
197 const namespace = zcu.namespacePtr(decl.src_namespace);
198 const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg;
199197
200 var decl_gen = DeclGen{198 var nav_gen = NavGen{
201 .gpa = gpa,199 .gpa = gpa,
202 .object = self,200 .object = self,
203 .pt = pt,201 .pt = pt,
204 .spv = &self.spv,202 .spv = &self.spv,
205 .decl_index = decl_index,203 .owner_nav = nav_index,
206 .air = air,204 .air = air,
207 .liveness = liveness,205 .liveness = liveness,
208 .intern_map = &self.intern_map,206 .intern_map = &self.intern_map,
...@@ -212,18 +210,18 @@ pub const Object = struct {...@@ -212,18 +210,18 @@ pub const Object = struct {
212 false => .{ .unstructured = .{} },210 false => .{ .unstructured = .{} },
213 },211 },
214 .current_block_label = undefined,212 .current_block_label = undefined,
215 .base_line = decl.navSrcLine(zcu),213 .base_line = zcu.navSrcLine(nav_index),
216 };214 };
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) {
220 error.CodegenFail => {218 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.?);
222 },220 },
223 else => |other| {221 else => |other| {
224 // There might be an error that happened *after* self.error_msg222 // There might be an error that happened *after* self.error_msg
225 // was already allocated, so be sure to free it.223 // 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| {
227 error_msg.deinit(gpa);225 error_msg.deinit(gpa);
228 }226 }
229227
...@@ -239,31 +237,30 @@ pub const Object = struct {...@@ -239,31 +237,30 @@ pub const Object = struct {
239 air: Air,237 air: Air,
240 liveness: Liveness,238 liveness: Liveness,
241 ) !void {239 ) !void {
242 const decl_index = pt.zcu.funcInfo(func_index).owner_decl;240 const nav = pt.zcu.funcInfo(func_index).owner_nav;
243 // TODO: Separate types for generating decls and functions?241 // 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);
245 }243 }
246244
247 pub fn updateDecl(245 pub fn updateNav(
248 self: *Object,246 self: *Object,
249 pt: Zcu.PerThread,247 pt: Zcu.PerThread,
250 decl_index: InternPool.DeclIndex,248 nav: InternPool.Nav.Index,
251 ) !void {249 ) !void {
252 try self.genDecl(pt, decl_index, undefined, undefined);250 try self.genNav(pt, nav, undefined, undefined);
253 }251 }
254252
255 /// Fetch or allocate a result id for decl index. This function also marks the decl as alive.253 /// Fetch or allocate a result id for nav index. This function also marks the nav as alive.
256 /// Note: Function does not actually generate the decl, it just allocates an index.254 /// Note: Function does not actually generate the nav, it just allocates an index.
257 pub fn resolveDecl(self: *Object, zcu: *Zcu, decl_index: InternPool.DeclIndex) !SpvModule.Decl.Index {255 pub fn resolveNav(self: *Object, zcu: *Zcu, nav_index: InternPool.Nav.Index) !SpvModule.Decl.Index {
258 const decl = zcu.declPtr(decl_index);256 const ip = &zcu.intern_pool;
259 assert(decl.has_tv); // TODO: Do we need to handle a situation where this is false?257 const entry = try self.nav_link.getOrPut(self.gpa, nav_index);
260
261 const entry = try self.decl_link.getOrPut(self.gpa, decl_index);
262 if (!entry.found_existing) {258 if (!entry.found_existing) {
259 const nav = ip.getNav(nav_index);
263 // TODO: Extern fn?260 // 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)))
265 .func262 .func
266 else switch (decl.@"addrspace") {263 else switch (nav.status.resolved.@"addrspace") {
267 .generic => .invocation_global,264 .generic => .invocation_global,
268 else => .global,265 else => .global,
269 };266 };
...@@ -276,8 +273,8 @@ pub const Object = struct {...@@ -276,8 +273,8 @@ pub const Object = struct {
276};273};
277274
278/// This structure is used to compile a declaration, and contains all relevant meta-information to deal with that.275/// This structure is used to compile a declaration, and contains all relevant meta-information to deal with that.
279const DeclGen = struct {276const NavGen = struct {
280 /// A general-purpose allocator that can be used for any allocations for this DeclGen.277 /// A general-purpose allocator that can be used for any allocations for this NavGen.
281 gpa: Allocator,278 gpa: Allocator,
282279
283 /// The object that this decl is generated into.280 /// The object that this decl is generated into.
...@@ -291,7 +288,7 @@ const DeclGen = struct {...@@ -291,7 +288,7 @@ const DeclGen = struct {
291 spv: *SpvModule,288 spv: *SpvModule,
292289
293 /// The decl we are currently generating code for.290 /// The decl we are currently generating code for.
294 decl_index: InternPool.DeclIndex,291 owner_nav: InternPool.Nav.Index,
295292
296 /// The intermediate code of the declaration we are currently generating. Note: If293 /// The intermediate code of the declaration we are currently generating. Note: If
297 /// the declaration is not a function, this value will be undefined!294 /// the declaration is not a function, this value will be undefined!
...@@ -399,8 +396,8 @@ const DeclGen = struct {...@@ -399,8 +396,8 @@ const DeclGen = struct {
399 indirect,396 indirect,
400 };397 };
401398
402 /// Free resources owned by the DeclGen.399 /// Free resources owned by the NavGen.
403 pub fn deinit(self: *DeclGen) void {400 pub fn deinit(self: *NavGen) void {
404 self.args.deinit(self.gpa);401 self.args.deinit(self.gpa);
405 self.inst_results.deinit(self.gpa);402 self.inst_results.deinit(self.gpa);
406 self.control_flow.deinit(self.gpa);403 self.control_flow.deinit(self.gpa);
...@@ -408,26 +405,26 @@ const DeclGen = struct {...@@ -408,26 +405,26 @@ const DeclGen = struct {
408 }405 }
409406
410 /// Return the target which we are currently compiling for.407 /// 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 {
412 return self.pt.zcu.getTarget();409 return self.pt.zcu.getTarget();
413 }410 }
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 {
416 @setCold(true);413 @setCold(true);
417 const zcu = self.pt.zcu;414 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);
419 assert(self.error_msg == null);416 assert(self.error_msg == null);
420 self.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, format, args);417 self.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, format, args);
421 return error.CodegenFail;418 return error.CodegenFail;
422 }419 }
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 {
425 return self.fail("TODO (SPIR-V): " ++ format, args);422 return self.fail("TODO (SPIR-V): " ++ format, args);
426 }423 }
427424
428 /// This imports the "default" extended instruction set for the target425 /// This imports the "default" extended instruction set for the target
429 /// For OpenCL, OpenCL.std.100. For Vulkan, GLSL.std.450.426 /// For OpenCL, OpenCL.std.100. For Vulkan, GLSL.std.450.
430 fn importExtendedSet(self: *DeclGen) !IdResult {427 fn importExtendedSet(self: *NavGen) !IdResult {
431 const target = self.getTarget();428 const target = self.getTarget();
432 return switch (target.os.tag) {429 return switch (target.os.tag) {
433 .opencl => try self.spv.importInstructionSet(.@"OpenCL.std"),430 .opencl => try self.spv.importInstructionSet(.@"OpenCL.std"),
...@@ -437,18 +434,18 @@ const DeclGen = struct {...@@ -437,18 +434,18 @@ const DeclGen = struct {
437 }434 }
438435
439 /// Fetch the result-id for a previously generated instruction or constant.436 /// 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 {
441 const pt = self.pt;438 const pt = self.pt;
442 const mod = pt.zcu;439 const mod = pt.zcu;
443 if (try self.air.value(inst, pt)) |val| {440 if (try self.air.value(inst, pt)) |val| {
444 const ty = self.typeOf(inst);441 const ty = self.typeOf(inst);
445 if (ty.zigTypeTag(mod) == .Fn) {442 if (ty.zigTypeTag(mod) == .Fn) {
446 const fn_decl_index = switch (mod.intern_pool.indexToKey(val.ip_index)) {443 const fn_nav = switch (mod.intern_pool.indexToKey(val.ip_index)) {
447 .extern_func => |extern_func| extern_func.decl,444 .@"extern" => |@"extern"| @"extern".owner_nav,
448 .func => |func| func.owner_decl,445 .func => |func| func.owner_nav,
449 else => unreachable,446 else => unreachable,
450 };447 };
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);
452 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});449 try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {});
453 return self.spv.declPtr(spv_decl_index).result_id;450 return self.spv.declPtr(spv_decl_index).result_id;
454 }451 }
...@@ -459,7 +456,7 @@ const DeclGen = struct {...@@ -459,7 +456,7 @@ const DeclGen = struct {
459 return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage.456 return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage.
460 }457 }
461458
462 fn resolveAnonDecl(self: *DeclGen, val: InternPool.Index) !IdRef {459 fn resolveUav(self: *NavGen, val: InternPool.Index) !IdRef {
463 // TODO: This cannot be a function at this point, but it should probably be handled anyway.460 // TODO: This cannot be a function at this point, but it should probably be handled anyway.
464461
465 const mod = self.pt.zcu;462 const mod = self.pt.zcu;
...@@ -467,7 +464,7 @@ const DeclGen = struct {...@@ -467,7 +464,7 @@ const DeclGen = struct {
467 const decl_ptr_ty_id = try self.ptrType(ty, .Generic);464 const decl_ptr_ty_id = try self.ptrType(ty, .Generic);
468465
469 const spv_decl_index = blk: {466 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 });
471 if (entry.found_existing) {468 if (entry.found_existing) {
472 try self.addFunctionDep(entry.value_ptr.*, .Function);469 try self.addFunctionDep(entry.value_ptr.*, .Function);
473470
...@@ -540,7 +537,7 @@ const DeclGen = struct {...@@ -540,7 +537,7 @@ const DeclGen = struct {
540 return try self.castToGeneric(decl_ptr_ty_id, result_id);537 return try self.castToGeneric(decl_ptr_ty_id, result_id);
541 }538 }
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 {
544 const target = self.getTarget();541 const target = self.getTarget();
545 if (target.os.tag == .vulkan) {542 if (target.os.tag == .vulkan) {
546 // Shader entry point dependencies must be variables with Input or Output storage class543 // Shader entry point dependencies must be variables with Input or Output storage class
...@@ -555,7 +552,7 @@ const DeclGen = struct {...@@ -555,7 +552,7 @@ const DeclGen = struct {
555 }552 }
556 }553 }
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 {
559 const target = self.getTarget();556 const target = self.getTarget();
560557
561 if (target.os.tag == .vulkan) {558 if (target.os.tag == .vulkan) {
...@@ -575,7 +572,7 @@ const DeclGen = struct {...@@ -575,7 +572,7 @@ const DeclGen = struct {
575 /// block we are currently generating.572 /// block we are currently generating.
576 /// Note that there is no such thing as nested blocks like in ZIR or AIR, so we don't need to573 /// Note that there is no such thing as nested blocks like in ZIR or AIR, so we don't need to
577 /// keep track of the previous block.574 /// keep track of the previous block.
578 fn beginSpvBlock(self: *DeclGen, label: IdResult) !void {575 fn beginSpvBlock(self: *NavGen, label: IdResult) !void {
579 try self.func.body.emit(self.spv.gpa, .OpLabel, .{ .id_result = label });576 try self.func.body.emit(self.spv.gpa, .OpLabel, .{ .id_result = label });
580 self.current_block_label = label;577 self.current_block_label = label;
581 }578 }
...@@ -590,7 +587,7 @@ const DeclGen = struct {...@@ -590,7 +587,7 @@ const DeclGen = struct {
590 /// TODO: The extension SPV_INTEL_arbitrary_precision_integers allows any integer size (at least up to 32 bits).587 /// TODO: The extension SPV_INTEL_arbitrary_precision_integers allows any integer size (at least up to 32 bits).
591 /// TODO: This probably needs an ABI-version as well (especially in combination with SPV_INTEL_arbitrary_precision_integers).588 /// TODO: This probably needs an ABI-version as well (especially in combination with SPV_INTEL_arbitrary_precision_integers).
592 /// TODO: Should the result of this function be cached?589 /// 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 {
594 const target = self.getTarget();591 const target = self.getTarget();
595592
596 // The backend will never be asked to compiler a 0-bit integer, so we won't have to handle those in this function.593 // 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 {...@@ -625,7 +622,7 @@ const DeclGen = struct {
625 /// In theory that could also be used, but since the spec says that it only guarantees support up to 32-bit ints there622 /// In theory that could also be used, but since the spec says that it only guarantees support up to 32-bit ints there
626 /// is no way of knowing whether those are actually supported.623 /// is no way of knowing whether those are actually supported.
627 /// TODO: Maybe this should be cached?624 /// TODO: Maybe this should be cached?
628 fn largestSupportedIntBits(self: *DeclGen) u16 {625 fn largestSupportedIntBits(self: *NavGen) u16 {
629 const target = self.getTarget();626 const target = self.getTarget();
630 return if (Target.spirv.featureSetHas(target.cpu.features, .Int64))627 return if (Target.spirv.featureSetHas(target.cpu.features, .Int64))
631 64628 64
...@@ -636,12 +633,12 @@ const DeclGen = struct {...@@ -636,12 +633,12 @@ const DeclGen = struct {
636 /// Checks whether the type is "composite int", an integer consisting of multiple native integers. These are represented by633 /// Checks whether the type is "composite int", an integer consisting of multiple native integers. These are represented by
637 /// arrays of largestSupportedIntBits().634 /// arrays of largestSupportedIntBits().
638 /// Asserts `ty` is an integer.635 /// Asserts `ty` is an integer.
639 fn isCompositeInt(self: *DeclGen, ty: Type) bool {636 fn isCompositeInt(self: *NavGen, ty: Type) bool {
640 return self.backingIntBits(ty) == null;637 return self.backingIntBits(ty) == null;
641 }638 }
642639
643 /// Checks whether the type can be directly translated to SPIR-V vectors640 /// 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 {
645 const mod = self.pt.zcu;642 const mod = self.pt.zcu;
646 const target = self.getTarget();643 const target = self.getTarget();
647 if (ty.zigTypeTag(mod) != .Vector) return false;644 if (ty.zigTypeTag(mod) != .Vector) return false;
...@@ -667,7 +664,7 @@ const DeclGen = struct {...@@ -667,7 +664,7 @@ const DeclGen = struct {
667 return is_scalar and (spirv_len or opencl_len);664 return is_scalar and (spirv_len or opencl_len);
668 }665 }
669666
670 fn arithmeticTypeInfo(self: *DeclGen, ty: Type) ArithmeticTypeInfo {667 fn arithmeticTypeInfo(self: *NavGen, ty: Type) ArithmeticTypeInfo {
671 const mod = self.pt.zcu;668 const mod = self.pt.zcu;
672 const target = self.getTarget();669 const target = self.getTarget();
673 var scalar_ty = ty.scalarType(mod);670 var scalar_ty = ty.scalarType(mod);
...@@ -715,7 +712,7 @@ const DeclGen = struct {...@@ -715,7 +712,7 @@ const DeclGen = struct {
715 }712 }
716713
717 /// Emits a bool constant in a particular representation.714 /// 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 {
719 // TODO: Cache?716 // TODO: Cache?
720717
721 const section = &self.spv.sections.types_globals_constants;718 const section = &self.spv.sections.types_globals_constants;
...@@ -742,7 +739,7 @@ const DeclGen = struct {...@@ -742,7 +739,7 @@ const DeclGen = struct {
742 /// Emits an integer constant.739 /// Emits an integer constant.
743 /// This function, unlike SpvModule.constInt, takes care to bitcast740 /// This function, unlike SpvModule.constInt, takes care to bitcast
744 /// the value to an unsigned int first for Kernels.741 /// 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 {
746 // TODO: Cache?743 // TODO: Cache?
747 const mod = self.pt.zcu;744 const mod = self.pt.zcu;
748 const scalar_ty = ty.scalarType(mod);745 const scalar_ty = ty.scalarType(mod);
...@@ -809,7 +806,7 @@ const DeclGen = struct {...@@ -809,7 +806,7 @@ const DeclGen = struct {
809 /// ty must be a struct type.806 /// ty must be a struct type.
810 /// Constituents should be in `indirect` representation (as the elements of a struct should be).807 /// Constituents should be in `indirect` representation (as the elements of a struct should be).
811 /// Result is in `direct` representation.808 /// 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 {
813 assert(types.len == constituents.len);810 assert(types.len == constituents.len);
814811
815 const result_id = self.spv.allocId();812 const result_id = self.spv.allocId();
...@@ -823,7 +820,7 @@ const DeclGen = struct {...@@ -823,7 +820,7 @@ const DeclGen = struct {
823820
824 /// Construct a vector at runtime.821 /// Construct a vector at runtime.
825 /// ty must be an vector type.822 /// 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 {
827 const mod = self.pt.zcu;824 const mod = self.pt.zcu;
828 assert(ty.vectorLen(mod) == constituents.len);825 assert(ty.vectorLen(mod) == constituents.len);
829826
...@@ -847,7 +844,7 @@ const DeclGen = struct {...@@ -847,7 +844,7 @@ const DeclGen = struct {
847844
848 /// Construct a vector at runtime with all lanes set to the same value.845 /// Construct a vector at runtime with all lanes set to the same value.
849 /// ty must be an vector type.846 /// 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 {
851 const mod = self.pt.zcu;848 const mod = self.pt.zcu;
852 const n = ty.vectorLen(mod);849 const n = ty.vectorLen(mod);
853850
...@@ -862,7 +859,7 @@ const DeclGen = struct {...@@ -862,7 +859,7 @@ const DeclGen = struct {
862 /// ty must be an array type.859 /// ty must be an array type.
863 /// Constituents should be in `indirect` representation (as the elements of an array should be).860 /// Constituents should be in `indirect` representation (as the elements of an array should be).
864 /// Result is in `direct` representation.861 /// 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 {
866 const result_id = self.spv.allocId();863 const result_id = self.spv.allocId();
867 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{864 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
868 .id_result_type = try self.resolveType(ty, .direct),865 .id_result_type = try self.resolveType(ty, .direct),
...@@ -878,7 +875,7 @@ const DeclGen = struct {...@@ -878,7 +875,7 @@ const DeclGen = struct {
878 /// is done by emitting a sequence of instructions that initialize the value.875 /// is done by emitting a sequence of instructions that initialize the value.
879 //876 //
880 /// This function should only be called during function code generation.877 /// 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 {
882 // Note: Using intern_map can only be used with constants that DO NOT generate any runtime code!!879 // Note: Using intern_map can only be used with constants that DO NOT generate any runtime code!!
883 // Ideally that should be all constants in the future, or it should be cleaned up somehow. For880 // Ideally that should be all constants in the future, or it should be cleaned up somehow. For
884 // now, only use the intern_map on case-by-case basis by breaking to :cache.881 // now, only use the intern_map on case-by-case basis by breaking to :cache.
...@@ -922,7 +919,7 @@ const DeclGen = struct {...@@ -922,7 +919,7 @@ const DeclGen = struct {
922 .undef => unreachable, // handled above919 .undef => unreachable, // handled above
923920
924 .variable,921 .variable,
925 .extern_func,922 .@"extern",
926 .func,923 .func,
927 .enum_literal,924 .enum_literal,
928 .empty_enum_value,925 .empty_enum_value,
...@@ -1142,7 +1139,7 @@ const DeclGen = struct {...@@ -1142,7 +1139,7 @@ const DeclGen = struct {
1142 return cacheable_id;1139 return cacheable_id;
1143 }1140 }
11441141
1145 fn constantPtr(self: *DeclGen, ptr_val: Value) Error!IdRef {1142 fn constantPtr(self: *NavGen, ptr_val: Value) Error!IdRef {
1146 // TODO: Caching??1143 // TODO: Caching??
11471144
1148 const pt = self.pt;1145 const pt = self.pt;
...@@ -1160,7 +1157,7 @@ const DeclGen = struct {...@@ -1160,7 +1157,7 @@ const DeclGen = struct {
1160 return self.derivePtr(derivation);1157 return self.derivePtr(derivation);
1161 }1158 }
11621159
1163 fn derivePtr(self: *DeclGen, derivation: Value.PointerDeriveStep) Error!IdRef {1160 fn derivePtr(self: *NavGen, derivation: Value.PointerDeriveStep) Error!IdRef {
1164 const pt = self.pt;1161 const pt = self.pt;
1165 const zcu = pt.zcu;1162 const zcu = pt.zcu;
1166 switch (derivation) {1163 switch (derivation) {
...@@ -1178,13 +1175,13 @@ const DeclGen = struct {...@@ -1178,13 +1175,13 @@ const DeclGen = struct {
1178 });1175 });
1179 return result_ptr_id;1176 return result_ptr_id;
1180 },1177 },
1181 .decl_ptr => |decl| {1178 .nav_ptr => |nav| {
1182 const result_ptr_ty = try zcu.declPtr(decl).declPtrType(pt);1179 const result_ptr_ty = try pt.navPtrType(nav);
1183 return self.constantDeclRef(result_ptr_ty, decl);1180 return self.constantNavRef(result_ptr_ty, nav);
1184 },1181 },
1185 .anon_decl_ptr => |ad| {1182 .uav_ptr => |uav| {
1186 const result_ptr_ty = Type.fromInterned(ad.orig_ty);1183 const result_ptr_ty = Type.fromInterned(uav.orig_ty);
1187 return self.constantAnonDeclRef(result_ptr_ty, ad);1184 return self.constantUavRef(result_ptr_ty, uav);
1188 },1185 },
1189 .eu_payload_ptr => @panic("TODO"),1186 .eu_payload_ptr => @panic("TODO"),
1190 .opt_payload_ptr => @panic("TODO"),1187 .opt_payload_ptr => @panic("TODO"),
...@@ -1227,10 +1224,10 @@ const DeclGen = struct {...@@ -1227,10 +1224,10 @@ const DeclGen = struct {
1227 }1224 }
1228 }1225 }
12291226
1230 fn constantAnonDeclRef(1227 fn constantUavRef(
1231 self: *DeclGen,1228 self: *NavGen,
1232 ty: Type,1229 ty: Type,
1233 anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl,1230 uav: InternPool.Key.Ptr.BaseAddr.Uav,
1234 ) !IdRef {1231 ) !IdRef {
1235 // TODO: Merge this function with constantDeclRef.1232 // TODO: Merge this function with constantDeclRef.
12361233
...@@ -1238,31 +1235,24 @@ const DeclGen = struct {...@@ -1238,31 +1235,24 @@ const DeclGen = struct {
1238 const mod = pt.zcu;1235 const mod = pt.zcu;
1239 const ip = &mod.intern_pool;1236 const ip = &mod.intern_pool;
1240 const ty_id = try self.resolveType(ty, .direct);1237 const ty_id = try self.resolveType(ty, .direct);
1241 const decl_val = anon_decl.val;1238 const uav_ty = Type.fromInterned(ip.typeOf(uav.val));
1242 const decl_ty = Type.fromInterned(ip.typeOf(decl_val));
12431239
1244 if (Value.fromInterned(decl_val).getFunction(mod)) |func| {1240 switch (ip.indexToKey(uav.val)) {
1245 _ = func;1241 .func => unreachable, // TODO
1246 unreachable; // TODO1242 .@"extern" => assert(!ip.isFunctionType(uav_ty.toIntern())),
1247 } else if (Value.fromInterned(decl_val).getExternFunc(mod)) |func| {1243 else => {},
1248 _ = func;
1249 unreachable;
1250 }1244 }
12511245
1252 // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;1246 // const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
1253 if (!decl_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {1247 if (!uav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1254 // Pointer to nothing - return undefoined1248 // Pointer to nothing - return undefined
1255 return self.spv.constUndef(ty_id);1249 return self.spv.constUndef(ty_id);
1256 }1250 }
12571251
1258 if (decl_ty.zigTypeTag(mod) == .Fn) {1252 // Uav refs are always generic.
1259 unreachable; // TODO
1260 }
1261
1262 // Anon decl refs are always generic.
1263 assert(ty.ptrAddressSpace(mod) == .generic);1253 assert(ty.ptrAddressSpace(mod) == .generic);
1264 const decl_ptr_ty_id = try self.ptrType(decl_ty, .Generic);1254 const decl_ptr_ty_id = try self.ptrType(uav_ty, .Generic);
1265 const ptr_id = try self.resolveAnonDecl(decl_val);1255 const ptr_id = try self.resolveUav(uav.val);
12661256
1267 if (decl_ptr_ty_id != ty_id) {1257 if (decl_ptr_ty_id != ty_id) {
1268 // Differing pointer types, insert a cast.1258 // Differing pointer types, insert a cast.
...@@ -1278,28 +1268,31 @@ const DeclGen = struct {...@@ -1278,28 +1268,31 @@ const DeclGen = struct {
1278 }1268 }
1279 }1269 }
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 {
1282 const pt = self.pt;1272 const pt = self.pt;
1283 const mod = pt.zcu;1273 const mod = pt.zcu;
1274 const ip = &mod.intern_pool;
1284 const ty_id = try self.resolveType(ty, .direct);1275 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())) {
1288 .func => {1281 .func => {
1289 // TODO: Properly lower function pointers. For now we are going to hack around it and1282 // TODO: Properly lower function pointers. For now we are going to hack around it and
1290 // just generate an empty pointer. Function pointers are represented by a pointer to usize.1283 // just generate an empty pointer. Function pointers are represented by a pointer to usize.
1291 return try self.spv.constUndef(ty_id);1284 return try self.spv.constUndef(ty_id);
1292 },1285 },
1293 .extern_func => unreachable, // TODO1286 .@"extern" => assert(!ip.isFunctionType(nav_ty.toIntern())), // TODO
1294 else => {},1287 else => {},
1295 }1288 }
12961289
1297 if (!decl.typeOf(mod).isFnOrHasRuntimeBitsIgnoreComptime(pt)) {1290 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(pt)) {
1298 // Pointer to nothing - return undefined.1291 // Pointer to nothing - return undefined.
1299 return self.spv.constUndef(ty_id);1292 return self.spv.constUndef(ty_id);
1300 }1293 }
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);
1303 const spv_decl = self.spv.declPtr(spv_decl_index);1296 const spv_decl = self.spv.declPtr(spv_decl_index);
13041297
1305 const decl_id = switch (spv_decl.kind) {1298 const decl_id = switch (spv_decl.kind) {
...@@ -1307,10 +1300,10 @@ const DeclGen = struct {...@@ -1307,10 +1300,10 @@ const DeclGen = struct {
1307 .global, .invocation_global => spv_decl.result_id,1300 .global, .invocation_global => spv_decl.result_id,
1308 };1301 };
13091302
1310 const final_storage_class = self.spvStorageClass(decl.@"addrspace");1303 const final_storage_class = self.spvStorageClass(nav.status.resolved.@"addrspace");
1311 try self.addFunctionDep(spv_decl_index, final_storage_class);1304 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
1315 const ptr_id = switch (final_storage_class) {1308 const ptr_id = switch (final_storage_class) {
1316 .Generic => try self.castToGeneric(decl_ptr_ty_id, decl_id),1309 .Generic => try self.castToGeneric(decl_ptr_ty_id, decl_id),
...@@ -1332,7 +1325,7 @@ const DeclGen = struct {...@@ -1332,7 +1325,7 @@ const DeclGen = struct {
1332 }1325 }
13331326
1334 // Turn a Zig type's name into a cache reference.1327 // 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 {
1336 var name = std.ArrayList(u8).init(self.gpa);1329 var name = std.ArrayList(u8).init(self.gpa);
1337 defer name.deinit();1330 defer name.deinit();
1338 try ty.print(name.writer(), self.pt);1331 try ty.print(name.writer(), self.pt);
...@@ -1343,7 +1336,7 @@ const DeclGen = struct {...@@ -1343,7 +1336,7 @@ const DeclGen = struct {
1343 /// The integer type that is returned by this function is the type that is used to perform1336 /// The integer type that is returned by this function is the type that is used to perform
1344 /// actual operations (as well as store) a Zig type of a particular number of bits. To create1337 /// actual operations (as well as store) a Zig type of a particular number of bits. To create
1345 /// a type with an exact size, use SpvModule.intType.1338 /// 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 {
1347 const backing_bits = self.backingIntBits(bits) orelse {1340 const backing_bits = self.backingIntBits(bits) orelse {
1348 // TODO: Integers too big for any native type are represented as "composite integers":1341 // TODO: Integers too big for any native type are represented as "composite integers":
1349 // An array of largestSupportedIntBits.1342 // An array of largestSupportedIntBits.
...@@ -1358,7 +1351,7 @@ const DeclGen = struct {...@@ -1358,7 +1351,7 @@ const DeclGen = struct {
1358 return self.spv.intType(.unsigned, backing_bits);1351 return self.spv.intType(.unsigned, backing_bits);
1359 }1352 }
13601353
1361 fn arrayType(self: *DeclGen, len: u32, child_ty: IdRef) !IdRef {1354 fn arrayType(self: *NavGen, len: u32, child_ty: IdRef) !IdRef {
1362 // TODO: Cache??1355 // TODO: Cache??
1363 const len_id = try self.constInt(Type.u32, len, .direct);1356 const len_id = try self.constInt(Type.u32, len, .direct);
1364 const result_id = self.spv.allocId();1357 const result_id = self.spv.allocId();
...@@ -1371,11 +1364,11 @@ const DeclGen = struct {...@@ -1371,11 +1364,11 @@ const DeclGen = struct {
1371 return result_id;1364 return result_id;
1372 }1365 }
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 {
1375 return try self.ptrType2(child_ty, storage_class, .indirect);1368 return try self.ptrType2(child_ty, storage_class, .indirect);
1376 }1369 }
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 {
1379 const key = .{ child_ty.toIntern(), storage_class, child_repr };1372 const key = .{ child_ty.toIntern(), storage_class, child_repr };
1380 const entry = try self.ptr_types.getOrPut(self.gpa, key);1373 const entry = try self.ptr_types.getOrPut(self.gpa, key);
1381 if (entry.found_existing) {1374 if (entry.found_existing) {
...@@ -1407,7 +1400,7 @@ const DeclGen = struct {...@@ -1407,7 +1400,7 @@ const DeclGen = struct {
1407 return result_id;1400 return result_id;
1408 }1401 }
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 {
1411 // TODO: Cache??1404 // TODO: Cache??
14121405
1413 const param_ids = try self.gpa.alloc(IdRef, param_types.len);1406 const param_ids = try self.gpa.alloc(IdRef, param_types.len);
...@@ -1427,7 +1420,7 @@ const DeclGen = struct {...@@ -1427,7 +1420,7 @@ const DeclGen = struct {
1427 return ty_id;1420 return ty_id;
1428 }1421 }
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 {
1431 const pt = self.pt;1424 const pt = self.pt;
1432 const new_scalar_ty = new_ty.scalarType(pt.zcu);1425 const new_scalar_ty = new_ty.scalarType(pt.zcu);
1433 if (!base_ty.isVector(pt.zcu)) {1426 if (!base_ty.isVector(pt.zcu)) {
...@@ -1458,7 +1451,7 @@ const DeclGen = struct {...@@ -1458,7 +1451,7 @@ const DeclGen = struct {
1458 /// padding: [padding_size]u8,1451 /// padding: [padding_size]u8,
1459 /// }1452 /// }
1460 /// If any of the fields' size is 0, it will be omitted.1453 /// 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 {
1462 const mod = self.pt.zcu;1455 const mod = self.pt.zcu;
1463 const ip = &mod.intern_pool;1456 const ip = &mod.intern_pool;
1464 const union_obj = mod.typeToUnion(ty).?;1457 const union_obj = mod.typeToUnion(ty).?;
...@@ -1509,7 +1502,7 @@ const DeclGen = struct {...@@ -1509,7 +1502,7 @@ const DeclGen = struct {
1509 return result_id;1502 return result_id;
1510 }1503 }
15111504
1512 fn resolveFnReturnType(self: *DeclGen, ret_ty: Type) !IdRef {1505 fn resolveFnReturnType(self: *NavGen, ret_ty: Type) !IdRef {
1513 const pt = self.pt;1506 const pt = self.pt;
1514 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {1507 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
1515 // If the return type is an error set or an error union, then we make this1508 // If the return type is an error set or an error union, then we make this
...@@ -1526,7 +1519,7 @@ const DeclGen = struct {...@@ -1526,7 +1519,7 @@ const DeclGen = struct {
1526 }1519 }
15271520
1528 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.1521 /// 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 {
1530 if (self.intern_map.get(.{ ty.toIntern(), repr })) |id| {1523 if (self.intern_map.get(.{ ty.toIntern(), repr })) |id| {
1531 return id;1524 return id;
1532 }1525 }
...@@ -1536,7 +1529,7 @@ const DeclGen = struct {...@@ -1536,7 +1529,7 @@ const DeclGen = struct {
1536 return id;1529 return id;
1537 }1530 }
15381531
1539 fn resolveTypeInner(self: *DeclGen, ty: Type, repr: Repr) Error!IdRef {1532 fn resolveTypeInner(self: *NavGen, ty: Type, repr: Repr) Error!IdRef {
1540 const pt = self.pt;1533 const pt = self.pt;
1541 const mod = pt.zcu;1534 const mod = pt.zcu;
1542 const ip = &mod.intern_pool;1535 const ip = &mod.intern_pool;
...@@ -1839,7 +1832,7 @@ const DeclGen = struct {...@@ -1839,7 +1832,7 @@ const DeclGen = struct {
1839 }1832 }
1840 }1833 }
18411834
1842 fn spvStorageClass(self: *DeclGen, as: std.builtin.AddressSpace) StorageClass {1835 fn spvStorageClass(self: *NavGen, as: std.builtin.AddressSpace) StorageClass {
1843 const target = self.getTarget();1836 const target = self.getTarget();
1844 return switch (as) {1837 return switch (as) {
1845 .generic => switch (target.os.tag) {1838 .generic => switch (target.os.tag) {
...@@ -1882,7 +1875,7 @@ const DeclGen = struct {...@@ -1882,7 +1875,7 @@ const DeclGen = struct {
1882 }1875 }
1883 };1876 };
18841877
1885 fn errorUnionLayout(self: *DeclGen, payload_ty: Type) ErrorUnionLayout {1878 fn errorUnionLayout(self: *NavGen, payload_ty: Type) ErrorUnionLayout {
1886 const pt = self.pt;1879 const pt = self.pt;
18871880
1888 const error_align = Type.anyerror.abiAlignment(pt);1881 const error_align = Type.anyerror.abiAlignment(pt);
...@@ -1913,7 +1906,7 @@ const DeclGen = struct {...@@ -1913,7 +1906,7 @@ const DeclGen = struct {
1913 total_fields: u32,1906 total_fields: u32,
1914 };1907 };
19151908
1916 fn unionLayout(self: *DeclGen, ty: Type) UnionLayout {1909 fn unionLayout(self: *NavGen, ty: Type) UnionLayout {
1917 const pt = self.pt;1910 const pt = self.pt;
1918 const mod = pt.zcu;1911 const mod = pt.zcu;
1919 const ip = &mod.intern_pool;1912 const ip = &mod.intern_pool;
...@@ -2004,25 +1997,25 @@ const DeclGen = struct {...@@ -2004,25 +1997,25 @@ const DeclGen = struct {
2004 return .{ .ty = ty, .value = .{ .singleton = singleton } };1997 return .{ .ty = ty, .value = .{ .singleton = singleton } };
2005 }1998 }
20061999
2007 fn materialize(self: Temporary, dg: *DeclGen) !IdResult {2000 fn materialize(self: Temporary, ng: *NavGen) !IdResult {
2008 const mod = dg.pt.zcu;2001 const mod = ng.pt.zcu;
2009 switch (self.value) {2002 switch (self.value) {
2010 .singleton => |id| return id,2003 .singleton => |id| return id,
2011 .exploded_vector => |range| {2004 .exploded_vector => |range| {
2012 assert(self.ty.isVector(mod));2005 assert(self.ty.isVector(mod));
2013 assert(self.ty.vectorLen(mod) == range.len);2006 assert(self.ty.vectorLen(mod) == range.len);
2014 const consituents = try dg.gpa.alloc(IdRef, range.len);2007 const consituents = try ng.gpa.alloc(IdRef, range.len);
2015 defer dg.gpa.free(consituents);2008 defer ng.gpa.free(consituents);
2016 for (consituents, 0..range.len) |*id, i| {2009 for (consituents, 0..range.len) |*id, i| {
2017 id.* = range.at(i);2010 id.* = range.at(i);
2018 }2011 }
2019 return dg.constructVector(self.ty, consituents);2012 return ng.constructVector(self.ty, consituents);
2020 },2013 },
2021 }2014 }
2022 }2015 }
20232016
2024 fn vectorization(self: Temporary, dg: *DeclGen) Vectorization {2017 fn vectorization(self: Temporary, ng: *NavGen) Vectorization {
2025 return Vectorization.fromType(self.ty, dg);2018 return Vectorization.fromType(self.ty, ng);
2026 }2019 }
20272020
2028 fn pun(self: Temporary, new_ty: Type) Temporary {2021 fn pun(self: Temporary, new_ty: Type) Temporary {
...@@ -2034,8 +2027,8 @@ const DeclGen = struct {...@@ -2034,8 +2027,8 @@ const DeclGen = struct {
20342027
2035 /// 'Explode' a temporary into separate elements. This turns a vector2028 /// 'Explode' a temporary into separate elements. This turns a vector
2036 /// into a bag of elements.2029 /// into a bag of elements.
2037 fn explode(self: Temporary, dg: *DeclGen) !IdRange {2030 fn explode(self: Temporary, ng: *NavGen) !IdRange {
2038 const mod = dg.pt.zcu;2031 const mod = ng.pt.zcu;
20392032
2040 // If the value is a scalar, then this is a no-op.2033 // If the value is a scalar, then this is a no-op.
2041 if (!self.ty.isVector(mod)) {2034 if (!self.ty.isVector(mod)) {
...@@ -2045,9 +2038,9 @@ const DeclGen = struct {...@@ -2045,9 +2038,9 @@ const DeclGen = struct {
2045 };2038 };
2046 }2039 }
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);
2049 const n = self.ty.vectorLen(mod);2042 const n = self.ty.vectorLen(mod);
2050 const results = dg.spv.allocIds(n);2043 const results = ng.spv.allocIds(n);
20512044
2052 const id = switch (self.value) {2045 const id = switch (self.value) {
2053 .singleton => |id| id,2046 .singleton => |id| id,
...@@ -2056,7 +2049,7 @@ const DeclGen = struct {...@@ -2056,7 +2049,7 @@ const DeclGen = struct {
20562049
2057 for (0..n) |i| {2050 for (0..n) |i| {
2058 const indexes = [_]u32{@intCast(i)};2051 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, .{
2060 .id_result_type = ty_id,2053 .id_result_type = ty_id,
2061 .id_result = results.at(i),2054 .id_result = results.at(i),
2062 .composite = id,2055 .composite = id,
...@@ -2069,7 +2062,7 @@ const DeclGen = struct {...@@ -2069,7 +2062,7 @@ const DeclGen = struct {
2069 };2062 };
20702063
2071 /// Initialize a `Temporary` from an AIR value.2064 /// 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 {
2073 return .{2066 return .{
2074 .ty = self.typeOf(inst),2067 .ty = self.typeOf(inst),
2075 .value = .{ .singleton = try self.resolve(inst) },2068 .value = .{ .singleton = try self.resolve(inst) },
...@@ -2093,11 +2086,11 @@ const DeclGen = struct {...@@ -2093,11 +2086,11 @@ const DeclGen = struct {
2093 /// Derive a vectorization from a particular type. This usually2086 /// Derive a vectorization from a particular type. This usually
2094 /// only checks the size, but the source-of-truth is implemented2087 /// only checks the size, but the source-of-truth is implemented
2095 /// by `isSpvVector()`.2088 /// by `isSpvVector()`.
2096 fn fromType(ty: Type, dg: *DeclGen) Vectorization {2089 fn fromType(ty: Type, ng: *NavGen) Vectorization {
2097 const mod = dg.pt.zcu;2090 const mod = ng.pt.zcu;
2098 if (!ty.isVector(mod)) {2091 if (!ty.isVector(mod)) {
2099 return .scalar;2092 return .scalar;
2100 } else if (dg.isSpvVector(ty)) {2093 } else if (ng.isSpvVector(ty)) {
2101 return .{ .spv_vectorized = ty.vectorLen(mod) };2094 return .{ .spv_vectorized = ty.vectorLen(mod) };
2102 } else {2095 } else {
2103 return .{ .unrolled = ty.vectorLen(mod) };2096 return .{ .unrolled = ty.vectorLen(mod) };
...@@ -2169,8 +2162,8 @@ const DeclGen = struct {...@@ -2169,8 +2162,8 @@ const DeclGen = struct {
21692162
2170 /// Turns `ty` into the result-type of an individual vector operation.2163 /// Turns `ty` into the result-type of an individual vector operation.
2171 /// `ty` may be a scalar or vector, it doesn't matter.2164 /// `ty` may be a scalar or vector, it doesn't matter.
2172 fn operationType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {2165 fn operationType(self: Vectorization, ng: *NavGen, ty: Type) !Type {
2173 const pt = dg.pt;2166 const pt = ng.pt;
2174 const scalar_ty = ty.scalarType(pt.zcu);2167 const scalar_ty = ty.scalarType(pt.zcu);
2175 return switch (self) {2168 return switch (self) {
2176 .scalar, .unrolled => scalar_ty,2169 .scalar, .unrolled => scalar_ty,
...@@ -2183,8 +2176,8 @@ const DeclGen = struct {...@@ -2183,8 +2176,8 @@ const DeclGen = struct {
21832176
2184 /// Turns `ty` into the result-type of the entire operation.2177 /// Turns `ty` into the result-type of the entire operation.
2185 /// `ty` may be a scalar or vector, it doesn't matter.2178 /// `ty` may be a scalar or vector, it doesn't matter.
2186 fn resultType(self: Vectorization, dg: *DeclGen, ty: Type) !Type {2179 fn resultType(self: Vectorization, ng: *NavGen, ty: Type) !Type {
2187 const pt = dg.pt;2180 const pt = ng.pt;
2188 const scalar_ty = ty.scalarType(pt.zcu);2181 const scalar_ty = ty.scalarType(pt.zcu);
2189 return switch (self) {2182 return switch (self) {
2190 .scalar => scalar_ty,2183 .scalar => scalar_ty,
...@@ -2198,10 +2191,10 @@ const DeclGen = struct {...@@ -2198,10 +2191,10 @@ const DeclGen = struct {
2198 /// Before a temporary can be used, some setup may need to be one. This function implements2191 /// Before a temporary can be used, some setup may need to be one. This function implements
2199 /// this setup, and returns a new type that holds the relevant information on how to access2192 /// this setup, and returns a new type that holds the relevant information on how to access
2200 /// elements of the input.2193 /// elements of the input.
2201 fn prepare(self: Vectorization, dg: *DeclGen, tmp: Temporary) !PreparedOperand {2194 fn prepare(self: Vectorization, ng: *NavGen, tmp: Temporary) !PreparedOperand {
2202 const pt = dg.pt;2195 const pt = ng.pt;
2203 const is_vector = tmp.ty.isVector(pt.zcu);2196 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);
2205 const value: PreparedOperand.Value = switch (tmp.value) {2198 const value: PreparedOperand.Value = switch (tmp.value) {
2206 .singleton => |id| switch (self) {2199 .singleton => |id| switch (self) {
2207 .scalar => blk: {2200 .scalar => blk: {
...@@ -2220,7 +2213,7 @@ const DeclGen = struct {...@@ -2220,7 +2213,7 @@ const DeclGen = struct {
2220 .child = tmp.ty.toIntern(),2213 .child = tmp.ty.toIntern(),
2221 });2214 });
22222215
2223 const vector = try dg.constructVectorSplat(vector_ty, id);2216 const vector = try ng.constructVectorSplat(vector_ty, id);
2224 return .{2217 return .{
2225 .ty = vector_ty,2218 .ty = vector_ty,
2226 .value = .{ .spv_vectorwise = vector },2219 .value = .{ .spv_vectorwise = vector },
...@@ -2228,7 +2221,7 @@ const DeclGen = struct {...@@ -2228,7 +2221,7 @@ const DeclGen = struct {
2228 },2221 },
2229 .unrolled => blk: {2222 .unrolled => blk: {
2230 if (is_vector) {2223 if (is_vector) {
2231 break :blk .{ .vector_exploded = try tmp.explode(dg) };2224 break :blk .{ .vector_exploded = try tmp.explode(ng) };
2232 } else {2225 } else {
2233 break :blk .{ .scalar_broadcast = id };2226 break :blk .{ .scalar_broadcast = id };
2234 }2227 }
...@@ -2243,7 +2236,7 @@ const DeclGen = struct {...@@ -2243,7 +2236,7 @@ const DeclGen = struct {
2243 // a type that cannot do that.2236 // a type that cannot do that.
2244 assert(is_spv_vector);2237 assert(is_spv_vector);
2245 assert(range.len == n);2238 assert(range.len == n);
2246 const vec = try tmp.materialize(dg);2239 const vec = try tmp.materialize(ng);
2247 break :blk .{ .spv_vectorwise = vec };2240 break :blk .{ .spv_vectorwise = vec };
2248 },2241 },
2249 .unrolled => |n| blk: {2242 .unrolled => |n| blk: {
...@@ -2324,7 +2317,7 @@ const DeclGen = struct {...@@ -2324,7 +2317,7 @@ const DeclGen = struct {
2324 /// - A `Vectorization` instance2317 /// - A `Vectorization` instance
2325 /// - A Type, in which case the vectorization is computed via `Vectorization.fromType`.2318 /// - A Type, in which case the vectorization is computed via `Vectorization.fromType`.
2326 /// - A Temporary, in which case the vectorization is computed via `Temporary.vectorization`.2319 /// - 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 {
2328 var v: Vectorization = undefined;2321 var v: Vectorization = undefined;
2329 assert(args.len >= 1);2322 assert(args.len >= 1);
2330 inline for (args, 0..) |arg, i| {2323 inline for (args, 0..) |arg, i| {
...@@ -2345,7 +2338,7 @@ const DeclGen = struct {...@@ -2345,7 +2338,7 @@ const DeclGen = struct {
23452338
2346 /// This function builds an OpSConvert of OpUConvert depending on the2339 /// This function builds an OpSConvert of OpUConvert depending on the
2347 /// signedness of the types.2340 /// 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 {
2349 const mod = self.pt.zcu;2342 const mod = self.pt.zcu;
23502343
2351 const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct);2344 const dst_ty_id = try self.resolveType(dst_ty.scalarType(mod), .direct);
...@@ -2384,7 +2377,7 @@ const DeclGen = struct {...@@ -2384,7 +2377,7 @@ const DeclGen = struct {
2384 return v.finalize(result_ty, results);2377 return v.finalize(result_ty, results);
2385 }2378 }
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 {
2388 const target = self.getTarget();2381 const target = self.getTarget();
23892382
2390 const v = self.vectorization(.{ a, b, c });2383 const v = self.vectorization(.{ a, b, c });
...@@ -2424,7 +2417,7 @@ const DeclGen = struct {...@@ -2424,7 +2417,7 @@ const DeclGen = struct {
2424 return v.finalize(result_ty, results);2417 return v.finalize(result_ty, results);
2425 }2418 }
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 {
2428 const mod = self.pt.zcu;2421 const mod = self.pt.zcu;
24292422
2430 const v = self.vectorization(.{ condition, lhs, rhs });2423 const v = self.vectorization(.{ condition, lhs, rhs });
...@@ -2475,7 +2468,7 @@ const DeclGen = struct {...@@ -2475,7 +2468,7 @@ const DeclGen = struct {
2475 f_oge,2468 f_oge,
2476 };2469 };
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 {
2479 const v = self.vectorization(.{ lhs, rhs });2472 const v = self.vectorization(.{ lhs, rhs });
2480 const ops = v.operations();2473 const ops = v.operations();
2481 const results = self.spv.allocIds(ops);2474 const results = self.spv.allocIds(ops);
...@@ -2543,7 +2536,7 @@ const DeclGen = struct {...@@ -2543,7 +2536,7 @@ const DeclGen = struct {
2543 log10,2536 log10,
2544 };2537 };
25452538
2546 fn buildUnary(self: *DeclGen, op: UnaryOp, operand: Temporary) !Temporary {2539 fn buildUnary(self: *NavGen, op: UnaryOp, operand: Temporary) !Temporary {
2547 const target = self.getTarget();2540 const target = self.getTarget();
2548 const v = blk: {2541 const v = blk: {
2549 const v = self.vectorization(.{operand});2542 const v = self.vectorization(.{operand});
...@@ -2673,7 +2666,7 @@ const DeclGen = struct {...@@ -2673,7 +2666,7 @@ const DeclGen = struct {
2673 l_or,2666 l_or,
2674 };2667 };
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 {
2677 const target = self.getTarget();2670 const target = self.getTarget();
26782671
2679 const v = self.vectorization(.{ lhs, rhs });2672 const v = self.vectorization(.{ lhs, rhs });
...@@ -2762,7 +2755,7 @@ const DeclGen = struct {...@@ -2762,7 +2755,7 @@ const DeclGen = struct {
2762 /// This function builds an extended multiplication, either OpSMulExtended or OpUMulExtended on Vulkan,2755 /// This function builds an extended multiplication, either OpSMulExtended or OpUMulExtended on Vulkan,
2763 /// or OpIMul and s_mul_hi or u_mul_hi on OpenCL.2756 /// or OpIMul and s_mul_hi or u_mul_hi on OpenCL.
2764 fn buildWideMul(2757 fn buildWideMul(
2765 self: *DeclGen,2758 self: *NavGen,
2766 op: enum {2759 op: enum {
2767 s_mul_extended,2760 s_mul_extended,
2768 u_mul_extended,2761 u_mul_extended,
...@@ -2893,7 +2886,7 @@ const DeclGen = struct {...@@ -2893,7 +2886,7 @@ const DeclGen = struct {
2893 /// OpFunctionEnd2886 /// OpFunctionEnd
2894 /// TODO is to also write out the error as a function call parameter, and to somehow fetch2887 /// TODO is to also write out the error as a function call parameter, and to somehow fetch
2895 /// the name of an error in the text executor.2888 /// 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 {
2897 const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct);2890 const anyerror_ty_id = try self.resolveType(Type.anyerror, .direct);
2898 const ptr_anyerror_ty = try self.pt.ptrType(.{2891 const ptr_anyerror_ty = try self.pt.ptrType(.{
2899 .child = Type.anyerror.toIntern(),2892 .child = Type.anyerror.toIntern(),
...@@ -2946,21 +2939,22 @@ const DeclGen = struct {...@@ -2946,21 +2939,22 @@ const DeclGen = struct {
2946 try self.spv.declareEntryPoint(spv_decl_index, test_name, .Kernel);2939 try self.spv.declareEntryPoint(spv_decl_index, test_name, .Kernel);
2947 }2940 }
29482941
2949 fn genDecl(self: *DeclGen) !void {2942 fn genNav(self: *NavGen) !void {
2950 const pt = self.pt;2943 const pt = self.pt;
2951 const mod = pt.zcu;2944 const mod = pt.zcu;
2952 const ip = &mod.intern_pool;2945 const ip = &mod.intern_pool;
2953 const decl = mod.declPtr(self.decl_index);2946 const spv_decl_index = try self.object.resolveNav(mod, self.owner_nav);
2954 const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index);
2955 const result_id = self.spv.declPtr(spv_decl_index).result_id;2947 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);
2957 switch (self.spv.declPtr(spv_decl_index).kind) {2952 switch (self.spv.declPtr(spv_decl_index).kind) {
2958 .func => {2953 .func => {
2959 assert(decl.typeOf(mod).zigTypeTag(mod) == .Fn);2954 const fn_info = mod.typeToFunc(ty).?;
2960 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
2961 const return_ty_id = try self.resolveFnReturnType(Type.fromInterned(fn_info.return_type));2955 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);
2964 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{2958 try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
2965 .id_result_type = return_ty_id,2959 .id_result_type = return_ty_id,
2966 .id_result = result_id,2960 .id_result = result_id,
...@@ -3012,27 +3006,26 @@ const DeclGen = struct {...@@ -3012,27 +3006,26 @@ const DeclGen = struct {
3012 // Append the actual code into the functions section.3006 // Append the actual code into the functions section.
3013 try self.spv.addFunction(spv_decl_index, self.func);3007 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
3017 // Temporarily generate a test kernel declaration if this is a test function.3011 // Temporarily generate a test kernel declaration if this is a test function.
3018 if (self.pt.zcu.test_functions.contains(self.decl_index)) {3012 if (self.pt.zcu.test_functions.contains(self.owner_nav)) {
3019 try self.generateTestEntryPoint(decl.fqn.toSlice(ip), spv_decl_index);3013 try self.generateTestEntryPoint(nav.fqn.toSlice(ip), spv_decl_index);
3020 }3014 }
3021 },3015 },
3022 .global => {3016 .global => {
3023 const maybe_init_val: ?Value = blk: {3017 const maybe_init_val: ?Value = switch (ip.indexToKey(val.toIntern())) {
3024 if (decl.val.getVariable(mod)) |payload| {3018 .func => unreachable,
3025 if (payload.is_extern) break :blk null;3019 .variable => |variable| Value.fromInterned(variable.init),
3026 break :blk Value.fromInterned(payload.init);3020 .@"extern" => null,
3027 }3021 else => val,
3028 break :blk decl.val;
3029 };3022 };
3030 assert(maybe_init_val == null); // TODO3023 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");
3033 assert(final_storage_class != .Generic); // These should be instance globals3026 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
3037 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{3030 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{
3038 .id_result_type = ptr_ty_id,3031 .id_result_type = ptr_ty_id,
...@@ -3040,21 +3033,20 @@ const DeclGen = struct {...@@ -3040,21 +3033,20 @@ const DeclGen = struct {
3040 .storage_class = final_storage_class,3033 .storage_class = final_storage_class,
3041 });3034 });
30423035
3043 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));3036 try self.spv.debugName(result_id, nav.fqn.toSlice(ip));
3044 try self.spv.declareDeclDeps(spv_decl_index, &.{});3037 try self.spv.declareDeclDeps(spv_decl_index, &.{});
3045 },3038 },
3046 .invocation_global => {3039 .invocation_global => {
3047 const maybe_init_val: ?Value = blk: {3040 const maybe_init_val: ?Value = switch (ip.indexToKey(val.toIntern())) {
3048 if (decl.val.getVariable(mod)) |payload| {3041 .func => unreachable,
3049 if (payload.is_extern) break :blk null;3042 .variable => |variable| Value.fromInterned(variable.init),
3050 break :blk Value.fromInterned(payload.init);3043 .@"extern" => null,
3051 }3044 else => val,
3052 break :blk decl.val;
3053 };3045 };
30543046
3055 try self.spv.declareDeclDeps(spv_decl_index, &.{});3047 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
3059 if (maybe_init_val) |init_val| {3051 if (maybe_init_val) |init_val| {
3060 // TODO: Combine with resolveAnonDecl?3052 // TODO: Combine with resolveAnonDecl?
...@@ -3074,7 +3066,7 @@ const DeclGen = struct {...@@ -3074,7 +3066,7 @@ const DeclGen = struct {
3074 });3066 });
3075 self.current_block_label = root_block_id;3067 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);
3078 try self.func.body.emit(self.spv.gpa, .OpStore, .{3070 try self.func.body.emit(self.spv.gpa, .OpStore, .{
3079 .pointer = result_id,3071 .pointer = result_id,
3080 .object = val_id,3072 .object = val_id,
...@@ -3084,7 +3076,7 @@ const DeclGen = struct {...@@ -3084,7 +3076,7 @@ const DeclGen = struct {
3084 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});3076 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
3085 try self.spv.addFunction(spv_decl_index, self.func);3077 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
3089 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{3081 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
3090 .id_result_type = ptr_ty_id,3082 .id_result_type = ptr_ty_id,
...@@ -3106,11 +3098,11 @@ const DeclGen = struct {...@@ -3106,11 +3098,11 @@ const DeclGen = struct {
3106 }3098 }
3107 }3099 }
31083100
3109 fn intFromBool(self: *DeclGen, value: Temporary) !Temporary {3101 fn intFromBool(self: *NavGen, value: Temporary) !Temporary {
3110 return try self.intFromBool2(value, Type.u1);3102 return try self.intFromBool2(value, Type.u1);
3111 }3103 }
31123104
3113 fn intFromBool2(self: *DeclGen, value: Temporary, result_ty: Type) !Temporary {3105 fn intFromBool2(self: *NavGen, value: Temporary, result_ty: Type) !Temporary {
3114 const zero_id = try self.constInt(result_ty, 0, .direct);3106 const zero_id = try self.constInt(result_ty, 0, .direct);
3115 const one_id = try self.constInt(result_ty, 1, .direct);3107 const one_id = try self.constInt(result_ty, 1, .direct);
31163108
...@@ -3123,7 +3115,7 @@ const DeclGen = struct {...@@ -3123,7 +3115,7 @@ const DeclGen = struct {
31233115
3124 /// Convert representation from indirect (in memory) to direct (in 'register')3116 /// Convert representation from indirect (in memory) to direct (in 'register')
3125 /// This converts the argument type from resolveType(ty, .indirect) to resolveType(ty, .direct).3117 /// 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 {
3127 const mod = self.pt.zcu;3119 const mod = self.pt.zcu;
3128 switch (ty.scalarType(mod).zigTypeTag(mod)) {3120 switch (ty.scalarType(mod).zigTypeTag(mod)) {
3129 .Bool => {3121 .Bool => {
...@@ -3149,7 +3141,7 @@ const DeclGen = struct {...@@ -3149,7 +3141,7 @@ const DeclGen = struct {
31493141
3150 /// Convert representation from direct (in 'register) to direct (in memory)3142 /// Convert representation from direct (in 'register) to direct (in memory)
3151 /// This converts the argument type from resolveType(ty, .direct) to resolveType(ty, .indirect).3143 /// 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 {
3153 const mod = self.pt.zcu;3145 const mod = self.pt.zcu;
3154 switch (ty.scalarType(mod).zigTypeTag(mod)) {3146 switch (ty.scalarType(mod).zigTypeTag(mod)) {
3155 .Bool => {3147 .Bool => {
...@@ -3160,7 +3152,7 @@ const DeclGen = struct {...@@ -3160,7 +3152,7 @@ const DeclGen = struct {
3160 }3152 }
3161 }3153 }
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 {
3164 const result_ty_id = try self.resolveType(result_ty, .indirect);3156 const result_ty_id = try self.resolveType(result_ty, .indirect);
3165 const result_id = self.spv.allocId();3157 const result_id = self.spv.allocId();
3166 const indexes = [_]u32{field};3158 const indexes = [_]u32{field};
...@@ -3174,7 +3166,7 @@ const DeclGen = struct {...@@ -3174,7 +3166,7 @@ const DeclGen = struct {
3174 return try self.convertToDirect(result_ty, result_id);3166 return try self.convertToDirect(result_ty, result_id);
3175 }3167 }
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 {
3178 // Whether this is an OpTypeVector or OpTypeArray, we need to emit the same instruction regardless.3170 // Whether this is an OpTypeVector or OpTypeArray, we need to emit the same instruction regardless.
3179 const result_ty_id = try self.resolveType(result_ty, .direct);3171 const result_ty_id = try self.resolveType(result_ty, .direct);
3180 const result_id = self.spv.allocId();3172 const result_id = self.spv.allocId();
...@@ -3193,7 +3185,7 @@ const DeclGen = struct {...@@ -3193,7 +3185,7 @@ const DeclGen = struct {
3193 is_volatile: bool = false,3185 is_volatile: bool = false,
3194 };3186 };
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 {
3197 const indirect_value_ty_id = try self.resolveType(value_ty, .indirect);3189 const indirect_value_ty_id = try self.resolveType(value_ty, .indirect);
3198 const result_id = self.spv.allocId();3190 const result_id = self.spv.allocId();
3199 const access = spec.MemoryAccess.Extended{3191 const access = spec.MemoryAccess.Extended{
...@@ -3208,7 +3200,7 @@ const DeclGen = struct {...@@ -3208,7 +3200,7 @@ const DeclGen = struct {
3208 return try self.convertToDirect(value_ty, result_id);3200 return try self.convertToDirect(value_ty, result_id);
3209 }3201 }
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 {
3212 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);3204 const indirect_value_id = try self.convertToIndirect(value_ty, value_id);
3213 const access = spec.MemoryAccess.Extended{3205 const access = spec.MemoryAccess.Extended{
3214 .Volatile = options.is_volatile,3206 .Volatile = options.is_volatile,
...@@ -3220,13 +3212,13 @@ const DeclGen = struct {...@@ -3220,13 +3212,13 @@ const DeclGen = struct {
3220 });3212 });
3221 }3213 }
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 {
3224 for (body) |inst| {3216 for (body) |inst| {
3225 try self.genInst(inst);3217 try self.genInst(inst);
3226 }3218 }
3227 }3219 }
32283220
3229 fn genInst(self: *DeclGen, inst: Air.Inst.Index) !void {3221 fn genInst(self: *NavGen, inst: Air.Inst.Index) !void {
3230 const mod = self.pt.zcu;3222 const mod = self.pt.zcu;
3231 const ip = &mod.intern_pool;3223 const ip = &mod.intern_pool;
3232 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))3224 if (self.liveness.isUnused(inst) and !self.air.mustLower(inst, ip))
...@@ -3397,7 +3389,7 @@ const DeclGen = struct {...@@ -3397,7 +3389,7 @@ const DeclGen = struct {
3397 try self.inst_results.putNoClobber(self.gpa, inst, result_id);3389 try self.inst_results.putNoClobber(self.gpa, inst, result_id);
3398 }3390 }
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 {
3401 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3393 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3402 const lhs = try self.temporary(bin_op.lhs);3394 const lhs = try self.temporary(bin_op.lhs);
3403 const rhs = try self.temporary(bin_op.rhs);3395 const rhs = try self.temporary(bin_op.rhs);
...@@ -3406,7 +3398,7 @@ const DeclGen = struct {...@@ -3406,7 +3398,7 @@ const DeclGen = struct {
3406 return try result.materialize(self);3398 return try result.materialize(self);
3407 }3399 }
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 {
3410 const mod = self.pt.zcu;3402 const mod = self.pt.zcu;
3411 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3403 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34123404
...@@ -3441,7 +3433,7 @@ const DeclGen = struct {...@@ -3441,7 +3433,7 @@ const DeclGen = struct {
34413433
3442 const MinMax = enum { min, max };3434 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 {
3445 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3437 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34463438
3447 const lhs = try self.temporary(bin_op.lhs);3439 const lhs = try self.temporary(bin_op.lhs);
...@@ -3451,7 +3443,7 @@ const DeclGen = struct {...@@ -3451,7 +3443,7 @@ const DeclGen = struct {
3451 return try result.materialize(self);3443 return try result.materialize(self);
3452 }3444 }
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 {
3455 const info = self.arithmeticTypeInfo(lhs.ty);3447 const info = self.arithmeticTypeInfo(lhs.ty);
34563448
3457 const binop: BinaryOp = switch (info.class) {3449 const binop: BinaryOp = switch (info.class) {
...@@ -3484,7 +3476,7 @@ const DeclGen = struct {...@@ -3484,7 +3476,7 @@ const DeclGen = struct {
3484 /// - Signed integers are also sign extended if they are negative.3476 /// - Signed integers are also sign extended if they are negative.
3485 /// All other values are returned unmodified (this makes strange integer3477 /// All other values are returned unmodified (this makes strange integer
3486 /// wrapping easier to use in generic operations).3478 /// 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 {
3488 const mod = self.pt.zcu;3480 const mod = self.pt.zcu;
3489 const ty = value.ty;3481 const ty = value.ty;
3490 switch (info.class) {3482 switch (info.class) {
...@@ -3507,7 +3499,7 @@ const DeclGen = struct {...@@ -3507,7 +3499,7 @@ const DeclGen = struct {
3507 }3499 }
3508 }3500 }
35093501
3510 fn airDivFloor(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3502 fn airDivFloor(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3511 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3503 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
35123504
3513 const lhs = try self.temporary(bin_op.lhs);3505 const lhs = try self.temporary(bin_op.lhs);
...@@ -3564,7 +3556,7 @@ const DeclGen = struct {...@@ -3564,7 +3556,7 @@ const DeclGen = struct {
3564 }3556 }
3565 }3557 }
35663558
3567 fn airDivTrunc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3559 fn airDivTrunc(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3568 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;3560 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
35693561
3570 const lhs = try self.temporary(bin_op.lhs);3562 const lhs = try self.temporary(bin_op.lhs);
...@@ -3592,7 +3584,7 @@ const DeclGen = struct {...@@ -3592,7 +3584,7 @@ const DeclGen = struct {
3592 }3584 }
3593 }3585 }
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 {
3596 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;3588 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
3597 const operand = try self.temporary(un_op);3589 const operand = try self.temporary(un_op);
3598 const result = try self.buildUnary(op, operand);3590 const result = try self.buildUnary(op, operand);
...@@ -3600,7 +3592,7 @@ const DeclGen = struct {...@@ -3600,7 +3592,7 @@ const DeclGen = struct {
3600 }3592 }
36013593
3602 fn airArithOp(3594 fn airArithOp(
3603 self: *DeclGen,3595 self: *NavGen,
3604 inst: Air.Inst.Index,3596 inst: Air.Inst.Index,
3605 comptime fop: BinaryOp,3597 comptime fop: BinaryOp,
3606 comptime sop: BinaryOp,3598 comptime sop: BinaryOp,
...@@ -3626,7 +3618,7 @@ const DeclGen = struct {...@@ -3626,7 +3618,7 @@ const DeclGen = struct {
3626 return try result.materialize(self);3618 return try result.materialize(self);
3627 }3619 }
36283620
3629 fn airAbs(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3621 fn airAbs(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3630 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3622 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
3631 const operand = try self.temporary(ty_op.operand);3623 const operand = try self.temporary(ty_op.operand);
3632 // Note: operand_ty may be signed, while ty is always unsigned!3624 // Note: operand_ty may be signed, while ty is always unsigned!
...@@ -3635,7 +3627,7 @@ const DeclGen = struct {...@@ -3635,7 +3627,7 @@ const DeclGen = struct {
3635 return try result.materialize(self);3627 return try result.materialize(self);
3636 }3628 }
36373629
3638 fn abs(self: *DeclGen, result_ty: Type, value: Temporary) !Temporary {3630 fn abs(self: *NavGen, result_ty: Type, value: Temporary) !Temporary {
3639 const target = self.getTarget();3631 const target = self.getTarget();
3640 const operand_info = self.arithmeticTypeInfo(value.ty);3632 const operand_info = self.arithmeticTypeInfo(value.ty);
36413633
...@@ -3658,7 +3650,7 @@ const DeclGen = struct {...@@ -3658,7 +3650,7 @@ const DeclGen = struct {
3658 }3650 }
36593651
3660 fn airAddSubOverflow(3652 fn airAddSubOverflow(
3661 self: *DeclGen,3653 self: *NavGen,
3662 inst: Air.Inst.Index,3654 inst: Air.Inst.Index,
3663 comptime add: BinaryOp,3655 comptime add: BinaryOp,
3664 comptime ucmp: CmpPredicate,3656 comptime ucmp: CmpPredicate,
...@@ -3724,7 +3716,7 @@ const DeclGen = struct {...@@ -3724,7 +3716,7 @@ const DeclGen = struct {
3724 );3716 );
3725 }3717 }
37263718
3727 fn airMulOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3719 fn airMulOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3728 const target = self.getTarget();3720 const target = self.getTarget();
3729 const pt = self.pt;3721 const pt = self.pt;
37303722
...@@ -3904,7 +3896,7 @@ const DeclGen = struct {...@@ -3904,7 +3896,7 @@ const DeclGen = struct {
3904 );3896 );
3905 }3897 }
39063898
3907 fn airShlOverflow(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3899 fn airShlOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3908 const mod = self.pt.zcu;3900 const mod = self.pt.zcu;
39093901
3910 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;3902 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -3944,7 +3936,7 @@ const DeclGen = struct {...@@ -3944,7 +3936,7 @@ const DeclGen = struct {
3944 );3936 );
3945 }3937 }
39463938
3947 fn airMulAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3939 fn airMulAdd(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3948 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;3940 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
3949 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;3941 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
39503942
...@@ -3960,7 +3952,7 @@ const DeclGen = struct {...@@ -3960,7 +3952,7 @@ const DeclGen = struct {
3960 return try result.materialize(self);3952 return try result.materialize(self);
3961 }3953 }
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 {
3964 if (self.liveness.isUnused(inst)) return null;3956 if (self.liveness.isUnused(inst)) return null;
39653957
3966 const mod = self.pt.zcu;3958 const mod = self.pt.zcu;
...@@ -3991,7 +3983,7 @@ const DeclGen = struct {...@@ -3991,7 +3983,7 @@ const DeclGen = struct {
3991 return try result.materialize(self);3983 return try result.materialize(self);
3992 }3984 }
39933985
3994 fn airSelect(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3986 fn airSelect(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
3995 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;3987 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
3996 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;3988 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
3997 const pred = try self.temporary(pl_op.operand);3989 const pred = try self.temporary(pl_op.operand);
...@@ -4002,7 +3994,7 @@ const DeclGen = struct {...@@ -4002,7 +3994,7 @@ const DeclGen = struct {
4002 return try result.materialize(self);3994 return try result.materialize(self);
4003 }3995 }
40043996
4005 fn airSplat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {3997 fn airSplat(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4006 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;3998 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
40073999
4008 const operand_id = try self.resolve(ty_op.operand);4000 const operand_id = try self.resolve(ty_op.operand);
...@@ -4011,7 +4003,7 @@ const DeclGen = struct {...@@ -4011,7 +4003,7 @@ const DeclGen = struct {
4011 return try self.constructVectorSplat(result_ty, operand_id);4003 return try self.constructVectorSplat(result_ty, operand_id);
4012 }4004 }
40134005
4014 fn airReduce(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4006 fn airReduce(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4015 const mod = self.pt.zcu;4007 const mod = self.pt.zcu;
4016 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;4008 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
4017 const operand = try self.resolve(reduce.operand);4009 const operand = try self.resolve(reduce.operand);
...@@ -4086,7 +4078,7 @@ const DeclGen = struct {...@@ -4086,7 +4078,7 @@ const DeclGen = struct {
4086 return result_id;4078 return result_id;
4087 }4079 }
40884080
4089 fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4081 fn airShuffle(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4090 const pt = self.pt;4082 const pt = self.pt;
4091 const mod = pt.zcu;4083 const mod = pt.zcu;
4092 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4084 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -4163,7 +4155,7 @@ const DeclGen = struct {...@@ -4163,7 +4155,7 @@ const DeclGen = struct {
4163 return try self.constructVector(result_ty, components);4155 return try self.constructVector(result_ty, components);
4164 }4156 }
41654157
4166 fn indicesToIds(self: *DeclGen, indices: []const u32) ![]IdRef {4158 fn indicesToIds(self: *NavGen, indices: []const u32) ![]IdRef {
4167 const ids = try self.gpa.alloc(IdRef, indices.len);4159 const ids = try self.gpa.alloc(IdRef, indices.len);
4168 errdefer self.gpa.free(ids);4160 errdefer self.gpa.free(ids);
4169 for (indices, ids) |index, *id| {4161 for (indices, ids) |index, *id| {
...@@ -4174,7 +4166,7 @@ const DeclGen = struct {...@@ -4174,7 +4166,7 @@ const DeclGen = struct {
4174 }4166 }
41754167
4176 fn accessChainId(4168 fn accessChainId(
4177 self: *DeclGen,4169 self: *NavGen,
4178 result_ty_id: IdRef,4170 result_ty_id: IdRef,
4179 base: IdRef,4171 base: IdRef,
4180 indices: []const IdRef,4172 indices: []const IdRef,
...@@ -4194,7 +4186,7 @@ const DeclGen = struct {...@@ -4194,7 +4186,7 @@ const DeclGen = struct {
4194 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain4186 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain
4195 /// is the latter and PtrAccessChain is the former.4187 /// is the latter and PtrAccessChain is the former.
4196 fn accessChain(4188 fn accessChain(
4197 self: *DeclGen,4189 self: *NavGen,
4198 result_ty_id: IdRef,4190 result_ty_id: IdRef,
4199 base: IdRef,4191 base: IdRef,
4200 indices: []const u32,4192 indices: []const u32,
...@@ -4205,7 +4197,7 @@ const DeclGen = struct {...@@ -4205,7 +4197,7 @@ const DeclGen = struct {
4205 }4197 }
42064198
4207 fn ptrAccessChain(4199 fn ptrAccessChain(
4208 self: *DeclGen,4200 self: *NavGen,
4209 result_ty_id: IdRef,4201 result_ty_id: IdRef,
4210 base: IdRef,4202 base: IdRef,
4211 element: IdRef,4203 element: IdRef,
...@@ -4225,7 +4217,7 @@ const DeclGen = struct {...@@ -4225,7 +4217,7 @@ const DeclGen = struct {
4225 return result_id;4217 return result_id;
4226 }4218 }
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 {
4229 const mod = self.pt.zcu;4221 const mod = self.pt.zcu;
4230 const result_ty_id = try self.resolveType(result_ty, .direct);4222 const result_ty_id = try self.resolveType(result_ty, .direct);
42314223
...@@ -4246,7 +4238,7 @@ const DeclGen = struct {...@@ -4246,7 +4238,7 @@ const DeclGen = struct {
4246 }4238 }
4247 }4239 }
42484240
4249 fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4241 fn airPtrAdd(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4250 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4242 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4251 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4243 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4252 const ptr_id = try self.resolve(bin_op.lhs);4244 const ptr_id = try self.resolve(bin_op.lhs);
...@@ -4257,7 +4249,7 @@ const DeclGen = struct {...@@ -4257,7 +4249,7 @@ const DeclGen = struct {
4257 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);4249 return try self.ptrAdd(result_ty, ptr_ty, ptr_id, offset_id);
4258 }4250 }
42594251
4260 fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4252 fn airPtrSub(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4261 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4253 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4262 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4254 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4263 const ptr_id = try self.resolve(bin_op.lhs);4255 const ptr_id = try self.resolve(bin_op.lhs);
...@@ -4277,7 +4269,7 @@ const DeclGen = struct {...@@ -4277,7 +4269,7 @@ const DeclGen = struct {
4277 }4269 }
42784270
4279 fn cmp(4271 fn cmp(
4280 self: *DeclGen,4272 self: *NavGen,
4281 op: std.math.CompareOperator,4273 op: std.math.CompareOperator,
4282 lhs: Temporary,4274 lhs: Temporary,
4283 rhs: Temporary,4275 rhs: Temporary,
...@@ -4443,7 +4435,7 @@ const DeclGen = struct {...@@ -4443,7 +4435,7 @@ const DeclGen = struct {
4443 }4435 }
44444436
4445 fn airCmp(4437 fn airCmp(
4446 self: *DeclGen,4438 self: *NavGen,
4447 inst: Air.Inst.Index,4439 inst: Air.Inst.Index,
4448 comptime op: std.math.CompareOperator,4440 comptime op: std.math.CompareOperator,
4449 ) !?IdRef {4441 ) !?IdRef {
...@@ -4455,7 +4447,7 @@ const DeclGen = struct {...@@ -4455,7 +4447,7 @@ const DeclGen = struct {
4455 return try result.materialize(self);4447 return try result.materialize(self);
4456 }4448 }
44574449
4458 fn airVectorCmp(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4450 fn airVectorCmp(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4459 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4451 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4460 const vec_cmp = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;4452 const vec_cmp = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
4461 const lhs = try self.temporary(vec_cmp.lhs);4453 const lhs = try self.temporary(vec_cmp.lhs);
...@@ -4468,7 +4460,7 @@ const DeclGen = struct {...@@ -4468,7 +4460,7 @@ const DeclGen = struct {
44684460
4469 /// Bitcast one type to another. Note: both types, input, output are expected in **direct** representation.4461 /// Bitcast one type to another. Note: both types, input, output are expected in **direct** representation.
4470 fn bitCast(4462 fn bitCast(
4471 self: *DeclGen,4463 self: *NavGen,
4472 dst_ty: Type,4464 dst_ty: Type,
4473 src_ty: Type,4465 src_ty: Type,
4474 src_id: IdRef,4466 src_id: IdRef,
...@@ -4536,7 +4528,7 @@ const DeclGen = struct {...@@ -4536,7 +4528,7 @@ const DeclGen = struct {
4536 return result_id;4528 return result_id;
4537 }4529 }
45384530
4539 fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4531 fn airBitCast(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4540 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4532 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4541 const operand_id = try self.resolve(ty_op.operand);4533 const operand_id = try self.resolve(ty_op.operand);
4542 const operand_ty = self.typeOf(ty_op.operand);4534 const operand_ty = self.typeOf(ty_op.operand);
...@@ -4544,7 +4536,7 @@ const DeclGen = struct {...@@ -4544,7 +4536,7 @@ const DeclGen = struct {
4544 return try self.bitCast(result_ty, operand_ty, operand_id);4536 return try self.bitCast(result_ty, operand_ty, operand_id);
4545 }4537 }
45464538
4547 fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4539 fn airIntCast(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4548 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4540 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4549 const src = try self.temporary(ty_op.operand);4541 const src = try self.temporary(ty_op.operand);
4550 const dst_ty = self.typeOfIndex(inst);4542 const dst_ty = self.typeOfIndex(inst);
...@@ -4570,7 +4562,7 @@ const DeclGen = struct {...@@ -4570,7 +4562,7 @@ const DeclGen = struct {
4570 return try result.materialize(self);4562 return try result.materialize(self);
4571 }4563 }
45724564
4573 fn intFromPtr(self: *DeclGen, operand_id: IdRef) !IdRef {4565 fn intFromPtr(self: *NavGen, operand_id: IdRef) !IdRef {
4574 const result_type_id = try self.resolveType(Type.usize, .direct);4566 const result_type_id = try self.resolveType(Type.usize, .direct);
4575 const result_id = self.spv.allocId();4567 const result_id = self.spv.allocId();
4576 try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{4568 try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{
...@@ -4581,13 +4573,13 @@ const DeclGen = struct {...@@ -4581,13 +4573,13 @@ const DeclGen = struct {
4581 return result_id;4573 return result_id;
4582 }4574 }
45834575
4584 fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4576 fn airIntFromPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4585 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4577 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4586 const operand_id = try self.resolve(un_op);4578 const operand_id = try self.resolve(un_op);
4587 return try self.intFromPtr(operand_id);4579 return try self.intFromPtr(operand_id);
4588 }4580 }
45894581
4590 fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4582 fn airFloatFromInt(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4591 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4583 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4592 const operand_ty = self.typeOf(ty_op.operand);4584 const operand_ty = self.typeOf(ty_op.operand);
4593 const operand_id = try self.resolve(ty_op.operand);4585 const operand_id = try self.resolve(ty_op.operand);
...@@ -4595,7 +4587,7 @@ const DeclGen = struct {...@@ -4595,7 +4587,7 @@ const DeclGen = struct {
4595 return try self.floatFromInt(result_ty, operand_ty, operand_id);4587 return try self.floatFromInt(result_ty, operand_ty, operand_id);
4596 }4588 }
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 {
4599 const operand_info = self.arithmeticTypeInfo(operand_ty);4591 const operand_info = self.arithmeticTypeInfo(operand_ty);
4600 const result_id = self.spv.allocId();4592 const result_id = self.spv.allocId();
4601 const result_ty_id = try self.resolveType(result_ty, .direct);4593 const result_ty_id = try self.resolveType(result_ty, .direct);
...@@ -4614,14 +4606,14 @@ const DeclGen = struct {...@@ -4614,14 +4606,14 @@ const DeclGen = struct {
4614 return result_id;4606 return result_id;
4615 }4607 }
46164608
4617 fn airIntFromFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4609 fn airIntFromFloat(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4618 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4610 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4619 const operand_id = try self.resolve(ty_op.operand);4611 const operand_id = try self.resolve(ty_op.operand);
4620 const result_ty = self.typeOfIndex(inst);4612 const result_ty = self.typeOfIndex(inst);
4621 return try self.intFromFloat(result_ty, operand_id);4613 return try self.intFromFloat(result_ty, operand_id);
4622 }4614 }
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 {
4625 const result_info = self.arithmeticTypeInfo(result_ty);4617 const result_info = self.arithmeticTypeInfo(result_ty);
4626 const result_ty_id = try self.resolveType(result_ty, .direct);4618 const result_ty_id = try self.resolveType(result_ty, .direct);
4627 const result_id = self.spv.allocId();4619 const result_id = self.spv.allocId();
...@@ -4640,14 +4632,14 @@ const DeclGen = struct {...@@ -4640,14 +4632,14 @@ const DeclGen = struct {
4640 return result_id;4632 return result_id;
4641 }4633 }
46424634
4643 fn airIntFromBool(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4635 fn airIntFromBool(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4644 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4636 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4645 const operand = try self.temporary(un_op);4637 const operand = try self.temporary(un_op);
4646 const result = try self.intFromBool(operand);4638 const result = try self.intFromBool(operand);
4647 return try result.materialize(self);4639 return try result.materialize(self);
4648 }4640 }
46494641
4650 fn airFloatCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4642 fn airFloatCast(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4651 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4643 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4652 const operand_id = try self.resolve(ty_op.operand);4644 const operand_id = try self.resolve(ty_op.operand);
4653 const dest_ty = self.typeOfIndex(inst);4645 const dest_ty = self.typeOfIndex(inst);
...@@ -4662,7 +4654,7 @@ const DeclGen = struct {...@@ -4662,7 +4654,7 @@ const DeclGen = struct {
4662 return result_id;4654 return result_id;
4663 }4655 }
46644656
4665 fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4657 fn airNot(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4666 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4658 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4667 const operand = try self.temporary(ty_op.operand);4659 const operand = try self.temporary(ty_op.operand);
4668 const result_ty = self.typeOfIndex(inst);4660 const result_ty = self.typeOfIndex(inst);
...@@ -4681,7 +4673,7 @@ const DeclGen = struct {...@@ -4681,7 +4673,7 @@ const DeclGen = struct {
4681 return try result.materialize(self);4673 return try result.materialize(self);
4682 }4674 }
46834675
4684 fn airArrayToSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4676 fn airArrayToSlice(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4685 const pt = self.pt;4677 const pt = self.pt;
4686 const mod = pt.zcu;4678 const mod = pt.zcu;
4687 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4679 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -4709,7 +4701,7 @@ const DeclGen = struct {...@@ -4709,7 +4701,7 @@ const DeclGen = struct {
4709 );4701 );
4710 }4702 }
47114703
4712 fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4704 fn airSlice(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4713 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4705 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4714 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4706 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
4715 const ptr_id = try self.resolve(bin_op.lhs);4707 const ptr_id = try self.resolve(bin_op.lhs);
...@@ -4726,7 +4718,7 @@ const DeclGen = struct {...@@ -4726,7 +4718,7 @@ const DeclGen = struct {
4726 );4718 );
4727 }4719 }
47284720
4729 fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4721 fn airAggregateInit(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4730 const pt = self.pt;4722 const pt = self.pt;
4731 const mod = pt.zcu;4723 const mod = pt.zcu;
4732 const ip = &mod.intern_pool;4724 const ip = &mod.intern_pool;
...@@ -4816,7 +4808,7 @@ const DeclGen = struct {...@@ -4816,7 +4808,7 @@ const DeclGen = struct {
4816 }4808 }
4817 }4809 }
48184810
4819 fn sliceOrArrayLen(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {4811 fn sliceOrArrayLen(self: *NavGen, operand_id: IdRef, ty: Type) !IdRef {
4820 const pt = self.pt;4812 const pt = self.pt;
4821 const mod = pt.zcu;4813 const mod = pt.zcu;
4822 switch (ty.ptrSize(mod)) {4814 switch (ty.ptrSize(mod)) {
...@@ -4832,7 +4824,7 @@ const DeclGen = struct {...@@ -4832,7 +4824,7 @@ const DeclGen = struct {
4832 }4824 }
4833 }4825 }
48344826
4835 fn sliceOrArrayPtr(self: *DeclGen, operand_id: IdRef, ty: Type) !IdRef {4827 fn sliceOrArrayPtr(self: *NavGen, operand_id: IdRef, ty: Type) !IdRef {
4836 const mod = self.pt.zcu;4828 const mod = self.pt.zcu;
4837 if (ty.isSlice(mod)) {4829 if (ty.isSlice(mod)) {
4838 const ptr_ty = ty.slicePtrFieldType(mod);4830 const ptr_ty = ty.slicePtrFieldType(mod);
...@@ -4841,7 +4833,7 @@ const DeclGen = struct {...@@ -4841,7 +4833,7 @@ const DeclGen = struct {
4841 return operand_id;4833 return operand_id;
4842 }4834 }
48434835
4844 fn airMemcpy(self: *DeclGen, inst: Air.Inst.Index) !void {4836 fn airMemcpy(self: *NavGen, inst: Air.Inst.Index) !void {
4845 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4837 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4846 const dest_slice = try self.resolve(bin_op.lhs);4838 const dest_slice = try self.resolve(bin_op.lhs);
4847 const src_slice = try self.resolve(bin_op.rhs);4839 const src_slice = try self.resolve(bin_op.rhs);
...@@ -4857,14 +4849,14 @@ const DeclGen = struct {...@@ -4857,14 +4849,14 @@ const DeclGen = struct {
4857 });4849 });
4858 }4850 }
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 {
4861 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;4853 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
4862 const field_ty = self.typeOfIndex(inst);4854 const field_ty = self.typeOfIndex(inst);
4863 const operand_id = try self.resolve(ty_op.operand);4855 const operand_id = try self.resolve(ty_op.operand);
4864 return try self.extractField(field_ty, operand_id, field);4856 return try self.extractField(field_ty, operand_id, field);
4865 }4857 }
48664858
4867 fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4859 fn airSliceElemPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4868 const mod = self.pt.zcu;4860 const mod = self.pt.zcu;
4869 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4861 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4870 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;4862 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
...@@ -4881,7 +4873,7 @@ const DeclGen = struct {...@@ -4881,7 +4873,7 @@ const DeclGen = struct {
4881 return try self.ptrAccessChain(ptr_ty_id, slice_ptr, index_id, &.{});4873 return try self.ptrAccessChain(ptr_ty_id, slice_ptr, index_id, &.{});
4882 }4874 }
48834875
4884 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4876 fn airSliceElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4885 const mod = self.pt.zcu;4877 const mod = self.pt.zcu;
4886 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4878 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4887 const slice_ty = self.typeOf(bin_op.lhs);4879 const slice_ty = self.typeOf(bin_op.lhs);
...@@ -4898,7 +4890,7 @@ const DeclGen = struct {...@@ -4898,7 +4890,7 @@ const DeclGen = struct {
4898 return try self.load(slice_ty.childType(mod), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(mod) });4890 return try self.load(slice_ty.childType(mod), elem_ptr, .{ .is_volatile = slice_ty.isVolatilePtr(mod) });
4899 }4891 }
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 {
4902 const mod = self.pt.zcu;4894 const mod = self.pt.zcu;
4903 // Construct new pointer type for the resulting pointer4895 // Construct new pointer type for the resulting pointer
4904 const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.4896 const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T.
...@@ -4913,7 +4905,7 @@ const DeclGen = struct {...@@ -4913,7 +4905,7 @@ const DeclGen = struct {
4913 }4905 }
4914 }4906 }
49154907
4916 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4908 fn airPtrElemPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4917 const pt = self.pt;4909 const pt = self.pt;
4918 const mod = pt.zcu;4910 const mod = pt.zcu;
4919 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4911 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -4931,7 +4923,7 @@ const DeclGen = struct {...@@ -4931,7 +4923,7 @@ const DeclGen = struct {
4931 return try self.ptrElemPtr(src_ptr_ty, ptr_id, index_id);4923 return try self.ptrElemPtr(src_ptr_ty, ptr_id, index_id);
4932 }4924 }
49334925
4934 fn airArrayElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4926 fn airArrayElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4935 const mod = self.pt.zcu;4927 const mod = self.pt.zcu;
4936 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4928 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4937 const array_ty = self.typeOf(bin_op.lhs);4929 const array_ty = self.typeOf(bin_op.lhs);
...@@ -4992,7 +4984,7 @@ const DeclGen = struct {...@@ -4992,7 +4984,7 @@ const DeclGen = struct {
4992 return try self.convertToDirect(elem_ty, result_id);4984 return try self.convertToDirect(elem_ty, result_id);
4993 }4985 }
49944986
4995 fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {4987 fn airPtrElemVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
4996 const mod = self.pt.zcu;4988 const mod = self.pt.zcu;
4997 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;4989 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
4998 const ptr_ty = self.typeOf(bin_op.lhs);4990 const ptr_ty = self.typeOf(bin_op.lhs);
...@@ -5003,7 +4995,7 @@ const DeclGen = struct {...@@ -5003,7 +4995,7 @@ const DeclGen = struct {
5003 return try self.load(elem_ty, elem_ptr_id, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });4995 return try self.load(elem_ty, elem_ptr_id, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
5004 }4996 }
50054997
5006 fn airVectorStoreElem(self: *DeclGen, inst: Air.Inst.Index) !void {4998 fn airVectorStoreElem(self: *NavGen, inst: Air.Inst.Index) !void {
5007 const mod = self.pt.zcu;4999 const mod = self.pt.zcu;
5008 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;5000 const data = self.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
5009 const extra = self.air.extraData(Air.Bin, data.payload).data;5001 const extra = self.air.extraData(Air.Bin, data.payload).data;
...@@ -5025,7 +5017,7 @@ const DeclGen = struct {...@@ -5025,7 +5017,7 @@ const DeclGen = struct {
5025 });5017 });
5026 }5018 }
50275019
5028 fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {5020 fn airSetUnionTag(self: *NavGen, inst: Air.Inst.Index) !void {
5029 const mod = self.pt.zcu;5021 const mod = self.pt.zcu;
5030 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5022 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5031 const un_ptr_ty = self.typeOf(bin_op.lhs);5023 const un_ptr_ty = self.typeOf(bin_op.lhs);
...@@ -5048,7 +5040,7 @@ const DeclGen = struct {...@@ -5048,7 +5040,7 @@ const DeclGen = struct {
5048 }5040 }
5049 }5041 }
50505042
5051 fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5043 fn airGetUnionTag(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5052 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5044 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5053 const un_ty = self.typeOf(ty_op.operand);5045 const un_ty = self.typeOf(ty_op.operand);
50545046
...@@ -5064,7 +5056,7 @@ const DeclGen = struct {...@@ -5064,7 +5056,7 @@ const DeclGen = struct {
5064 }5056 }
50655057
5066 fn unionInit(5058 fn unionInit(
5067 self: *DeclGen,5059 self: *NavGen,
5068 ty: Type,5060 ty: Type,
5069 active_field: u32,5061 active_field: u32,
5070 payload: ?IdRef,5062 payload: ?IdRef,
...@@ -5129,7 +5121,7 @@ const DeclGen = struct {...@@ -5129,7 +5121,7 @@ const DeclGen = struct {
5129 return try self.load(ty, tmp_id, .{});5121 return try self.load(ty, tmp_id, .{});
5130 }5122 }
51315123
5132 fn airUnionInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5124 fn airUnionInit(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5133 const pt = self.pt;5125 const pt = self.pt;
5134 const mod = pt.zcu;5126 const mod = pt.zcu;
5135 const ip = &mod.intern_pool;5127 const ip = &mod.intern_pool;
...@@ -5146,7 +5138,7 @@ const DeclGen = struct {...@@ -5146,7 +5138,7 @@ const DeclGen = struct {
5146 return try self.unionInit(ty, extra.field_index, payload);5138 return try self.unionInit(ty, extra.field_index, payload);
5147 }5139 }
51485140
5149 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5141 fn airStructFieldVal(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5150 const pt = self.pt;5142 const pt = self.pt;
5151 const mod = pt.zcu;5143 const mod = pt.zcu;
5152 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5144 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -5191,7 +5183,7 @@ const DeclGen = struct {...@@ -5191,7 +5183,7 @@ const DeclGen = struct {
5191 }5183 }
5192 }5184 }
51935185
5194 fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5186 fn airFieldParentPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5195 const pt = self.pt;5187 const pt = self.pt;
5196 const mod = pt.zcu;5188 const mod = pt.zcu;
5197 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5189 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
...@@ -5225,7 +5217,7 @@ const DeclGen = struct {...@@ -5225,7 +5217,7 @@ const DeclGen = struct {
5225 }5217 }
52265218
5227 fn structFieldPtr(5219 fn structFieldPtr(
5228 self: *DeclGen,5220 self: *NavGen,
5229 result_ptr_ty: Type,5221 result_ptr_ty: Type,
5230 object_ptr_ty: Type,5222 object_ptr_ty: Type,
5231 object_ptr: IdRef,5223 object_ptr: IdRef,
...@@ -5273,7 +5265,7 @@ const DeclGen = struct {...@@ -5273,7 +5265,7 @@ const DeclGen = struct {
5273 }5265 }
5274 }5266 }
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 {
5277 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5269 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5278 const struct_ptr = try self.resolve(ty_op.operand);5270 const struct_ptr = try self.resolve(ty_op.operand);
5279 const struct_ptr_ty = self.typeOf(ty_op.operand);5271 const struct_ptr_ty = self.typeOf(ty_op.operand);
...@@ -5294,7 +5286,7 @@ const DeclGen = struct {...@@ -5294,7 +5286,7 @@ const DeclGen = struct {
5294 // which is in the Generic address space. The variable is actually5286 // which is in the Generic address space. The variable is actually
5295 // placed in the Function address space.5287 // placed in the Function address space.
5296 fn alloc(5288 fn alloc(
5297 self: *DeclGen,5289 self: *NavGen,
5298 ty: Type,5290 ty: Type,
5299 options: AllocOptions,5291 options: AllocOptions,
5300 ) !IdRef {5292 ) !IdRef {
...@@ -5326,7 +5318,7 @@ const DeclGen = struct {...@@ -5326,7 +5318,7 @@ const DeclGen = struct {
5326 }5318 }
5327 }5319 }
53285320
5329 fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5321 fn airAlloc(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5330 const mod = self.pt.zcu;5322 const mod = self.pt.zcu;
5331 const ptr_ty = self.typeOfIndex(inst);5323 const ptr_ty = self.typeOfIndex(inst);
5332 assert(ptr_ty.ptrAddressSpace(mod) == .generic);5324 assert(ptr_ty.ptrAddressSpace(mod) == .generic);
...@@ -5334,7 +5326,7 @@ const DeclGen = struct {...@@ -5334,7 +5326,7 @@ const DeclGen = struct {
5334 return try self.alloc(child_ty, .{});5326 return try self.alloc(child_ty, .{});
5335 }5327 }
53365328
5337 fn airArg(self: *DeclGen) IdRef {5329 fn airArg(self: *NavGen) IdRef {
5338 defer self.next_arg_index += 1;5330 defer self.next_arg_index += 1;
5339 return self.args.items[self.next_arg_index];5331 return self.args.items[self.next_arg_index];
5340 }5332 }
...@@ -5343,7 +5335,7 @@ const DeclGen = struct {...@@ -5343,7 +5335,7 @@ const DeclGen = struct {
5343 /// block to jump to. This function emits instructions, so it should be emitted5335 /// block to jump to. This function emits instructions, so it should be emitted
5344 /// inside the merge block of the block.5336 /// inside the merge block of the block.
5345 /// This function should only be called with structured control flow generation.5337 /// 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 {
5347 assert(self.control_flow == .structured);5339 assert(self.control_flow == .structured);
53485340
5349 const result_id = self.spv.allocId();5341 const result_id = self.spv.allocId();
...@@ -5362,7 +5354,7 @@ const DeclGen = struct {...@@ -5362,7 +5354,7 @@ const DeclGen = struct {
5362 /// Jumps to the block with the target block-id. This function must only be called when5354 /// Jumps to the block with the target block-id. This function must only be called when
5363 /// terminating a body, there should be no instructions after it.5355 /// terminating a body, there should be no instructions after it.
5364 /// This function should only be called with structured control flow generation.5356 /// 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 {
5366 assert(self.control_flow == .structured);5358 assert(self.control_flow == .structured);
53675359
5368 const sblock = self.control_flow.structured.block_stack.getLast();5360 const sblock = self.control_flow.structured.block_stack.getLast();
...@@ -5393,7 +5385,7 @@ const DeclGen = struct {...@@ -5393,7 +5385,7 @@ const DeclGen = struct {
5393 /// should still be emitted to the block that should follow this structured body.5385 /// should still be emitted to the block that should follow this structured body.
5394 /// This function should only be called with structured control flow generation.5386 /// This function should only be called with structured control flow generation.
5395 fn genStructuredBody(5387 fn genStructuredBody(
5396 self: *DeclGen,5388 self: *NavGen,
5397 /// This parameter defines the method that this structured body is exited with.5389 /// This parameter defines the method that this structured body is exited with.
5398 block_merge_type: union(enum) {5390 block_merge_type: union(enum) {
5399 /// Using selection; early exits from this body are surrounded with5391 /// Using selection; early exits from this body are surrounded with
...@@ -5487,13 +5479,13 @@ const DeclGen = struct {...@@ -5487,13 +5479,13 @@ const DeclGen = struct {
5487 }5479 }
5488 }5480 }
54895481
5490 fn airBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5482 fn airBlock(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5491 const inst_datas = self.air.instructions.items(.data);5483 const inst_datas = self.air.instructions.items(.data);
5492 const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);5484 const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);
5493 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));5485 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
5494 }5486 }
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 {
5497 // In AIR, a block doesn't really define an entry point like a block, but5489 // In AIR, a block doesn't really define an entry point like a block, but
5498 // more like a scope that breaks can jump out of and "return" a value from.5490 // more like a scope that breaks can jump out of and "return" a value from.
5499 // This cannot be directly modelled in SPIR-V, so in a block instruction,5491 // This cannot be directly modelled in SPIR-V, so in a block instruction,
...@@ -5633,7 +5625,7 @@ const DeclGen = struct {...@@ -5633,7 +5625,7 @@ const DeclGen = struct {
5633 return null;5625 return null;
5634 }5626 }
56355627
5636 fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {5628 fn airBr(self: *NavGen, inst: Air.Inst.Index) !void {
5637 const pt = self.pt;5629 const pt = self.pt;
5638 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;5630 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
5639 const operand_ty = self.typeOf(br.operand);5631 const operand_ty = self.typeOf(br.operand);
...@@ -5670,7 +5662,7 @@ const DeclGen = struct {...@@ -5670,7 +5662,7 @@ const DeclGen = struct {
5670 }5662 }
5671 }5663 }
56725664
5673 fn airCondBr(self: *DeclGen, inst: Air.Inst.Index) !void {5665 fn airCondBr(self: *NavGen, inst: Air.Inst.Index) !void {
5674 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5666 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
5675 const cond_br = self.air.extraData(Air.CondBr, pl_op.payload);5667 const cond_br = self.air.extraData(Air.CondBr, pl_op.payload);
5676 const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[cond_br.end..][0..cond_br.data.then_body_len]);5668 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 {...@@ -5730,7 +5722,7 @@ const DeclGen = struct {
5730 }5722 }
5731 }5723 }
57325724
5733 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {5725 fn airLoop(self: *NavGen, inst: Air.Inst.Index) !void {
5734 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5726 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5735 const loop = self.air.extraData(Air.Block, ty_pl.payload);5727 const loop = self.air.extraData(Air.Block, ty_pl.payload);
5736 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);5728 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
...@@ -5777,7 +5769,7 @@ const DeclGen = struct {...@@ -5777,7 +5769,7 @@ const DeclGen = struct {
5777 }5769 }
5778 }5770 }
57795771
5780 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5772 fn airLoad(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5781 const mod = self.pt.zcu;5773 const mod = self.pt.zcu;
5782 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5774 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5783 const ptr_ty = self.typeOf(ty_op.operand);5775 const ptr_ty = self.typeOf(ty_op.operand);
...@@ -5788,7 +5780,7 @@ const DeclGen = struct {...@@ -5788,7 +5780,7 @@ const DeclGen = struct {
5788 return try self.load(elem_ty, operand, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });5780 return try self.load(elem_ty, operand, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
5789 }5781 }
57905782
5791 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {5783 fn airStore(self: *NavGen, inst: Air.Inst.Index) !void {
5792 const mod = self.pt.zcu;5784 const mod = self.pt.zcu;
5793 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;5785 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
5794 const ptr_ty = self.typeOf(bin_op.lhs);5786 const ptr_ty = self.typeOf(bin_op.lhs);
...@@ -5799,14 +5791,13 @@ const DeclGen = struct {...@@ -5799,14 +5791,13 @@ const DeclGen = struct {
5799 try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });5791 try self.store(elem_ty, ptr, value, .{ .is_volatile = ptr_ty.isVolatilePtr(mod) });
5800 }5792 }
58015793
5802 fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {5794 fn airRet(self: *NavGen, inst: Air.Inst.Index) !void {
5803 const pt = self.pt;5795 const pt = self.pt;
5804 const mod = pt.zcu;5796 const mod = pt.zcu;
5805 const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5797 const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5806 const ret_ty = self.typeOf(operand);5798 const ret_ty = self.typeOf(operand);
5807 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {5799 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5808 const decl = mod.declPtr(self.decl_index);5800 const fn_info = mod.typeToFunc(mod.navValue(self.owner_nav).typeOf(mod)).?;
5809 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
5810 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5801 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5811 // Functions with an empty error set are emitted with an error code5802 // Functions with an empty error set are emitted with an error code
5812 // return type and return zero so they can be function pointers coerced5803 // return type and return zero so they can be function pointers coerced
...@@ -5822,7 +5813,7 @@ const DeclGen = struct {...@@ -5822,7 +5813,7 @@ const DeclGen = struct {
5822 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });5813 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
5823 }5814 }
58245815
5825 fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {5816 fn airRetLoad(self: *NavGen, inst: Air.Inst.Index) !void {
5826 const pt = self.pt;5817 const pt = self.pt;
5827 const mod = pt.zcu;5818 const mod = pt.zcu;
5828 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5819 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
...@@ -5830,8 +5821,7 @@ const DeclGen = struct {...@@ -5830,8 +5821,7 @@ const DeclGen = struct {
5830 const ret_ty = ptr_ty.childType(mod);5821 const ret_ty = ptr_ty.childType(mod);
58315822
5832 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {5823 if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
5833 const decl = mod.declPtr(self.decl_index);5824 const fn_info = mod.typeToFunc(mod.navValue(self.owner_nav).typeOf(mod)).?;
5834 const fn_info = mod.typeToFunc(decl.typeOf(mod)).?;
5835 if (Type.fromInterned(fn_info.return_type).isError(mod)) {5825 if (Type.fromInterned(fn_info.return_type).isError(mod)) {
5836 // Functions with an empty error set are emitted with an error code5826 // Functions with an empty error set are emitted with an error code
5837 // return type and return zero so they can be function pointers coerced5827 // return type and return zero so they can be function pointers coerced
...@@ -5850,7 +5840,7 @@ const DeclGen = struct {...@@ -5850,7 +5840,7 @@ const DeclGen = struct {
5850 });5840 });
5851 }5841 }
58525842
5853 fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5843 fn airTry(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5854 const mod = self.pt.zcu;5844 const mod = self.pt.zcu;
5855 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;5845 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
5856 const err_union_id = try self.resolve(pl_op.operand);5846 const err_union_id = try self.resolve(pl_op.operand);
...@@ -5920,7 +5910,7 @@ const DeclGen = struct {...@@ -5920,7 +5910,7 @@ const DeclGen = struct {
5920 return try self.extractField(payload_ty, err_union_id, eu_layout.payloadFieldIndex());5910 return try self.extractField(payload_ty, err_union_id, eu_layout.payloadFieldIndex());
5921 }5911 }
59225912
5923 fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5913 fn airErrUnionErr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5924 const mod = self.pt.zcu;5914 const mod = self.pt.zcu;
5925 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5915 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5926 const operand_id = try self.resolve(ty_op.operand);5916 const operand_id = try self.resolve(ty_op.operand);
...@@ -5943,7 +5933,7 @@ const DeclGen = struct {...@@ -5943,7 +5933,7 @@ const DeclGen = struct {
5943 return try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());5933 return try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex());
5944 }5934 }
59455935
5946 fn airErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5936 fn airErrUnionPayload(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5947 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5937 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5948 const operand_id = try self.resolve(ty_op.operand);5938 const operand_id = try self.resolve(ty_op.operand);
5949 const payload_ty = self.typeOfIndex(inst);5939 const payload_ty = self.typeOfIndex(inst);
...@@ -5956,7 +5946,7 @@ const DeclGen = struct {...@@ -5956,7 +5946,7 @@ const DeclGen = struct {
5956 return try self.extractField(payload_ty, operand_id, eu_layout.payloadFieldIndex());5946 return try self.extractField(payload_ty, operand_id, eu_layout.payloadFieldIndex());
5957 }5947 }
59585948
5959 fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5949 fn airWrapErrUnionErr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5960 const mod = self.pt.zcu;5950 const mod = self.pt.zcu;
5961 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5951 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5962 const err_union_ty = self.typeOfIndex(inst);5952 const err_union_ty = self.typeOfIndex(inst);
...@@ -5981,7 +5971,7 @@ const DeclGen = struct {...@@ -5981,7 +5971,7 @@ const DeclGen = struct {
5981 return try self.constructStruct(err_union_ty, &types, &members);5971 return try self.constructStruct(err_union_ty, &types, &members);
5982 }5972 }
59835973
5984 fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {5974 fn airWrapErrUnionPayload(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
5985 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5975 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5986 const err_union_ty = self.typeOfIndex(inst);5976 const err_union_ty = self.typeOfIndex(inst);
5987 const operand_id = try self.resolve(ty_op.operand);5977 const operand_id = try self.resolve(ty_op.operand);
...@@ -6003,7 +5993,7 @@ const DeclGen = struct {...@@ -6003,7 +5993,7 @@ const DeclGen = struct {
6003 return try self.constructStruct(err_union_ty, &types, &members);5993 return try self.constructStruct(err_union_ty, &types, &members);
6004 }5994 }
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 {
6007 const pt = self.pt;5997 const pt = self.pt;
6008 const mod = pt.zcu;5998 const mod = pt.zcu;
6009 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5999 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
...@@ -6080,7 +6070,7 @@ const DeclGen = struct {...@@ -6080,7 +6070,7 @@ const DeclGen = struct {
6080 };6070 };
6081 }6071 }
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 {
6084 const mod = self.pt.zcu;6074 const mod = self.pt.zcu;
6085 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6075 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
6086 const operand_id = try self.resolve(un_op);6076 const operand_id = try self.resolve(un_op);
...@@ -6113,7 +6103,7 @@ const DeclGen = struct {...@@ -6113,7 +6103,7 @@ const DeclGen = struct {
6113 return result_id;6103 return result_id;
6114 }6104 }
61156105
6116 fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6106 fn airUnwrapOptional(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6117 const pt = self.pt;6107 const pt = self.pt;
6118 const mod = pt.zcu;6108 const mod = pt.zcu;
6119 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6109 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -6130,7 +6120,7 @@ const DeclGen = struct {...@@ -6130,7 +6120,7 @@ const DeclGen = struct {
6130 return try self.extractField(payload_ty, operand_id, 0);6120 return try self.extractField(payload_ty, operand_id, 0);
6131 }6121 }
61326122
6133 fn airUnwrapOptionalPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6123 fn airUnwrapOptionalPtr(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6134 const pt = self.pt;6124 const pt = self.pt;
6135 const mod = pt.zcu;6125 const mod = pt.zcu;
6136 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6126 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -6155,7 +6145,7 @@ const DeclGen = struct {...@@ -6155,7 +6145,7 @@ const DeclGen = struct {
6155 return try self.accessChain(result_ty_id, operand_id, &.{0});6145 return try self.accessChain(result_ty_id, operand_id, &.{0});
6156 }6146 }
61576147
6158 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6148 fn airWrapOptional(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6159 const pt = self.pt;6149 const pt = self.pt;
6160 const mod = pt.zcu;6150 const mod = pt.zcu;
6161 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6151 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
...@@ -6178,7 +6168,7 @@ const DeclGen = struct {...@@ -6178,7 +6168,7 @@ const DeclGen = struct {
6178 return try self.constructStruct(optional_ty, &types, &members);6168 return try self.constructStruct(optional_ty, &types, &members);
6179 }6169 }
61806170
6181 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {6171 fn airSwitchBr(self: *NavGen, inst: Air.Inst.Index) !void {
6182 const pt = self.pt;6172 const pt = self.pt;
6183 const mod = pt.zcu;6173 const mod = pt.zcu;
6184 const target = self.getTarget();6174 const target = self.getTarget();
...@@ -6347,16 +6337,15 @@ const DeclGen = struct {...@@ -6347,16 +6337,15 @@ const DeclGen = struct {
6347 }6337 }
6348 }6338 }
63496339
6350 fn airUnreach(self: *DeclGen) !void {6340 fn airUnreach(self: *NavGen) !void {
6351 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});6341 try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
6352 }6342 }
63536343
6354 fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {6344 fn airDbgStmt(self: *NavGen, inst: Air.Inst.Index) !void {
6355 const pt = self.pt;6345 const pt = self.pt;
6356 const mod = pt.zcu;6346 const mod = pt.zcu;
6357 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;6347 const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
6358 const decl = mod.declPtr(self.decl_index);6348 const path = mod.navFileScope(self.owner_nav).sub_file_path;
6359 const path = decl.getFileScope(mod).sub_file_path;
6360 try self.func.body.emit(self.spv.gpa, .OpLine, .{6349 try self.func.body.emit(self.spv.gpa, .OpLine, .{
6361 .file = try self.spv.resolveString(path),6350 .file = try self.spv.resolveString(path),
6362 .line = self.base_line + dbg_stmt.line + 1,6351 .line = self.base_line + dbg_stmt.line + 1,
...@@ -6364,25 +6353,24 @@ const DeclGen = struct {...@@ -6364,25 +6353,24 @@ const DeclGen = struct {
6364 });6353 });
6365 }6354 }
63666355
6367 fn airDbgInlineBlock(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6356 fn airDbgInlineBlock(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6368 const mod = self.pt.zcu;6357 const mod = self.pt.zcu;
6369 const inst_datas = self.air.instructions.items(.data);6358 const inst_datas = self.air.instructions.items(.data);
6370 const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload);6359 const extra = self.air.extraData(Air.DbgInlineBlock, inst_datas[@intFromEnum(inst)].ty_pl.payload);
6371 const decl = mod.funcOwnerDeclPtr(extra.data.func);
6372 const old_base_line = self.base_line;6360 const old_base_line = self.base_line;
6373 defer self.base_line = old_base_line;6361 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);
6375 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));6363 return self.lowerBlock(inst, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
6376 }6364 }
63776365
6378 fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void {6366 fn airDbgVar(self: *NavGen, inst: Air.Inst.Index) !void {
6379 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6367 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6380 const target_id = try self.resolve(pl_op.operand);6368 const target_id = try self.resolve(pl_op.operand);
6381 const name = self.air.nullTerminatedString(pl_op.payload);6369 const name = self.air.nullTerminatedString(pl_op.payload);
6382 try self.spv.debugName(target_id, name);6370 try self.spv.debugName(target_id, name);
6383 }6371 }
63846372
6385 fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6373 fn airAssembly(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6386 const mod = self.pt.zcu;6374 const mod = self.pt.zcu;
6387 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;6375 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
6388 const extra = self.air.extraData(Air.Asm, ty_pl.payload);6376 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
...@@ -6465,7 +6453,7 @@ const DeclGen = struct {...@@ -6465,7 +6453,7 @@ const DeclGen = struct {
6465 // TODO: Translate proper error locations.6453 // TODO: Translate proper error locations.
6466 assert(as.errors.items.len != 0);6454 assert(as.errors.items.len != 0);
6467 assert(self.error_msg == null);6455 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);
6469 self.error_msg = try Zcu.ErrorMsg.create(mod.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});6457 self.error_msg = try Zcu.ErrorMsg.create(mod.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
6470 const notes = try mod.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len);6458 const notes = try mod.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len);
64716459
...@@ -6511,7 +6499,7 @@ const DeclGen = struct {...@@ -6511,7 +6499,7 @@ const DeclGen = struct {
6511 return null;6499 return null;
6512 }6500 }
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 {
6515 _ = modifier;6503 _ = modifier;
65166504
6517 const pt = self.pt;6505 const pt = self.pt;
...@@ -6566,7 +6554,7 @@ const DeclGen = struct {...@@ -6566,7 +6554,7 @@ const DeclGen = struct {
6566 return result_id;6554 return result_id;
6567 }6555 }
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 {
6570 if (dimension >= 3) {6558 if (dimension >= 3) {
6571 return try self.constInt(result_ty, out_of_range_value, .direct);6559 return try self.constInt(result_ty, out_of_range_value, .direct);
6572 }6560 }
...@@ -6582,7 +6570,7 @@ const DeclGen = struct {...@@ -6582,7 +6570,7 @@ const DeclGen = struct {
6582 return try self.extractVectorComponent(result_ty, vec, dimension);6570 return try self.extractVectorComponent(result_ty, vec, dimension);
6583 }6571 }
65846572
6585 fn airWorkItemId(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6573 fn airWorkItemId(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6586 if (self.liveness.isUnused(inst)) return null;6574 if (self.liveness.isUnused(inst)) return null;
6587 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6575 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6588 const dimension = pl_op.payload;6576 const dimension = pl_op.payload;
...@@ -6593,7 +6581,7 @@ const DeclGen = struct {...@@ -6593,7 +6581,7 @@ const DeclGen = struct {
6593 return try result.materialize(self);6581 return try result.materialize(self);
6594 }6582 }
65956583
6596 fn airWorkGroupSize(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6584 fn airWorkGroupSize(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6597 if (self.liveness.isUnused(inst)) return null;6585 if (self.liveness.isUnused(inst)) return null;
6598 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6586 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6599 const dimension = pl_op.payload;6587 const dimension = pl_op.payload;
...@@ -6604,7 +6592,7 @@ const DeclGen = struct {...@@ -6604,7 +6592,7 @@ const DeclGen = struct {
6604 return try result.materialize(self);6592 return try result.materialize(self);
6605 }6593 }
66066594
6607 fn airWorkGroupId(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {6595 fn airWorkGroupId(self: *NavGen, inst: Air.Inst.Index) !?IdRef {
6608 if (self.liveness.isUnused(inst)) return null;6596 if (self.liveness.isUnused(inst)) return null;
6609 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;6597 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
6610 const dimension = pl_op.payload;6598 const dimension = pl_op.payload;
...@@ -6615,12 +6603,12 @@ const DeclGen = struct {...@@ -6615,12 +6603,12 @@ const DeclGen = struct {
6615 return try result.materialize(self);6603 return try result.materialize(self);
6616 }6604 }
66176605
6618 fn typeOf(self: *DeclGen, inst: Air.Inst.Ref) Type {6606 fn typeOf(self: *NavGen, inst: Air.Inst.Ref) Type {
6619 const mod = self.pt.zcu;6607 const mod = self.pt.zcu;
6620 return self.air.typeOf(inst, &mod.intern_pool);6608 return self.air.typeOf(inst, &mod.intern_pool);
6621 }6609 }
66226610
6623 fn typeOfIndex(self: *DeclGen, inst: Air.Inst.Index) Type {6611 fn typeOfIndex(self: *NavGen, inst: Air.Inst.Index) Type {
6624 const mod = self.pt.zcu;6612 const mod = self.pt.zcu;
6625 return self.air.typeOfIndex(inst, &mod.intern_pool);6613 return self.air.typeOfIndex(inst, &mod.intern_pool);
6626 }6614 }
src/link.zig+31-57
...@@ -216,8 +216,8 @@ pub const File = struct {...@@ -216,8 +216,8 @@ pub const File = struct {
216 }216 }
217 }217 }
218218
219 pub fn cast(base: *File, comptime T: type) ?*T {219 pub fn cast(base: *File, comptime tag: Tag) if (dev.env.supports(tag.devFeature())) ?*tag.Type() else ?noreturn {
220 return if (base.tag == T.base_tag) @fieldParentPtr("base", base) else null;220 return if (dev.env.supports(tag.devFeature()) and base.tag == tag) @fieldParentPtr("base", base) else null;
221 }221 }
222222
223 pub fn makeWritable(base: *File) !void {223 pub fn makeWritable(base: *File) !void {
...@@ -231,7 +231,7 @@ pub const File = struct {...@@ -231,7 +231,7 @@ pub const File = struct {
231 const emit = base.emit;231 const emit = base.emit;
232 if (base.child_pid) |pid| {232 if (base.child_pid) |pid| {
233 if (builtin.os.tag == .windows) {233 if (builtin.os.tag == .windows) {
234 base.cast(Coff).?.ptraceAttach(pid) catch |err| {234 base.cast(.coff).?.ptraceAttach(pid) catch |err| {
235 log.warn("attaching failed with error: {s}", .{@errorName(err)});235 log.warn("attaching failed with error: {s}", .{@errorName(err)});
236 };236 };
237 } else {237 } else {
...@@ -249,7 +249,7 @@ pub const File = struct {...@@ -249,7 +249,7 @@ pub const File = struct {
249 .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {249 .linux => std.posix.ptrace(std.os.linux.PTRACE.ATTACH, pid, 0, 0) catch |err| {
250 log.warn("ptrace failure: {s}", .{@errorName(err)});250 log.warn("ptrace failure: {s}", .{@errorName(err)});
251 },251 },
252 .macos => base.cast(MachO).?.ptraceAttach(pid) catch |err| {252 .macos => base.cast(.macho).?.ptraceAttach(pid) catch |err| {
253 log.warn("attaching failed with error: {s}", .{@errorName(err)});253 log.warn("attaching failed with error: {s}", .{@errorName(err)});
254 },254 },
255 .windows => unreachable,255 .windows => unreachable,
...@@ -317,10 +317,10 @@ pub const File = struct {...@@ -317,10 +317,10 @@ pub const File = struct {
317317
318 if (base.child_pid) |pid| {318 if (base.child_pid) |pid| {
319 switch (builtin.os.tag) {319 switch (builtin.os.tag) {
320 .macos => base.cast(MachO).?.ptraceDetach(pid) catch |err| {320 .macos => base.cast(.macho).?.ptraceDetach(pid) catch |err| {
321 log.warn("detaching failed with error: {s}", .{@errorName(err)});321 log.warn("detaching failed with error: {s}", .{@errorName(err)});
322 },322 },
323 .windows => base.cast(Coff).?.ptraceDetach(pid),323 .windows => base.cast(.coff).?.ptraceDetach(pid),
324 else => return error.HotSwapUnavailableOnHostOperatingSystem,324 else => return error.HotSwapUnavailableOnHostOperatingSystem,
325 }325 }
326 }326 }
...@@ -329,7 +329,7 @@ pub const File = struct {...@@ -329,7 +329,7 @@ pub const File = struct {
329 }329 }
330 }330 }
331331
332 pub const UpdateDeclError = error{332 pub const UpdateNavError = error{
333 OutOfMemory,333 OutOfMemory,
334 Overflow,334 Overflow,
335 Underflow,335 Underflow,
...@@ -367,27 +367,12 @@ pub const File = struct {...@@ -367,27 +367,12 @@ pub const File = struct {
367 HotSwapUnavailableOnHostOperatingSystem,367 HotSwapUnavailableOnHostOperatingSystem,
368 };368 };
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
385 /// Called from within CodeGen to retrieve the symbol index of a global symbol.370 /// Called from within CodeGen to retrieve the symbol index of a global symbol.
386 /// If no symbol exists yet with this name, a new undefined global symbol will371 /// If no symbol exists yet with this name, a new undefined global symbol will
387 /// be created. This symbol may get resolved once all relocatables are (re-)linked.372 /// be created. This symbol may get resolved once all relocatables are (re-)linked.
388 /// Optionally, it is possible to specify where to expect the symbol defined if it373 /// Optionally, it is possible to specify where to expect the symbol defined if it
389 /// is an import.374 /// 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 {
391 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });376 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });
392 switch (base.tag) {377 switch (base.tag) {
393 .plan9 => unreachable,378 .plan9 => unreachable,
...@@ -401,14 +386,14 @@ pub const File = struct {...@@ -401,14 +386,14 @@ pub const File = struct {
401 }386 }
402 }387 }
403388
404 /// May be called before or after updateExports for any given Decl.389 /// May be called before or after updateExports for any given Nav.
405 pub fn updateDecl(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {390 pub fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void {
406 const decl = pt.zcu.declPtr(decl_index);391 const nav = pt.zcu.intern_pool.getNav(nav_index);
407 assert(decl.has_tv);392 assert(nav.status == .resolved);
408 switch (base.tag) {393 switch (base.tag) {
409 inline else => |tag| {394 inline else => |tag| {
410 dev.check(tag.devFeature());395 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);
412 },397 },
413 }398 }
414 }399 }
...@@ -420,7 +405,7 @@ pub const File = struct {...@@ -420,7 +405,7 @@ pub const File = struct {
420 func_index: InternPool.Index,405 func_index: InternPool.Index,
421 air: Air,406 air: Air,
422 liveness: Liveness,407 liveness: Liveness,
423 ) UpdateDeclError!void {408 ) UpdateNavError!void {
424 switch (base.tag) {409 switch (base.tag) {
425 inline else => |tag| {410 inline else => |tag| {
426 dev.check(tag.devFeature());411 dev.check(tag.devFeature());
...@@ -429,14 +414,16 @@ pub const File = struct {...@@ -429,14 +414,16 @@ pub const File = struct {
429 }414 }
430 }415 }
431416
432 pub fn updateDeclLineNumber(base: *File, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) UpdateDeclError!void {417 pub fn updateNavLineNumber(
433 const decl = pt.zcu.declPtr(decl_index);418 base: *File,
434 assert(decl.has_tv);419 pt: Zcu.PerThread,
420 nav_index: InternPool.Nav.Index,
421 ) UpdateNavError!void {
435 switch (base.tag) {422 switch (base.tag) {
436 .spirv, .nvptx => {},423 .spirv, .nvptx => {},
437 inline else => |tag| {424 inline else => |tag| {
438 dev.check(tag.devFeature());425 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);
440 },427 },
441 }428 }
442 }429 }
...@@ -675,52 +662,50 @@ pub const File = struct {...@@ -675,52 +662,50 @@ pub const File = struct {
675 addend: u32,662 addend: u32,
676 };663 };
677664
678 /// Get allocated `Decl`'s address in virtual memory.665 /// Get allocated `Nav`'s address in virtual memory.
679 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's666 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's
680 /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the667 /// 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.668 /// `Nav`'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 allocate669 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
683 /// the block/atom.670 /// 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 {
685 switch (base.tag) {672 switch (base.tag) {
686 .c => unreachable,673 .c => unreachable,
687 .spirv => unreachable,674 .spirv => unreachable,
688 .nvptx => unreachable,675 .nvptx => unreachable,
689 inline else => |tag| {676 inline else => |tag| {
690 dev.check(tag.devFeature());677 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);
692 },679 },
693 }680 }
694 }681 }
695682
696 pub const LowerResult = @import("codegen.zig").Result;683 pub fn lowerUav(
697
698 pub fn lowerAnonDecl(
699 base: *File,684 base: *File,
700 pt: Zcu.PerThread,685 pt: Zcu.PerThread,
701 decl_val: InternPool.Index,686 decl_val: InternPool.Index,
702 decl_align: InternPool.Alignment,687 decl_align: InternPool.Alignment,
703 src_loc: Zcu.LazySrcLoc,688 src_loc: Zcu.LazySrcLoc,
704 ) !LowerResult {689 ) !@import("codegen.zig").GenResult {
705 switch (base.tag) {690 switch (base.tag) {
706 .c => unreachable,691 .c => unreachable,
707 .spirv => unreachable,692 .spirv => unreachable,
708 .nvptx => unreachable,693 .nvptx => unreachable,
709 inline else => |tag| {694 inline else => |tag| {
710 dev.check(tag.devFeature());695 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);
712 },697 },
713 }698 }
714 }699 }
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 {
717 switch (base.tag) {702 switch (base.tag) {
718 .c => unreachable,703 .c => unreachable,
719 .spirv => unreachable,704 .spirv => unreachable,
720 .nvptx => unreachable,705 .nvptx => unreachable,
721 inline else => |tag| {706 inline else => |tag| {
722 dev.check(tag.devFeature());707 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);
724 },709 },
725 }710 }
726 }711 }
...@@ -964,18 +949,7 @@ pub const File = struct {...@@ -964,18 +949,7 @@ pub const File = struct {
964 pub const Kind = enum { code, const_data };949 pub const Kind = enum { code, const_data };
965950
966 kind: Kind,951 kind: Kind,
967 ty: Type,952 ty: InternPool.Index,
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 }
979 };953 };
980954
981 pub fn effectiveOutputMode(955 pub fn effectiveOutputMode(
src/link/C.zig+112-130
...@@ -19,28 +19,27 @@ const Value = @import("../Value.zig");...@@ -19,28 +19,27 @@ const Value = @import("../Value.zig");
19const Air = @import("../Air.zig");19const Air = @import("../Air.zig");
20const Liveness = @import("../Liveness.zig");20const Liveness = @import("../Liveness.zig");
2121
22pub const base_tag: link.File.Tag = .c;
23pub const zig_h = "#include \"zig.h\"\n";22pub const zig_h = "#include \"zig.h\"\n";
2423
25base: link.File,24base: link.File,
26/// This linker backend does not try to incrementally link output C source code.25/// This linker backend does not try to incrementally link output C source code.
27/// Instead, it tracks all declarations in this table, and iterates over it26/// Instead, it tracks all declarations in this table, and iterates over it
28/// in the flush function, stitching pre-rendered pieces of C code together.27/// 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) = .{},
30/// All the string bytes of rendered C code, all squished into one array.29/// All the string bytes of rendered C code, all squished into one array.
31/// While in progress, a separate buffer is used, and then when finished, the30/// While in progress, a separate buffer is used, and then when finished, the
32/// buffer is copied into this one.31/// buffer is copied into this one.
33string_bytes: std.ArrayListUnmanaged(u8) = .{},32string_bytes: std.ArrayListUnmanaged(u8) = .{},
34/// Tracks all the anonymous decls that are used by all the decls so they can33/// Tracks all the anonymous decls that are used by all the decls so they can
35/// be rendered during flush().34/// be rendered during flush().
36anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{},35uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, AvBlock) = .{},
37/// Sparse set of anon decls that are overaligned. Underaligned anon decls are36/// Sparse set of uavs that are overaligned. Underaligned anon decls are
38/// lowered the same as ABI-aligned anon decls. The keys here are a subset of37/// lowered the same as ABI-aligned anon decls. The keys here are a subset of
39/// the keys of `anon_decls`.38/// the keys of `uavs`.
40aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{},39aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{},
4140
42exported_decls: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, ExportedBlock) = .{},41exported_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, ExportedBlock) = .{},
43exported_values: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock) = .{},42exported_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock) = .{},
4443
45/// Optimization, `updateDecl` reuses this buffer rather than creating a new44/// Optimization, `updateDecl` reuses this buffer rather than creating a new
46/// one with every call.45/// one with every call.
...@@ -67,7 +66,7 @@ const String = extern struct {...@@ -67,7 +66,7 @@ const String = extern struct {
67};66};
6867
69/// Per-declaration data.68/// Per-declaration data.
70pub const DeclBlock = struct {69pub const AvBlock = struct {
71 code: String = String.empty,70 code: String = String.empty,
72 fwd_decl: String = String.empty,71 fwd_decl: String = String.empty,
73 /// Each `Decl` stores a set of used `CType`s. In `flush()`, we iterate72 /// Each `Decl` stores a set of used `CType`s. In `flush()`, we iterate
...@@ -76,10 +75,10 @@ pub const DeclBlock = struct {...@@ -76,10 +75,10 @@ pub const DeclBlock = struct {
76 /// May contain string references to ctype_pool75 /// May contain string references to ctype_pool
77 lazy_fns: codegen.LazyFnMap = .{},76 lazy_fns: codegen.LazyFnMap = .{},
7877
79 fn deinit(db: *DeclBlock, gpa: Allocator) void {78 fn deinit(ab: *AvBlock, gpa: Allocator) void {
80 db.lazy_fns.deinit(gpa);79 ab.lazy_fns.deinit(gpa);
81 db.ctype_pool.deinit(gpa);80 ab.ctype_pool.deinit(gpa);
82 db.* = undefined;81 ab.* = undefined;
83 }82 }
84};83};
8584
...@@ -158,16 +157,16 @@ pub fn createEmpty(...@@ -158,16 +157,16 @@ pub fn createEmpty(
158pub fn deinit(self: *C) void {157pub fn deinit(self: *C) void {
159 const gpa = self.base.comp.gpa;158 const gpa = self.base.comp.gpa;
160159
161 for (self.decl_table.values()) |*db| {160 for (self.navs.values()) |*db| {
162 db.deinit(gpa);161 db.deinit(gpa);
163 }162 }
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| {
167 db.deinit(gpa);166 db.deinit(gpa);
168 }167 }
169 self.anon_decls.deinit(gpa);168 self.uavs.deinit(gpa);
170 self.aligned_anon_decls.deinit(gpa);169 self.aligned_uavs.deinit(gpa);
171170
172 self.string_bytes.deinit(gpa);171 self.string_bytes.deinit(gpa);
173 self.fwd_decl_buf.deinit(gpa);172 self.fwd_decl_buf.deinit(gpa);
...@@ -194,9 +193,7 @@ pub fn updateFunc(...@@ -194,9 +193,7 @@ pub fn updateFunc(
194 const zcu = pt.zcu;193 const zcu = pt.zcu;
195 const gpa = zcu.gpa;194 const gpa = zcu.gpa;
196 const func = zcu.funcInfo(func_index);195 const func = zcu.funcInfo(func_index);
197 const decl_index = func.owner_decl;196 const gop = try self.navs.getOrPut(gpa, func.owner_nav);
198 const decl = zcu.declPtr(decl_index);
199 const gop = try self.decl_table.getOrPut(gpa, decl_index);
200 if (!gop.found_existing) gop.value_ptr.* = .{};197 if (!gop.found_existing) gop.value_ptr.* = .{};
201 const ctype_pool = &gop.value_ptr.ctype_pool;198 const ctype_pool = &gop.value_ptr.ctype_pool;
202 const lazy_fns = &gop.value_ptr.lazy_fns;199 const lazy_fns = &gop.value_ptr.lazy_fns;
...@@ -208,8 +205,6 @@ pub fn updateFunc(...@@ -208,8 +205,6 @@ pub fn updateFunc(
208 fwd_decl.clearRetainingCapacity();205 fwd_decl.clearRetainingCapacity();
209 code.clearRetainingCapacity();206 code.clearRetainingCapacity();
210207
211 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
212
213 var function: codegen.Function = .{208 var function: codegen.Function = .{
214 .value_map = codegen.CValueMap.init(gpa),209 .value_map = codegen.CValueMap.init(gpa),
215 .air = air,210 .air = air,
...@@ -219,15 +214,15 @@ pub fn updateFunc(...@@ -219,15 +214,15 @@ pub fn updateFunc(
219 .dg = .{214 .dg = .{
220 .gpa = gpa,215 .gpa = gpa,
221 .pt = pt,216 .pt = pt,
222 .mod = file_scope.mod,217 .mod = zcu.navFileScope(func.owner_nav).mod,
223 .error_msg = null,218 .error_msg = null,
224 .pass = .{ .decl = decl_index },219 .pass = .{ .nav = func.owner_nav },
225 .is_naked_fn = decl.typeOf(zcu).fnCallingConvention(zcu) == .Naked,220 .is_naked_fn = zcu.navValue(func.owner_nav).typeOf(zcu).fnCallingConvention(zcu) == .Naked,
226 .fwd_decl = fwd_decl.toManaged(gpa),221 .fwd_decl = fwd_decl.toManaged(gpa),
227 .ctype_pool = ctype_pool.*,222 .ctype_pool = ctype_pool.*,
228 .scratch = .{},223 .scratch = .{},
229 .anon_decl_deps = self.anon_decls,224 .uav_deps = self.uavs,
230 .aligned_anon_decls = self.aligned_anon_decls,225 .aligned_uavs = self.aligned_uavs,
231 },226 },
232 .code = code.toManaged(gpa),227 .code = code.toManaged(gpa),
233 .indent_writer = undefined, // set later so we can get a pointer to object.code228 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -236,8 +231,8 @@ pub fn updateFunc(...@@ -236,8 +231,8 @@ pub fn updateFunc(
236 };231 };
237 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };232 function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() };
238 defer {233 defer {
239 self.anon_decls = function.object.dg.anon_decl_deps;234 self.uavs = function.object.dg.uav_deps;
240 self.aligned_anon_decls = function.object.dg.aligned_anon_decls;235 self.aligned_uavs = function.object.dg.aligned_uavs;
241 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();236 fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged();
242 ctype_pool.* = function.object.dg.ctype_pool.move();237 ctype_pool.* = function.object.dg.ctype_pool.move();
243 ctype_pool.freeUnusedCapacity(gpa);238 ctype_pool.freeUnusedCapacity(gpa);
...@@ -248,13 +243,10 @@ pub fn updateFunc(...@@ -248,13 +243,10 @@ pub fn updateFunc(
248 function.deinit();243 function.deinit();
249 }244 }
250245
251 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);246 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
252 codegen.genFunc(&function) catch |err| switch (err) {247 codegen.genFunc(&function) catch |err| switch (err) {
253 error.AnalysisFail => {248 error.AnalysisFail => {
254 zcu.failed_analysis.putAssumeCapacityNoClobber(249 zcu.failed_codegen.putAssumeCapacityNoClobber(func.owner_nav, function.object.dg.error_msg.?);
255 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
256 function.object.dg.error_msg.?,
257 );
258 return;250 return;
259 },251 },
260 else => |e| return e,252 else => |e| return e,
...@@ -263,9 +255,9 @@ pub fn updateFunc(...@@ -263,9 +255,9 @@ pub fn updateFunc(
263 gop.value_ptr.code = try self.addString(function.object.code.items);255 gop.value_ptr.code = try self.addString(function.object.code.items);
264}256}
265257
266fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {258fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void {
267 const gpa = self.base.comp.gpa;259 const gpa = self.base.comp.gpa;
268 const anon_decl = self.anon_decls.keys()[i];260 const uav = self.uavs.keys()[i];
269261
270 const fwd_decl = &self.fwd_decl_buf;262 const fwd_decl = &self.fwd_decl_buf;
271 const code = &self.code_buf;263 const code = &self.code_buf;
...@@ -278,21 +270,21 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {...@@ -278,21 +270,21 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
278 .pt = pt,270 .pt = pt,
279 .mod = pt.zcu.root_mod,271 .mod = pt.zcu.root_mod,
280 .error_msg = null,272 .error_msg = null,
281 .pass = .{ .anon = anon_decl },273 .pass = .{ .uav = uav },
282 .is_naked_fn = false,274 .is_naked_fn = false,
283 .fwd_decl = fwd_decl.toManaged(gpa),275 .fwd_decl = fwd_decl.toManaged(gpa),
284 .ctype_pool = codegen.CType.Pool.empty,276 .ctype_pool = codegen.CType.Pool.empty,
285 .scratch = .{},277 .scratch = .{},
286 .anon_decl_deps = self.anon_decls,278 .uav_deps = self.uavs,
287 .aligned_anon_decls = self.aligned_anon_decls,279 .aligned_uavs = self.aligned_uavs,
288 },280 },
289 .code = code.toManaged(gpa),281 .code = code.toManaged(gpa),
290 .indent_writer = undefined, // set later so we can get a pointer to object.code282 .indent_writer = undefined, // set later so we can get a pointer to object.code
291 };283 };
292 object.indent_writer = .{ .underlying_writer = object.code.writer() };284 object.indent_writer = .{ .underlying_writer = object.code.writer() };
293 defer {285 defer {
294 self.anon_decls = object.dg.anon_decl_deps;286 self.uavs = object.dg.uav_deps;
295 self.aligned_anon_decls = object.dg.aligned_anon_decls;287 self.aligned_uavs = object.dg.aligned_uavs;
296 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();288 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
297 object.dg.ctype_pool.deinit(object.dg.gpa);289 object.dg.ctype_pool.deinit(object.dg.gpa);
298 object.dg.scratch.deinit(gpa);290 object.dg.scratch.deinit(gpa);
...@@ -300,8 +292,8 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {...@@ -300,8 +292,8 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
300 }292 }
301 try object.dg.ctype_pool.init(gpa);293 try object.dg.ctype_pool.init(gpa);
302294
303 const c_value: codegen.CValue = .{ .constant = Value.fromInterned(anon_decl) };295 const c_value: codegen.CValue = .{ .constant = Value.fromInterned(uav) };
304 const alignment: Alignment = self.aligned_anon_decls.get(anon_decl) orelse .none;296 const alignment: Alignment = self.aligned_uavs.get(uav) orelse .none;
305 codegen.genDeclValue(&object, c_value.constant, c_value, alignment, .none) catch |err| switch (err) {297 codegen.genDeclValue(&object, c_value.constant, c_value, alignment, .none) catch |err| switch (err) {
306 error.AnalysisFail => {298 error.AnalysisFail => {
307 @panic("TODO: C backend AnalysisFail on anonymous decl");299 @panic("TODO: C backend AnalysisFail on anonymous decl");
...@@ -312,23 +304,22 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {...@@ -312,23 +304,22 @@ fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void {
312 };304 };
313305
314 object.dg.ctype_pool.freeUnusedCapacity(gpa);306 object.dg.ctype_pool.freeUnusedCapacity(gpa);
315 object.dg.anon_decl_deps.values()[i] = .{307 object.dg.uav_deps.values()[i] = .{
316 .code = try self.addString(object.code.items),308 .code = try self.addString(object.code.items),
317 .fwd_decl = try self.addString(object.dg.fwd_decl.items),309 .fwd_decl = try self.addString(object.dg.fwd_decl.items),
318 .ctype_pool = object.dg.ctype_pool.move(),310 .ctype_pool = object.dg.ctype_pool.move(),
319 };311 };
320}312}
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 {
323 const tracy = trace(@src());315 const tracy = trace(@src());
324 defer tracy.end();316 defer tracy.end();
325317
326 const gpa = self.base.comp.gpa;318 const gpa = self.base.comp.gpa;
327319
328 const zcu = pt.zcu;320 const zcu = pt.zcu;
329 const decl = zcu.declPtr(decl_index);321 const gop = try self.navs.getOrPut(gpa, nav_index);
330 const gop = try self.decl_table.getOrPut(gpa, decl_index);322 errdefer _ = self.navs.pop();
331 errdefer _ = self.decl_table.pop();
332 if (!gop.found_existing) gop.value_ptr.* = .{};323 if (!gop.found_existing) gop.value_ptr.* = .{};
333 const ctype_pool = &gop.value_ptr.ctype_pool;324 const ctype_pool = &gop.value_ptr.ctype_pool;
334 const fwd_decl = &self.fwd_decl_buf;325 const fwd_decl = &self.fwd_decl_buf;
...@@ -338,29 +329,27 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)...@@ -338,29 +329,27 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
338 fwd_decl.clearRetainingCapacity();329 fwd_decl.clearRetainingCapacity();
339 code.clearRetainingCapacity();330 code.clearRetainingCapacity();
340331
341 const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu);
342
343 var object: codegen.Object = .{332 var object: codegen.Object = .{
344 .dg = .{333 .dg = .{
345 .gpa = gpa,334 .gpa = gpa,
346 .pt = pt,335 .pt = pt,
347 .mod = file_scope.mod,336 .mod = zcu.navFileScope(nav_index).mod,
348 .error_msg = null,337 .error_msg = null,
349 .pass = .{ .decl = decl_index },338 .pass = .{ .nav = nav_index },
350 .is_naked_fn = false,339 .is_naked_fn = false,
351 .fwd_decl = fwd_decl.toManaged(gpa),340 .fwd_decl = fwd_decl.toManaged(gpa),
352 .ctype_pool = ctype_pool.*,341 .ctype_pool = ctype_pool.*,
353 .scratch = .{},342 .scratch = .{},
354 .anon_decl_deps = self.anon_decls,343 .uav_deps = self.uavs,
355 .aligned_anon_decls = self.aligned_anon_decls,344 .aligned_uavs = self.aligned_uavs,
356 },345 },
357 .code = code.toManaged(gpa),346 .code = code.toManaged(gpa),
358 .indent_writer = undefined, // set later so we can get a pointer to object.code347 .indent_writer = undefined, // set later so we can get a pointer to object.code
359 };348 };
360 object.indent_writer = .{ .underlying_writer = object.code.writer() };349 object.indent_writer = .{ .underlying_writer = object.code.writer() };
361 defer {350 defer {
362 self.anon_decls = object.dg.anon_decl_deps;351 self.uavs = object.dg.uav_deps;
363 self.aligned_anon_decls = object.dg.aligned_anon_decls;352 self.aligned_uavs = object.dg.aligned_uavs;
364 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();353 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
365 ctype_pool.* = object.dg.ctype_pool.move();354 ctype_pool.* = object.dg.ctype_pool.move();
366 ctype_pool.freeUnusedCapacity(gpa);355 ctype_pool.freeUnusedCapacity(gpa);
...@@ -368,13 +357,10 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)...@@ -368,13 +357,10 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
368 code.* = object.code.moveToUnmanaged();357 code.* = object.code.moveToUnmanaged();
369 }358 }
370359
371 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);360 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
372 codegen.genDecl(&object) catch |err| switch (err) {361 codegen.genDecl(&object) catch |err| switch (err) {
373 error.AnalysisFail => {362 error.AnalysisFail => {
374 zcu.failed_analysis.putAssumeCapacityNoClobber(363 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, object.dg.error_msg.?);
375 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),
376 object.dg.error_msg.?,
377 );
378 return;364 return;
379 },365 },
380 else => |e| return e,366 else => |e| return e,
...@@ -383,12 +369,12 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)...@@ -383,12 +369,12 @@ pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex)
383 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);369 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
384}370}
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 {
387 // The C backend does not have the ability to fix line numbers without re-generating373 // The C backend does not have the ability to fix line numbers without re-generating
388 // the entire Decl.374 // the entire Decl.
389 _ = self;375 _ = self;
390 _ = pt;376 _ = pt;
391 _ = decl_index;377 _ = nav_index;
392}378}
393379
394pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {380pub 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:...@@ -422,12 +408,13 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
422 const comp = self.base.comp;408 const comp = self.base.comp;
423 const gpa = comp.gpa;409 const gpa = comp.gpa;
424 const zcu = self.base.comp.module.?;410 const zcu = self.base.comp.module.?;
411 const ip = &zcu.intern_pool;
425 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = tid };412 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = tid };
426413
427 {414 {
428 var i: usize = 0;415 var i: usize = 0;
429 while (i < self.anon_decls.count()) : (i += 1) {416 while (i < self.uavs.count()) : (i += 1) {
430 try updateAnonDecl(self, pt, i);417 try self.updateUav(pt, i);
431 }418 }
432 }419 }
433420
...@@ -484,30 +471,28 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:...@@ -484,30 +471,28 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
484 }471 }
485 }472 }
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(
488 pt,475 pt,
489 zcu.root_mod,476 zcu.root_mod,
490 &f,477 &f,
491 decl_block,478 av_block,
492 self.exported_values.getPtr(value),479 self.exported_uavs.getPtr(uav),
493 export_names,480 export_names,
494 .none,481 .none,
495 );482 );
496483
497 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, *decl_block| {484 for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock(
498 const decl = zcu.declPtr(decl_index);485 pt,
499 const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none;486 zcu.navFileScope(nav).mod,
500 const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod;487 &f,
501 try self.flushDeclBlock(488 av_block,
502 pt,489 self.exported_navs.getPtr(nav),
503 mod,490 export_names,
504 &f,491 if (ip.indexToKey(zcu.navValue(nav).toIntern()) == .@"extern")
505 decl_block,492 ip.getNav(nav).name.toOptional()
506 self.exported_decls.getPtr(decl_index),493 else
507 export_names,494 .none,
508 extern_name,495 );
509 );
510 }
511 }496 }
512497
513 {498 {
...@@ -516,12 +501,12 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:...@@ -516,12 +501,12 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
516 try f.ctype_pool.init(gpa);501 try f.ctype_pool.init(gpa);
517 try self.flushCTypes(zcu, &f, .flush, &f.lazy_ctype_pool);502 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| {504 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| {
520 try self.flushCTypes(zcu, &f, .{ .anon = anon_decl }, &decl_block.ctype_pool);505 try self.flushCTypes(zcu, &f, .{ .uav = uav }, &av_block.ctype_pool);
521 }506 }
522507
523 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| {508 for (self.navs.keys(), self.navs.values()) |nav, av_block| {
524 try self.flushCTypes(zcu, &f, .{ .decl = decl_index }, &decl_block.ctype_pool);509 try self.flushCTypes(zcu, &f, .{ .nav = nav }, &av_block.ctype_pool);
525 }510 }
526 }511 }
527512
...@@ -539,26 +524,21 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:...@@ -539,26 +524,21 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
539 f.file_size += lazy_fwd_decl_len;524 f.file_size += lazy_fwd_decl_len;
540525
541 // Now the code.526 // 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);
543 f.appendBufAssumeCapacity(self.lazy_code_buf.items);528 f.appendBufAssumeCapacity(self.lazy_code_buf.items);
544 for (self.anon_decls.keys(), self.anon_decls.values()) |anon_decl, decl_block| f.appendCodeAssumeCapacity(529 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| f.appendCodeAssumeCapacity(
545 if (self.exported_values.contains(anon_decl))530 if (self.exported_uavs.contains(uav)) .default else switch (ip.indexToKey(uav)) {
546 .default531 .@"extern" => .zig_extern,
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,
550 else => .static,532 else => .static,
551 },533 },
552 self.getString(decl_block.code),534 self.getString(av_block.code),
553 );535 );
554 for (self.decl_table.keys(), self.decl_table.values()) |decl_index, decl_block| f.appendCodeAssumeCapacity(536 for (self.navs.keys(), self.navs.values()) |nav, av_block| f.appendCodeAssumeCapacity(
555 if (self.exported_decls.contains(decl_index))537 if (self.exported_navs.contains(nav)) .default else switch (ip.indexToKey(zcu.navValue(nav).toIntern())) {
556 .default538 .@"extern" => .zig_extern,
557 else if (zcu.declPtr(decl_index).isExtern(zcu))539 else => .static,
558 .zig_extern540 },
559 else541 self.getString(av_block.code),
560 .static,
561 self.getString(decl_block.code),
562 );542 );
563543
564 const file = self.base.file.?;544 const file = self.base.file.?;
...@@ -689,16 +669,16 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F...@@ -689,16 +669,16 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F
689 .fwd_decl = fwd_decl.toManaged(gpa),669 .fwd_decl = fwd_decl.toManaged(gpa),
690 .ctype_pool = ctype_pool.*,670 .ctype_pool = ctype_pool.*,
691 .scratch = .{},671 .scratch = .{},
692 .anon_decl_deps = self.anon_decls,672 .uav_deps = self.uavs,
693 .aligned_anon_decls = self.aligned_anon_decls,673 .aligned_uavs = self.aligned_uavs,
694 },674 },
695 .code = code.toManaged(gpa),675 .code = code.toManaged(gpa),
696 .indent_writer = undefined, // set later so we can get a pointer to object.code676 .indent_writer = undefined, // set later so we can get a pointer to object.code
697 };677 };
698 object.indent_writer = .{ .underlying_writer = object.code.writer() };678 object.indent_writer = .{ .underlying_writer = object.code.writer() };
699 defer {679 defer {
700 self.anon_decls = object.dg.anon_decl_deps;680 self.uavs = object.dg.uav_deps;
701 self.aligned_anon_decls = object.dg.aligned_anon_decls;681 self.aligned_uavs = object.dg.aligned_uavs;
702 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();682 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
703 ctype_pool.* = object.dg.ctype_pool.move();683 ctype_pool.* = object.dg.ctype_pool.move();
704 ctype_pool.freeUnusedCapacity(gpa);684 ctype_pool.freeUnusedCapacity(gpa);
...@@ -736,8 +716,8 @@ fn flushLazyFn(...@@ -736,8 +716,8 @@ fn flushLazyFn(
736 .fwd_decl = fwd_decl.toManaged(gpa),716 .fwd_decl = fwd_decl.toManaged(gpa),
737 .ctype_pool = ctype_pool.*,717 .ctype_pool = ctype_pool.*,
738 .scratch = .{},718 .scratch = .{},
739 .anon_decl_deps = .{},719 .uav_deps = .{},
740 .aligned_anon_decls = .{},720 .aligned_uavs = .{},
741 },721 },
742 .code = code.toManaged(gpa),722 .code = code.toManaged(gpa),
743 .indent_writer = undefined, // set later so we can get a pointer to object.code723 .indent_writer = undefined, // set later so we can get a pointer to object.code
...@@ -746,8 +726,8 @@ fn flushLazyFn(...@@ -746,8 +726,8 @@ fn flushLazyFn(
746 defer {726 defer {
747 // If this assert trips just handle the anon_decl_deps the same as727 // If this assert trips just handle the anon_decl_deps the same as
748 // `updateFunc()` does.728 // `updateFunc()` does.
749 assert(object.dg.anon_decl_deps.count() == 0);729 assert(object.dg.uav_deps.count() == 0);
750 assert(object.dg.aligned_anon_decls.count() == 0);730 assert(object.dg.aligned_uavs.count() == 0);
751 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();731 fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
752 ctype_pool.* = object.dg.ctype_pool.move();732 ctype_pool.* = object.dg.ctype_pool.move();
753 ctype_pool.freeUnusedCapacity(gpa);733 ctype_pool.freeUnusedCapacity(gpa);
...@@ -781,31 +761,33 @@ fn flushLazyFns(...@@ -781,31 +761,33 @@ fn flushLazyFns(
781 }761 }
782}762}
783763
784fn flushDeclBlock(764fn flushAvBlock(
785 self: *C,765 self: *C,
786 pt: Zcu.PerThread,766 pt: Zcu.PerThread,
787 mod: *Module,767 mod: *Module,
788 f: *Flush,768 f: *Flush,
789 decl_block: *const DeclBlock,769 av_block: *const AvBlock,
790 exported_block: ?*const ExportedBlock,770 exported_block: ?*const ExportedBlock,
791 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),771 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
792 extern_name: InternPool.OptionalNullTerminatedString,772 extern_name: InternPool.OptionalNullTerminatedString,
793) FlushDeclError!void {773) FlushDeclError!void {
794 const gpa = self.base.comp.gpa;774 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);
796 try f.all_buffers.ensureUnusedCapacity(gpa, 1);776 try f.all_buffers.ensureUnusedCapacity(gpa, 1);
797 // avoid emitting extern decls that are already exported777 // avoid emitting extern decls that are already exported
798 if (extern_name.unwrap()) |name| if (export_names.contains(name)) return;778 if (extern_name.unwrap()) |name| if (export_names.contains(name)) return;
799 f.appendBufAssumeCapacity(self.getString(if (exported_block) |exported|779 f.appendBufAssumeCapacity(self.getString(if (exported_block) |exported|
800 exported.fwd_decl780 exported.fwd_decl
801 else781 else
802 decl_block.fwd_decl));782 av_block.fwd_decl));
803}783}
804784
805pub fn flushEmitH(zcu: *Zcu) !void {785pub fn flushEmitH(zcu: *Zcu) !void {
806 const tracy = trace(@src());786 const tracy = trace(@src());
807 defer tracy.end();787 defer tracy.end();
808788
789 if (true) return; // emit-h is regressed
790
809 const emit_h = zcu.emit_h orelse return;791 const emit_h = zcu.emit_h orelse return;
810792
811 // We collect a list of buffers to write, and write them all at once with pwritev 😎793 // We collect a list of buffers to write, and write them all at once with pwritev 😎
...@@ -854,17 +836,17 @@ pub fn updateExports(...@@ -854,17 +836,17 @@ pub fn updateExports(
854 const zcu = pt.zcu;836 const zcu = pt.zcu;
855 const gpa = zcu.gpa;837 const gpa = zcu.gpa;
856 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {838 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {
857 .decl_index => |decl_index| .{839 .nav => |nav| .{
858 zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod,840 zcu.navFileScope(nav).mod,
859 .{ .decl = decl_index },841 .{ .nav = nav },
860 self.decl_table.getPtr(decl_index).?,842 self.navs.getPtr(nav).?,
861 (try self.exported_decls.getOrPut(gpa, decl_index)).value_ptr,843 (try self.exported_navs.getOrPut(gpa, nav)).value_ptr,
862 },844 },
863 .value => |value| .{845 .uav => |uav| .{
864 zcu.root_mod,846 zcu.root_mod,
865 .{ .anon = value },847 .{ .uav = uav },
866 self.anon_decls.getPtr(value).?,848 self.uavs.getPtr(uav).?,
867 (try self.exported_values.getOrPut(gpa, value)).value_ptr,849 (try self.exported_uavs.getOrPut(gpa, uav)).value_ptr,
868 },850 },
869 };851 };
870 const ctype_pool = &decl_block.ctype_pool;852 const ctype_pool = &decl_block.ctype_pool;
...@@ -880,12 +862,12 @@ pub fn updateExports(...@@ -880,12 +862,12 @@ pub fn updateExports(
880 .fwd_decl = fwd_decl.toManaged(gpa),862 .fwd_decl = fwd_decl.toManaged(gpa),
881 .ctype_pool = decl_block.ctype_pool,863 .ctype_pool = decl_block.ctype_pool,
882 .scratch = .{},864 .scratch = .{},
883 .anon_decl_deps = .{},865 .uav_deps = .{},
884 .aligned_anon_decls = .{},866 .aligned_uavs = .{},
885 };867 };
886 defer {868 defer {
887 assert(dg.anon_decl_deps.count() == 0);869 assert(dg.uav_deps.count() == 0);
888 assert(dg.aligned_anon_decls.count() == 0);870 assert(dg.aligned_uavs.count() == 0);
889 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();871 fwd_decl.* = dg.fwd_decl.moveToUnmanaged();
890 ctype_pool.* = dg.ctype_pool.move();872 ctype_pool.* = dg.ctype_pool.move();
891 ctype_pool.freeUnusedCapacity(gpa);873 ctype_pool.freeUnusedCapacity(gpa);
...@@ -901,7 +883,7 @@ pub fn deleteExport(...@@ -901,7 +883,7 @@ pub fn deleteExport(
901 _: InternPool.NullTerminatedString,883 _: InternPool.NullTerminatedString,
902) void {884) void {
903 switch (exported) {885 switch (exported) {
904 .decl_index => |decl_index| _ = self.exported_decls.swapRemove(decl_index),886 .nav => |nav| _ = self.exported_navs.swapRemove(nav),
905 .value => |value| _ = self.exported_values.swapRemove(value),887 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),
906 }888 }
907}889}
src/link/Coff.zig+177-223
...@@ -65,8 +65,8 @@ imports_count_dirty: bool = true,...@@ -65,8 +65,8 @@ imports_count_dirty: bool = true,
65/// Table of tracked LazySymbols.65/// Table of tracked LazySymbols.
66lazy_syms: LazySymbolTable = .{},66lazy_syms: LazySymbolTable = .{},
6767
68/// Table of tracked Decls.68/// Table of tracked `Nav`s.
69decls: DeclTable = .{},69navs: NavTable = .{},
7070
71/// List of atoms that are either synthetic or map directly to the Zig source program.71/// List of atoms that are either synthetic or map directly to the Zig source program.
72atoms: std.ArrayListUnmanaged(Atom) = .{},72atoms: std.ArrayListUnmanaged(Atom) = .{},
...@@ -74,27 +74,7 @@ atoms: std.ArrayListUnmanaged(Atom) = .{},...@@ -74,27 +74,7 @@ atoms: std.ArrayListUnmanaged(Atom) = .{},
74/// Table of atoms indexed by the symbol index.74/// Table of atoms indexed by the symbol index.
75atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{},75atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{},
7676
77/// Table of unnamed constants associated with a parent `Decl`.77uavs: UavTable = .{},
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 = .{},
9878
99/// A table of relocations indexed by the owning them `Atom`.79/// A table of relocations indexed by the owning them `Atom`.
100/// Note that once we refactor `Atom`'s lifetime and ownership rules,80/// Note that once we refactor `Atom`'s lifetime and ownership rules,
...@@ -120,11 +100,10 @@ const HotUpdateState = struct {...@@ -120,11 +100,10 @@ const HotUpdateState = struct {
120 loaded_base_address: ?std.os.windows.HMODULE = null,100 loaded_base_address: ?std.os.windows.HMODULE = null,
121};101};
122102
123const DeclTable = std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);103const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
124const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);104const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata);
125const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));105const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));
126const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));106const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));
127const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Atom.Index));
128107
129const default_file_alignment: u16 = 0x200;108const default_file_alignment: u16 = 0x200;
130const default_size_of_stack_reserve: u32 = 0x1000000;109const default_size_of_stack_reserve: u32 = 0x1000000;
...@@ -155,7 +134,7 @@ const Section = struct {...@@ -155,7 +134,7 @@ const Section = struct {
155 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},134 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
156};135};
157136
158const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);137const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
159138
160const LazySymbolMetadata = struct {139const LazySymbolMetadata = struct {
161 const State = enum { unused, pending_flush, flushed };140 const State = enum { unused, pending_flush, flushed };
...@@ -165,17 +144,17 @@ const LazySymbolMetadata = struct {...@@ -165,17 +144,17 @@ const LazySymbolMetadata = struct {
165 rdata_state: State = .unused,144 rdata_state: State = .unused,
166};145};
167146
168const DeclMetadata = struct {147const AvMetadata = struct {
169 atom: Atom.Index,148 atom: Atom.Index,
170 section: u16,149 section: u16,
171 /// A list of all exports aliases of this Decl.150 /// A list of all exports aliases of this Decl.
172 exports: std.ArrayListUnmanaged(u32) = .{},151 exports: std.ArrayListUnmanaged(u32) = .{},
173152
174 fn deinit(m: *DeclMetadata, allocator: Allocator) void {153 fn deinit(m: *AvMetadata, allocator: Allocator) void {
175 m.exports.deinit(allocator);154 m.exports.deinit(allocator);
176 }155 }
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 {
179 for (m.exports.items) |exp| {158 for (m.exports.items) |exp| {
180 if (mem.eql(u8, name, coff_file.getSymbolName(.{159 if (mem.eql(u8, name, coff_file.getSymbolName(.{
181 .sym_index = exp,160 .sym_index = exp,
...@@ -185,7 +164,7 @@ const DeclMetadata = struct {...@@ -185,7 +164,7 @@ const DeclMetadata = struct {
185 return null;164 return null;
186 }165 }
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 {
189 for (m.exports.items) |*exp| {168 for (m.exports.items) |*exp| {
190 if (mem.eql(u8, name, coff_file.getSymbolName(.{169 if (mem.eql(u8, name, coff_file.getSymbolName(.{
191 .sym_index = exp.*,170 .sym_index = exp.*,
...@@ -486,24 +465,19 @@ pub fn deinit(self: *Coff) void {...@@ -486,24 +465,19 @@ pub fn deinit(self: *Coff) void {
486465
487 self.lazy_syms.deinit(gpa);466 self.lazy_syms.deinit(gpa);
488467
489 for (self.decls.values()) |*metadata| {468 for (self.navs.values()) |*metadata| {
490 metadata.deinit(gpa);469 metadata.deinit(gpa);
491 }470 }
492 self.decls.deinit(gpa);471 self.navs.deinit(gpa);
493472
494 self.atom_by_index_table.deinit(gpa);473 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
501 {475 {
502 var it = self.anon_decls.iterator();476 var it = self.uavs.iterator();
503 while (it.next()) |entry| {477 while (it.next()) |entry| {
504 entry.value_ptr.exports.deinit(gpa);478 entry.value_ptr.exports.deinit(gpa);
505 }479 }
506 self.anon_decls.deinit(gpa);480 self.uavs.deinit(gpa);
507 }481 }
508482
509 for (self.relocs.values()) |*relocs| {483 for (self.relocs.values()) |*relocs| {
...@@ -1132,23 +1106,20 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -1132,23 +1106,20 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,
1132 const tracy = trace(@src());1106 const tracy = trace(@src());
1133 defer tracy.end();1107 defer tracy.end();
11341108
1135 const mod = pt.zcu;1109 const zcu = pt.zcu;
1136 const func = mod.funcInfo(func_index);1110 const gpa = zcu.gpa;
1137 const decl_index = func.owner_decl;1111 const func = zcu.funcInfo(func_index);
1138 const decl = mod.declPtr(decl_index);
11391112
1140 const atom_index = try self.getOrCreateAtomForDecl(decl_index);1113 const atom_index = try self.getOrCreateAtomForNav(func.owner_nav);
1141 self.freeUnnamedConsts(decl_index);
1142 Atom.freeRelocations(self, atom_index);1114 Atom.freeRelocations(self, atom_index);
11431115
1144 const gpa = self.base.comp.gpa;
1145 var code_buffer = std.ArrayList(u8).init(gpa);1116 var code_buffer = std.ArrayList(u8).init(gpa);
1146 defer code_buffer.deinit();1117 defer code_buffer.deinit();
11471118
1148 const res = try codegen.generateFunction(1119 const res = try codegen.generateFunction(
1149 &self.base,1120 &self.base,
1150 pt,1121 pt,
1151 decl.navSrcLoc(mod),1122 zcu.navSrcLoc(func.owner_nav),
1152 func_index,1123 func_index,
1153 air,1124 air,
1154 liveness,1125 liveness,
...@@ -1158,45 +1129,16 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -1158,45 +1129,16 @@ pub fn updateFunc(self: *Coff, pt: Zcu.PerThread, func_index: InternPool.Index,
1158 const code = switch (res) {1129 const code = switch (res) {
1159 .ok => code_buffer.items,1130 .ok => code_buffer.items,
1160 .fail => |em| {1131 .fail => |em| {
1161 func.setAnalysisState(&mod.intern_pool, .codegen_failure);1132 try zcu.failed_codegen.put(zcu.gpa, func.owner_nav, em);
1162 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1163 return;1133 return;
1164 },1134 },
1165 };1135 };
11661136
1167 try self.updateDeclCode(pt, decl_index, code, .FUNCTION);1137 try self.updateNavCode(pt, func.owner_nav, code, .FUNCTION);
11681138
1169 // Exports will be updated by `Zcu.processExports` after the update.1139 // Exports will be updated by `Zcu.processExports` after the update.
1170}1140}
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
1200const LowerConstResult = union(enum) {1142const LowerConstResult = union(enum) {
1201 ok: Atom.Index,1143 ok: Atom.Index,
1202 fail: *Module.ErrorMsg,1144 fail: *Module.ErrorMsg,
...@@ -1246,57 +1188,62 @@ fn lowerConst(...@@ -1246,57 +1188,62 @@ fn lowerConst(
1246 return .{ .ok = atom_index };1188 return .{ .ok = atom_index };
1247}1189}
12481190
1249pub fn updateDecl(1191pub fn updateNav(
1250 self: *Coff,1192 self: *Coff,
1251 pt: Zcu.PerThread,1193 pt: Zcu.PerThread,
1252 decl_index: InternPool.DeclIndex,1194 nav_index: InternPool.Nav.Index,
1253) link.File.UpdateDeclError!void {1195) link.File.UpdateNavError!void {
1254 const mod = pt.zcu;
1255 if (build_options.skip_non_native and builtin.object_format != .coff) {1196 if (build_options.skip_non_native and builtin.object_format != .coff) {
1256 @panic("Attempted to compile for object format that was disabled by build configuration");1197 @panic("Attempted to compile for object format that was disabled by build configuration");
1257 }1198 }
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);
1259 const tracy = trace(@src());1200 const tracy = trace(@src());
1260 defer tracy.end();1201 defer tracy.end();
12611202
1262 const decl = mod.declPtr(decl_index);1203 const zcu = pt.zcu;
12631204 const gpa = zcu.gpa;
1264 if (decl.val.getExternFunc(mod)) |_| {1205 const ip = &zcu.intern_pool;
1265 return;1206 const nav = ip.getNav(nav_index);
1266 }1207
12671208 const init_val = switch (ip.indexToKey(nav.status.resolved.val)) {
1268 const gpa = self.base.comp.gpa;1209 .variable => |variable| variable.init,
1269 if (decl.isExtern(mod)) {1210 .@"extern" => |@"extern"| {
1270 // TODO make this part of getGlobalSymbol1211 if (ip.isFunctionType(nav.typeOf(ip))) return;
1271 const variable = decl.getOwnedVariable(mod).?;1212 // TODO make this part of getGlobalSymbol
1272 const name = decl.name.toSlice(&mod.intern_pool);1213 const name = nav.name.toSlice(ip);
1273 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);1214 const lib_name = @"extern".lib_name.toSlice(ip);
1274 const global_index = try self.getGlobalSymbol(name, lib_name);1215 const global_index = try self.getGlobalSymbol(name, lib_name);
1275 try self.need_got_table.put(gpa, global_index, {});1216 try self.need_got_table.put(gpa, global_index, {});
1276 return;1217 return;
1277 }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);
1280 Atom.freeRelocations(self, atom_index);1223 Atom.freeRelocations(self, atom_index);
1281 const atom = self.getAtom(atom_index);1224 const atom = self.getAtom(atom_index);
12821225
1283 var code_buffer = std.ArrayList(u8).init(gpa);1226 var code_buffer = std.ArrayList(u8).init(gpa);
1284 defer code_buffer.deinit();1227 defer code_buffer.deinit();
12851228
1286 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;1229 const res = try codegen.generateSymbol(
1287 const res = try codegen.generateSymbol(&self.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{1230 &self.base,
1288 .parent_atom_index = atom.getSymbolIndex().?,1231 pt,
1289 });1232 zcu.navSrcLoc(nav_index),
1233 Value.fromInterned(init_val),
1234 &code_buffer,
1235 .none,
1236 .{ .parent_atom_index = atom.getSymbolIndex().? },
1237 );
1290 const code = switch (res) {1238 const code = switch (res) {
1291 .ok => code_buffer.items,1239 .ok => code_buffer.items,
1292 .fail => |em| {1240 .fail => |em| {
1293 decl.analysis = .codegen_failure;1241 try zcu.failed_codegen.put(gpa, nav_index, em);
1294 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1295 return;1242 return;
1296 },1243 },
1297 };1244 };
12981245
1299 try self.updateDeclCode(pt, decl_index, code, .NULL);1246 try self.updateNavCode(pt, nav_index, code, .NULL);
13001247
1301 // Exports will be updated by `Zcu.processExports` after the update.1248 // Exports will be updated by `Zcu.processExports` after the update.
1302}1249}
...@@ -1317,14 +1264,14 @@ fn updateLazySymbolAtom(...@@ -1317,14 +1264,14 @@ fn updateLazySymbolAtom(
13171264
1318 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1265 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1319 @tagName(sym.kind),1266 @tagName(sym.kind),
1320 sym.ty.fmt(pt),1267 Type.fromInterned(sym.ty).fmt(pt),
1321 });1268 });
1322 defer gpa.free(name);1269 defer gpa.free(name);
13231270
1324 const atom = self.getAtomPtr(atom_index);1271 const atom = self.getAtomPtr(atom_index);
1325 const local_sym_index = atom.getSymbolIndex().?;1272 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;
1328 const res = try codegen.generateLazySymbol(1275 const res = try codegen.generateLazySymbol(
1329 &self.base,1276 &self.base,
1330 pt,1277 pt,
...@@ -1362,52 +1309,55 @@ fn updateLazySymbolAtom(...@@ -1362,52 +1309,55 @@ fn updateLazySymbolAtom(
1362 try self.writeAtom(atom_index, code);1309 try self.writeAtom(atom_index, code);
1363}1310}
13641311
1365pub fn getOrCreateAtomForLazySymbol(self: *Coff, pt: Zcu.PerThread, sym: link.File.LazySymbol) !Atom.Index {1312pub fn getOrCreateAtomForLazySymbol(
1366 const gpa = self.base.comp.gpa;1313 self: *Coff,
1367 const mod = self.base.comp.module.?;1314 pt: Zcu.PerThread,
1368 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod));1315 lazy_sym: link.File.LazySymbol,
1316) !Atom.Index {
1317 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
1369 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();1318 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1370 if (!gop.found_existing) gop.value_ptr.* = .{};1319 if (!gop.found_existing) gop.value_ptr.* = .{};
1371 const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {1320 const atom_ptr, const state_ptr = switch (lazy_sym.kind) {
1372 .code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },1321 .code => .{ &gop.value_ptr.text_atom, &gop.value_ptr.text_state },
1373 .const_data => .{ .atom = &gop.value_ptr.rdata_atom, .state = &gop.value_ptr.rdata_state },1322 .const_data => .{ &gop.value_ptr.rdata_atom, &gop.value_ptr.rdata_state },
1374 };1323 };
1375 switch (metadata.state.*) {1324 switch (state_ptr.*) {
1376 .unused => metadata.atom.* = try self.createAtom(),1325 .unused => atom_ptr.* = try self.createAtom(),
1377 .pending_flush => return metadata.atom.*,1326 .pending_flush => return atom_ptr.*,
1378 .flushed => {},1327 .flushed => {},
1379 }1328 }
1380 metadata.state.* = .pending_flush;1329 state_ptr.* = .pending_flush;
1381 const atom = metadata.atom.*;1330 const atom = atom_ptr.*;
1382 // anyerror needs to be deferred until flushModule1331 // 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) {
1384 .code => self.text_section_index.?,1333 .code => self.text_section_index.?,
1385 .const_data => self.rdata_section_index.?,1334 .const_data => self.rdata_section_index.?,
1386 });1335 });
1387 return atom;1336 return atom;
1388}1337}
13891338
1390pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !Atom.Index {1339pub fn getOrCreateAtomForNav(self: *Coff, nav_index: InternPool.Nav.Index) !Atom.Index {
1391 const gpa = self.base.comp.gpa;1340 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);
1393 if (!gop.found_existing) {1342 if (!gop.found_existing) {
1394 gop.value_ptr.* = .{1343 gop.value_ptr.* = .{
1395 .atom = try self.createAtom(),1344 .atom = try self.createAtom(),
1396 .section = self.getDeclOutputSection(decl_index),1345 .section = self.getNavOutputSection(nav_index),
1397 .exports = .{},1346 .exports = .{},
1398 };1347 };
1399 }1348 }
1400 return gop.value_ptr.atom;1349 return gop.value_ptr.atom;
1401}1350}
14021351
1403fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {1352fn getNavOutputSection(self: *Coff, nav_index: InternPool.Nav.Index) u16 {
1404 const decl = self.base.comp.module.?.declPtr(decl_index);1353 const zcu = self.base.comp.module.?;
1405 const mod = self.base.comp.module.?;1354 const ip = &zcu.intern_pool;
1406 const ty = decl.typeOf(mod);1355 const nav = ip.getNav(nav_index);
1407 const zig_ty = ty.zigTypeTag(mod);1356 const ty = Type.fromInterned(nav.typeOf(ip));
1408 const val = decl.val;1357 const zig_ty = ty.zigTypeTag(zcu);
1358 const val = Value.fromInterned(nav.status.resolved.val);
1409 const index: u16 = blk: {1359 const index: u16 = blk: {
1410 if (val.isUndefDeep(mod)) {1360 if (val.isUndefDeep(zcu)) {
1411 // TODO in release-fast and release-small, we should put undef in .bss1361 // TODO in release-fast and release-small, we should put undef in .bss
1412 break :blk self.data_section_index.?;1362 break :blk self.data_section_index.?;
1413 }1363 }
...@@ -1416,7 +1366,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {...@@ -1416,7 +1366,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
1416 // TODO: what if this is a function pointer?1366 // TODO: what if this is a function pointer?
1417 .Fn => break :blk self.text_section_index.?,1367 .Fn => break :blk self.text_section_index.?,
1418 else => {1368 else => {
1419 if (val.getVariable(mod)) |_| {1369 if (val.getVariable(zcu)) |_| {
1420 break :blk self.data_section_index.?;1370 break :blk self.data_section_index.?;
1421 }1371 }
1422 break :blk self.rdata_section_index.?;1372 break :blk self.rdata_section_index.?;
...@@ -1426,31 +1376,41 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {...@@ -1426,31 +1376,41 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
1426 return index;1376 return index;
1427}1377}
14281378
1429fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void {1379fn updateNavCode(
1430 const mod = pt.zcu;1380 self: *Coff,
1431 const decl = mod.declPtr(decl_index);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 });1390 log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index });
1434 const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
14351391
1436 const decl_metadata = self.decls.get(decl_index).?;1392 const required_alignment = pt.navAlignment(nav_index).max(
1437 const atom_index = decl_metadata.atom;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;
1438 const atom = self.getAtom(atom_index);1398 const atom = self.getAtom(atom_index);
1439 const sym_index = atom.getSymbolIndex().?;1399 const sym_index = atom.getSymbolIndex().?;
1440 const sect_index = decl_metadata.section;1400 const sect_index = nav_metadata.section;
1441 const code_len = @as(u32, @intCast(code.len));1401 const code_len = @as(u32, @intCast(code.len));
14421402
1443 if (atom.size != 0) {1403 if (atom.size != 0) {
1444 const sym = atom.getSymbolPtr(self);1404 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));
1446 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));1406 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
1447 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };1407 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14481408
1449 const capacity = atom.capacity(self);1409 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);
1451 if (need_realloc) {1411 if (need_realloc) {
1452 const vaddr = try self.growAtom(atom_index, code_len, required_alignment);1412 const vaddr = try self.growAtom(atom_index, code_len, @intCast(required_alignment.toByteUnits() orelse 0));
1453 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), sym.value, vaddr });1413 log.debug("growing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), sym.value, vaddr });
1454 log.debug(" (required alignment 0x{x}", .{required_alignment});1414 log.debug(" (required alignment 0x{x}", .{required_alignment});
14551415
1456 if (vaddr != sym.value) {1416 if (vaddr != sym.value) {
...@@ -1466,13 +1426,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd...@@ -1466,13 +1426,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
1466 self.getAtomPtr(atom_index).size = code_len;1426 self.getAtomPtr(atom_index).size = code_len;
1467 } else {1427 } else {
1468 const sym = atom.getSymbolPtr(self);1428 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));
1470 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));1430 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
1471 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };1431 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));
1474 errdefer self.freeAtom(atom_index);1434 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 });
1476 self.getAtomPtr(atom_index).size = code_len;1436 self.getAtomPtr(atom_index).size = code_len;
1477 sym.value = vaddr;1437 sym.value = vaddr;
14781438
...@@ -1482,28 +1442,15 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd...@@ -1482,28 +1442,15 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
1482 try self.writeAtom(atom_index, code);1442 try self.writeAtom(atom_index, code);
1483}1443}
14841444
1485fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void {1445pub fn freeNav(self: *Coff, nav_index: InternPool.NavIndex) void {
1486 const gpa = self.base.comp.gpa;1446 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav_index);
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);
14961447
1497 const gpa = self.base.comp.gpa;1448 const gpa = self.base.comp.gpa;
1498 const mod = self.base.comp.module.?;1449 log.debug("freeDecl 0x{x}", .{nav_index});
1499 const decl = mod.declPtr(decl_index);
15001450
1501 log.debug("freeDecl {*}", .{decl});1451 if (self.decls.fetchOrderedRemove(nav_index)) |const_kv| {
1502
1503 if (self.decls.fetchOrderedRemove(decl_index)) |const_kv| {
1504 var kv = const_kv;1452 var kv = const_kv;
1505 self.freeAtom(kv.value.atom);1453 self.freeAtom(kv.value.atom);
1506 self.freeUnnamedConsts(decl_index);
1507 kv.value.exports.deinit(gpa);1454 kv.value.exports.deinit(gpa);
1508 }1455 }
1509}1456}
...@@ -1528,20 +1475,21 @@ pub fn updateExports(...@@ -1528,20 +1475,21 @@ pub fn updateExports(
1528 // detect the default subsystem.1475 // detect the default subsystem.
1529 for (export_indices) |export_idx| {1476 for (export_indices) |export_idx| {
1530 const exp = mod.all_exports.items[export_idx];1477 const exp = mod.all_exports.items[export_idx];
1531 const exported_decl_index = switch (exp.exported) {1478 const exported_nav_index = switch (exp.exported) {
1532 .decl_index => |i| i,1479 .nav => |nav| nav,
1533 .value => continue,1480 .uav => continue,
1534 };1481 };
1535 const exported_decl = mod.declPtr(exported_decl_index);1482 const exported_nav = ip.getNav(exported_nav_index);
1536 if (exported_decl.getOwnedFunction(mod) == null) continue;1483 const exported_ty = exported_nav.typeOf(ip);
1537 const winapi_cc = switch (target.cpu.arch) {1484 if (!ip.isFunctionType(exported_ty)) continue;
1538 .x86 => std.builtin.CallingConvention.Stdcall,1485 const winapi_cc: std.builtin.CallingConvention = switch (target.cpu.arch) {
1539 else => std.builtin.CallingConvention.C,1486 .x86 => .Stdcall,
1487 else => .C,
1540 };1488 };
1541 const decl_cc = exported_decl.typeOf(mod).fnCallingConvention(mod);1489 const exported_cc = Type.fromInterned(exported_ty).fnCallingConvention(mod);
1542 if (decl_cc == .C and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) {1490 if (exported_cc == .C and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) {
1543 mod.stage1_flags.have_c_main = true;1491 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) {
1545 if (exp.opts.name.eqlSlice("WinMain", ip)) {1493 if (exp.opts.name.eqlSlice("WinMain", ip)) {
1546 mod.stage1_flags.have_winmain = true;1494 mod.stage1_flags.have_winmain = true;
1547 } else if (exp.opts.name.eqlSlice("wWinMain", ip)) {1495 } else if (exp.opts.name.eqlSlice("wWinMain", ip)) {
...@@ -1562,15 +1510,15 @@ pub fn updateExports(...@@ -1562,15 +1510,15 @@ pub fn updateExports(
1562 const gpa = comp.gpa;1510 const gpa = comp.gpa;
15631511
1564 const metadata = switch (exported) {1512 const metadata = switch (exported) {
1565 .decl_index => |decl_index| blk: {1513 .nav => |nav| blk: {
1566 _ = try self.getOrCreateAtomForDecl(decl_index);1514 _ = try self.getOrCreateAtomForNav(nav);
1567 break :blk self.decls.getPtr(decl_index).?;1515 break :blk self.navs.getPtr(nav).?;
1568 },1516 },
1569 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1517 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1570 const first_exp = mod.all_exports.items[export_indices[0]];1518 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);
1572 switch (res) {1520 switch (res) {
1573 .ok => {},1521 .mcv => {},
1574 .fail => |em| {1522 .fail => |em| {
1575 // TODO maybe it's enough to return an error here and let Module.processExportsInner1523 // TODO maybe it's enough to return an error here and let Module.processExportsInner
1576 // handle the error?1524 // handle the error?
...@@ -1579,7 +1527,7 @@ pub fn updateExports(...@@ -1579,7 +1527,7 @@ pub fn updateExports(
1579 return;1527 return;
1580 },1528 },
1581 }1529 }
1582 break :blk self.anon_decls.getPtr(value).?;1530 break :blk self.uavs.getPtr(uav).?;
1583 },1531 },
1584 };1532 };
1585 const atom_index = metadata.atom;1533 const atom_index = metadata.atom;
...@@ -1654,9 +1602,9 @@ pub fn deleteExport(...@@ -1654,9 +1602,9 @@ pub fn deleteExport(
1654) void {1602) void {
1655 if (self.llvm_object) |_| return;1603 if (self.llvm_object) |_| return;
1656 const metadata = switch (exported) {1604 const metadata = switch (exported) {
1657 .decl_index => |decl_index| self.decls.getPtr(decl_index) orelse return,1605 .nav => |nav| self.navs.getPtr(nav),
1658 .value => |value| self.anon_decls.getPtr(value) orelse return,1606 .uav => |uav| self.uavs.getPtr(uav),
1659 };1607 } orelse return;
1660 const mod = self.base.comp.module.?;1608 const mod = self.base.comp.module.?;
1661 const name_slice = name.toSlice(&mod.intern_pool);1609 const name_slice = name.toSlice(&mod.intern_pool);
1662 const sym_index = metadata.getExportPtr(self, name_slice) orelse return;1610 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...@@ -1748,7 +1696,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
1748 // anyerror needs to wait for everything to be flushed.1696 // anyerror needs to wait for everything to be flushed.
1749 if (metadata.text_state != .unused) self.updateLazySymbolAtom(1697 if (metadata.text_state != .unused) self.updateLazySymbolAtom(
1750 pt,1698 pt,
1751 link.File.LazySymbol.initDecl(.code, null, pt.zcu),1699 .{ .kind = .code, .ty = .anyerror_type },
1752 metadata.text_atom,1700 metadata.text_atom,
1753 self.text_section_index.?,1701 self.text_section_index.?,
1754 ) catch |err| return switch (err) {1702 ) catch |err| return switch (err) {
...@@ -1757,7 +1705,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no...@@ -1757,7 +1705,7 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
1757 };1705 };
1758 if (metadata.rdata_state != .unused) self.updateLazySymbolAtom(1706 if (metadata.rdata_state != .unused) self.updateLazySymbolAtom(
1759 pt,1707 pt,
1760 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),1708 .{ .kind = .const_data, .ty = .anyerror_type },
1761 metadata.rdata_atom,1709 metadata.rdata_atom,
1762 self.rdata_section_index.?,1710 self.rdata_section_index.?,
1763 ) catch |err| return switch (err) {1711 ) catch |err| return switch (err) {
...@@ -1856,22 +1804,20 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no...@@ -1856,22 +1804,20 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
1856 assert(!self.imports_count_dirty);1804 assert(!self.imports_count_dirty);
1857}1805}
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 {
1860 assert(self.llvm_object == null);1813 assert(self.llvm_object == null);
1861 const zcu = pt.zcu;1814 const zcu = pt.zcu;
1862 const ip = &zcu.intern_pool;1815 const ip = &zcu.intern_pool;
1863 const decl = zcu.declPtr(decl_index);1816 const nav = ip.getNav(nav_index);
1864 log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index });1817 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
1865 const sym_index = if (decl.isExtern(zcu)) blk: {1818 const sym_index = switch (ip.indexToKey(nav.status.resolved.val)) {
1866 const name = decl.name.toSlice(ip);1819 .@"extern" => |@"extern"| try self.getGlobalSymbol(nav.name.toSlice(ip), @"extern".lib_name.toSlice(ip)),
1867 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|1820 else => self.getAtom(try self.getOrCreateAtomForNav(nav_index)).getSymbolIndex().?,
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().?;
1875 };1821 };
1876 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;1822 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
1877 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };1823 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...@@ -1888,36 +1834,36 @@ pub fn getDeclVAddr(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclI
1888 return 0;1834 return 0;
1889}1835}
18901836
1891pub fn lowerAnonDecl(1837pub fn lowerUav(
1892 self: *Coff,1838 self: *Coff,
1893 pt: Zcu.PerThread,1839 pt: Zcu.PerThread,
1894 decl_val: InternPool.Index,1840 uav: InternPool.Index,
1895 explicit_alignment: InternPool.Alignment,1841 explicit_alignment: InternPool.Alignment,
1896 src_loc: Module.LazySrcLoc,1842 src_loc: Module.LazySrcLoc,
1897) !codegen.Result {1843) !codegen.GenResult {
1898 const gpa = self.base.comp.gpa;1844 const zcu = pt.zcu;
1899 const mod = self.base.comp.module.?;1845 const gpa = zcu.gpa;
1900 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));1846 const val = Value.fromInterned(uav);
1901 const decl_alignment = switch (explicit_alignment) {1847 const uav_alignment = switch (explicit_alignment) {
1902 .none => ty.abiAlignment(pt),1848 .none => val.typeOf(zcu).abiAlignment(pt),
1903 else => explicit_alignment,1849 else => explicit_alignment,
1904 };1850 };
1905 if (self.anon_decls.get(decl_val)) |metadata| {1851 if (self.uavs.get(uav)) |metadata| {
1906 const existing_addr = self.getAtom(metadata.atom).getSymbol(self).value;1852 const atom = self.getAtom(metadata.atom);
1907 if (decl_alignment.check(existing_addr))1853 const existing_addr = atom.getSymbol(self).value;
1908 return .ok;1854 if (uav_alignment.check(existing_addr))
1855 return .{ .mcv = .{ .load_direct = atom.getSymbolIndex().? } };
1909 }1856 }
19101857
1911 const val = Value.fromInterned(decl_val);
1912 var name_buf: [32]u8 = undefined;1858 var name_buf: [32]u8 = undefined;
1913 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{1859 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
1914 @intFromEnum(decl_val),1860 @intFromEnum(uav),
1915 }) catch unreachable;1861 }) catch unreachable;
1916 const res = self.lowerConst(1862 const res = self.lowerConst(
1917 pt,1863 pt,
1918 name,1864 name,
1919 val,1865 val,
1920 decl_alignment,1866 uav_alignment,
1921 self.rdata_section_index.?,1867 self.rdata_section_index.?,
1922 src_loc,1868 src_loc,
1923 ) catch |err| switch (err) {1869 ) catch |err| switch (err) {
...@@ -1933,14 +1879,23 @@ pub fn lowerAnonDecl(...@@ -1933,14 +1879,23 @@ pub fn lowerAnonDecl(
1933 .ok => |atom_index| atom_index,1879 .ok => |atom_index| atom_index,
1934 .fail => |em| return .{ .fail = em },1880 .fail => |em| return .{ .fail = em },
1935 };1881 };
1936 try self.anon_decls.put(gpa, decl_val, .{ .atom = atom_index, .section = self.rdata_section_index.? });1882 try self.uavs.put(gpa, uav, .{
1937 return .ok;1883 .atom = atom_index,
1884 .section = self.rdata_section_index.?,
1885 });
1886 return .{ .mcv = .{
1887 .load_direct = self.getAtom(atom_index).getSymbolIndex().?,
1888 } };
1938}1889}
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 {
1941 assert(self.llvm_object == null);1896 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;
1944 const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?;1899 const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?;
1945 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;1900 const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?;
1946 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };1901 const target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
...@@ -2760,6 +2715,7 @@ const Allocator = std.mem.Allocator;...@@ -2760,6 +2715,7 @@ const Allocator = std.mem.Allocator;
2760const codegen = @import("../codegen.zig");2715const codegen = @import("../codegen.zig");
2761const link = @import("../link.zig");2716const link = @import("../link.zig");
2762const lld = @import("Coff/lld.zig");2717const lld = @import("Coff/lld.zig");
2718const target_util = @import("../target.zig");
2763const trace = @import("../tracy.zig").trace;2719const trace = @import("../tracy.zig").trace;
27642720
2765const Air = @import("../Air.zig");2721const Air = @import("../Air.zig");
...@@ -2781,6 +2737,4 @@ const Value = @import("../Value.zig");...@@ -2781,6 +2737,4 @@ const Value = @import("../Value.zig");
2781const AnalUnit = InternPool.AnalUnit;2737const AnalUnit = InternPool.AnalUnit;
2782const dev = @import("../dev.zig");2738const dev = @import("../dev.zig");
27832739
2784pub const base_tag: link.File.Tag = .coff;
2785
2786const msdos_stub = @embedFile("msdos-stub.bin");2740const 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) = .{},...@@ -9,7 +9,7 @@ src_fn_free_list: std.AutoHashMapUnmanaged(Atom.Index, void) = .{},
9src_fn_first_index: ?Atom.Index = null,9src_fn_first_index: ?Atom.Index = null,
10src_fn_last_index: ?Atom.Index = null,10src_fn_last_index: ?Atom.Index = null,
11src_fns: std.ArrayListUnmanaged(Atom) = .{},11src_fns: std.ArrayListUnmanaged(Atom) = .{},
12src_fn_decls: AtomTable = .{},12src_fn_navs: AtomTable = .{},
1313
14/// A list of `Atom`s whose corresponding .debug_info tags have surplus capacity.14/// A list of `Atom`s whose corresponding .debug_info tags have surplus capacity.
15/// This is the same concept as `text_block_free_list`; see those doc comments.15/// 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) = .{},...@@ -17,7 +17,7 @@ di_atom_free_list: std.AutoHashMapUnmanaged(Atom.Index, void) = .{},
17di_atom_first_index: ?Atom.Index = null,17di_atom_first_index: ?Atom.Index = null,
18di_atom_last_index: ?Atom.Index = null,18di_atom_last_index: ?Atom.Index = null,
19di_atoms: std.ArrayListUnmanaged(Atom) = .{},19di_atoms: std.ArrayListUnmanaged(Atom) = .{},
20di_atom_decls: AtomTable = .{},20di_atom_navs: AtomTable = .{},
2121
22dbg_line_header: DbgLineHeader,22dbg_line_header: DbgLineHeader,
2323
...@@ -27,7 +27,7 @@ abbrev_table_offset: ?u64 = null,...@@ -27,7 +27,7 @@ abbrev_table_offset: ?u64 = null,
27/// Table of debug symbol names.27/// Table of debug symbol names.
28strtab: StringTable = .{},28strtab: 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.
31/// They will end up in the DWARF debug_line header as two lists:31/// They will end up in the DWARF debug_line header as two lists:
32/// * []include_directory32/// * []include_directory
33/// * []file_names33/// * []file_names
...@@ -35,13 +35,13 @@ di_files: std.AutoArrayHashMapUnmanaged(*const Zcu.File, void) = .{},...@@ -35,13 +35,13 @@ di_files: std.AutoArrayHashMapUnmanaged(*const Zcu.File, void) = .{},
3535
36global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},36global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
3737
38const AtomTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index);38const AtomTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, Atom.Index);
3939
40const Atom = struct {40const Atom = struct {
41 /// Offset into .debug_info pointing to the tag for this Decl, or41 /// Offset into .debug_info pointing to the tag for this Nav, or
42 /// offset from the beginning of the Debug Line Program header that contains this function.42 /// offset from the beginning of the Debug Line Program header that contains this function.
43 off: u32,43 off: u32,
44 /// Size of the .debug_info tag for this Decl, not including padding, or44 /// Size of the .debug_info tag for this Nav, not including padding, or
45 /// size of the line number program component belonging to this function, not45 /// size of the line number program component belonging to this function, not
46 /// including padding.46 /// including padding.
47 len: u32,47 len: u32,
...@@ -61,14 +61,14 @@ const DbgLineHeader = struct {...@@ -61,14 +61,14 @@ const DbgLineHeader = struct {
61 opcode_base: u8,61 opcode_base: u8,
62};62};
6363
64/// Represents state of the analysed Decl.64/// Represents state of the analysed Nav.
65/// Includes Decl's abbrev table of type Types, matching arena65/// Includes Nav's abbrev table of type Types, matching arena
66/// and a set of relocations that will be resolved once this66/// and a set of relocations that will be resolved once this
67/// Decl's inner Atom is assigned an offset within the DWARF section.67/// Nav's inner Atom is assigned an offset within the DWARF section.
68pub const DeclState = struct {68pub const NavState = struct {
69 dwarf: *Dwarf,69 dwarf: *Dwarf,
70 pt: Zcu.PerThread,70 pt: Zcu.PerThread,
71 di_atom_decls: *const AtomTable,71 di_atom_navs: *const AtomTable,
72 dbg_line_func: InternPool.Index,72 dbg_line_func: InternPool.Index,
73 dbg_line: std.ArrayList(u8),73 dbg_line: std.ArrayList(u8),
74 dbg_info: std.ArrayList(u8),74 dbg_info: std.ArrayList(u8),
...@@ -78,20 +78,20 @@ pub const DeclState = struct {...@@ -78,20 +78,20 @@ pub const DeclState = struct {
78 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation),78 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation),
79 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation),79 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation),
8080
81 pub fn deinit(self: *DeclState) void {81 pub fn deinit(ns: *NavState) void {
82 const gpa = self.dwarf.allocator;82 const gpa = ns.dwarf.allocator;
83 self.dbg_line.deinit();83 ns.dbg_line.deinit();
84 self.dbg_info.deinit();84 ns.dbg_info.deinit();
85 self.abbrev_type_arena.deinit();85 ns.abbrev_type_arena.deinit();
86 self.abbrev_table.deinit(gpa);86 ns.abbrev_table.deinit(gpa);
87 self.abbrev_resolver.deinit(gpa);87 ns.abbrev_resolver.deinit(gpa);
88 self.abbrev_relocs.deinit(gpa);88 ns.abbrev_relocs.deinit(gpa);
89 self.exprloc_relocs.deinit(gpa);89 ns.exprloc_relocs.deinit(gpa);
90 }90 }
9191
92 /// Adds local type relocation of the form: @offset => @this + addend92 /// Adds local type relocation of the form: @offset => @this + addend
93 /// @this signifies the offset within the .debug_abbrev section of the containing atom.93 /// @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 {
95 log.debug("{x}: @this + {x}", .{ offset, addend });95 log.debug("{x}: @this + {x}", .{ offset, addend });
96 try self.abbrev_relocs.append(self.dwarf.allocator, .{96 try self.abbrev_relocs.append(self.dwarf.allocator, .{
97 .target = null,97 .target = null,
...@@ -104,7 +104,7 @@ pub const DeclState = struct {...@@ -104,7 +104,7 @@ pub const DeclState = struct {
104 /// Adds global type relocation of the form: @offset => @symbol + 0104 /// Adds global type relocation of the form: @offset => @symbol + 0
105 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section105 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
106 /// which we use as our target of the relocation.106 /// 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 {
108 const gpa = self.dwarf.allocator;108 const gpa = self.dwarf.allocator;
109 const resolv = self.abbrev_resolver.get(ty.toIntern()) orelse blk: {109 const resolv = self.abbrev_resolver.get(ty.toIntern()) orelse blk: {
110 const sym_index: u32 = @intCast(self.abbrev_table.items.len);110 const sym_index: u32 = @intCast(self.abbrev_table.items.len);
...@@ -127,7 +127,7 @@ pub const DeclState = struct {...@@ -127,7 +127,7 @@ pub const DeclState = struct {
127 }127 }
128128
129 fn addDbgInfoType(129 fn addDbgInfoType(
130 self: *DeclState,130 self: *NavState,
131 pt: Zcu.PerThread,131 pt: Zcu.PerThread,
132 atom_index: Atom.Index,132 atom_index: Atom.Index,
133 ty: Type,133 ty: Type,
...@@ -550,15 +550,15 @@ pub const DeclState = struct {...@@ -550,15 +550,15 @@ pub const DeclState = struct {
550 };550 };
551551
552 pub fn genArgDbgInfo(552 pub fn genArgDbgInfo(
553 self: *DeclState,553 self: *NavState,
554 name: [:0]const u8,554 name: [:0]const u8,
555 ty: Type,555 ty: Type,
556 owner_decl: InternPool.DeclIndex,556 owner_nav: InternPool.Nav.Index,
557 loc: DbgInfoLoc,557 loc: DbgInfoLoc,
558 ) error{OutOfMemory}!void {558 ) error{OutOfMemory}!void {
559 const pt = self.pt;559 const pt = self.pt;
560 const dbg_info = &self.dbg_info;560 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).?;
562 const name_with_null = name.ptr[0 .. name.len + 1];562 const name_with_null = name.ptr[0 .. name.len + 1];
563563
564 switch (loc) {564 switch (loc) {
...@@ -639,6 +639,7 @@ pub const DeclState = struct {...@@ -639,6 +639,7 @@ pub const DeclState = struct {
639 leb128.writeIleb128(dbg_info.writer(), info.offset) catch unreachable;639 leb128.writeIleb128(dbg_info.writer(), info.offset) catch unreachable;
640 },640 },
641 .wasm_local => |value| {641 .wasm_local => |value| {
642 @import("../dev.zig").check(.wasm_linker);
642 const leb_size = link.File.Wasm.getUleb128Size(value);643 const leb_size = link.File.Wasm.getUleb128Size(value);
643 try dbg_info.ensureUnusedCapacity(3 + leb_size);644 try dbg_info.ensureUnusedCapacity(3 + leb_size);
644 // wasm locations are encoded as follow:645 // wasm locations are encoded as follow:
...@@ -665,15 +666,15 @@ pub const DeclState = struct {...@@ -665,15 +666,15 @@ pub const DeclState = struct {
665 }666 }
666667
667 pub fn genVarDbgInfo(668 pub fn genVarDbgInfo(
668 self: *DeclState,669 self: *NavState,
669 name: [:0]const u8,670 name: [:0]const u8,
670 ty: Type,671 ty: Type,
671 owner_decl: InternPool.DeclIndex,672 owner_nav: InternPool.Nav.Index,
672 is_ptr: bool,673 is_ptr: bool,
673 loc: DbgInfoLoc,674 loc: DbgInfoLoc,
674 ) error{OutOfMemory}!void {675 ) error{OutOfMemory}!void {
675 const dbg_info = &self.dbg_info;676 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).?;
677 const name_with_null = name.ptr[0 .. name.len + 1];678 const name_with_null = name.ptr[0 .. name.len + 1];
678 try dbg_info.append(@intFromEnum(AbbrevCode.variable));679 try dbg_info.append(@intFromEnum(AbbrevCode.variable));
679 const gpa = self.dwarf.allocator;680 const gpa = self.dwarf.allocator;
...@@ -881,7 +882,7 @@ pub const DeclState = struct {...@@ -881,7 +882,7 @@ pub const DeclState = struct {
881 }882 }
882883
883 pub fn advancePCAndLine(884 pub fn advancePCAndLine(
884 self: *DeclState,885 self: *NavState,
885 delta_line: i33,886 delta_line: i33,
886 delta_pc: u64,887 delta_pc: u64,
887 ) error{OutOfMemory}!void {888 ) error{OutOfMemory}!void {
...@@ -921,21 +922,21 @@ pub const DeclState = struct {...@@ -921,21 +922,21 @@ pub const DeclState = struct {
921 }922 }
922 }923 }
923924
924 pub fn setColumn(self: *DeclState, column: u32) error{OutOfMemory}!void {925 pub fn setColumn(self: *NavState, column: u32) error{OutOfMemory}!void {
925 try self.dbg_line.ensureUnusedCapacity(1 + 5);926 try self.dbg_line.ensureUnusedCapacity(1 + 5);
926 self.dbg_line.appendAssumeCapacity(DW.LNS.set_column);927 self.dbg_line.appendAssumeCapacity(DW.LNS.set_column);
927 leb128.writeUleb128(self.dbg_line.writer(), column + 1) catch unreachable;928 leb128.writeUleb128(self.dbg_line.writer(), column + 1) catch unreachable;
928 }929 }
929930
930 pub fn setPrologueEnd(self: *DeclState) error{OutOfMemory}!void {931 pub fn setPrologueEnd(self: *NavState) error{OutOfMemory}!void {
931 try self.dbg_line.append(DW.LNS.set_prologue_end);932 try self.dbg_line.append(DW.LNS.set_prologue_end);
932 }933 }
933934
934 pub fn setEpilogueBegin(self: *DeclState) error{OutOfMemory}!void {935 pub fn setEpilogueBegin(self: *NavState) error{OutOfMemory}!void {
935 try self.dbg_line.append(DW.LNS.set_epilogue_begin);936 try self.dbg_line.append(DW.LNS.set_epilogue_begin);
936 }937 }
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 {
939 const zcu = self.pt.zcu;940 const zcu = self.pt.zcu;
940 if (self.dbg_line_func == func) return;941 if (self.dbg_line_func == func) return;
941942
...@@ -944,15 +945,15 @@ pub const DeclState = struct {...@@ -944,15 +945,15 @@ pub const DeclState = struct {
944 const old_func_info = zcu.funcInfo(self.dbg_line_func);945 const old_func_info = zcu.funcInfo(self.dbg_line_func);
945 const new_func_info = zcu.funcInfo(func);946 const new_func_info = zcu.funcInfo(func);
946947
947 const old_file = try self.dwarf.addDIFile(zcu, old_func_info.owner_decl);948 const old_file = try self.dwarf.addDIFile(zcu, old_func_info.owner_nav);
948 const new_file = try self.dwarf.addDIFile(zcu, new_func_info.owner_decl);949 const new_file = try self.dwarf.addDIFile(zcu, new_func_info.owner_nav);
949 if (old_file != new_file) {950 if (old_file != new_file) {
950 self.dbg_line.appendAssumeCapacity(DW.LNS.set_file);951 self.dbg_line.appendAssumeCapacity(DW.LNS.set_file);
951 leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file);952 leb128.writeUnsignedFixed(4, self.dbg_line.addManyAsArrayAssumeCapacity(4), new_file);
952 }953 }
953954
954 const old_src_line: i33 = zcu.declPtr(old_func_info.owner_decl).navSrcLine(zcu);955 const old_src_line: i33 = zcu.navSrcLine(old_func_info.owner_nav);
955 const new_src_line: i33 = zcu.declPtr(new_func_info.owner_decl).navSrcLine(zcu);956 const new_src_line: i33 = zcu.navSrcLine(new_func_info.owner_nav);
956 if (new_src_line != old_src_line) {957 if (new_src_line != old_src_line) {
957 self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);958 self.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
958 leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line);959 leb128.writeSignedFixed(5, self.dbg_line.addManyAsArrayAssumeCapacity(5), new_src_line - old_src_line);
...@@ -1064,31 +1065,31 @@ pub fn deinit(self: *Dwarf) void {...@@ -1064,31 +1065,31 @@ pub fn deinit(self: *Dwarf) void {
10641065
1065 self.src_fn_free_list.deinit(gpa);1066 self.src_fn_free_list.deinit(gpa);
1066 self.src_fns.deinit(gpa);1067 self.src_fns.deinit(gpa);
1067 self.src_fn_decls.deinit(gpa);1068 self.src_fn_navs.deinit(gpa);
10681069
1069 self.di_atom_free_list.deinit(gpa);1070 self.di_atom_free_list.deinit(gpa);
1070 self.di_atoms.deinit(gpa);1071 self.di_atoms.deinit(gpa);
1071 self.di_atom_decls.deinit(gpa);1072 self.di_atom_navs.deinit(gpa);
10721073
1073 self.strtab.deinit(gpa);1074 self.strtab.deinit(gpa);
1074 self.di_files.deinit(gpa);1075 self.di_files.deinit(gpa);
1075 self.global_abbrev_relocs.deinit(gpa);1076 self.global_abbrev_relocs.deinit(gpa);
1076}1077}
10771078
1078/// Initializes Decl's state and its matching output buffers.1079/// Initializes Nav's state and its matching output buffers.
1079/// Call this before `commitDeclState`.1080/// Call this before `commitNavState`.
1080pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !DeclState {1081pub fn initNavState(self: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !NavState {
1081 const tracy = trace(@src());1082 const tracy = trace(@src());
1082 defer tracy.end();1083 defer tracy.end();
10831084
1084 const decl = pt.zcu.declPtr(decl_index);1085 const nav = pt.zcu.intern_pool.getNav(nav_index);
1085 log.debug("initDeclState {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });1086 log.debug("initNavState {}", .{nav.fqn.fmt(&pt.zcu.intern_pool)});
10861087
1087 const gpa = self.allocator;1088 const gpa = self.allocator;
1088 var decl_state: DeclState = .{1089 var nav_state: NavState = .{
1089 .dwarf = self,1090 .dwarf = self,
1090 .pt = pt,1091 .pt = pt,
1091 .di_atom_decls = &self.di_atom_decls,1092 .di_atom_navs = &self.di_atom_navs,
1092 .dbg_line_func = undefined,1093 .dbg_line_func = undefined,
1093 .dbg_line = std.ArrayList(u8).init(gpa),1094 .dbg_line = std.ArrayList(u8).init(gpa),
1094 .dbg_info = std.ArrayList(u8).init(gpa),1095 .dbg_info = std.ArrayList(u8).init(gpa),
...@@ -1098,30 +1099,30 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec...@@ -1098,30 +1099,30 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
1098 .abbrev_relocs = .{},1099 .abbrev_relocs = .{},
1099 .exprloc_relocs = .{},1100 .exprloc_relocs = .{},
1100 };1101 };
1101 errdefer decl_state.deinit();1102 errdefer nav_state.deinit();
1102 const dbg_line_buffer = &decl_state.dbg_line;1103 const dbg_line_buffer = &nav_state.dbg_line;
1103 const dbg_info_buffer = &decl_state.dbg_info;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)) {
1110 .Fn => {1111 .Fn => {
1111 _ = try self.getOrCreateAtomForDecl(.src_fn, decl_index);1112 _ = try self.getOrCreateAtomForNav(.src_fn, nav_index);
11121113
1113 // For functions we need to add a prologue to the debug line program.1114 // For functions we need to add a prologue to the debug line program.
1114 const ptr_width_bytes = self.ptrWidthBytes();1115 const ptr_width_bytes = self.ptrWidthBytes();
1115 try dbg_line_buffer.ensureTotalCapacity((3 + ptr_width_bytes) + (1 + 4) + (1 + 4) + (1 + 5) + 1);1116 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 nav_state.dbg_line_func = nav_val.toIntern();
1118 const func = decl.val.getFunction(pt.zcu).?;1119 const func = nav_val.getFunction(pt.zcu).?;
1119 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{1120 log.debug("src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1120 decl.navSrcLine(pt.zcu),1121 pt.zcu.navSrcLine(nav_index),
1121 func.lbrace_line,1122 func.lbrace_line,
1122 func.rbrace_line,1123 func.rbrace_line,
1123 });1124 });
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
1126 dbg_line_buffer.appendSliceAssumeCapacity(&.{1127 dbg_line_buffer.appendSliceAssumeCapacity(&.{
1127 DW.LNS.extended_op,1128 DW.LNS.extended_op,
...@@ -1143,7 +1144,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec...@@ -1143,7 +1144,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
1143 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);1144 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
1144 // Once we support more than one source file, this will have the ability to be more1145 // Once we support more than one source file, this will have the ability to be more
1145 // than one possible value.1146 // 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);
1147 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index);1148 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index);
11481149
1149 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column);1150 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_column);
...@@ -1154,12 +1155,12 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec...@@ -1154,12 +1155,12 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
1154 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);1155 dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy);
11551156
1156 // .debug_info subprogram1157 // .debug_info subprogram
1157 const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);1158 const nav_name_slice = nav.name.toSlice(&pt.zcu.intern_pool);
1158 const decl_linkage_name_slice = decl.fqn.toSlice(&pt.zcu.intern_pool);1159 const nav_linkage_name_slice = nav.fqn.toSlice(&pt.zcu.intern_pool);
1159 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +1160 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);
1163 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(pt);1164 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits(pt);
1164 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(1165 dbg_info_buffer.appendAssumeCapacity(@intFromEnum(
1165 @as(AbbrevCode, if (fn_ret_has_bits) .subprogram else .subprogram_retvoid),1166 @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...@@ -1172,14 +1173,14 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
1172 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);1173 assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len);
1173 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); // DW.AT.high_pc, DW.FORM.data41174 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); // DW.AT.high_pc, DW.FORM.data4
1174 if (fn_ret_has_bits) {1175 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));
1176 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); // DW.AT.type, DW.FORM.ref41177 dbg_info_buffer.appendNTimesAssumeCapacity(0, 4); // DW.AT.type, DW.FORM.ref4
1177 }1178 }
1178 dbg_info_buffer.appendSliceAssumeCapacity(1179 dbg_info_buffer.appendSliceAssumeCapacity(
1179 decl_name_slice[0 .. decl_name_slice.len + 1],1180 nav_name_slice[0 .. nav_name_slice.len + 1],
1180 ); // DW.AT.name, DW.FORM.string1181 ); // DW.AT.name, DW.FORM.string
1181 dbg_info_buffer.appendSliceAssumeCapacity(1182 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],
1183 ); // DW.AT.linkage_name, DW.FORM.string1184 ); // DW.AT.linkage_name, DW.FORM.string
1184 },1185 },
1185 else => {1186 else => {
...@@ -1187,37 +1188,36 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec...@@ -1187,37 +1188,36 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
1187 },1188 },
1188 }1189 }
11891190
1190 return decl_state;1191 return nav_state;
1191}1192}
11921193
1193pub fn commitDeclState(1194pub fn commitNavState(
1194 self: *Dwarf,1195 self: *Dwarf,
1195 pt: Zcu.PerThread,1196 pt: Zcu.PerThread,
1196 decl_index: InternPool.DeclIndex,1197 nav_index: InternPool.Nav.Index,
1197 sym_addr: u64,1198 sym_addr: u64,
1198 sym_size: u64,1199 sym_size: u64,
1199 decl_state: *DeclState,1200 nav_state: *NavState,
1200) !void {1201) !void {
1201 const tracy = trace(@src());1202 const tracy = trace(@src());
1202 defer tracy.end();1203 defer tracy.end();
12031204
1204 const gpa = self.allocator;1205 const gpa = self.allocator;
1205 const zcu = pt.zcu;1206 const zcu = pt.zcu;
1206 const decl = zcu.declPtr(decl_index);
1207 const ip = &zcu.intern_pool;1207 const ip = &zcu.intern_pool;
1208 const namespace = zcu.namespacePtr(decl.src_namespace);1208 const nav = ip.getNav(nav_index);
1209 const target = namespace.fileScope(zcu).mod.resolved_target.result;1209 const target = zcu.navFileScope(nav_index).mod.resolved_target.result;
1210 const target_endian = target.cpu.arch.endian();1210 const target_endian = target.cpu.arch.endian();
12111211
1212 var dbg_line_buffer = &decl_state.dbg_line;1212 var dbg_line_buffer = &nav_state.dbg_line;
1213 var dbg_info_buffer = &decl_state.dbg_info;1213 var dbg_info_buffer = &nav_state.dbg_info;
12141214
1215 assert(decl.has_tv);1215 const nav_val = Value.fromInterned(nav.status.resolved.val);
1216 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {1216 switch (nav_val.typeOf(zcu).zigTypeTag(zcu)) {
1217 .Fn => {1217 .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.
1221 // Perform the relocations based on vaddr.1221 // Perform the relocations based on vaddr.
1222 switch (self.ptr_width) {1222 switch (self.ptr_width) {
1223 .p32 => {1223 .p32 => {
...@@ -1254,10 +1254,10 @@ pub fn commitDeclState(...@@ -1254,10 +1254,10 @@ pub fn commitDeclState(
12541254
1255 // Now we have the full contents and may allocate a region to store it.1255 // 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` for1257 // This logic is nearly identical to the logic below in `updateNavDebugInfo` for
1258 // `TextBlock` and the .debug_info. If you are editing this logic, you1258 // `TextBlock` and the .debug_info. If you are editing this logic, you
1259 // probably need to edit that logic too.1259 // 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).?;
1261 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);1261 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);
1262 src_fn.len = @intCast(dbg_line_buffer.items.len);1262 src_fn.len = @intCast(dbg_line_buffer.items.len);
12631263
...@@ -1275,33 +1275,26 @@ pub fn commitDeclState(...@@ -1275,33 +1275,26 @@ pub fn commitDeclState(
1275 next.prev_index = src_fn.prev_index;1275 next.prev_index = src_fn.prev_index;
1276 src_fn.next_index = null;1276 src_fn.next_index = null;
1277 // Populate where it used to be with NOPs.1277 // Populate where it used to be with NOPs.
1278 switch (self.bin_file.tag) {1278 if (self.bin_file.cast(.elf)) |elf_file| {
1279 .elf => {1279 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
1280 const elf_file = self.bin_file.cast(File.Elf).?;1280 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1281 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];1281 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1282 const file_pos = debug_line_sect.sh_offset + src_fn.off;1282 } else if (self.bin_file.cast(.macho)) |macho_file| {
1283 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);1283 if (macho_file.base.isRelocatable()) {
1284 },1284 const debug_line_sect = &macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
1285 .macho => {1285 const file_pos = debug_line_sect.offset + src_fn.off;
1286 const macho_file = self.bin_file.cast(File.MachO).?;1286 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);
1287 if (macho_file.base.isRelocatable()) {1287 } else {
1288 const debug_line_sect = &macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];1288 const d_sym = macho_file.getDebugSymbols().?;
1289 const file_pos = debug_line_sect.offset + src_fn.off;1289 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1290 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, src_fn.len);1290 const file_pos = debug_line_sect.offset + src_fn.off;
1291 } else {1291 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1292 const d_sym = macho_file.getDebugSymbols().?;1292 }
1293 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);1293 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1294 const file_pos = debug_line_sect.offset + src_fn.off;1294 _ = wasm_file;
1295 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);1295 // const debug_line = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
1296 }1296 // writeDbgLineNopsBuffered(debug_line.items, src_fn.off, 0, &.{}, src_fn.len);
1297 },1297 } else unreachable;
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 }
1305 // TODO Look at the free list before appending at the end.1298 // TODO Look at the free list before appending at the end.
1306 src_fn.prev_index = last_index;1299 src_fn.prev_index = last_index;
1307 const last = self.getAtomPtr(.src_fn, last_index);1300 const last = self.getAtomPtr(.src_fn, last_index);
...@@ -1342,76 +1335,67 @@ pub fn commitDeclState(...@@ -1342,76 +1335,67 @@ pub fn commitDeclState(
13421335
1343 // We only have support for one compilation unit so far, so the offsets are directly1336 // We only have support for one compilation unit so far, so the offsets are directly
1344 // from the .debug_line section.1337 // from the .debug_line section.
1345 switch (self.bin_file.tag) {1338 if (self.bin_file.cast(.elf)) |elf_file| {
1346 .elf => {1339 const shdr_index = elf_file.debug_line_section_index.?;
1347 const elf_file = self.bin_file.cast(File.Elf).?;1340 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
1348 const shdr_index = elf_file.debug_line_section_index.?;1341 const debug_line_sect = elf_file.shdrs.items[shdr_index];
1349 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);1342 const file_pos = debug_line_sect.sh_offset + src_fn.off;
1350 const debug_line_sect = elf_file.shdrs.items[shdr_index];1343 try pwriteDbgLineNops(
1351 const file_pos = debug_line_sect.sh_offset + src_fn.off;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;
1352 try pwriteDbgLineNops(1356 try pwriteDbgLineNops(
1353 elf_file.base.file.?,1357 macho_file.base.file.?,
1354 file_pos,1358 file_pos,
1355 prev_padding_size,1359 prev_padding_size,
1356 dbg_line_buffer.items,1360 dbg_line_buffer.items,
1357 next_padding_size,1361 next_padding_size,
1358 );1362 );
1359 },1363 } else {
13601364 const d_sym = macho_file.getDebugSymbols().?;
1361 .macho => {1365 const sect_index = d_sym.debug_line_section_index.?;
1362 const macho_file = self.bin_file.cast(File.MachO).?;1366 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1363 if (macho_file.base.isRelocatable()) {1367 const sect = d_sym.getSection(sect_index);
1364 const sect_index = macho_file.debug_line_sect_index.?;1368 const file_pos = sect.offset + src_fn.off;
1365 try macho_file.growSection(sect_index, needed_size);1369 try pwriteDbgLineNops(
1366 const sect = macho_file.sections.items(.header)[sect_index];1370 d_sym.file,
1367 const file_pos = sect.offset + src_fn.off;1371 file_pos,
1368 try pwriteDbgLineNops(1372 prev_padding_size,
1369 macho_file.base.file.?,1373 dbg_line_buffer.items,
1370 file_pos,1374 next_padding_size,
1371 prev_padding_size,1375 );
1372 dbg_line_buffer.items,1376 }
1373 next_padding_size,1377 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1374 );1378 _ = wasm_file;
1375 } else {1379 // const atom = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?);
1376 const d_sym = macho_file.getDebugSymbols().?;1380 // const debug_line = &atom.code;
1377 const sect_index = d_sym.debug_line_section_index.?;1381 // const segment_size = debug_line.items.len;
1378 try d_sym.growSection(sect_index, needed_size, true, macho_file);1382 // if (needed_size != segment_size) {
1379 const sect = d_sym.getSection(sect_index);1383 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});
1380 const file_pos = sect.offset + src_fn.off;1384 // if (needed_size > segment_size) {
1381 try pwriteDbgLineNops(1385 // log.debug(" allocating {d} bytes for 'debug line' information", .{needed_size - segment_size});
1382 d_sym.file,1386 // try debug_line.resize(self.allocator, needed_size);
1383 file_pos,1387 // @memset(debug_line.items[segment_size..], 0);
1384 prev_padding_size,1388 // }
1385 dbg_line_buffer.items,1389 // debug_line.items.len = needed_size;
1386 next_padding_size,1390 // }
1387 );1391 // writeDbgLineNopsBuffered(
1388 }1392 // debug_line.items,
1389 },1393 // src_fn.off,
13901394 // prev_padding_size,
1391 .wasm => {1395 // dbg_line_buffer.items,
1392 // const wasm_file = self.bin_file.cast(File.Wasm).?;1396 // next_padding_size,
1393 // const atom = wasm_file.getAtomPtr(wasm_file.debug_line_atom.?);1397 // );
1394 // const debug_line = &atom.code;1398 } else unreachable;
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 }
14151399
1416 // .debug_info - End the TAG.subprogram children.1400 // .debug_info - End the TAG.subprogram children.
1417 try dbg_info_buffer.append(0);1401 try dbg_info_buffer.append(0);
...@@ -1422,27 +1406,27 @@ pub fn commitDeclState(...@@ -1422,27 +1406,27 @@ pub fn commitDeclState(
1422 if (dbg_info_buffer.items.len == 0)1406 if (dbg_info_buffer.items.len == 0)
1423 return;1407 return;
14241408
1425 const di_atom_index = self.di_atom_decls.get(decl_index).?;1409 const di_atom_index = self.di_atom_navs.get(nav_index).?;
1426 if (decl_state.abbrev_table.items.len > 0) {1410 if (nav_state.abbrev_table.items.len > 0) {
1427 // Now we emit the .debug_info types of the Decl. These will count towards the size of1411 // Now we emit the .debug_info types of the Nav. These will count towards the size of
1428 // the buffer, so we have to do it before computing the offset, and we can't perform the actual1412 // the buffer, so we have to do it before computing the offset, and we can't perform the actual
1429 // relocations yet.1413 // relocations yet.
1430 var sym_index: usize = 0;1414 var sym_index: usize = 0;
1431 while (sym_index < decl_state.abbrev_table.items.len) : (sym_index += 1) {1415 while (sym_index < nav_state.abbrev_table.items.len) : (sym_index += 1) {
1432 const symbol = &decl_state.abbrev_table.items[sym_index];1416 const symbol = &nav_state.abbrev_table.items[sym_index];
1433 const ty = symbol.type;1417 const ty = symbol.type;
1434 if (ip.isErrorSetType(ty.toIntern())) continue;1418 if (ip.isErrorSetType(ty.toIntern())) continue;
14351419
1436 symbol.offset = @intCast(dbg_info_buffer.items.len);1420 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);
1438 }1422 }
1439 }1423 }
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| {
1444 if (reloc.target) |reloc_target| {1428 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];
1446 const ty = symbol.type;1430 const ty = symbol.type;
1447 if (ip.isErrorSetType(ty.toIntern())) {1431 if (ip.isErrorSetType(ty.toIntern())) {
1448 log.debug("resolving %{d} deferred until flush", .{reloc_target});1432 log.debug("resolving %{d} deferred until flush", .{reloc_target});
...@@ -1479,38 +1463,35 @@ pub fn commitDeclState(...@@ -1479,38 +1463,35 @@ pub fn commitDeclState(
1479 }1463 }
1480 }1464 }
14811465
1482 while (decl_state.exprloc_relocs.popOrNull()) |reloc| {1466 while (nav_state.exprloc_relocs.popOrNull()) |reloc| {
1483 switch (self.bin_file.tag) {1467 if (self.bin_file.cast(.elf)) |elf_file| {
1484 .macho => {1468 _ = elf_file; // TODO
1485 const macho_file = self.bin_file.cast(File.MachO).?;1469 } else if (self.bin_file.cast(.macho)) |macho_file| {
1486 if (macho_file.base.isRelocatable()) {1470 if (macho_file.base.isRelocatable()) {
1487 // TODO1471 // TODO
1488 } else {1472 } else {
1489 const d_sym = macho_file.getDebugSymbols().?;1473 const d_sym = macho_file.getDebugSymbols().?;
1490 try d_sym.relocs.append(d_sym.allocator, .{1474 try d_sym.relocs.append(d_sym.allocator, .{
1491 .type = switch (reloc.type) {1475 .type = switch (reloc.type) {
1492 .direct_load => .direct_load,1476 .direct_load => .direct_load,
1493 .got_load => .got_load,1477 .got_load => .got_load,
1494 },1478 },
1495 .target = reloc.target,1479 .target = reloc.target,
1496 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,1480 .offset = reloc.offset + self.getAtom(.di_atom, di_atom_index).off,
1497 .addend = 0,1481 .addend = 0,
1498 });1482 });
1499 }1483 }
1500 },1484 } else unreachable;
1501 .elf => {}, // TODO
1502 else => unreachable,
1503 }
1504 }1485 }
15051486
1506 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);1487 try self.writeNavDebugInfo(di_atom_index, dbg_info_buffer.items);
1507}1488}
15081489
1509fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) !void {1490fn updateNavDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) !void {
1510 const tracy = trace(@src());1491 const tracy = trace(@src());
1511 defer tracy.end();1492 defer tracy.end();
15121493
1513 // This logic is nearly identical to the logic above in `updateDecl` for1494 // This logic is nearly identical to the logic above in `updateNav` for
1514 // `SrcFn` and the line number programs. If you are editing this logic, you1495 // `SrcFn` and the line number programs. If you are editing this logic, you
1515 // probably need to edit that logic too.1496 // probably need to edit that logic too.
1516 const gpa = self.allocator;1497 const gpa = self.allocator;
...@@ -1521,7 +1502,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)...@@ -1521,7 +1502,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
1521 if (atom_index == last_index) break :blk;1502 if (atom_index == last_index) break :blk;
1522 if (atom.next_index) |next_index| {1503 if (atom.next_index) |next_index| {
1523 const next = self.getAtomPtr(.di_atom, next_index);1504 const next = self.getAtomPtr(.di_atom, next_index);
1524 // Update existing Decl - non-last item.1505 // Update existing Nav - non-last item.
1525 if (atom.off + atom.len + min_nop_size > next.off) {1506 if (atom.off + atom.len + min_nop_size > next.off) {
1526 // It grew too big, so we move it to a new location.1507 // It grew too big, so we move it to a new location.
1527 if (atom.prev_index) |prev_index| {1508 if (atom.prev_index) |prev_index| {
...@@ -1531,34 +1512,27 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)...@@ -1531,34 +1512,27 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
1531 next.prev_index = atom.prev_index;1512 next.prev_index = atom.prev_index;
1532 atom.next_index = null;1513 atom.next_index = null;
1533 // Populate where it used to be with NOPs.1514 // Populate where it used to be with NOPs.
1534 switch (self.bin_file.tag) {1515 if (self.bin_file.cast(.elf)) |elf_file| {
1535 .elf => {1516 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
1536 const elf_file = self.bin_file.cast(File.Elf).?;1517 const file_pos = debug_info_sect.sh_offset + atom.off;
1537 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];1518 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1538 const file_pos = debug_info_sect.sh_offset + atom.off;1519 } else if (self.bin_file.cast(.macho)) |macho_file| {
1539 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);1520 if (macho_file.base.isRelocatable()) {
1540 },1521 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
1541 .macho => {1522 const file_pos = debug_info_sect.offset + atom.off;
1542 const macho_file = self.bin_file.cast(File.MachO).?;1523 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);
1543 if (macho_file.base.isRelocatable()) {1524 } else {
1544 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];1525 const d_sym = macho_file.getDebugSymbols().?;
1545 const file_pos = debug_info_sect.offset + atom.off;1526 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
1546 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, &[0]u8{}, atom.len, false);1527 const file_pos = debug_info_sect.offset + atom.off;
1547 } else {1528 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1548 const d_sym = macho_file.getDebugSymbols().?;1529 }
1549 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);1530 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1550 const file_pos = debug_info_sect.offset + atom.off;1531 _ = wasm_file;
1551 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);1532 // const debug_info_index = wasm_file.debug_info_atom.?;
1552 }1533 // const debug_info = &wasm_file.getAtomPtr(debug_info_index).code;
1553 },1534 // try writeDbgInfoNopsToArrayList(gpa, debug_info, atom.off, 0, &.{0}, atom.len, false);
1554 .wasm => {1535 } else unreachable;
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 }
1562 // TODO Look at the free list before appending at the end.1536 // TODO Look at the free list before appending at the end.
1563 atom.prev_index = last_index;1537 atom.prev_index = last_index;
1564 const last = self.getAtomPtr(.di_atom, last_index);1538 const last = self.getAtomPtr(.di_atom, last_index);
...@@ -1568,7 +1542,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)...@@ -1568,7 +1542,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
1568 atom.off = last.off + padToIdeal(last.len);1542 atom.off = last.off + padToIdeal(last.len);
1569 }1543 }
1570 } else if (atom.prev_index == null) {1544 } else if (atom.prev_index == null) {
1571 // Append new Decl.1545 // Append new Nav.
1572 // TODO Look at the free list before appending at the end.1546 // TODO Look at the free list before appending at the end.
1573 atom.prev_index = last_index;1547 atom.prev_index = last_index;
1574 const last = self.getAtomPtr(.di_atom, last_index);1548 const last = self.getAtomPtr(.di_atom, last_index);
...@@ -1578,7 +1552,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)...@@ -1578,7 +1552,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
1578 atom.off = last.off + padToIdeal(last.len);1552 atom.off = last.off + padToIdeal(last.len);
1579 }1553 }
1580 } else {1554 } else {
1581 // This is the first Decl of the .debug_info1555 // This is the first Nav of the .debug_info
1582 self.di_atom_first_index = atom_index;1556 self.di_atom_first_index = atom_index;
1583 self.di_atom_last_index = atom_index;1557 self.di_atom_last_index = atom_index;
15841558
...@@ -1586,19 +1560,19 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)...@@ -1586,19 +1560,19 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32)
1586 }1560 }
1587}1561}
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 {
1590 const tracy = trace(@src());1564 const tracy = trace(@src());
1591 defer tracy.end();1565 defer tracy.end();
15921566
1593 // This logic is nearly identical to the logic above in `updateDecl` for1567 // This logic is nearly identical to the logic above in `updateNav` for
1594 // `SrcFn` and the line number programs. If you are editing this logic, you1568 // `SrcFn` and the line number programs. If you are editing this logic, you
1595 // probably need to edit that logic too.1569 // probably need to edit that logic too.
15961570
1597 const atom = self.getAtom(.di_atom, atom_index);1571 const atom = self.getAtom(.di_atom, atom_index);
1598 const last_decl_index = self.di_atom_last_index.?;1572 const last_nav_index = self.di_atom_last_index.?;
1599 const last_decl = self.getAtom(.di_atom, last_decl_index);1573 const last_nav = self.getAtom(.di_atom, last_nav_index);
1600 // +1 for a trailing zero to end the children of the decl tag.1574 // +1 for a trailing zero to end the children of the nav tag.
1601 const needed_size = last_decl.off + last_decl.len + 1;1575 const needed_size = last_nav.off + last_nav.len + 1;
1602 const prev_padding_size: u32 = if (atom.prev_index) |prev_index| blk: {1576 const prev_padding_size: u32 = if (atom.prev_index) |prev_index| blk: {
1603 const prev = self.getAtom(.di_atom, prev_index);1577 const prev = self.getAtom(.di_atom, prev_index);
1604 break :blk atom.off - (prev.off + prev.len);1578 break :blk atom.off - (prev.off + prev.len);
...@@ -1608,107 +1582,99 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons...@@ -1608,107 +1582,99 @@ fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []cons
1608 break :blk next.off - (atom.off + atom.len);1582 break :blk next.off - (atom.off + atom.len);
1609 } else 0;1583 } else 0;
16101584
1611 // To end the children of the decl tag.1585 // To end the children of the nav tag.
1612 const trailing_zero = atom.next_index == null;1586 const trailing_zero = atom.next_index == null;
16131587
1614 // We only have support for one compilation unit so far, so the offsets are directly1588 // We only have support for one compilation unit so far, so the offsets are directly
1615 // from the .debug_info section.1589 // from the .debug_info section.
1616 switch (self.bin_file.tag) {1590 if (self.bin_file.cast(.elf)) |elf_file| {
1617 .elf => {1591 const shdr_index = elf_file.debug_info_section_index.?;
1618 const elf_file = self.bin_file.cast(File.Elf).?;1592 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
1619 const shdr_index = elf_file.debug_info_section_index.?;1593 const debug_info_sect = &elf_file.shdrs.items[shdr_index];
1620 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);1594 const file_pos = debug_info_sect.sh_offset + atom.off;
1621 const debug_info_sect = &elf_file.shdrs.items[shdr_index];1595 try pwriteDbgInfoNops(
1622 const file_pos = debug_info_sect.sh_offset + atom.off;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;
1623 try pwriteDbgInfoNops(1609 try pwriteDbgInfoNops(
1624 elf_file.base.file.?,1610 macho_file.base.file.?,
1625 file_pos,1611 file_pos,
1626 prev_padding_size,1612 prev_padding_size,
1627 dbg_info_buf,1613 dbg_info_buf,
1628 next_padding_size,1614 next_padding_size,
1629 trailing_zero,1615 trailing_zero,
1630 );1616 );
1631 },1617 } else {
16321618 const d_sym = macho_file.getDebugSymbols().?;
1633 .macho => {1619 const sect_index = d_sym.debug_info_section_index.?;
1634 const macho_file = self.bin_file.cast(File.MachO).?;1620 try d_sym.growSection(sect_index, needed_size, true, macho_file);
1635 if (macho_file.base.isRelocatable()) {1621 const sect = d_sym.getSection(sect_index);
1636 const sect_index = macho_file.debug_info_sect_index.?;1622 const file_pos = sect.offset + atom.off;
1637 try macho_file.growSection(sect_index, needed_size);1623 try pwriteDbgInfoNops(
1638 const sect = macho_file.sections.items(.header)[sect_index];1624 d_sym.file,
1639 const file_pos = sect.offset + atom.off;1625 file_pos,
1640 try pwriteDbgInfoNops(1626 prev_padding_size,
1641 macho_file.base.file.?,1627 dbg_info_buf,
1642 file_pos,1628 next_padding_size,
1643 prev_padding_size,1629 trailing_zero,
1644 dbg_info_buf,1630 );
1645 next_padding_size,1631 }
1646 trailing_zero,1632 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1647 );1633 _ = wasm_file;
1648 } else {1634 // const info_atom = wasm_file.debug_info_atom.?;
1649 const d_sym = macho_file.getDebugSymbols().?;1635 // const debug_info = &wasm_file.getAtomPtr(info_atom).code;
1650 const sect_index = d_sym.debug_info_section_index.?;1636 // const segment_size = debug_info.items.len;
1651 try d_sym.growSection(sect_index, needed_size, true, macho_file);1637 // if (needed_size != segment_size) {
1652 const sect = d_sym.getSection(sect_index);1638 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});
1653 const file_pos = sect.offset + atom.off;1639 // if (needed_size > segment_size) {
1654 try pwriteDbgInfoNops(1640 // log.debug(" allocating {d} bytes for 'debug info' information", .{needed_size - segment_size});
1655 d_sym.file,1641 // try debug_info.resize(self.allocator, needed_size);
1656 file_pos,1642 // @memset(debug_info.items[segment_size..], 0);
1657 prev_padding_size,1643 // }
1658 dbg_info_buf,1644 // debug_info.items.len = needed_size;
1659 next_padding_size,1645 // }
1660 trailing_zero,1646 // log.debug(" writeDbgInfoNopsToArrayList debug_info_len={d} offset={d} content_len={d} next_padding_size={d}", .{
1661 );1647 // debug_info.items.len, atom.off, dbg_info_buf.len, next_padding_size,
1662 }1648 // });
1663 },1649 // try writeDbgInfoNopsToArrayList(
16641650 // gpa,
1665 .wasm => {1651 // debug_info,
1666 // const wasm_file = self.bin_file.cast(File.Wasm).?;1652 // atom.off,
1667 // const info_atom = wasm_file.debug_info_atom.?;1653 // prev_padding_size,
1668 // const debug_info = &wasm_file.getAtomPtr(info_atom).code;1654 // dbg_info_buf,
1669 // const segment_size = debug_info.items.len;1655 // next_padding_size,
1670 // if (needed_size != segment_size) {1656 // trailing_zero,
1671 // log.debug(" needed size does not equal allocated size: {d}", .{needed_size});1657 // );
1672 // if (needed_size > segment_size) {1658 } else unreachable;
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 }
1694}1659}
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 {
1697 const tracy = trace(@src());1662 const tracy = trace(@src());
1698 defer tracy.end();1663 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);
1701 const atom = self.getAtom(.src_fn, atom_index);1666 const atom = self.getAtom(.src_fn, atom_index);
1702 if (atom.len == 0) return;1667 if (atom.len == 0) return;
17031668
1704 const decl = zcu.declPtr(decl_index);1669 const nav = zcu.intern_pool.getNav(nav_index);
1705 const func = decl.val.getFunction(zcu).?;1670 const nav_val = Value.fromInterned(nav.status.resolved.val);
1706 log.debug("decl.src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{1671 const func = nav_val.getFunction(zcu).?;
1707 decl.navSrcLine(zcu),1672 log.debug("src_line={d}, func.lbrace_line={d}, func.rbrace_line={d}", .{
1673 zcu.navSrcLine(nav_index),
1708 func.lbrace_line,1674 func.lbrace_line,
1709 func.rbrace_line,1675 func.rbrace_line,
1710 });1676 });
1711 const line: u28 = @intCast(decl.navSrcLine(zcu) + func.lbrace_line);1677 const line: u28 = @intCast(zcu.navSrcLine(nav_index) + func.lbrace_line);
1712 var data: [4]u8 = undefined;1678 var data: [4]u8 = undefined;
1713 leb128.writeUnsignedFixed(4, &data, line);1679 leb128.writeUnsignedFixed(4, &data, line);
17141680
...@@ -1742,11 +1708,11 @@ pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.Decl...@@ -1742,11 +1708,11 @@ pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.Decl
1742 }1708 }
1743}1709}
17441710
1745pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void {1711pub fn freeNav(self: *Dwarf, nav_index: InternPool.Nav.Index) void {
1746 const gpa = self.allocator;1712 const gpa = self.allocator;
17471713
1748 // Free SrcFn atom1714 // Free SrcFn atom
1749 if (self.src_fn_decls.fetchRemove(decl_index)) |kv| {1715 if (self.src_fn_navs.fetchRemove(nav_index)) |kv| {
1750 const src_fn_index = kv.value;1716 const src_fn_index = kv.value;
1751 const src_fn = self.getAtom(.src_fn, src_fn_index);1717 const src_fn = self.getAtom(.src_fn, src_fn_index);
1752 _ = self.src_fn_free_list.remove(src_fn_index);1718 _ = self.src_fn_free_list.remove(src_fn_index);
...@@ -1773,7 +1739,7 @@ pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void {...@@ -1773,7 +1739,7 @@ pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void {
1773 }1739 }
17741740
1775 // Free DI atom1741 // Free DI atom
1776 if (self.di_atom_decls.fetchRemove(decl_index)) |kv| {1742 if (self.di_atom_navs.fetchRemove(nav_index)) |kv| {
1777 const di_atom_index = kv.value;1743 const di_atom_index = kv.value;
1778 const di_atom = self.getAtomPtr(.di_atom, di_atom_index);1744 const di_atom = self.getAtomPtr(.di_atom, di_atom_index);
17791745
...@@ -1930,40 +1896,33 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {...@@ -1930,40 +1896,33 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
1930 self.abbrev_table_offset = abbrev_offset;1896 self.abbrev_table_offset = abbrev_offset;
19311897
1932 const needed_size = abbrev_buf.len;1898 const needed_size = abbrev_buf.len;
1933 switch (self.bin_file.tag) {1899 if (self.bin_file.cast(.elf)) |elf_file| {
1934 .elf => {1900 const shdr_index = elf_file.debug_abbrev_section_index.?;
1935 const elf_file = self.bin_file.cast(File.Elf).?;1901 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, false);
1936 const shdr_index = elf_file.debug_abbrev_section_index.?;1902 const debug_abbrev_sect = &elf_file.shdrs.items[shdr_index];
1937 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, false);1903 const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;
1938 const debug_abbrev_sect = &elf_file.shdrs.items[shdr_index];1904 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1939 const file_pos = debug_abbrev_sect.sh_offset + abbrev_offset;1905 } else if (self.bin_file.cast(.macho)) |macho_file| {
1940 try elf_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);1906 if (macho_file.base.isRelocatable()) {
1941 },1907 const sect_index = macho_file.debug_abbrev_sect_index.?;
1942 .macho => {1908 try macho_file.growSection(sect_index, needed_size);
1943 const macho_file = self.bin_file.cast(File.MachO).?;1909 const sect = macho_file.sections.items(.header)[sect_index];
1944 if (macho_file.base.isRelocatable()) {1910 const file_pos = sect.offset + abbrev_offset;
1945 const sect_index = macho_file.debug_abbrev_sect_index.?;1911 try macho_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);
1946 try macho_file.growSection(sect_index, needed_size);1912 } else {
1947 const sect = macho_file.sections.items(.header)[sect_index];1913 const d_sym = macho_file.getDebugSymbols().?;
1948 const file_pos = sect.offset + abbrev_offset;1914 const sect_index = d_sym.debug_abbrev_section_index.?;
1949 try macho_file.base.file.?.pwriteAll(&abbrev_buf, file_pos);1915 try d_sym.growSection(sect_index, needed_size, false, macho_file);
1950 } else {1916 const sect = d_sym.getSection(sect_index);
1951 const d_sym = macho_file.getDebugSymbols().?;1917 const file_pos = sect.offset + abbrev_offset;
1952 const sect_index = d_sym.debug_abbrev_section_index.?;1918 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);
1953 try d_sym.growSection(sect_index, needed_size, false, macho_file);1919 }
1954 const sect = d_sym.getSection(sect_index);1920 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
1955 const file_pos = sect.offset + abbrev_offset;1921 _ = wasm_file;
1956 try d_sym.file.pwriteAll(&abbrev_buf, file_pos);1922 // const debug_abbrev = &wasm_file.getAtomPtr(wasm_file.debug_abbrev_atom.?).code;
1957 }1923 // try debug_abbrev.resize(gpa, needed_size);
1958 },1924 // debug_abbrev.items[0..abbrev_buf.len].* = abbrev_buf;
1959 .wasm => {1925 } else unreachable;
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 }
1967}1926}
19681927
1969fn dbgInfoHeaderBytes(self: *Dwarf) usize {1928fn dbgInfoHeaderBytes(self: *Dwarf) usize {
...@@ -2027,37 +1986,30 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Zcu, low_pc: u64, high_pc: u64) !v...@@ -2027,37 +1986,30 @@ pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Zcu, low_pc: u64, high_pc: u64) !v
2027 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99, target_endian);1986 mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99, target_endian);
20281987
2029 if (di_buf.items.len > first_dbg_info_off) {1988 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.
2031 @panic("TODO: handle .debug_info header exceeding its padding");1990 @panic("TODO: handle .debug_info header exceeding its padding");
2032 }1991 }
2033 const jmp_amt = first_dbg_info_off - di_buf.items.len;1992 const jmp_amt = first_dbg_info_off - di_buf.items.len;
2034 switch (self.bin_file.tag) {1993 if (self.bin_file.cast(.elf)) |elf_file| {
2035 .elf => {1994 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
2036 const elf_file = self.bin_file.cast(File.Elf).?;1995 const file_pos = debug_info_sect.sh_offset;
2037 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];1996 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
2038 const file_pos = debug_info_sect.sh_offset;1997 } else if (self.bin_file.cast(.macho)) |macho_file| {
2039 try pwriteDbgInfoNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);1998 if (macho_file.base.isRelocatable()) {
2040 },1999 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2041 .macho => {2000 const file_pos = debug_info_sect.offset;
2042 const macho_file = self.bin_file.cast(File.MachO).?;2001 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);
2043 if (macho_file.base.isRelocatable()) {2002 } else {
2044 const debug_info_sect = macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];2003 const d_sym = macho_file.getDebugSymbols().?;
2045 const file_pos = debug_info_sect.offset;2004 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);
2046 try pwriteDbgInfoNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt, false);2005 const file_pos = debug_info_sect.offset;
2047 } else {2006 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
2048 const d_sym = macho_file.getDebugSymbols().?;2007 }
2049 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);2008 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2050 const file_pos = debug_info_sect.offset;2009 _ = wasm_file;
2051 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);2010 // const debug_info = &wasm_file.getAtomPtr(wasm_file.debug_info_atom.?).code;
2052 }2011 // try writeDbgInfoNopsToArrayList(self.allocator, debug_info, 0, 0, di_buf.items, jmp_amt, false);
2053 },2012 } else unreachable;
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 }
2061}2013}
20622014
2063fn resolveCompilationDir(zcu: *Zcu, buffer: *[std.fs.max_path_bytes]u8) []const u8 {2015fn 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 {...@@ -2360,40 +2312,33 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
2360 }2312 }
23612313
2362 const needed_size: u32 = @intCast(di_buf.items.len);2314 const needed_size: u32 = @intCast(di_buf.items.len);
2363 switch (self.bin_file.tag) {2315 if (self.bin_file.cast(.elf)) |elf_file| {
2364 .elf => {2316 const shdr_index = elf_file.debug_aranges_section_index.?;
2365 const elf_file = self.bin_file.cast(File.Elf).?;2317 try elf_file.growNonAllocSection(shdr_index, needed_size, 16, false);
2366 const shdr_index = elf_file.debug_aranges_section_index.?;2318 const debug_aranges_sect = &elf_file.shdrs.items[shdr_index];
2367 try elf_file.growNonAllocSection(shdr_index, needed_size, 16, false);2319 const file_pos = debug_aranges_sect.sh_offset;
2368 const debug_aranges_sect = &elf_file.shdrs.items[shdr_index];2320 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2369 const file_pos = debug_aranges_sect.sh_offset;2321 } else if (self.bin_file.cast(.macho)) |macho_file| {
2370 try elf_file.base.file.?.pwriteAll(di_buf.items, file_pos);2322 if (macho_file.base.isRelocatable()) {
2371 },2323 const sect_index = macho_file.debug_aranges_sect_index.?;
2372 .macho => {2324 try macho_file.growSection(sect_index, needed_size);
2373 const macho_file = self.bin_file.cast(File.MachO).?;2325 const sect = macho_file.sections.items(.header)[sect_index];
2374 if (macho_file.base.isRelocatable()) {2326 const file_pos = sect.offset;
2375 const sect_index = macho_file.debug_aranges_sect_index.?;2327 try macho_file.base.file.?.pwriteAll(di_buf.items, file_pos);
2376 try macho_file.growSection(sect_index, needed_size);2328 } else {
2377 const sect = macho_file.sections.items(.header)[sect_index];2329 const d_sym = macho_file.getDebugSymbols().?;
2378 const file_pos = sect.offset;2330 const sect_index = d_sym.debug_aranges_section_index.?;
2379 try macho_file.base.file.?.pwriteAll(di_buf.items, file_pos);2331 try d_sym.growSection(sect_index, needed_size, false, macho_file);
2380 } else {2332 const sect = d_sym.getSection(sect_index);
2381 const d_sym = macho_file.getDebugSymbols().?;2333 const file_pos = sect.offset;
2382 const sect_index = d_sym.debug_aranges_section_index.?;2334 try d_sym.file.pwriteAll(di_buf.items, file_pos);
2383 try d_sym.growSection(sect_index, needed_size, false, macho_file);2335 }
2384 const sect = d_sym.getSection(sect_index);2336 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2385 const file_pos = sect.offset;2337 _ = wasm_file;
2386 try d_sym.file.pwriteAll(di_buf.items, file_pos);2338 // const debug_ranges = &wasm_file.getAtomPtr(wasm_file.debug_ranges_atom.?).code;
2387 }2339 // try debug_ranges.resize(gpa, needed_size);
2388 },2340 // @memcpy(debug_ranges.items[0..di_buf.items.len], di_buf.items);
2389 .wasm => {2341 } else unreachable;
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 }
2397}2342}
23982343
2399pub fn writeDbgLineHeader(self: *Dwarf) !void {2344pub fn writeDbgLineHeader(self: *Dwarf) !void {
...@@ -2502,60 +2447,52 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {...@@ -2502,60 +2447,52 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
25022447
2503 var src_fn_index = first_fn_index;2448 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);
2506 defer gpa.free(buffer);2451 defer gpa.free(buffer);
25072452
2508 switch (self.bin_file.tag) {2453 if (self.bin_file.cast(.elf)) |elf_file| {
2509 .elf => {2454 const shdr_index = elf_file.debug_line_section_index.?;
2510 const elf_file = self.bin_file.cast(File.Elf).?;2455 const needed_size = elf_file.shdrs.items[shdr_index].sh_size + delta;
2511 const shdr_index = elf_file.debug_line_section_index.?;2456 try elf_file.growNonAllocSection(shdr_index, needed_size, 1, true);
2512 const needed_size = elf_file.shdrs.items[shdr_index].sh_size + delta;2457 const file_pos = elf_file.shdrs.items[shdr_index].sh_offset + first_fn.off;
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;
25152458
2516 const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);2459 const amt = try elf_file.base.file.?.preadAll(buffer, file_pos);
2517 if (amt != buffer.len) return error.InputOutput;2460 if (amt != buffer.len) return error.InputOutput;
25182461
2519 try elf_file.base.file.?.pwriteAll(buffer, file_pos + delta);2462 try elf_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2520 },2463 } else if (self.bin_file.cast(.macho)) |macho_file| {
2521 .macho => {2464 if (macho_file.base.isRelocatable()) {
2522 const macho_file = self.bin_file.cast(File.MachO).?;2465 const sect_index = macho_file.debug_line_sect_index.?;
2523 if (macho_file.base.isRelocatable()) {2466 const needed_size: u32 = @intCast(macho_file.sections.items(.header)[sect_index].size + delta);
2524 const sect_index = macho_file.debug_line_sect_index.?;2467 try macho_file.growSection(sect_index, needed_size);
2525 const needed_size: u32 = @intCast(macho_file.sections.items(.header)[sect_index].size + delta);2468 const file_pos = macho_file.sections.items(.header)[sect_index].offset + first_fn.off;
2526 try macho_file.growSection(sect_index, needed_size);
2527 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);2470 const amt = try macho_file.base.file.?.preadAll(buffer, file_pos);
2530 if (amt != buffer.len) return error.InputOutput;2471 if (amt != buffer.len) return error.InputOutput;
25312472
2532 try macho_file.base.file.?.pwriteAll(buffer, file_pos + delta);2473 try macho_file.base.file.?.pwriteAll(buffer, file_pos + delta);
2533 } else {2474 } else {
2534 const d_sym = macho_file.getDebugSymbols().?;2475 const d_sym = macho_file.getDebugSymbols().?;
2535 const sect_index = d_sym.debug_line_section_index.?;2476 const sect_index = d_sym.debug_line_section_index.?;
2536 const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta);2477 const needed_size: u32 = @intCast(d_sym.getSection(sect_index).size + delta);
2537 try d_sym.growSection(sect_index, needed_size, true, macho_file);2478 try d_sym.growSection(sect_index, needed_size, true, macho_file);
2538 const file_pos = d_sym.getSection(sect_index).offset + first_fn.off;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);2481 const amt = try d_sym.file.preadAll(buffer, file_pos);
2541 if (amt != buffer.len) return error.InputOutput;2482 if (amt != buffer.len) return error.InputOutput;
25422483
2543 try d_sym.file.pwriteAll(buffer, file_pos + delta);2484 try d_sym.file.pwriteAll(buffer, file_pos + delta);
2544 }2485 }
2545 },2486 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2546 .wasm => {2487 _ = wasm_file;
2547 _ = &buffer;2488 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
2548 // const wasm_file = self.bin_file.cast(File.Wasm).?;2489 // {
2549 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;2490 // const src = debug_line.items[first_fn.off..];
2550 // {2491 // @memcpy(buffer[0..src.len], src);
2551 // const src = debug_line.items[first_fn.off..];2492 // }
2552 // @memcpy(buffer[0..src.len], src);2493 // try debug_line.resize(self.allocator, debug_line.items.len + delta);
2553 // }2494 // @memcpy(debug_line.items[first_fn.off + delta ..][0..buffer.len], buffer);
2554 // try debug_line.resize(self.allocator, debug_line.items.len + delta);2495 } else unreachable;
2555 // @memcpy(debug_line.items[first_fn.off + delta ..][0..buffer.len], buffer);
2556 },
2557 else => unreachable,
2558 }
25592496
2560 while (true) {2497 while (true) {
2561 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);2498 const src_fn = self.getAtomPtr(.src_fn, src_fn_index);
...@@ -2580,33 +2517,26 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {...@@ -2580,33 +2517,26 @@ pub fn writeDbgLineHeader(self: *Dwarf) !void {
25802517
2581 // We use NOPs because consumers empirically do not respect the header length field.2518 // We use NOPs because consumers empirically do not respect the header length field.
2582 const jmp_amt = self.getDebugLineProgramOff().? - di_buf.items.len;2519 const jmp_amt = self.getDebugLineProgramOff().? - di_buf.items.len;
2583 switch (self.bin_file.tag) {2520 if (self.bin_file.cast(.elf)) |elf_file| {
2584 .elf => {2521 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];
2585 const elf_file = self.bin_file.cast(File.Elf).?;2522 const file_pos = debug_line_sect.sh_offset;
2586 const debug_line_sect = &elf_file.shdrs.items[elf_file.debug_line_section_index.?];2523 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2587 const file_pos = debug_line_sect.sh_offset;2524 } else if (self.bin_file.cast(.macho)) |macho_file| {
2588 try pwriteDbgLineNops(elf_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);2525 if (macho_file.base.isRelocatable()) {
2589 },2526 const debug_line_sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];
2590 .macho => {2527 const file_pos = debug_line_sect.offset;
2591 const macho_file = self.bin_file.cast(File.MachO).?;2528 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);
2592 if (macho_file.base.isRelocatable()) {2529 } else {
2593 const debug_line_sect = macho_file.sections.items(.header)[macho_file.debug_line_sect_index.?];2530 const d_sym = macho_file.getDebugSymbols().?;
2594 const file_pos = debug_line_sect.offset;2531 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);
2595 try pwriteDbgLineNops(macho_file.base.file.?, file_pos, 0, di_buf.items, jmp_amt);2532 const file_pos = debug_line_sect.offset;
2596 } else {2533 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2597 const d_sym = macho_file.getDebugSymbols().?;2534 }
2598 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);2535 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2599 const file_pos = debug_line_sect.offset;2536 _ = wasm_file;
2600 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);2537 // const debug_line = &wasm_file.getAtomPtr(wasm_file.debug_line_atom.?).code;
2601 }2538 // writeDbgLineNopsBuffered(debug_line.items, 0, 0, di_buf.items, jmp_amt);
2602 },2539 } else unreachable;
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 }
2610}2540}
26112541
2612fn getDebugInfoOff(self: Dwarf) ?u32 {2542fn getDebugInfoOff(self: Dwarf) ?u32 {
...@@ -2704,85 +2634,66 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {...@@ -2704,85 +2634,66 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {
2704 );2634 );
27052635
2706 const di_atom_index = try self.createAtom(.di_atom);2636 const di_atom_index = try self.createAtom(.di_atom);
2707 log.debug("updateDeclDebugInfoAllocation in flushModule", .{});2637 log.debug("updateNavDebugInfoAllocation in flushModule", .{});
2708 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));2638 try self.updateNavDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));
2709 log.debug("writeDeclDebugInfo in flushModule", .{});2639 log.debug("writeNavDebugInfo in flushModule", .{});
2710 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);2640 try self.writeNavDebugInfo(di_atom_index, dbg_info_buffer.items);
27112641
2712 const file_pos = switch (self.bin_file.tag) {2642 const file_pos = if (self.bin_file.cast(.elf)) |elf_file| pos: {
2713 .elf => pos: {2643 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];
2714 const elf_file = self.bin_file.cast(File.Elf).?;2644 break :pos debug_info_sect.sh_offset;
2715 const debug_info_sect = &elf_file.shdrs.items[elf_file.debug_info_section_index.?];2645 } else if (self.bin_file.cast(.macho)) |macho_file| pos: {
2716 break :pos debug_info_sect.sh_offset;2646 if (macho_file.base.isRelocatable()) {
2717 },2647 const debug_info_sect = &macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];
2718 .macho => pos: {2648 break :pos debug_info_sect.offset;
2719 const macho_file = self.bin_file.cast(File.MachO).?;2649 } else {
2720 if (macho_file.base.isRelocatable()) {2650 const d_sym = macho_file.getDebugSymbols().?;
2721 const debug_info_sect = &macho_file.sections.items(.header)[macho_file.debug_info_sect_index.?];2651 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2722 break :pos debug_info_sect.offset;2652 break :pos debug_info_sect.offset;
2723 } else {2653 }
2724 const d_sym = macho_file.getDebugSymbols().?;2654 } else if (self.bin_file.cast(.wasm)) |_|
2725 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2726 break :pos debug_info_sect.offset;
2727 }
2728 },
2729 // for wasm, the offset is always 0 as we write to memory first2655 // for wasm, the offset is always 0 as we write to memory first
2730 .wasm => 0,2656 0
2731 else => unreachable,2657 else
2732 };2658 unreachable;
27332659
2734 var buf: [@sizeOf(u32)]u8 = undefined;2660 var buf: [@sizeOf(u32)]u8 = undefined;
2735 mem.writeInt(u32, &buf, self.getAtom(.di_atom, di_atom_index).off, target.cpu.arch.endian());2661 mem.writeInt(u32, &buf, self.getAtom(.di_atom, di_atom_index).off, target.cpu.arch.endian());
27362662
2737 while (self.global_abbrev_relocs.popOrNull()) |reloc| {2663 while (self.global_abbrev_relocs.popOrNull()) |reloc| {
2738 const atom = self.getAtom(.di_atom, reloc.atom_index);2664 const atom = self.getAtom(.di_atom, reloc.atom_index);
2739 switch (self.bin_file.tag) {2665 if (self.bin_file.cast(.elf)) |elf_file| {
2740 .elf => {2666 try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2741 const elf_file = self.bin_file.cast(File.Elf).?;2667 } else if (self.bin_file.cast(.macho)) |macho_file| {
2742 try elf_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);2668 if (macho_file.base.isRelocatable()) {
2743 },2669 try macho_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2744 .macho => {2670 } else {
2745 const macho_file = self.bin_file.cast(File.MachO).?;2671 const d_sym = macho_file.getDebugSymbols().?;
2746 if (macho_file.base.isRelocatable()) {2672 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);
2747 try macho_file.base.file.?.pwriteAll(&buf, file_pos + atom.off + reloc.offset);2673 }
2748 } else {2674 } else if (self.bin_file.cast(.wasm)) |wasm_file| {
2749 const d_sym = macho_file.getDebugSymbols().?;2675 _ = wasm_file;
2750 try d_sym.file.pwriteAll(&buf, file_pos + atom.off + reloc.offset);2676 // const debug_info = wasm_file.getAtomPtr(wasm_file.debug_info_atom.?).code;
2751 }2677 // debug_info.items[atom.off + reloc.offset ..][0..buf.len].* = buf;
2752 },2678 } else unreachable;
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 }
2760 }2679 }
2761 }2680 }
2762}2681}
27632682
2764fn addDIFile(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !u28 {2683fn addDIFile(self: *Dwarf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !u28 {
2765 const decl = zcu.declPtr(decl_index);2684 const file_scope = zcu.navFileScope(nav_index);
2766 const file_scope = decl.getFileScope(zcu);
2767 const gop = try self.di_files.getOrPut(self.allocator, file_scope);2685 const gop = try self.di_files.getOrPut(self.allocator, file_scope);
2768 if (!gop.found_existing) {2686 if (!gop.found_existing) {
2769 switch (self.bin_file.tag) {2687 if (self.bin_file.cast(.elf)) |elf_file| {
2770 .elf => {2688 elf_file.markDirty(elf_file.debug_line_section_index.?);
2771 const elf_file = self.bin_file.cast(File.Elf).?;2689 } else if (self.bin_file.cast(.macho)) |macho_file| {
2772 elf_file.markDirty(elf_file.debug_line_section_index.?);2690 if (macho_file.base.isRelocatable()) {
2773 },2691 macho_file.markDirty(macho_file.debug_line_sect_index.?);
2774 .macho => {2692 } else {
2775 const macho_file = self.bin_file.cast(File.MachO).?;2693 const d_sym = macho_file.getDebugSymbols().?;
2776 if (macho_file.base.isRelocatable()) {2694 d_sym.markDirty(d_sym.debug_line_section_index.?, macho_file);
2777 macho_file.markDirty(macho_file.debug_line_sect_index.?);2695 }
2778 } else {2696 } else if (self.bin_file.cast(.wasm)) |_| {} else unreachable;
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 }
2786 }2697 }
2787 return @intCast(gop.index + 1);2698 return @intCast(gop.index + 1);
2788}2699}
...@@ -2909,17 +2820,17 @@ fn createAtom(self: *Dwarf, comptime kind: Kind) !Atom.Index {...@@ -2909,17 +2820,17 @@ fn createAtom(self: *Dwarf, comptime kind: Kind) !Atom.Index {
2909 return index;2820 return index;
2910}2821}
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 {
2913 switch (kind) {2824 switch (kind) {
2914 .src_fn => {2825 .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);
2916 if (!gop.found_existing) {2827 if (!gop.found_existing) {
2917 gop.value_ptr.* = try self.createAtom(kind);2828 gop.value_ptr.* = try self.createAtom(kind);
2918 }2829 }
2919 return gop.value_ptr.*;2830 return gop.value_ptr.*;
2920 },2831 },
2921 .di_atom => {2832 .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);
2923 if (!gop.found_existing) {2834 if (!gop.found_existing) {
2924 gop.value_ptr.* = try self.createAtom(kind);2835 gop.value_ptr.* = try self.createAtom(kind);
2925 }2836 }
src/link/Elf.zig+18-22
...@@ -478,24 +478,24 @@ pub fn deinit(self: *Elf) void {...@@ -478,24 +478,24 @@ pub fn deinit(self: *Elf) void {
478 self.comdat_group_sections.deinit(gpa);478 self.comdat_group_sections.deinit(gpa);
479}479}
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 {
482 assert(self.llvm_object == null);482 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);
484}484}
485485
486pub fn lowerAnonDecl(486pub fn lowerUav(
487 self: *Elf,487 self: *Elf,
488 pt: Zcu.PerThread,488 pt: Zcu.PerThread,
489 decl_val: InternPool.Index,489 uav: InternPool.Index,
490 explicit_alignment: InternPool.Alignment,490 explicit_alignment: InternPool.Alignment,
491 src_loc: Zcu.LazySrcLoc,491 src_loc: Zcu.LazySrcLoc,
492) !codegen.Result {492) !codegen.GenResult {
493 return self.zigObjectPtr().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc);493 return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment, src_loc);
494}494}
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 {
497 assert(self.llvm_object == null);497 assert(self.llvm_object == null);
498 return self.zigObjectPtr().?.getAnonDeclVAddr(self, decl_val, reloc_info);498 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);
499}499}
500500
501/// Returns end pos of collision, if any.501/// Returns end pos of collision, if any.
...@@ -2913,9 +2913,9 @@ pub fn writeElfHeader(self: *Elf) !void {...@@ -2913,9 +2913,9 @@ pub fn writeElfHeader(self: *Elf) !void {
2913 try self.base.file.?.pwriteAll(hdr_buf[0..index], 0);2913 try self.base.file.?.pwriteAll(hdr_buf[0..index], 0);
2914}2914}
29152915
2916pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void {2916pub fn freeNav(self: *Elf, nav: InternPool.Nav.Index) void {
2917 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);2917 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav);
2918 return self.zigObjectPtr().?.freeDecl(self, decl_index);2918 return self.zigObjectPtr().?.freeNav(self, nav);
2919}2919}
29202920
2921pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {2921pub 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...@@ -2926,20 +2926,16 @@ pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, a
2926 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness);2926 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness);
2927}2927}
29282928
2929pub fn updateDecl(2929pub fn updateNav(
2930 self: *Elf,2930 self: *Elf,
2931 pt: Zcu.PerThread,2931 pt: Zcu.PerThread,
2932 decl_index: InternPool.DeclIndex,2932 nav: InternPool.Nav.Index,
2933) link.File.UpdateDeclError!void {2933) link.File.UpdateNavError!void {
2934 if (build_options.skip_non_native and builtin.object_format != .elf) {2934 if (build_options.skip_non_native and builtin.object_format != .elf) {
2935 @panic("Attempted to compile for object format that was disabled by build configuration");2935 @panic("Attempted to compile for object format that was disabled by build configuration");
2936 }2936 }
2937 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);2937 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
2938 return self.zigObjectPtr().?.updateDecl(self, pt, decl_index);2938 return self.zigObjectPtr().?.updateNav(self, pt, nav);
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);
2943}2939}
29442940
2945pub fn updateExports(2941pub fn updateExports(
...@@ -2955,9 +2951,9 @@ pub fn updateExports(...@@ -2955,9 +2951,9 @@ pub fn updateExports(
2955 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);2951 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
2956}2952}
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 {
2959 if (self.llvm_object) |_| return;2955 if (self.llvm_object) |_| return;
2960 return self.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);2956 return self.zigObjectPtr().?.updateNavLineNumber(pt, nav);
2961}2957}
29622958
2963pub fn deleteExport(2959pub fn deleteExport(
src/link/Elf/ZigObject.zig+223-322
...@@ -32,35 +32,14 @@ dwarf: ?Dwarf = null,...@@ -32,35 +32,14 @@ dwarf: ?Dwarf = null,
32/// Table of tracked LazySymbols.32/// Table of tracked LazySymbols.
33lazy_syms: LazySymbolTable = .{},33lazy_syms: LazySymbolTable = .{},
3434
35/// Table of tracked Decls.35/// Table of tracked `Nav`s.
36decls: DeclTable = .{},36navs: NavTable = .{},
3737
38/// TLS variables indexed by Atom.Index.38/// TLS variables indexed by Atom.Index.
39tls_variables: TlsTable = .{},39tls_variables: TlsTable = .{},
4040
41/// Table of unnamed constants associated with a parent `Decl`.41/// Table of tracked `Uav`s.
42/// We store them here so that we can free the constants whenever the `Decl`42uavs: UavTable = .{},
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 = .{},
6443
65debug_strtab_dirty: bool = false,44debug_strtab_dirty: bool = false,
66debug_abbrev_section_dirty: bool = false,45debug_abbrev_section_dirty: bool = false,
...@@ -124,29 +103,21 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -124,29 +103,21 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
124 self.relocs.deinit(allocator);103 self.relocs.deinit(allocator);
125104
126 {105 {
127 var it = self.decls.iterator();106 var it = self.navs.iterator();
128 while (it.next()) |entry| {107 while (it.next()) |entry| {
129 entry.value_ptr.exports.deinit(allocator);108 entry.value_ptr.exports.deinit(allocator);
130 }109 }
131 self.decls.deinit(allocator);110 self.navs.deinit(allocator);
132 }111 }
133112
134 self.lazy_syms.deinit(allocator);113 self.lazy_syms.deinit(allocator);
135114
136 {115 {
137 var it = self.unnamed_consts.valueIterator();116 var it = self.uavs.iterator();
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();
146 while (it.next()) |entry| {117 while (it.next()) |entry| {
147 entry.value_ptr.exports.deinit(allocator);118 entry.value_ptr.exports.deinit(allocator);
148 }119 }
149 self.anon_decls.deinit(allocator);120 self.uavs.deinit(allocator);
150 }121 }
151122
152 for (self.tls_variables.values()) |*tlv| {123 for (self.tls_variables.values()) |*tlv| {
...@@ -161,7 +132,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -161,7 +132,7 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
161132
162pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {133pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
163 // Handle any lazy symbols that were emitted by incremental compilation.134 // 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| {
165 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };136 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };
166137
167 // Most lazy symbols can be updated on first use, but138 // 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...@@ -169,7 +140,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
169 if (metadata.text_state != .unused) self.updateLazySymbol(140 if (metadata.text_state != .unused) self.updateLazySymbol(
170 elf_file,141 elf_file,
171 pt,142 pt,
172 link.File.LazySymbol.initDecl(.code, null, pt.zcu),143 .{ .kind = .code, .ty = .anyerror_type },
173 metadata.text_symbol_index,144 metadata.text_symbol_index,
174 ) catch |err| return switch (err) {145 ) catch |err| return switch (err) {
175 error.CodegenFail => error.FlushFailure,146 error.CodegenFail => error.FlushFailure,
...@@ -178,7 +149,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -178,7 +149,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
178 if (metadata.rodata_state != .unused) self.updateLazySymbol(149 if (metadata.rodata_state != .unused) self.updateLazySymbol(
179 elf_file,150 elf_file,
180 pt,151 pt,
181 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),152 .{ .kind = .const_data, .ty = .anyerror_type },
182 metadata.rodata_symbol_index,153 metadata.rodata_symbol_index,
183 ) catch |err| return switch (err) {154 ) catch |err| return switch (err) {
184 error.CodegenFail => error.FlushFailure,155 error.CodegenFail => error.FlushFailure,
...@@ -661,25 +632,25 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8...@@ -661,25 +632,25 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8
661 return code;632 return code;
662}633}
663634
664pub fn getDeclVAddr(635pub fn getNavVAddr(
665 self: *ZigObject,636 self: *ZigObject,
666 elf_file: *Elf,637 elf_file: *Elf,
667 pt: Zcu.PerThread,638 pt: Zcu.PerThread,
668 decl_index: InternPool.DeclIndex,639 nav_index: InternPool.Nav.Index,
669 reloc_info: link.File.RelocInfo,640 reloc_info: link.File.RelocInfo,
670) !u64 {641) !u64 {
671 const zcu = pt.zcu;642 const zcu = pt.zcu;
672 const ip = &zcu.intern_pool;643 const ip = &zcu.intern_pool;
673 const decl = zcu.declPtr(decl_index);644 const nav = ip.getNav(nav_index);
674 log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index });645 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
675 const this_sym_index = if (decl.isExtern(zcu)) blk: {646 const this_sym_index = switch (ip.indexToKey(nav.status.resolved.val)) {
676 const name = decl.name.toSlice(ip);647 .@"extern" => |@"extern"| try self.getGlobalSymbol(
677 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|648 elf_file,
678 ext_fn.lib_name.toSlice(ip)649 nav.name.toSlice(ip),
679 else650 @"extern".lib_name.toSlice(ip),
680 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);651 ),
681 break :blk try self.getGlobalSymbol(elf_file, name, lib_name);652 else => try self.getOrCreateMetadataForNav(elf_file, nav_index),
682 } else try self.getOrCreateMetadataForDecl(elf_file, decl_index);653 };
683 const this_sym = self.symbol(this_sym_index);654 const this_sym = self.symbol(this_sym_index);
684 const vaddr = this_sym.address(.{}, elf_file);655 const vaddr = this_sym.address(.{}, elf_file);
685 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;656 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
...@@ -692,13 +663,13 @@ pub fn getDeclVAddr(...@@ -692,13 +663,13 @@ pub fn getDeclVAddr(
692 return @intCast(vaddr);663 return @intCast(vaddr);
693}664}
694665
695pub fn getAnonDeclVAddr(666pub fn getUavVAddr(
696 self: *ZigObject,667 self: *ZigObject,
697 elf_file: *Elf,668 elf_file: *Elf,
698 decl_val: InternPool.Index,669 uav: InternPool.Index,
699 reloc_info: link.File.RelocInfo,670 reloc_info: link.File.RelocInfo,
700) !u64 {671) !u64 {
701 const sym_index = self.anon_decls.get(decl_val).?.symbol_index;672 const sym_index = self.uavs.get(uav).?.symbol_index;
702 const sym = self.symbol(sym_index);673 const sym = self.symbol(sym_index);
703 const vaddr = sym.address(.{}, elf_file);674 const vaddr = sym.address(.{}, elf_file);
704 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;675 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
...@@ -711,43 +682,43 @@ pub fn getAnonDeclVAddr(...@@ -711,43 +682,43 @@ pub fn getAnonDeclVAddr(
711 return @intCast(vaddr);682 return @intCast(vaddr);
712}683}
713684
714pub fn lowerAnonDecl(685pub fn lowerUav(
715 self: *ZigObject,686 self: *ZigObject,
716 elf_file: *Elf,687 elf_file: *Elf,
717 pt: Zcu.PerThread,688 pt: Zcu.PerThread,
718 decl_val: InternPool.Index,689 uav: InternPool.Index,
719 explicit_alignment: InternPool.Alignment,690 explicit_alignment: InternPool.Alignment,
720 src_loc: Module.LazySrcLoc,691 src_loc: Zcu.LazySrcLoc,
721) !codegen.Result {692) !codegen.GenResult {
722 const gpa = elf_file.base.comp.gpa;693 const zcu = pt.zcu;
723 const mod = elf_file.base.comp.module.?;694 const gpa = zcu.gpa;
724 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));695 const val = Value.fromInterned(uav);
725 const decl_alignment = switch (explicit_alignment) {696 const uav_alignment = switch (explicit_alignment) {
726 .none => ty.abiAlignment(pt),697 .none => val.typeOf(zcu).abiAlignment(pt),
727 else => explicit_alignment,698 else => explicit_alignment,
728 };699 };
729 if (self.anon_decls.get(decl_val)) |metadata| {700 if (self.uavs.get(uav)) |metadata| {
730 const existing_alignment = self.symbol(metadata.symbol_index).atom(elf_file).?.alignment;701 const sym = self.symbol(metadata.symbol_index);
731 if (decl_alignment.order(existing_alignment).compare(.lte))702 const existing_alignment = sym.atom(elf_file).?.alignment;
732 return .ok;703 if (uav_alignment.order(existing_alignment).compare(.lte))
704 return .{ .mcv = .{ .load_symbol = metadata.symbol_index } };
733 }705 }
734706
735 const val = Value.fromInterned(decl_val);
736 var name_buf: [32]u8 = undefined;707 var name_buf: [32]u8 = undefined;
737 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{708 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
738 @intFromEnum(decl_val),709 @intFromEnum(uav),
739 }) catch unreachable;710 }) catch unreachable;
740 const res = self.lowerConst(711 const res = self.lowerConst(
741 elf_file,712 elf_file,
742 pt,713 pt,
743 name,714 name,
744 val,715 val,
745 decl_alignment,716 uav_alignment,
746 elf_file.zig_data_rel_ro_section_index.?,717 elf_file.zig_data_rel_ro_section_index.?,
747 src_loc,718 src_loc,
748 ) catch |err| switch (err) {719 ) catch |err| switch (err) {
749 error.OutOfMemory => return error.OutOfMemory,720 error.OutOfMemory => return error.OutOfMemory,
750 else => |e| return .{ .fail = try Module.ErrorMsg.create(721 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
751 gpa,722 gpa,
752 src_loc,723 src_loc,
753 "unable to lower constant value: {s}",724 "unable to lower constant value: {s}",
...@@ -758,8 +729,8 @@ pub fn lowerAnonDecl(...@@ -758,8 +729,8 @@ pub fn lowerAnonDecl(
758 .ok => |sym_index| sym_index,729 .ok => |sym_index| sym_index,
759 .fail => |em| return .{ .fail = em },730 .fail => |em| return .{ .fail = em },
760 };731 };
761 try self.anon_decls.put(gpa, decl_val, .{ .symbol_index = sym_index });732 try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index });
762 return .ok;733 return .{ .mcv = .{ .load_symbol = sym_index } };
763}734}
764735
765pub fn getOrCreateMetadataForLazySymbol(736pub fn getOrCreateMetadataForLazySymbol(
...@@ -768,51 +739,32 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -768,51 +739,32 @@ pub fn getOrCreateMetadataForLazySymbol(
768 pt: Zcu.PerThread,739 pt: Zcu.PerThread,
769 lazy_sym: link.File.LazySymbol,740 lazy_sym: link.File.LazySymbol,
770) !Symbol.Index {741) !Symbol.Index {
771 const mod = pt.zcu;742 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
772 const gpa = mod.gpa;
773 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
774 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();743 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
775 if (!gop.found_existing) gop.value_ptr.* = .{};744 if (!gop.found_existing) gop.value_ptr.* = .{};
776 const metadata: struct {745 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
777 symbol_index: *Symbol.Index,746 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },
778 state: *LazySymbolMetadata.State,747 .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_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 },
788 };748 };
789 switch (metadata.state.*) {749 switch (state_ptr.*) {
790 .unused => {750 .unused => {
751 const gpa = elf_file.base.comp.gpa;
791 const symbol_index = try self.newSymbolWithAtom(gpa, 0);752 const symbol_index = try self.newSymbolWithAtom(gpa, 0);
792 const sym = self.symbol(symbol_index);753 const sym = self.symbol(symbol_index);
793 sym.flags.needs_zig_got = true;754 sym.flags.needs_zig_got = true;
794 metadata.symbol_index.* = symbol_index;755 symbol_index_ptr.* = symbol_index;
795 },756 },
796 .pending_flush => return metadata.symbol_index.*,757 .pending_flush => return symbol_index_ptr.*,
797 .flushed => {},758 .flushed => {},
798 }759 }
799 metadata.state.* = .pending_flush;760 state_ptr.* = .pending_flush;
800 const symbol_index = metadata.symbol_index.*;761 const symbol_index = symbol_index_ptr.*;
801 // anyerror needs to be deferred until flushModule762 // 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);
803 return symbol_index;764 return symbol_index;
804}765}
805766
806fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void {767fn freeNavMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) 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 {
816 const sym = self.symbol(sym_index);768 const sym = self.symbol(sym_index);
817 sym.atom(elf_file).?.free(elf_file);769 sym.atom(elf_file).?.free(elf_file);
818 log.debug("adding %{d} to local symbols free list", .{sym_index});770 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...@@ -820,38 +772,37 @@ fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) v
820 // TODO free GOT entry here772 // TODO free GOT entry here
821}773}
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 {
824 const gpa = elf_file.base.comp.gpa;776 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| {
829 var kv = const_kv;781 var kv = const_kv;
830 const sym_index = kv.value.symbol_index;782 const sym_index = kv.value.symbol_index;
831 self.freeDeclMetadata(elf_file, sym_index);783 self.freeNavMetadata(elf_file, sym_index);
832 self.freeUnnamedConsts(elf_file, decl_index);
833 kv.value.exports.deinit(gpa);784 kv.value.exports.deinit(gpa);
834 }785 }
835786
836 if (self.dwarf) |*dw| {787 if (self.dwarf) |*dw| {
837 dw.freeDecl(decl_index);788 dw.freeNav(nav_index);
838 }789 }
839}790}
840791
841pub fn getOrCreateMetadataForDecl(792pub fn getOrCreateMetadataForNav(
842 self: *ZigObject,793 self: *ZigObject,
843 elf_file: *Elf,794 elf_file: *Elf,
844 decl_index: InternPool.DeclIndex,795 nav_index: InternPool.Nav.Index,
845) !Symbol.Index {796) !Symbol.Index {
846 const gpa = elf_file.base.comp.gpa;797 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);
848 if (!gop.found_existing) {799 if (!gop.found_existing) {
849 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;800 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
850 const symbol_index = try self.newSymbolWithAtom(gpa, 0);801 const symbol_index = try self.newSymbolWithAtom(gpa, 0);
851 const mod = elf_file.base.comp.module.?;802 const zcu = elf_file.base.comp.module.?;
852 const decl = mod.declPtr(decl_index);803 const nav_val = Value.fromInterned(zcu.intern_pool.getNav(nav_index).status.resolved.val);
853 const sym = self.symbol(symbol_index);804 const sym = self.symbol(symbol_index);
854 if (decl.getOwnedVariable(mod)) |variable| {805 if (nav_val.getVariable(zcu)) |variable| {
855 if (variable.is_threadlocal and any_non_single_threaded) {806 if (variable.is_threadlocal and any_non_single_threaded) {
856 sym.flags.is_tls = true;807 sym.flags.is_tls = true;
857 }808 }
...@@ -864,89 +815,81 @@ pub fn getOrCreateMetadataForDecl(...@@ -864,89 +815,81 @@ pub fn getOrCreateMetadataForDecl(
864 return gop.value_ptr.symbol_index;815 return gop.value_ptr.symbol_index;
865}816}
866817
867fn getDeclShdrIndex(818fn getNavShdrIndex(
868 self: *ZigObject,819 self: *ZigObject,
869 elf_file: *Elf,820 elf_file: *Elf,
870 decl: *const Module.Decl,821 zcu: *Zcu,
822 nav_index: InternPool.Nav.Index,
871 code: []const u8,823 code: []const u8,
872) error{OutOfMemory}!u32 {824) error{OutOfMemory}!u32 {
873 _ = self;825 _ = self;
874 const mod = elf_file.base.comp.module.?;826 const ip = &zcu.intern_pool;
875 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;827 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
876 const shdr_index = switch (decl.typeOf(mod).zigTypeTag(mod)) {828 const nav_val = zcu.navValue(nav_index);
877 .Fn => elf_file.zig_text_section_index.?,829 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return elf_file.zig_text_section_index.?;
878 else => blk: {830 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
879 if (decl.getOwnedVariable(mod)) |variable| {831 .variable => |variable| .{ false, variable.is_threadlocal, variable.init },
880 if (variable.is_threadlocal and any_non_single_threaded) {832 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
881 const is_all_zeroes = for (code) |byte| {833 else => .{ true, false, nav_val.toIntern() },
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 },
917 };834 };
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.?;
919}861}
920862
921fn updateDeclCode(863fn updateNavCode(
922 self: *ZigObject,864 self: *ZigObject,
923 elf_file: *Elf,865 elf_file: *Elf,
924 pt: Zcu.PerThread,866 pt: Zcu.PerThread,
925 decl_index: InternPool.DeclIndex,867 nav_index: InternPool.Nav.Index,
926 sym_index: Symbol.Index,868 sym_index: Symbol.Index,
927 shdr_index: u32,869 shdr_index: u32,
928 code: []const u8,870 code: []const u8,
929 stt_bits: u8,871 stt_bits: u8,
930) !void {872) !void {
931 const gpa = elf_file.base.comp.gpa;873 const zcu = pt.zcu;
932 const mod = pt.zcu;874 const gpa = zcu.gpa;
933 const ip = &mod.intern_pool;875 const ip = &zcu.intern_pool;
934 const decl = mod.declPtr(decl_index);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(880 const required_alignment = pt.navAlignment(nav_index).max(
939 target_util.minFunctionAlignment(mod.getTarget()),881 target_util.minFunctionAlignment(zcu.navFileScope(nav_index).mod.resolved_target.result),
940 );882 );
941883
942 const sym = self.symbol(sym_index);884 const sym = self.symbol(sym_index);
943 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];885 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
944 const atom_ptr = sym.atom(elf_file).?;886 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
947 atom_ptr.alive = true;889 atom_ptr.alive = true;
948 atom_ptr.name_offset = name_offset;890 atom_ptr.name_offset = name_offset;
949 atom_ptr.output_section_index = shdr_index;891 atom_ptr.output_section_index = shdr_index;
892
950 sym.name_offset = name_offset;893 sym.name_offset = name_offset;
951 esym.st_name = name_offset;894 esym.st_name = name_offset;
952 esym.st_info |= stt_bits;895 esym.st_info |= stt_bits;
...@@ -962,7 +905,7 @@ fn updateDeclCode(...@@ -962,7 +905,7 @@ fn updateDeclCode(
962 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));905 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));
963 if (need_realloc) {906 if (need_realloc) {
964 try atom_ptr.grow(elf_file);907 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 });
966 if (old_vaddr != atom_ptr.value) {909 if (old_vaddr != atom_ptr.value) {
967 sym.value = 0;910 sym.value = 0;
968 esym.st_value = 0;911 esym.st_value = 0;
...@@ -979,7 +922,7 @@ fn updateDeclCode(...@@ -979,7 +922,7 @@ fn updateDeclCode(
979 }922 }
980 } else {923 } else {
981 try atom_ptr.allocate(elf_file);924 try atom_ptr.allocate(elf_file);
982 errdefer self.freeDeclMetadata(elf_file, sym_index);925 errdefer self.freeNavMetadata(elf_file, sym_index);
983926
984 sym.value = 0;927 sym.value = 0;
985 sym.flags.needs_zig_got = true;928 sym.flags.needs_zig_got = true;
...@@ -1023,24 +966,24 @@ fn updateTlv(...@@ -1023,24 +966,24 @@ fn updateTlv(
1023 self: *ZigObject,966 self: *ZigObject,
1024 elf_file: *Elf,967 elf_file: *Elf,
1025 pt: Zcu.PerThread,968 pt: Zcu.PerThread,
1026 decl_index: InternPool.DeclIndex,969 nav_index: InternPool.Nav.Index,
1027 sym_index: Symbol.Index,970 sym_index: Symbol.Index,
1028 shndx: u32,971 shndx: u32,
1029 code: []const u8,972 code: []const u8,
1030) !void {973) !void {
1031 const mod = pt.zcu;974 const zcu = pt.zcu;
1032 const ip = &mod.intern_pool;975 const ip = &zcu.intern_pool;
1033 const gpa = mod.gpa;976 const gpa = zcu.gpa;
1034 const decl = mod.declPtr(decl_index);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
1040 const sym = self.symbol(sym_index);983 const sym = self.symbol(sym_index);
1041 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];984 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
1042 const atom_ptr = sym.atom(elf_file).?;985 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
1045 sym.value = 0;988 sym.value = 0;
1046 sym.name_offset = name_offset;989 sym.name_offset = name_offset;
...@@ -1049,6 +992,7 @@ fn updateTlv(...@@ -1049,6 +992,7 @@ fn updateTlv(
1049 atom_ptr.alive = true;992 atom_ptr.alive = true;
1050 atom_ptr.name_offset = name_offset;993 atom_ptr.name_offset = name_offset;
1051994
995 sym.name_offset = name_offset;
1052 esym.st_value = 0;996 esym.st_value = 0;
1053 esym.st_name = name_offset;997 esym.st_name = name_offset;
1054 esym.st_info = elf.STT_TLS;998 esym.st_info = elf.STT_TLS;
...@@ -1086,53 +1030,49 @@ pub fn updateFunc(...@@ -1086,53 +1030,49 @@ pub fn updateFunc(
1086 const tracy = trace(@src());1030 const tracy = trace(@src());
1087 defer tracy.end();1031 defer tracy.end();
10881032
1089 const mod = pt.zcu;1033 const zcu = pt.zcu;
1090 const ip = &mod.intern_pool;1034 const ip = &zcu.intern_pool;
1091 const gpa = elf_file.base.comp.gpa;1035 const gpa = elf_file.base.comp.gpa;
1092 const func = mod.funcInfo(func_index);1036 const func = zcu.funcInfo(func_index);
1093 const decl_index = func.owner_decl;
1094 const decl = mod.declPtr(decl_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);1040 const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);
1099 self.freeUnnamedConsts(elf_file, decl_index);
1100 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);1041 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
11011042
1102 var code_buffer = std.ArrayList(u8).init(gpa);1043 var code_buffer = std.ArrayList(u8).init(gpa);
1103 defer code_buffer.deinit();1044 defer code_buffer.deinit();
11041045
1105 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;1046 var dwarf_state = if (self.dwarf) |*dw| try dw.initNavState(pt, func.owner_nav) else null;
1106 defer if (decl_state) |*ds| ds.deinit();1047 defer if (dwarf_state) |*ds| ds.deinit();
11071048
1108 const res = try codegen.generateFunction(1049 const res = try codegen.generateFunction(
1109 &elf_file.base,1050 &elf_file.base,
1110 pt,1051 pt,
1111 decl.navSrcLoc(mod),1052 zcu.navSrcLoc(func.owner_nav),
1112 func_index,1053 func_index,
1113 air,1054 air,
1114 liveness,1055 liveness,
1115 &code_buffer,1056 &code_buffer,
1116 if (decl_state) |*ds| .{ .dwarf = ds } else .none,1057 if (dwarf_state) |*ds| .{ .dwarf = ds } else .none,
1117 );1058 );
11181059
1119 const code = switch (res) {1060 const code = switch (res) {
1120 .ok => code_buffer.items,1061 .ok => code_buffer.items,
1121 .fail => |em| {1062 .fail => |em| {
1122 func.setAnalysisState(&mod.intern_pool, .codegen_failure);1063 try zcu.failed_codegen.put(gpa, func.owner_nav, em);
1123 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1124 return;1064 return;
1125 },1065 },
1126 };1066 };
11271067
1128 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);1068 const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, code);
1129 try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC);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| {
1132 const sym = self.symbol(sym_index);1072 const sym = self.symbol(sym_index);
1133 try self.dwarf.?.commitDeclState(1073 try self.dwarf.?.commitNavState(
1134 pt,1074 pt,
1135 decl_index,1075 func.owner_nav,
1136 @intCast(sym.address(.{}, elf_file)),1076 @intCast(sym.address(.{}, elf_file)),
1137 sym.atom(elf_file).?.size,1077 sym.atom(elf_file).?.size,
1138 ds,1078 ds,
...@@ -1142,78 +1082,80 @@ pub fn updateFunc(...@@ -1142,78 +1082,80 @@ pub fn updateFunc(
1142 // Exports will be updated by `Zcu.processExports` after the update.1082 // Exports will be updated by `Zcu.processExports` after the update.
1143}1083}
11441084
1145pub fn updateDecl(1085pub fn updateNav(
1146 self: *ZigObject,1086 self: *ZigObject,
1147 elf_file: *Elf,1087 elf_file: *Elf,
1148 pt: Zcu.PerThread,1088 pt: Zcu.PerThread,
1149 decl_index: InternPool.DeclIndex,1089 nav_index: InternPool.Nav.Index,
1150) link.File.UpdateDeclError!void {1090) link.File.UpdateNavError!void {
1151 const tracy = trace(@src());1091 const tracy = trace(@src());
1152 defer tracy.end();1092 defer tracy.end();
11531093
1154 const mod = pt.zcu;1094 const zcu = pt.zcu;
1155 const ip = &mod.intern_pool;1095 const ip = &zcu.intern_pool;
1156 const decl = mod.declPtr(decl_index);1096 const nav = ip.getNav(nav_index);
11571097
1158 log.debug("updateDecl {}({d})", .{ decl.fqn.fmt(ip), decl_index });1098 log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index });
11591099
1160 if (decl.val.getExternFunc(mod)) |_| return;1100 const nav_val = zcu.navValue(nav_index);
1161 if (decl.isExtern(mod)) {1101 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
1162 // Extern variable gets a .got entry only.1102 .variable => |variable| Value.fromInterned(variable.init),
1163 const variable = decl.getOwnedVariable(mod).?;1103 .@"extern" => |@"extern"| {
1164 const name = decl.name.toSlice(&mod.intern_pool);1104 if (ip.isFunctionType(@"extern".ty)) return;
1165 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);1105 // Extern variable gets a .got entry only.
1166 const sym_index = try self.getGlobalSymbol(elf_file, name, lib_name);1106 const sym_index = try self.getGlobalSymbol(
1167 self.symbol(sym_index).flags.needs_got = true;1107 elf_file,
1168 return;1108 nav.name.toSlice(ip),
1169 }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);
1172 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);1118 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
11731119
1174 const gpa = elf_file.base.comp.gpa;1120 var code_buffer = std.ArrayList(u8).init(zcu.gpa);
1175 var code_buffer = std.ArrayList(u8).init(gpa);
1176 defer code_buffer.deinit();1121 defer code_buffer.deinit();
11771122
1178 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;1123 var nav_state: ?Dwarf.NavState = if (self.dwarf) |*dw| try dw.initNavState(pt, nav_index) else null;
1179 defer if (decl_state) |*ds| ds.deinit();1124 defer if (nav_state) |*ns| ns.deinit();
11801125
1181 // TODO implement .debug_info for global variables1126 // TODO implement .debug_info for global variables
1182 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;1127 const res = try codegen.generateSymbol(
1183 const res = if (decl_state) |*ds|1128 &elf_file.base,
1184 try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .{1129 pt,
1185 .dwarf = ds,1130 zcu.navSrcLoc(nav_index),
1186 }, .{1131 nav_init,
1187 .parent_atom_index = sym_index,1132 &code_buffer,
1188 })1133 if (nav_state) |*ns| .{ .dwarf = ns } else .none,
1189 else1134 .{ .parent_atom_index = sym_index },
1190 try codegen.generateSymbol(&elf_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, .none, .{1135 );
1191 .parent_atom_index = sym_index,
1192 });
11931136
1194 const code = switch (res) {1137 const code = switch (res) {
1195 .ok => code_buffer.items,1138 .ok => code_buffer.items,
1196 .fail => |em| {1139 .fail => |em| {
1197 decl.analysis = .codegen_failure;1140 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
1198 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
1199 return;1141 return;
1200 },1142 },
1201 };1143 };
12021144
1203 const shndx = try self.getDeclShdrIndex(elf_file, decl, code);1145 const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, code);
1204 if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0)1146 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)
1206 else1148 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| {
1210 const sym = self.symbol(sym_index);1152 const sym = self.symbol(sym_index);
1211 try self.dwarf.?.commitDeclState(1153 try self.dwarf.?.commitNavState(
1212 pt,1154 pt,
1213 decl_index,1155 nav_index,
1214 @intCast(sym.address(.{}, elf_file)),1156 @intCast(sym.address(.{}, elf_file)),
1215 sym.atom(elf_file).?.size,1157 sym.atom(elf_file).?.size,
1216 ds,1158 ns,
1217 );1159 );
1218 }1160 }
12191161
...@@ -1237,13 +1179,13 @@ fn updateLazySymbol(...@@ -1237,13 +1179,13 @@ fn updateLazySymbol(
1237 const name_str_index = blk: {1179 const name_str_index = blk: {
1238 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1180 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1239 @tagName(sym.kind),1181 @tagName(sym.kind),
1240 sym.ty.fmt(pt),1182 Type.fromInterned(sym.ty).fmt(pt),
1241 });1183 });
1242 defer gpa.free(name);1184 defer gpa.free(name);
1243 break :blk try self.strtab.insert(gpa, name);1185 break :blk try self.strtab.insert(gpa, name);
1244 };1186 };
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;
1247 const res = try codegen.generateLazySymbol(1189 const res = try codegen.generateLazySymbol(
1248 &elf_file.base,1190 &elf_file.base,
1249 pt,1191 pt,
...@@ -1280,7 +1222,7 @@ fn updateLazySymbol(...@@ -1280,7 +1222,7 @@ fn updateLazySymbol(
1280 atom_ptr.output_section_index = output_section_index;1222 atom_ptr.output_section_index = output_section_index;
12811223
1282 try atom_ptr.allocate(elf_file);1224 try atom_ptr.allocate(elf_file);
1283 errdefer self.freeDeclMetadata(elf_file, symbol_index);1225 errdefer self.freeNavMetadata(elf_file, symbol_index);
12841226
1285 local_sym.value = 0;1227 local_sym.value = 0;
1286 local_sym.flags.needs_zig_got = true;1228 local_sym.flags.needs_zig_got = true;
...@@ -1296,49 +1238,9 @@ fn updateLazySymbol(...@@ -1296,49 +1238,9 @@ fn updateLazySymbol(
1296 try elf_file.base.file.?.pwriteAll(code, file_offset);1238 try elf_file.base.file.?.pwriteAll(code, file_offset);
1297}1239}
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
1339const LowerConstResult = union(enum) {1241const LowerConstResult = union(enum) {
1340 ok: Symbol.Index,1242 ok: Symbol.Index,
1341 fail: *Module.ErrorMsg,1243 fail: *Zcu.ErrorMsg,
1342};1244};
13431245
1344fn lowerConst(1246fn lowerConst(
...@@ -1349,7 +1251,7 @@ fn lowerConst(...@@ -1349,7 +1251,7 @@ fn lowerConst(
1349 val: Value,1251 val: Value,
1350 required_alignment: InternPool.Alignment,1252 required_alignment: InternPool.Alignment,
1351 output_section_index: u32,1253 output_section_index: u32,
1352 src_loc: Module.LazySrcLoc,1254 src_loc: Zcu.LazySrcLoc,
1353) !LowerConstResult {1255) !LowerConstResult {
1354 const gpa = pt.zcu.gpa;1256 const gpa = pt.zcu.gpa;
13551257
...@@ -1384,7 +1286,8 @@ fn lowerConst(...@@ -1384,7 +1286,8 @@ fn lowerConst(
1384 atom_ptr.output_section_index = output_section_index;1286 atom_ptr.output_section_index = output_section_index;
13851287
1386 try atom_ptr.allocate(elf_file);1288 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
1389 const shdr = elf_file.shdrs.items[output_section_index];1292 const shdr = elf_file.shdrs.items[output_section_index];
1390 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));1293 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
...@@ -1397,7 +1300,7 @@ pub fn updateExports(...@@ -1397,7 +1300,7 @@ pub fn updateExports(
1397 self: *ZigObject,1300 self: *ZigObject,
1398 elf_file: *Elf,1301 elf_file: *Elf,
1399 pt: Zcu.PerThread,1302 pt: Zcu.PerThread,
1400 exported: Module.Exported,1303 exported: Zcu.Exported,
1401 export_indices: []const u32,1304 export_indices: []const u32,
1402) link.File.UpdateExportsError!void {1305) link.File.UpdateExportsError!void {
1403 const tracy = trace(@src());1306 const tracy = trace(@src());
...@@ -1406,24 +1309,24 @@ pub fn updateExports(...@@ -1406,24 +1309,24 @@ pub fn updateExports(
1406 const mod = pt.zcu;1309 const mod = pt.zcu;
1407 const gpa = elf_file.base.comp.gpa;1310 const gpa = elf_file.base.comp.gpa;
1408 const metadata = switch (exported) {1311 const metadata = switch (exported) {
1409 .decl_index => |decl_index| blk: {1312 .nav => |nav| blk: {
1410 _ = try self.getOrCreateMetadataForDecl(elf_file, decl_index);1313 _ = try self.getOrCreateMetadataForNav(elf_file, nav);
1411 break :blk self.decls.getPtr(decl_index).?;1314 break :blk self.navs.getPtr(nav).?;
1412 },1315 },
1413 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1316 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1414 const first_exp = mod.all_exports.items[export_indices[0]];1317 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);
1416 switch (res) {1319 switch (res) {
1417 .ok => {},1320 .mcv => {},
1418 .fail => |em| {1321 .fail => |em| {
1419 // TODO maybe it's enough to return an error here and let Module.processExportsInner1322 // TODO maybe it's enough to return an error here and let Zcu.processExportsInner
1420 // handle the error?1323 // handle the error?
1421 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);1324 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
1422 mod.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);1325 mod.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);
1423 return;1326 return;
1424 },1327 },
1425 }1328 }
1426 break :blk self.anon_decls.getPtr(value).?;1329 break :blk self.uavs.getPtr(uav).?;
1427 },1330 },
1428 };1331 };
1429 const sym_index = metadata.symbol_index;1332 const sym_index = metadata.symbol_index;
...@@ -1436,7 +1339,7 @@ pub fn updateExports(...@@ -1436,7 +1339,7 @@ pub fn updateExports(
1436 if (exp.opts.section.unwrap()) |section_name| {1339 if (exp.opts.section.unwrap()) |section_name| {
1437 if (!section_name.eqlSlice(".text", &mod.intern_pool)) {1340 if (!section_name.eqlSlice(".text", &mod.intern_pool)) {
1438 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);1341 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(
1440 gpa,1343 gpa,
1441 exp.src,1344 exp.src,
1442 "Unimplemented: ExportOptions.section",1345 "Unimplemented: ExportOptions.section",
...@@ -1451,7 +1354,7 @@ pub fn updateExports(...@@ -1451,7 +1354,7 @@ pub fn updateExports(
1451 .weak => elf.STB_WEAK,1354 .weak => elf.STB_WEAK,
1452 .link_once => {1355 .link_once => {
1453 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);1356 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(
1455 gpa,1358 gpa,
1456 exp.src,1359 exp.src,
1457 "Unimplemented: GlobalLinkage.LinkOnce",1360 "Unimplemented: GlobalLinkage.LinkOnce",
...@@ -1487,21 +1390,22 @@ pub fn updateExports(...@@ -1487,21 +1390,22 @@ pub fn updateExports(
1487 }1390 }
1488}1391}
14891392
1490/// Must be called only after a successful call to `updateDecl`.1393/// Must be called only after a successful call to `updateNav`.
1491pub fn updateDeclLineNumber(1394pub fn updateNavLineNumber(
1492 self: *ZigObject,1395 self: *ZigObject,
1493 pt: Zcu.PerThread,1396 pt: Zcu.PerThread,
1494 decl_index: InternPool.DeclIndex,1397 nav_index: InternPool.Nav.Index,
1495) !void {1398) !void {
1496 const tracy = trace(@src());1399 const tracy = trace(@src());
1497 defer tracy.end();1400 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
1503 if (self.dwarf) |*dw| {1407 if (self.dwarf) |*dw| {
1504 try dw.updateDeclLineNumber(pt.zcu, decl_index);1408 try dw.updateNavLineNumber(pt.zcu, nav_index);
1505 }1409 }
1506}1410}
15071411
...@@ -1512,9 +1416,9 @@ pub fn deleteExport(...@@ -1512,9 +1416,9 @@ pub fn deleteExport(
1512 name: InternPool.NullTerminatedString,1416 name: InternPool.NullTerminatedString,
1513) void {1417) void {
1514 const metadata = switch (exported) {1418 const metadata = switch (exported) {
1515 .decl_index => |decl_index| self.decls.getPtr(decl_index) orelse return,1419 .nav => |nav| self.navs.getPtr(nav),
1516 .value => |value| self.anon_decls.getPtr(value) orelse return,1420 .uav => |uav| self.uavs.getPtr(uav),
1517 };1421 } orelse return;
1518 const mod = elf_file.base.comp.module.?;1422 const mod = elf_file.base.comp.module.?;
1519 const exp_name = name.toSlice(&mod.intern_pool);1423 const exp_name = name.toSlice(&mod.intern_pool);
1520 const esym_index = metadata.@"export"(self, exp_name) orelse return;1424 const esym_index = metadata.@"export"(self, exp_name) orelse return;
...@@ -1754,14 +1658,14 @@ const LazySymbolMetadata = struct {...@@ -1754,14 +1658,14 @@ const LazySymbolMetadata = struct {
1754 rodata_state: State = .unused,1658 rodata_state: State = .unused,
1755};1659};
17561660
1757const DeclMetadata = struct {1661const AvMetadata = struct {
1758 symbol_index: Symbol.Index,1662 symbol_index: Symbol.Index,
1759 /// A list of all exports aliases of this Decl.1663 /// A list of all exports aliases of this Av.
1760 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},1664 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 {
1763 for (m.exports.items) |*exp| {1667 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);
1765 if (mem.eql(u8, name, exp_name)) return exp;1669 if (mem.eql(u8, name, exp_name)) return exp;
1766 }1670 }
1767 return null;1671 return null;
...@@ -1778,10 +1682,9 @@ const TlsVariable = struct {...@@ -1778,10 +1682,9 @@ const TlsVariable = struct {
1778};1682};
17791683
1780const AtomList = std.ArrayListUnmanaged(Atom.Index);1684const AtomList = std.ArrayListUnmanaged(Atom.Index);
1781const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index));1685const NavTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1782const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);1686const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata);
1783const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);1687const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
1784const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
1785const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);1688const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
17861689
1787const assert = std.debug.assert;1690const assert = std.debug.assert;
...@@ -1792,8 +1695,8 @@ const link = @import("../../link.zig");...@@ -1792,8 +1695,8 @@ const link = @import("../../link.zig");
1792const log = std.log.scoped(.link);1695const log = std.log.scoped(.link);
1793const mem = std.mem;1696const mem = std.mem;
1794const relocation = @import("relocation.zig");1697const relocation = @import("relocation.zig");
1795const trace = @import("../../tracy.zig").trace;
1796const target_util = @import("../../target.zig");1698const target_util = @import("../../target.zig");
1699const trace = @import("../../tracy.zig").trace;
1797const std = @import("std");1700const std = @import("std");
17981701
1799const Air = @import("../../Air.zig");1702const Air = @import("../../Air.zig");
...@@ -1806,8 +1709,6 @@ const File = @import("file.zig").File;...@@ -1806,8 +1709,6 @@ const File = @import("file.zig").File;
1806const InternPool = @import("../../InternPool.zig");1709const InternPool = @import("../../InternPool.zig");
1807const Liveness = @import("../../Liveness.zig");1710const Liveness = @import("../../Liveness.zig");
1808const Zcu = @import("../../Zcu.zig");1711const Zcu = @import("../../Zcu.zig");
1809/// Deprecated.
1810const Module = Zcu;
1811const Object = @import("Object.zig");1712const Object = @import("Object.zig");
1812const Symbol = @import("Symbol.zig");1713const Symbol = @import("Symbol.zig");
1813const StringTable = @import("../StringTable.zig");1714const 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,...@@ -2998,21 +2998,17 @@ pub fn updateFunc(self: *MachO, pt: Zcu.PerThread, func_index: InternPool.Index,
2998 return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness);2998 return self.getZigObject().?.updateFunc(self, pt, func_index, air, liveness);
2999}2999}
30003000
3001pub fn lowerUnnamedConst(self: *MachO, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {3001pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
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 {
3006 if (build_options.skip_non_native and builtin.object_format != .macho) {3002 if (build_options.skip_non_native and builtin.object_format != .macho) {
3007 @panic("Attempted to compile for object format that was disabled by build configuration");3003 @panic("Attempted to compile for object format that was disabled by build configuration");
3008 }3004 }
3009 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);3005 if (self.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
3010 return self.getZigObject().?.updateDecl(self, pt, decl_index);3006 return self.getZigObject().?.updateNav(self, pt, nav);
3011}3007}
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 {
3014 if (self.llvm_object) |_| return;3010 if (self.llvm_object) |_| return;
3015 return self.getZigObject().?.updateDeclLineNumber(pt, decl_index);3011 return self.getZigObject().?.updateNavLineNumber(pt, nav);
3016}3012}
30173013
3018pub fn updateExports(3014pub fn updateExports(
...@@ -3037,29 +3033,29 @@ pub fn deleteExport(...@@ -3037,29 +3033,29 @@ pub fn deleteExport(
3037 return self.getZigObject().?.deleteExport(self, exported, name);3033 return self.getZigObject().?.deleteExport(self, exported, name);
3038}3034}
30393035
3040pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {3036pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {
3041 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);3037 if (self.llvm_object) |llvm_object| return llvm_object.freeNav(nav);
3042 return self.getZigObject().?.freeDecl(decl_index);3038 return self.getZigObject().?.freeNav(nav);
3043}3039}
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 {
3046 assert(self.llvm_object == null);3042 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);
3048}3044}
30493045
3050pub fn lowerAnonDecl(3046pub fn lowerUav(
3051 self: *MachO,3047 self: *MachO,
3052 pt: Zcu.PerThread,3048 pt: Zcu.PerThread,
3053 decl_val: InternPool.Index,3049 uav: InternPool.Index,
3054 explicit_alignment: InternPool.Alignment,3050 explicit_alignment: InternPool.Alignment,
3055 src_loc: Module.LazySrcLoc,3051 src_loc: Module.LazySrcLoc,
3056) !codegen.Result {3052) !codegen.GenResult {
3057 return self.getZigObject().?.lowerAnonDecl(self, pt, decl_val, explicit_alignment, src_loc);3053 return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment, src_loc);
3058}3054}
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 {
3061 assert(self.llvm_object == null);3057 assert(self.llvm_object == null);
3062 return self.getZigObject().?.getAnonDeclVAddr(self, decl_val, reloc_info);3058 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);
3063}3059}
30643060
3065pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {3061pub 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) {...@@ -4051,8 +4047,6 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {
40514047
4052const default_entry_symbol_name = "_main";4048const default_entry_symbol_name = "_main";
40534049
4054pub const base_tag: link.File.Tag = link.File.Tag.macho;
4055
4056const Section = struct {4050const Section = struct {
4057 header: macho.section_64,4051 header: macho.section_64,
4058 segment_id: u8,4052 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...@@ -992,6 +992,8 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r
992 const tracy = trace(@src());992 const tracy = trace(@src());
993 defer tracy.end();993 defer tracy.end();
994994
995 relocs_log.debug("{x}: {s}", .{ self.getAddress(macho_file), self.getName(macho_file) });
996
995 const cpu_arch = macho_file.getTarget().cpu.arch;997 const cpu_arch = macho_file.getTarget().cpu.arch;
996 const relocs = self.getRelocs(macho_file);998 const relocs = self.getRelocs(macho_file);
997999
...@@ -1015,6 +1017,24 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r...@@ -1015,6 +1017,24 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.r
1015 addend += target;1017 addend += target;
1016 }1018 }
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
1018 switch (cpu_arch) {1038 switch (cpu_arch) {
1019 .aarch64 => {1039 .aarch64 => {
1020 if (rel.type == .unsigned) switch (rel.meta.length) {1040 if (rel.type == .unsigned) switch (rel.meta.length) {
src/link/MachO/ZigObject.zig+225-329
...@@ -19,32 +19,11 @@ atoms_extra: std.ArrayListUnmanaged(u32) = .{},...@@ -19,32 +19,11 @@ atoms_extra: std.ArrayListUnmanaged(u32) = .{},
19/// Table of tracked LazySymbols.19/// Table of tracked LazySymbols.
20lazy_syms: LazySymbolTable = .{},20lazy_syms: LazySymbolTable = .{},
2121
22/// Table of tracked Decls.22/// Table of tracked Navs.
23decls: DeclTable = .{},23navs: NavTable = .{},
2424
25/// Table of unnamed constants associated with a parent `Decl`.25/// Table of tracked Uavs.
26/// We store them here so that we can free the constants whenever the `Decl`26uavs: UavTable = .{},
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 = .{},
4827
49/// TLV initializers indexed by Atom.Index.28/// TLV initializers indexed by Atom.Index.
50tlv_initializers: TlvInitializerTable = .{},29tlv_initializers: TlvInitializerTable = .{},
...@@ -100,31 +79,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -100,31 +79,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
100 self.atoms_indexes.deinit(allocator);79 self.atoms_indexes.deinit(allocator);
101 self.atoms_extra.deinit(allocator);80 self.atoms_extra.deinit(allocator);
10281
103 {82 for (self.navs.values()) |*meta| {
104 var it = self.decls.iterator();83 meta.exports.deinit(allocator);
105 while (it.next()) |entry| {
106 entry.value_ptr.exports.deinit(allocator);
107 }
108 self.decls.deinit(allocator);
109 }84 }
85 self.navs.deinit(allocator);
11086
111 self.lazy_syms.deinit(allocator);87 self.lazy_syms.deinit(allocator);
11288
113 {89 for (self.uavs.values()) |*meta| {
114 var it = self.unnamed_consts.valueIterator();90 meta.exports.deinit(allocator);
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);
127 }91 }
92 self.uavs.deinit(allocator);
12893
129 for (self.relocs.items) |*list| {94 for (self.relocs.items) |*list| {
130 list.deinit(allocator);95 list.deinit(allocator);
...@@ -601,7 +566,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se...@@ -601,7 +566,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se
601566
602pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) !void {567pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) !void {
603 // Handle any lazy symbols that were emitted by incremental compilation.568 // 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| {
605 const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid };570 const pt: Zcu.PerThread = .{ .zcu = macho_file.base.comp.module.?, .tid = tid };
606571
607 // Most lazy symbols can be updated on first use, but572 // 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)...@@ -609,7 +574,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
609 if (metadata.text_state != .unused) self.updateLazySymbol(574 if (metadata.text_state != .unused) self.updateLazySymbol(
610 macho_file,575 macho_file,
611 pt,576 pt,
612 link.File.LazySymbol.initDecl(.code, null, pt.zcu),577 .{ .kind = .code, .ty = .anyerror_type },
613 metadata.text_symbol_index,578 metadata.text_symbol_index,
614 ) catch |err| return switch (err) {579 ) catch |err| return switch (err) {
615 error.CodegenFail => error.FlushFailure,580 error.CodegenFail => error.FlushFailure,
...@@ -618,7 +583,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)...@@ -618,7 +583,7 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
618 if (metadata.const_state != .unused) self.updateLazySymbol(583 if (metadata.const_state != .unused) self.updateLazySymbol(
619 macho_file,584 macho_file,
620 pt,585 pt,
621 link.File.LazySymbol.initDecl(.const_data, null, pt.zcu),586 .{ .kind = .const_data, .ty = .anyerror_type },
622 metadata.const_symbol_index,587 metadata.const_symbol_index,
623 ) catch |err| return switch (err) {588 ) catch |err| return switch (err) {
624 error.CodegenFail => error.FlushFailure,589 error.CodegenFail => error.FlushFailure,
...@@ -691,25 +656,25 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)...@@ -691,25 +656,25 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id)
691 assert(!self.debug_strtab_dirty);656 assert(!self.debug_strtab_dirty);
692}657}
693658
694pub fn getDeclVAddr(659pub fn getNavVAddr(
695 self: *ZigObject,660 self: *ZigObject,
696 macho_file: *MachO,661 macho_file: *MachO,
697 pt: Zcu.PerThread,662 pt: Zcu.PerThread,
698 decl_index: InternPool.DeclIndex,663 nav_index: InternPool.Nav.Index,
699 reloc_info: link.File.RelocInfo,664 reloc_info: link.File.RelocInfo,
700) !u64 {665) !u64 {
701 const zcu = pt.zcu;666 const zcu = pt.zcu;
702 const ip = &zcu.intern_pool;667 const ip = &zcu.intern_pool;
703 const decl = zcu.declPtr(decl_index);668 const nav = ip.getNav(nav_index);
704 log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index });669 log.debug("getNavVAddr {}({d})", .{ nav.fqn.fmt(ip), nav_index });
705 const sym_index = if (decl.isExtern(zcu)) blk: {670 const sym_index = switch (ip.indexToKey(nav.status.resolved.val)) {
706 const name = decl.name.toSlice(ip);671 .@"extern" => |@"extern"| try self.getGlobalSymbol(
707 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|672 macho_file,
708 ext_fn.lib_name.toSlice(ip)673 nav.name.toSlice(ip),
709 else674 @"extern".lib_name.toSlice(ip),
710 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);675 ),
711 break :blk try self.getGlobalSymbol(macho_file, name, lib_name);676 else => try self.getOrCreateMetadataForNav(macho_file, nav_index),
712 } else try self.getOrCreateMetadataForDecl(macho_file, decl_index);677 };
713 const sym = self.symbols.items[sym_index];678 const sym = self.symbols.items[sym_index];
714 const vaddr = sym.getAddress(.{}, macho_file);679 const vaddr = sym.getAddress(.{}, macho_file);
715 const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;680 const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
...@@ -729,13 +694,13 @@ pub fn getDeclVAddr(...@@ -729,13 +694,13 @@ pub fn getDeclVAddr(
729 return vaddr;694 return vaddr;
730}695}
731696
732pub fn getAnonDeclVAddr(697pub fn getUavVAddr(
733 self: *ZigObject,698 self: *ZigObject,
734 macho_file: *MachO,699 macho_file: *MachO,
735 decl_val: InternPool.Index,700 uav: InternPool.Index,
736 reloc_info: link.File.RelocInfo,701 reloc_info: link.File.RelocInfo,
737) !u64 {702) !u64 {
738 const sym_index = self.anon_decls.get(decl_val).?.symbol_index;703 const sym_index = self.uavs.get(uav).?.symbol_index;
739 const sym = self.symbols.items[sym_index];704 const sym = self.symbols.items[sym_index];
740 const vaddr = sym.getAddress(.{}, macho_file);705 const vaddr = sym.getAddress(.{}, macho_file);
741 const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;706 const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
...@@ -755,42 +720,43 @@ pub fn getAnonDeclVAddr(...@@ -755,42 +720,43 @@ pub fn getAnonDeclVAddr(
755 return vaddr;720 return vaddr;
756}721}
757722
758pub fn lowerAnonDecl(723pub fn lowerUav(
759 self: *ZigObject,724 self: *ZigObject,
760 macho_file: *MachO,725 macho_file: *MachO,
761 pt: Zcu.PerThread,726 pt: Zcu.PerThread,
762 decl_val: InternPool.Index,727 uav: InternPool.Index,
763 explicit_alignment: Atom.Alignment,728 explicit_alignment: Atom.Alignment,
764 src_loc: Module.LazySrcLoc,729 src_loc: Zcu.LazySrcLoc,
765) !codegen.Result {730) !codegen.GenResult {
766 const gpa = macho_file.base.comp.gpa;731 const zcu = pt.zcu;
767 const mod = macho_file.base.comp.module.?;732 const gpa = zcu.gpa;
768 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));733 const val = Value.fromInterned(uav);
769 const decl_alignment = switch (explicit_alignment) {734 const uav_alignment = switch (explicit_alignment) {
770 .none => ty.abiAlignment(pt),735 .none => val.typeOf(zcu).abiAlignment(pt),
771 else => explicit_alignment,736 else => explicit_alignment,
772 };737 };
773 if (self.anon_decls.get(decl_val)) |metadata| {738 if (self.uavs.get(uav)) |metadata| {
774 const existing_alignment = self.symbols.items[metadata.symbol_index].getAtom(macho_file).?.alignment;739 const sym = self.symbols.items[metadata.symbol_index];
775 if (decl_alignment.order(existing_alignment).compare(.lte))740 const existing_alignment = sym.getAtom(macho_file).?.alignment;
776 return .ok;741 if (uav_alignment.order(existing_alignment).compare(.lte))
742 return .{ .mcv = .{ .load_symbol = sym.nlist_idx } };
777 }743 }
778744
779 var name_buf: [32]u8 = undefined;745 var name_buf: [32]u8 = undefined;
780 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{746 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
781 @intFromEnum(decl_val),747 @intFromEnum(uav),
782 }) catch unreachable;748 }) catch unreachable;
783 const res = self.lowerConst(749 const res = self.lowerConst(
784 macho_file,750 macho_file,
785 pt,751 pt,
786 name,752 name,
787 Value.fromInterned(decl_val),753 val,
788 decl_alignment,754 uav_alignment,
789 macho_file.zig_const_sect_index.?,755 macho_file.zig_const_sect_index.?,
790 src_loc,756 src_loc,
791 ) catch |err| switch (err) {757 ) catch |err| switch (err) {
792 error.OutOfMemory => return error.OutOfMemory,758 error.OutOfMemory => return error.OutOfMemory,
793 else => |e| return .{ .fail = try Module.ErrorMsg.create(759 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
794 gpa,760 gpa,
795 src_loc,761 src_loc,
796 "unable to lower constant value: {s}",762 "unable to lower constant value: {s}",
...@@ -801,20 +767,13 @@ pub fn lowerAnonDecl(...@@ -801,20 +767,13 @@ pub fn lowerAnonDecl(
801 .ok => |sym_index| sym_index,767 .ok => |sym_index| sym_index,
802 .fail => |em| return .{ .fail = em },768 .fail => |em| return .{ .fail = em },
803 };769 };
804 try self.anon_decls.put(gpa, decl_val, .{ .symbol_index = sym_index });770 try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index });
805 return .ok;771 return .{ .mcv = .{
806}772 .load_symbol = self.symbols.items[sym_index].nlist_idx,
807773 } };
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);
815}774}
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 {
818 const sym = self.symbols.items[sym_index];777 const sym = self.symbols.items[sym_index];
819 sym.getAtom(macho_file).?.free(macho_file);778 sym.getAtom(macho_file).?.free(macho_file);
820 log.debug("adding %{d} to local symbols free list", .{sym_index});779 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...@@ -822,18 +781,14 @@ fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Inde
822 // TODO free GOT entry here781 // TODO free GOT entry here
823}782}
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 {
826 const gpa = macho_file.base.comp.gpa;785 const gpa = macho_file.base.comp.gpa;
827 const mod = macho_file.base.comp.module.?;786 log.debug("freeNav 0x{x}", .{nav_index});
828 const decl = mod.declPtr(decl_index);
829787
830 log.debug("freeDecl {*}", .{decl});788 if (self.navs.fetchRemove(nav_index)) |const_kv| {
831
832 if (self.decls.fetchRemove(decl_index)) |const_kv| {
833 var kv = const_kv;789 var kv = const_kv;
834 const sym_index = kv.value.symbol_index;790 const sym_index = kv.value.symbol_index;
835 self.freeDeclMetadata(macho_file, sym_index);791 self.freeNavMetadata(macho_file, sym_index);
836 self.freeUnnamedConsts(macho_file, decl_index);
837 kv.value.exports.deinit(gpa);792 kv.value.exports.deinit(gpa);
838 }793 }
839794
...@@ -851,51 +806,46 @@ pub fn updateFunc(...@@ -851,51 +806,46 @@ pub fn updateFunc(
851 const tracy = trace(@src());806 const tracy = trace(@src());
852 defer tracy.end();807 defer tracy.end();
853808
854 const mod = pt.zcu;809 const zcu = pt.zcu;
855 const gpa = mod.gpa;810 const gpa = zcu.gpa;
856 const func = mod.funcInfo(func_index);811 const func = zcu.funcInfo(func_index);
857 const decl_index = func.owner_decl;
858 const decl = mod.declPtr(decl_index);
859812
860 const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);813 const sym_index = try self.getOrCreateMetadataForNav(macho_file, func.owner_nav);
861 self.freeUnnamedConsts(macho_file, decl_index);
862 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);814 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
863815
864 var code_buffer = std.ArrayList(u8).init(gpa);816 var code_buffer = std.ArrayList(u8).init(gpa);
865 defer code_buffer.deinit();817 defer code_buffer.deinit();
866818
867 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;819 var dwarf_state = if (self.dwarf) |*dw| try dw.initNavState(pt, func.owner_nav) else null;
868 defer if (decl_state) |*ds| ds.deinit();820 defer if (dwarf_state) |*ds| ds.deinit();
869821
870 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
871 const res = try codegen.generateFunction(822 const res = try codegen.generateFunction(
872 &macho_file.base,823 &macho_file.base,
873 pt,824 pt,
874 decl.navSrcLoc(mod),825 zcu.navSrcLoc(func.owner_nav),
875 func_index,826 func_index,
876 air,827 air,
877 liveness,828 liveness,
878 &code_buffer,829 &code_buffer,
879 dio,830 if (dwarf_state) |*ds| .{ .dwarf = ds } else .none,
880 );831 );
881832
882 const code = switch (res) {833 const code = switch (res) {
883 .ok => code_buffer.items,834 .ok => code_buffer.items,
884 .fail => |em| {835 .fail => |em| {
885 func.setAnalysisState(&mod.intern_pool, .codegen_failure);836 try zcu.failed_codegen.put(gpa, func.owner_nav, em);
886 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
887 return;837 return;
888 },838 },
889 };839 };
890840
891 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);841 const sect_index = try self.getNavOutputSection(macho_file, zcu, func.owner_nav, code);
892 try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, 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| {
895 const sym = self.symbols.items[sym_index];845 const sym = self.symbols.items[sym_index];
896 try self.dwarf.?.commitDeclState(846 try self.dwarf.?.commitNavState(
897 pt,847 pt,
898 decl_index,848 func.owner_nav,
899 sym.getAddress(.{}, macho_file),849 sym.getAddress(.{}, macho_file),
900 sym.getAtom(macho_file).?.size,850 sym.getAtom(macho_file).?.size,
901 ds,851 ds,
...@@ -905,96 +855,98 @@ pub fn updateFunc(...@@ -905,96 +855,98 @@ pub fn updateFunc(
905 // Exports will be updated by `Zcu.processExports` after the update.855 // Exports will be updated by `Zcu.processExports` after the update.
906}856}
907857
908pub fn updateDecl(858pub fn updateNav(
909 self: *ZigObject,859 self: *ZigObject,
910 macho_file: *MachO,860 macho_file: *MachO,
911 pt: Zcu.PerThread,861 pt: Zcu.PerThread,
912 decl_index: InternPool.DeclIndex,862 nav_index: InternPool.Nav.Index,
913) link.File.UpdateDeclError!void {863) link.File.UpdateNavError!void {
914 const tracy = trace(@src());864 const tracy = trace(@src());
915 defer tracy.end();865 defer tracy.end();
916866
917 const mod = pt.zcu;867 const zcu = pt.zcu;
918 const decl = mod.declPtr(decl_index);868 const ip = &zcu.intern_pool;
919869 const nav_val = zcu.navValue(nav_index);
920 if (decl.val.getExternFunc(mod)) |_| {870 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
921 return;871 .variable => |variable| Value.fromInterned(variable.init),
922 }872 .@"extern" => |@"extern"| {
923873 if (ip.isFunctionType(@"extern".ty)) return;
924 if (decl.isExtern(mod)) {874 // Extern variable gets a __got entry only
925 // Extern variable gets a __got entry only875 const name = @"extern".name.toSlice(ip);
926 const variable = decl.getOwnedVariable(mod).?;876 const lib_name = @"extern".lib_name.toSlice(ip);
927 const name = decl.name.toSlice(&mod.intern_pool);877 const index = try self.getGlobalSymbol(macho_file, name, lib_name);
928 const lib_name = variable.lib_name.toSlice(&mod.intern_pool);878 const sym = &self.symbols.items[index];
929 const index = try self.getGlobalSymbol(macho_file, name, lib_name);879 sym.setSectionFlags(.{ .needs_got = true });
930 const sym = &self.symbols.items[index];880 return;
931 sym.setSectionFlags(.{ .needs_got = true });881 },
932 return;882 else => nav_val,
933 }883 };
934884
935 const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);885 const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index);
936 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);886 self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
937887
938 const gpa = macho_file.base.comp.gpa;888 var code_buffer = std.ArrayList(u8).init(zcu.gpa);
939 var code_buffer = std.ArrayList(u8).init(gpa);
940 defer code_buffer.deinit();889 defer code_buffer.deinit();
941890
942 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(pt, decl_index) else null;891 var nav_state: ?Dwarf.NavState = if (self.dwarf) |*dw| try dw.initNavState(pt, nav_index) else null;
943 defer if (decl_state) |*ds| ds.deinit();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;894 const res = try codegen.generateSymbol(
946 const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;895 &macho_file.base,
947 const res = try codegen.generateSymbol(&macho_file.base, pt, decl.navSrcLoc(mod), decl_val, &code_buffer, dio, .{896 pt,
948 .parent_atom_index = sym_index,897 zcu.navSrcLoc(nav_index),
949 });898 nav_init,
899 &code_buffer,
900 if (nav_state) |*ns| .{ .dwarf = ns } else .none,
901 .{ .parent_atom_index = sym_index },
902 );
950903
951 const code = switch (res) {904 const code = switch (res) {
952 .ok => code_buffer.items,905 .ok => code_buffer.items,
953 .fail => |em| {906 .fail => |em| {
954 decl.analysis = .codegen_failure;907 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
955 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
956 return;908 return;
957 },909 },
958 };910 };
959 if (isThreadlocal(macho_file, decl_index)) {911 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
960 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);912 if (isThreadlocal(macho_file, nav_index))
961 try self.updateTlv(macho_file, pt, decl_index, sym_index, sect_index, code);913 try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)
962 } else {914 else
963 const sect_index = try self.getDeclOutputSection(macho_file, decl, code);915 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
964 try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code);
965 }
966916
967 if (decl_state) |*ds| {917 if (nav_state) |*ns| {
968 const sym = self.symbols.items[sym_index];918 const sym = self.symbols.items[sym_index];
969 try self.dwarf.?.commitDeclState(919 try self.dwarf.?.commitNavState(
970 pt,920 pt,
971 decl_index,921 nav_index,
972 sym.getAddress(.{}, macho_file),922 sym.getAddress(.{}, macho_file),
973 sym.getAtom(macho_file).?.size,923 sym.getAtom(macho_file).?.size,
974 ds,924 ns,
975 );925 );
976 }926 }
977927
978 // Exports will be updated by `Zcu.processExports` after the update.928 // Exports will be updated by `Zcu.processExports` after the update.
979}929}
980930
981fn updateDeclCode(931fn updateNavCode(
982 self: *ZigObject,932 self: *ZigObject,
983 macho_file: *MachO,933 macho_file: *MachO,
984 pt: Zcu.PerThread,934 pt: Zcu.PerThread,
985 decl_index: InternPool.DeclIndex,935 nav_index: InternPool.Nav.Index,
986 sym_index: Symbol.Index,936 sym_index: Symbol.Index,
987 sect_index: u8,937 sect_index: u8,
988 code: []const u8,938 code: []const u8,
989) !void {939) !void {
990 const gpa = macho_file.base.comp.gpa;940 const zcu = pt.zcu;
991 const mod = pt.zcu;941 const gpa = zcu.gpa;
992 const ip = &mod.intern_pool;942 const ip = &zcu.intern_pool;
993 const decl = mod.declPtr(decl_index);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
999 const sect = &macho_file.sections.items(.header)[sect_index];951 const sect = &macho_file.sections.items(.header)[sect_index];
1000 const sym = &self.symbols.items[sym_index];952 const sym = &self.symbols.items[sym_index];
...@@ -1004,7 +956,7 @@ fn updateDeclCode(...@@ -1004,7 +956,7 @@ fn updateDeclCode(
1004 sym.out_n_sect = sect_index;956 sym.out_n_sect = sect_index;
1005 atom.out_n_sect = sect_index;957 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)});
1008 defer gpa.free(sym_name);960 defer gpa.free(sym_name);
1009 sym.name = try self.addString(gpa, sym_name);961 sym.name = try self.addString(gpa, sym_name);
1010 atom.setAlive(true);962 atom.setAlive(true);
...@@ -1025,7 +977,7 @@ fn updateDeclCode(...@@ -1025,7 +977,7 @@ fn updateDeclCode(
1025977
1026 if (need_realloc) {978 if (need_realloc) {
1027 try atom.grow(macho_file);979 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 });
1029 if (old_vaddr != atom.value) {981 if (old_vaddr != atom.value) {
1030 sym.value = 0;982 sym.value = 0;
1031 nlist.n_value = 0;983 nlist.n_value = 0;
...@@ -1045,7 +997,7 @@ fn updateDeclCode(...@@ -1045,7 +997,7 @@ fn updateDeclCode(
1045 }997 }
1046 } else {998 } else {
1047 try atom.allocate(macho_file);999 try atom.allocate(macho_file);
1048 errdefer self.freeDeclMetadata(macho_file, sym_index);1000 errdefer self.freeNavMetadata(macho_file, sym_index);
10491001
1050 sym.value = 0;1002 sym.value = 0;
1051 sym.setSectionFlags(.{ .needs_zig_got = true });1003 sym.setSectionFlags(.{ .needs_zig_got = true });
...@@ -1070,27 +1022,27 @@ fn updateTlv(...@@ -1070,27 +1022,27 @@ fn updateTlv(
1070 self: *ZigObject,1022 self: *ZigObject,
1071 macho_file: *MachO,1023 macho_file: *MachO,
1072 pt: Zcu.PerThread,1024 pt: Zcu.PerThread,
1073 decl_index: InternPool.DeclIndex,1025 nav_index: InternPool.Nav.Index,
1074 sym_index: Symbol.Index,1026 sym_index: Symbol.Index,
1075 sect_index: u8,1027 sect_index: u8,
1076 code: []const u8,1028 code: []const u8,
1077) !void {1029) !void {
1078 const ip = &pt.zcu.intern_pool;1030 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
1083 // 1. Lower TLV initializer1035 // 1. Lower TLV initializer
1084 const init_sym_index = try self.createTlvInitializer(1036 const init_sym_index = try self.createTlvInitializer(
1085 macho_file,1037 macho_file,
1086 decl.fqn.toSlice(ip),1038 nav.fqn.toSlice(ip),
1087 decl.getAlignment(pt),1039 pt.navAlignment(nav_index),
1088 sect_index,1040 sect_index,
1089 code,1041 code,
1090 );1042 );
10911043
1092 // 2. Create TLV descriptor1044 // 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));
1094}1046}
10951047
1096fn createTlvInitializer(1048fn createTlvInitializer(
...@@ -1197,102 +1149,52 @@ fn createTlvDescriptor(...@@ -1197,102 +1149,52 @@ fn createTlvDescriptor(
1197 });1149 });
1198}1150}
11991151
1200fn getDeclOutputSection(1152fn getNavOutputSection(
1201 self: *ZigObject,1153 self: *ZigObject,
1202 macho_file: *MachO,1154 macho_file: *MachO,
1203 decl: *const Module.Decl,1155 zcu: *Zcu,
1156 nav_index: InternPool.Nav.Index,
1204 code: []const u8,1157 code: []const u8,
1205) error{OutOfMemory}!u8 {1158) error{OutOfMemory}!u8 {
1206 _ = self;1159 _ = self;
1207 const mod = macho_file.base.comp.module.?;1160 const ip = &zcu.intern_pool;
1208 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;1161 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)) {1162 const nav_val = zcu.navValue(nav_index);
1210 .Fn => macho_file.zig_text_sect_index.?,1163 if (ip.isFunctionType(nav_val.typeOf(zcu).toIntern())) return macho_file.zig_text_sect_index.?;
1211 else => blk: {1164 const is_const, const is_threadlocal, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
1212 if (decl.getOwnedVariable(mod)) |variable| {1165 .variable => |variable| .{ false, variable.is_threadlocal, variable.init },
1213 if (variable.is_threadlocal and any_non_single_threaded) {1166 .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none },
1214 const is_all_zeroes = for (code) |byte| {1167 else => .{ true, false, nav_val.toIntern() },
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 },
1249 };1168 };
1250 return sect_id;1169 if (any_non_single_threaded and is_threadlocal) {
1251}1170 for (code) |byte| {
12521171 if (byte != 0) break;
1253pub fn lowerUnnamedConst(1172 } else return macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
1254 self: *ZigObject,1173 "__DATA",
1255 macho_file: *MachO,1174 "__thread_bss",
1256 pt: Zcu.PerThread,1175 .{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
1257 val: Value,1176 );
1258 decl_index: InternPool.DeclIndex,1177 return macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
1259) !u32 {1178 "__DATA",
1260 const mod = pt.zcu;1179 "__thread_data",
1261 const gpa = mod.gpa;1180 .{ .flags = macho.S_THREAD_LOCAL_REGULAR },
1262 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);1181 );
1263 if (!gop.found_existing) {
1264 gop.value_ptr.* = .{};
1265 }1182 }
1266 const unnamed_consts = gop.value_ptr;1183 if (is_const) return macho_file.zig_const_sect_index.?;
1267 const decl = mod.declPtr(decl_index);1184 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu))
1268 const index = unnamed_consts.items.len;1185 return switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
1269 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });1186 .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?,
1270 defer gpa.free(name);1187 .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?,
1271 const sym_index = switch (try self.lowerConst(1188 };
1272 macho_file,1189 for (code) |byte| {
1273 pt,1190 if (byte != 0) break;
1274 name,1191 } else return macho_file.zig_bss_sect_index.?;
1275 val,1192 return macho_file.zig_data_sect_index.?;
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;
1291}1193}
12921194
1293const LowerConstResult = union(enum) {1195const LowerConstResult = union(enum) {
1294 ok: Symbol.Index,1196 ok: Symbol.Index,
1295 fail: *Module.ErrorMsg,1197 fail: *Zcu.ErrorMsg,
1296};1198};
12971199
1298fn lowerConst(1200fn lowerConst(
...@@ -1303,7 +1205,7 @@ fn lowerConst(...@@ -1303,7 +1205,7 @@ fn lowerConst(
1303 val: Value,1205 val: Value,
1304 required_alignment: Atom.Alignment,1206 required_alignment: Atom.Alignment,
1305 output_section_index: u8,1207 output_section_index: u8,
1306 src_loc: Module.LazySrcLoc,1208 src_loc: Zcu.LazySrcLoc,
1307) !LowerConstResult {1209) !LowerConstResult {
1308 const gpa = macho_file.base.comp.gpa;1210 const gpa = macho_file.base.comp.gpa;
13091211
...@@ -1338,7 +1240,7 @@ fn lowerConst(...@@ -1338,7 +1240,7 @@ fn lowerConst(
13381240
1339 try atom.allocate(macho_file);1241 try atom.allocate(macho_file);
1340 // TODO rename and re-audit this method1242 // TODO rename and re-audit this method
1341 errdefer self.freeDeclMetadata(macho_file, sym_index);1243 errdefer self.freeNavMetadata(macho_file, sym_index);
13421244
1343 const sect = macho_file.sections.items(.header)[output_section_index];1245 const sect = macho_file.sections.items(.header)[output_section_index];
1344 const file_offset = sect.offset + atom.value;1246 const file_offset = sect.offset + atom.value;
...@@ -1351,7 +1253,7 @@ pub fn updateExports(...@@ -1351,7 +1253,7 @@ pub fn updateExports(
1351 self: *ZigObject,1253 self: *ZigObject,
1352 macho_file: *MachO,1254 macho_file: *MachO,
1353 pt: Zcu.PerThread,1255 pt: Zcu.PerThread,
1354 exported: Module.Exported,1256 exported: Zcu.Exported,
1355 export_indices: []const u32,1257 export_indices: []const u32,
1356) link.File.UpdateExportsError!void {1258) link.File.UpdateExportsError!void {
1357 const tracy = trace(@src());1259 const tracy = trace(@src());
...@@ -1360,24 +1262,24 @@ pub fn updateExports(...@@ -1360,24 +1262,24 @@ pub fn updateExports(
1360 const mod = pt.zcu;1262 const mod = pt.zcu;
1361 const gpa = macho_file.base.comp.gpa;1263 const gpa = macho_file.base.comp.gpa;
1362 const metadata = switch (exported) {1264 const metadata = switch (exported) {
1363 .decl_index => |decl_index| blk: {1265 .nav => |nav| blk: {
1364 _ = try self.getOrCreateMetadataForDecl(macho_file, decl_index);1266 _ = try self.getOrCreateMetadataForNav(macho_file, nav);
1365 break :blk self.decls.getPtr(decl_index).?;1267 break :blk self.navs.getPtr(nav).?;
1366 },1268 },
1367 .value => |value| self.anon_decls.getPtr(value) orelse blk: {1269 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1368 const first_exp = mod.all_exports.items[export_indices[0]];1270 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);
1370 switch (res) {1272 switch (res) {
1371 .ok => {},1273 .mcv => {},
1372 .fail => |em| {1274 .fail => |em| {
1373 // TODO maybe it's enough to return an error here and let Module.processExportsInner1275 // TODO maybe it's enough to return an error here and let Zcu.processExportsInner
1374 // handle the error?1276 // handle the error?
1375 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);1277 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
1376 mod.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);1278 mod.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);
1377 return;1279 return;
1378 },1280 },
1379 }1281 }
1380 break :blk self.anon_decls.getPtr(value).?;1282 break :blk self.uavs.getPtr(uav).?;
1381 },1283 },
1382 };1284 };
1383 const sym_index = metadata.symbol_index;1285 const sym_index = metadata.symbol_index;
...@@ -1389,7 +1291,7 @@ pub fn updateExports(...@@ -1389,7 +1291,7 @@ pub fn updateExports(
1389 if (exp.opts.section.unwrap()) |section_name| {1291 if (exp.opts.section.unwrap()) |section_name| {
1390 if (!section_name.eqlSlice("__text", &mod.intern_pool)) {1292 if (!section_name.eqlSlice("__text", &mod.intern_pool)) {
1391 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);1293 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(
1393 gpa,1295 gpa,
1394 exp.src,1296 exp.src,
1395 "Unimplemented: ExportOptions.section",1297 "Unimplemented: ExportOptions.section",
...@@ -1399,7 +1301,7 @@ pub fn updateExports(...@@ -1399,7 +1301,7 @@ pub fn updateExports(
1399 }1301 }
1400 }1302 }
1401 if (exp.opts.linkage == .link_once) {1303 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(
1403 gpa,1305 gpa,
1404 exp.src,1306 exp.src,
1405 "Unimplemented: GlobalLinkage.link_once",1307 "Unimplemented: GlobalLinkage.link_once",
...@@ -1454,8 +1356,8 @@ fn updateLazySymbol(...@@ -1454,8 +1356,8 @@ fn updateLazySymbol(
1454 lazy_sym: link.File.LazySymbol,1356 lazy_sym: link.File.LazySymbol,
1455 symbol_index: Symbol.Index,1357 symbol_index: Symbol.Index,
1456) !void {1358) !void {
1457 const gpa = macho_file.base.comp.gpa;1359 const zcu = pt.zcu;
1458 const mod = macho_file.base.comp.module.?;1360 const gpa = zcu.gpa;
14591361
1460 var required_alignment: Atom.Alignment = .none;1362 var required_alignment: Atom.Alignment = .none;
1461 var code_buffer = std.ArrayList(u8).init(gpa);1363 var code_buffer = std.ArrayList(u8).init(gpa);
...@@ -1464,13 +1366,13 @@ fn updateLazySymbol(...@@ -1464,13 +1366,13 @@ fn updateLazySymbol(
1464 const name_str = blk: {1366 const name_str = blk: {
1465 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1367 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1466 @tagName(lazy_sym.kind),1368 @tagName(lazy_sym.kind),
1467 lazy_sym.ty.fmt(pt),1369 Type.fromInterned(lazy_sym.ty).fmt(pt),
1468 });1370 });
1469 defer gpa.free(name);1371 defer gpa.free(name);
1470 break :blk try self.addString(gpa, name);1372 break :blk try self.addString(gpa, name);
1471 };1373 };
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;
1474 const res = try codegen.generateLazySymbol(1376 const res = try codegen.generateLazySymbol(
1475 &macho_file.base,1377 &macho_file.base,
1476 pt,1378 pt,
...@@ -1511,7 +1413,7 @@ fn updateLazySymbol(...@@ -1511,7 +1413,7 @@ fn updateLazySymbol(
1511 atom.out_n_sect = output_section_index;1413 atom.out_n_sect = output_section_index;
15121414
1513 try atom.allocate(macho_file);1415 try atom.allocate(macho_file);
1514 errdefer self.freeDeclMetadata(macho_file, symbol_index);1416 errdefer self.freeNavMetadata(macho_file, symbol_index);
15151417
1516 sym.value = 0;1418 sym.value = 0;
1517 sym.setSectionFlags(.{ .needs_zig_got = true });1419 sym.setSectionFlags(.{ .needs_zig_got = true });
...@@ -1527,10 +1429,14 @@ fn updateLazySymbol(...@@ -1527,10 +1429,14 @@ fn updateLazySymbol(
1527 try macho_file.base.file.?.pwriteAll(code, file_offset);1429 try macho_file.base.file.?.pwriteAll(code, file_offset);
1528}1430}
15291431
1530/// Must be called only after a successful call to `updateDecl`.1432/// Must be called only after a successful call to `updateNav`.
1531pub fn updateDeclLineNumber(self: *ZigObject, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {1433pub fn updateNavLineNumber(
1434 self: *ZigObject,
1435 pt: Zcu.PerThread,
1436 nav_index: InternPool.Nav.Index,
1437) !void {
1532 if (self.dwarf) |*dw| {1438 if (self.dwarf) |*dw| {
1533 try dw.updateDeclLineNumber(pt.zcu, decl_index);1439 try dw.updateNavLineNumber(pt.zcu, nav_index);
1534 }1440 }
1535}1441}
15361442
...@@ -1543,9 +1449,9 @@ pub fn deleteExport(...@@ -1543,9 +1449,9 @@ pub fn deleteExport(
1543 const mod = macho_file.base.comp.module.?;1449 const mod = macho_file.base.comp.module.?;
15441450
1545 const metadata = switch (exported) {1451 const metadata = switch (exported) {
1546 .decl_index => |decl_index| self.decls.getPtr(decl_index) orelse return,1452 .nav => |nav| self.navs.getPtr(nav),
1547 .value => |value| self.anon_decls.getPtr(value) orelse return,1453 .uav => |uav| self.uavs.getPtr(uav),
1548 };1454 } orelse return;
1549 const nlist_index = metadata.@"export"(self, name.toSlice(&mod.intern_pool)) orelse return;1455 const nlist_index = metadata.@"export"(self, name.toSlice(&mod.intern_pool)) orelse return;
15501456
1551 log.debug("deleting export '{}'", .{name.fmt(&mod.intern_pool)});1457 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...@@ -1577,17 +1483,17 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
1577 return lookup_gop.value_ptr.*;1483 return lookup_gop.value_ptr.*;
1578}1484}
15791485
1580pub fn getOrCreateMetadataForDecl(1486pub fn getOrCreateMetadataForNav(
1581 self: *ZigObject,1487 self: *ZigObject,
1582 macho_file: *MachO,1488 macho_file: *MachO,
1583 decl_index: InternPool.DeclIndex,1489 nav_index: InternPool.Nav.Index,
1584) !Symbol.Index {1490) !Symbol.Index {
1585 const gpa = macho_file.base.comp.gpa;1491 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);
1587 if (!gop.found_existing) {1493 if (!gop.found_existing) {
1588 const sym_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);1494 const sym_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);
1589 const sym = &self.symbols.items[sym_index];1495 const sym = &self.symbols.items[sym_index];
1590 if (isThreadlocal(macho_file, decl_index)) {1496 if (isThreadlocal(macho_file, nav_index)) {
1591 sym.flags.tlv = true;1497 sym.flags.tlv = true;
1592 } else {1498 } else {
1593 sym.setSectionFlags(.{ .needs_zig_got = true });1499 sym.setSectionFlags(.{ .needs_zig_got = true });
...@@ -1603,47 +1509,39 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1603,47 +1509,39 @@ pub fn getOrCreateMetadataForLazySymbol(
1603 pt: Zcu.PerThread,1509 pt: Zcu.PerThread,
1604 lazy_sym: link.File.LazySymbol,1510 lazy_sym: link.File.LazySymbol,
1605) !Symbol.Index {1511) !Symbol.Index {
1606 const mod = pt.zcu;1512 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
1607 const gpa = mod.gpa;
1608 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
1609 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();1513 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1610 if (!gop.found_existing) gop.value_ptr.* = .{};1514 if (!gop.found_existing) gop.value_ptr.* = .{};
1611 const metadata: struct {1515 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
1612 symbol_index: *Symbol.Index,1516 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },
1613 state: *LazySymbolMetadata.State,1517 .const_data => .{ &gop.value_ptr.const_symbol_index, &gop.value_ptr.const_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 },
1623 };1518 };
1624 switch (metadata.state.*) {1519 switch (state_ptr.*) {
1625 .unused => {1520 .unused => {
1626 const symbol_index = try self.newSymbolWithAtom(gpa, .{}, macho_file);1521 const symbol_index = try self.newSymbolWithAtom(pt.zcu.gpa, .{}, macho_file);
1627 const sym = &self.symbols.items[symbol_index];1522 const sym = &self.symbols.items[symbol_index];
1628 sym.setSectionFlags(.{ .needs_zig_got = true });1523 sym.setSectionFlags(.{ .needs_zig_got = true });
1629 metadata.symbol_index.* = symbol_index;1524 symbol_index_ptr.* = symbol_index;
1630 },1525 },
1631 .pending_flush => return metadata.symbol_index.*,1526 .pending_flush => return symbol_index_ptr.*,
1632 .flushed => {},1527 .flushed => {},
1633 }1528 }
1634 metadata.state.* = .pending_flush;1529 state_ptr.* = .pending_flush;
1635 const symbol_index = metadata.symbol_index.*;1530 const symbol_index = symbol_index_ptr.*;
1636 // anyerror needs to be deferred until flushModule1531 // 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);
1638 return symbol_index;1533 return symbol_index;
1639}1534}
16401535
1641fn isThreadlocal(macho_file: *MachO, decl_index: InternPool.DeclIndex) bool {1536fn isThreadlocal(macho_file: *MachO, nav_index: InternPool.Nav.Index) bool {
1642 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;1537 if (!macho_file.base.comp.config.any_non_single_threaded)
1643 const zcu = macho_file.base.comp.module.?;1538 return false;
1644 const decl = zcu.declPtr(decl_index);1539 const ip = &macho_file.base.comp.module.?.intern_pool;
1645 const variable = decl.getOwnedVariable(zcu) orelse return false;1540 return switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) {
1646 return variable.is_threadlocal and any_non_single_threaded;1541 .variable => |variable| variable.is_threadlocal,
1542 .@"extern" => |@"extern"| @"extern".is_threadlocal,
1543 else => false,
1544 };
1647}1545}
16481546
1649fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index {1547fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index {
...@@ -1848,12 +1746,12 @@ fn formatAtoms(...@@ -1848,12 +1746,12 @@ fn formatAtoms(
1848 }1746 }
1849}1747}
18501748
1851const DeclMetadata = struct {1749const AvMetadata = struct {
1852 symbol_index: Symbol.Index,1750 symbol_index: Symbol.Index,
1853 /// A list of all exports aliases of this Decl.1751 /// A list of all exports aliases of this Av.
1854 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},1752 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 {
1857 for (m.exports.items) |*exp| {1755 for (m.exports.items) |*exp| {
1858 const nlist = zig_object.symtab.items(.nlist)[exp.*];1756 const nlist = zig_object.symtab.items(.nlist)[exp.*];
1859 const exp_name = zig_object.strtab.getAssumeExists(nlist.n_strx);1757 const exp_name = zig_object.strtab.getAssumeExists(nlist.n_strx);
...@@ -1880,10 +1778,9 @@ const TlvInitializer = struct {...@@ -1880,10 +1778,9 @@ const TlvInitializer = struct {
1880 }1778 }
1881};1779};
18821780
1883const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);1781const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1884const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index));1782const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);
1885const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata);1783const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
1886const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
1887const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));1784const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));
1888const TlvInitializerTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlvInitializer);1785const TlvInitializerTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlvInitializer);
18891786
...@@ -1894,6 +1791,7 @@ const link = @import("../../link.zig");...@@ -1894,6 +1791,7 @@ const link = @import("../../link.zig");
1894const log = std.log.scoped(.link);1791const log = std.log.scoped(.link);
1895const macho = std.macho;1792const macho = std.macho;
1896const mem = std.mem;1793const mem = std.mem;
1794const target_util = @import("../../target.zig");
1897const trace = @import("../../tracy.zig").trace;1795const trace = @import("../../tracy.zig").trace;
1898const std = @import("std");1796const std = @import("std");
18991797
...@@ -1908,8 +1806,6 @@ const Liveness = @import("../../Liveness.zig");...@@ -1908,8 +1806,6 @@ const Liveness = @import("../../Liveness.zig");
1908const MachO = @import("../MachO.zig");1806const MachO = @import("../MachO.zig");
1909const Nlist = Object.Nlist;1807const Nlist = Object.Nlist;
1910const Zcu = @import("../../Zcu.zig");1808const Zcu = @import("../../Zcu.zig");
1911/// Deprecated.
1912const Module = Zcu;
1913const Object = @import("Object.zig");1809const Object = @import("Object.zig");
1914const Relocation = @import("Relocation.zig");1810const Relocation = @import("Relocation.zig");
1915const Symbol = @import("Symbol.zig");1811const 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,...@@ -86,8 +86,8 @@ pub fn updateFunc(self: *NvPtx, pt: Zcu.PerThread, func_index: InternPool.Index,
86 try self.llvm_object.updateFunc(pt, func_index, air, liveness);86 try self.llvm_object.updateFunc(pt, func_index, air, liveness);
87}87}
8888
89pub fn updateDecl(self: *NvPtx, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {89pub fn updateNav(self: *NvPtx, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
90 return self.llvm_object.updateDecl(pt, decl_index);90 return self.llvm_object.updateNav(pt, nav);
91}91}
9292
93pub fn updateExports(93pub fn updateExports(
src/link/Plan9.zig+191-336
...@@ -24,8 +24,6 @@ const Allocator = std.mem.Allocator;...@@ -24,8 +24,6 @@ const Allocator = std.mem.Allocator;
24const log = std.log.scoped(.link);24const log = std.log.scoped(.link);
25const assert = std.debug.assert;25const assert = std.debug.assert;
2626
27pub const base_tag = .plan9;
28
29base: link.File,27base: link.File,
30sixtyfour_bit: bool,28sixtyfour_bit: bool,
31bases: Bases,29bases: Bases,
...@@ -53,40 +51,19 @@ path_arena: std.heap.ArenaAllocator,...@@ -53,40 +51,19 @@ path_arena: std.heap.ArenaAllocator,
53/// The debugger looks for the first file (aout.Sym.Type.z) preceeding the text symbol51/// The debugger looks for the first file (aout.Sym.Type.z) preceeding the text symbol
54/// of the function to know what file it came from.52/// of the function to know what file it came from.
55/// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place)53/// 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(54fn_nav_table: std.AutoArrayHashMapUnmanaged(
57 *Zcu.File,55 Zcu.File.Index,
58 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, FnDeclOutput) = .{} },56 struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, FnNavOutput) = .{} },
59) = .{},57) = .{},
60/// the code is modified when relocated, so that is why it is mutable58/// 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) = .{},
62/// When `updateExports` is called, we store the export indices here, to be used60/// When `updateExports` is called, we store the export indices here, to be used
63/// during flush.61/// during flush.
64decl_exports: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, []u32) = .{},62nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []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 = .{},
8663
87lazy_syms: LazySymbolTable = .{},64lazy_syms: LazySymbolTable = .{},
8865
89anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},66uavs: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
9067
91relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},68relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},
92hdr: aout.ExecHdr = undefined,69hdr: aout.ExecHdr = undefined,
...@@ -104,7 +81,7 @@ got_index_free_list: std.ArrayListUnmanaged(usize) = .{},...@@ -104,7 +81,7 @@ got_index_free_list: std.ArrayListUnmanaged(usize) = .{},
104syms_index_free_list: std.ArrayListUnmanaged(usize) = .{},81syms_index_free_list: std.ArrayListUnmanaged(usize) = .{},
10582
106atoms: std.ArrayListUnmanaged(Atom) = .{},83atoms: std.ArrayListUnmanaged(Atom) = .{},
107decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata) = .{},84navs: std.AutoHashMapUnmanaged(InternPool.Nav.Index, NavMetadata) = .{},
10885
109/// Indices of the three "special" symbols into atoms86/// Indices of the three "special" symbols into atoms
110etext_edata_end_atom_indices: [3]?Atom.Index = .{ null, null, null },87etext_edata_end_atom_indices: [3]?Atom.Index = .{ null, null, null },
...@@ -131,9 +108,7 @@ const Bases = struct {...@@ -131,9 +108,7 @@ const Bases = struct {
131 data: u64,108 data: u64,
132};109};
133110
134const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Atom.Index));111const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
135
136const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata);
137112
138const LazySymbolMetadata = struct {113const LazySymbolMetadata = struct {
139 const State = enum { unused, pending_flush, flushed };114 const State = enum { unused, pending_flush, flushed };
...@@ -161,7 +136,7 @@ pub const Atom = struct {...@@ -161,7 +136,7 @@ pub const Atom = struct {
161 /// offset into got136 /// offset into got
162 got_index: ?usize,137 got_index: ?usize,
163 /// We include the code here to be use in relocs138 /// 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.
165 /// But, in the case of function and data decls, they own the code and this field140 /// But, in the case of function and data decls, they own the code and this field
166 /// is just a pointer for convience.141 /// is just a pointer for convience.
167 code: CodePtr,142 code: CodePtr,
...@@ -170,22 +145,23 @@ pub const Atom = struct {...@@ -170,22 +145,23 @@ pub const Atom = struct {
170 code_ptr: ?[*]u8,145 code_ptr: ?[*]u8,
171 other: union {146 other: union {
172 code_len: usize,147 code_len: usize,
173 decl_index: InternPool.DeclIndex,148 nav_index: InternPool.Nav.Index,
174 },149 },
175 fn fromSlice(slice: []u8) CodePtr {150 fn fromSlice(slice: []u8) CodePtr {
176 return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } };151 return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } };
177 }152 }
178 fn getCode(self: CodePtr, plan9: *const Plan9) []u8 {153 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;
180 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {156 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {
181 const decl_index = self.other.decl_index;157 const nav_index = self.other.nav_index;
182 const decl = mod.declPtr(decl_index);158 const nav = ip.getNav(nav_index);
183 if (decl.typeOf(mod).zigTypeTag(mod) == .Fn) {159 if (ip.isFunctionType(nav.typeOf(ip))) {
184 const table = plan9.fn_decl_table.get(decl.getFileScope(mod)).?.functions;160 const table = plan9.fn_nav_table.get(zcu.navFileScopeIndex(nav_index)).?.functions;
185 const output = table.get(decl_index).?;161 const output = table.get(nav_index).?;
186 break :blk output.code;162 break :blk output.code;
187 } else {163 } else {
188 break :blk plan9.data_decl_table.get(decl_index).?;164 break :blk plan9.data_nav_table.get(nav_index).?;
189 }165 }
190 };166 };
191 }167 }
...@@ -241,11 +217,11 @@ pub const DebugInfoOutput = struct {...@@ -241,11 +217,11 @@ pub const DebugInfoOutput = struct {
241 pc_quanta: u8,217 pc_quanta: u8,
242};218};
243219
244const DeclMetadata = struct {220const NavMetadata = struct {
245 index: Atom.Index,221 index: Atom.Index,
246 exports: std.ArrayListUnmanaged(usize) = .{},222 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 {
249 for (m.exports.items) |exp| {225 for (m.exports.items) |exp| {
250 const sym = p9.syms.items[exp];226 const sym = p9.syms.items[exp];
251 if (mem.eql(u8, name, sym.name)) return exp;227 if (mem.eql(u8, name, sym.name)) return exp;
...@@ -254,7 +230,7 @@ const DeclMetadata = struct {...@@ -254,7 +230,7 @@ const DeclMetadata = struct {
254 }230 }
255};231};
256232
257const FnDeclOutput = struct {233const FnNavOutput = struct {
258 /// this code is modified when relocated so it is mutable234 /// this code is modified when relocated so it is mutable
259 code: []u8,235 code: []u8,
260 /// this might have to be modified in the linker, so thats why its mutable236 /// this might have to be modified in the linker, so thats why its mutable
...@@ -338,18 +314,18 @@ pub fn createEmpty(...@@ -338,18 +314,18 @@ pub fn createEmpty(
338 return self;314 return self;
339}315}
340316
341fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !void {317fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void {
342 const gpa = self.base.comp.gpa;318 const gpa = self.base.comp.gpa;
343 const mod = self.base.comp.module.?;319 const mod = self.base.comp.module.?;
344 const decl = mod.declPtr(decl_index);320 const file_scope = mod.navFileScopeIndex(nav_index);
345 const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope(mod));321 const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope);
346 if (fn_map_res.found_existing) {322 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| {
348 gpa.free(old_entry.value.code);324 gpa.free(old_entry.value.code);
349 gpa.free(old_entry.value.lineinfo);325 gpa.free(old_entry.value.lineinfo);
350 }326 }
351 } else {327 } else {
352 const file = decl.getFileScope(mod);328 const file = mod.fileByIndex(file_scope);
353 const arena = self.path_arena.allocator();329 const arena = self.path_arena.allocator();
354 // each file gets a symbol330 // each file gets a symbol
355 fn_map_res.value_ptr.* = .{331 fn_map_res.value_ptr.* = .{
...@@ -359,7 +335,7 @@ fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !voi...@@ -359,7 +335,7 @@ fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !voi
359 break :blk @as(u32, @intCast(self.syms.items.len - 1));335 break :blk @as(u32, @intCast(self.syms.items.len - 1));
360 },336 },
361 };337 };
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
364 var a = std.ArrayList(u8).init(arena);340 var a = std.ArrayList(u8).init(arena);
365 errdefer a.deinit();341 errdefer a.deinit();
...@@ -418,11 +394,8 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -418,11 +394,8 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
418 const gpa = mod.gpa;394 const gpa = mod.gpa;
419 const target = self.base.comp.root_mod.resolved_target.result;395 const target = self.base.comp.root_mod.resolved_target.result;
420 const func = mod.funcInfo(func_index);396 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
427 var code_buffer = std.ArrayList(u8).init(gpa);400 var code_buffer = std.ArrayList(u8).init(gpa);
428 defer code_buffer.deinit();401 defer code_buffer.deinit();
...@@ -439,7 +412,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -439,7 +412,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
439 const res = try codegen.generateFunction(412 const res = try codegen.generateFunction(
440 &self.base,413 &self.base,
441 pt,414 pt,
442 decl.navSrcLoc(mod),415 mod.navSrcLoc(func.owner_nav),
443 func_index,416 func_index,
444 air,417 air,
445 liveness,418 liveness,
...@@ -449,128 +422,72 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -449,128 +422,72 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index,
449 const code = switch (res) {422 const code = switch (res) {
450 .ok => try code_buffer.toOwnedSlice(),423 .ok => try code_buffer.toOwnedSlice(),
451 .fail => |em| {424 .fail => |em| {
452 func.setAnalysisState(&mod.intern_pool, .codegen_failure);425 try mod.failed_codegen.put(gpa, func.owner_nav, em);
453 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
454 return;426 return;
455 },427 },
456 };428 };
457 self.getAtomPtr(atom_idx).code = .{429 self.getAtomPtr(atom_idx).code = .{
458 .code_ptr = null,430 .code_ptr = null,
459 .other = .{ .decl_index = decl_index },431 .other = .{ .nav_index = func.owner_nav },
460 };432 };
461 const out: FnDeclOutput = .{433 const out: FnNavOutput = .{
462 .code = code,434 .code = code,
463 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),435 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),
464 .start_line = dbg_info_output.start_line.?,436 .start_line = dbg_info_output.start_line.?,
465 .end_line = dbg_info_output.end_line,437 .end_line = dbg_info_output.end_line,
466 };438 };
467 try self.putFn(decl_index, out);439 try self.putFn(func.owner_nav, out);
468 return self.updateFinish(decl_index);440 return self.updateFinish(pt, func.owner_nav);
469}441}
470442
471pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 {443pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
472 const mod = pt.zcu;444 const zcu = pt.zcu;
473 const gpa = mod.gpa;445 const gpa = zcu.gpa;
474 _ = try self.seeDecl(decl_index);446 const ip = &zcu.intern_pool;
475 var code_buffer = std.ArrayList(u8).init(gpa);447 const nav = ip.getNav(nav_index);
476 defer code_buffer.deinit();448 const nav_val = zcu.navValue(nav_index);
477449 const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
478 const decl = mod.declPtr(decl_index);450 .variable => |variable| Value.fromInterned(variable.init),
479451 .@"extern" => {
480 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);452 log.debug("found extern decl: {}", .{nav.name.fmt(ip)});
481 if (!gop.found_existing) {453 return;
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;
518 },454 },
455 else => nav_val,
519 };456 };
520 // duped_code is freed when the unnamed const is freed457 const atom_idx = try self.seeNav(pt, nav_index);
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);
541458
542 var code_buffer = std.ArrayList(u8).init(gpa);459 var code_buffer = std.ArrayList(u8).init(gpa);
543 defer code_buffer.deinit();460 defer code_buffer.deinit();
544 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
545 // TODO we need the symbol index for symbol in the table of locals for the containing atom461 // 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 = {} }, .{462 const res = try codegen.generateSymbol(&self.base, pt, zcu.navSrcLoc(nav_index), nav_init, &code_buffer, .none, .{
547 .parent_atom_index = @as(Atom.Index, @intCast(atom_idx)),463 .parent_atom_index = @intCast(atom_idx),
548 });464 });
549 const code = switch (res) {465 const code = switch (res) {
550 .ok => code_buffer.items,466 .ok => code_buffer.items,
551 .fail => |em| {467 .fail => |em| {
552 decl.analysis = .codegen_failure;468 try zcu.failed_codegen.put(gpa, nav_index, em);
553 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
554 return;469 return;
555 },470 },
556 };471 };
557 try self.data_decl_table.ensureUnusedCapacity(gpa, 1);472 try self.data_nav_table.ensureUnusedCapacity(gpa, 1);
558 const duped_code = try gpa.dupe(u8, code);473 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 } };474 self.getAtomPtr(self.navs.get(nav_index).?.index).code = .{ .code_ptr = null, .other = .{ .nav_index = nav_index } };
560 if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| {475 if (self.data_nav_table.fetchPutAssumeCapacity(nav_index, duped_code)) |old_entry| {
561 gpa.free(old_entry.value);476 gpa.free(old_entry.value);
562 }477 }
563 return self.updateFinish(decl_index);478 return self.updateFinish(pt, nav_index);
564}479}
480
565/// called at the end of update{Decl,Func}481/// called at the end of update{Decl,Func}
566fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {482fn updateFinish(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
567 const gpa = self.base.comp.gpa;483 const zcu = pt.zcu;
568 const mod = self.base.comp.module.?;484 const gpa = zcu.gpa;
569 const decl = mod.declPtr(decl_index);485 const ip = &zcu.intern_pool;
570 const is_fn = (decl.typeOf(mod).zigTypeTag(mod) == .Fn);486 const nav = ip.getNav(nav_index);
487 const is_fn = ip.isFunctionType(nav.typeOf(ip));
571 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;488 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);
574 // write the internal linker metadata491 // write the internal linker metadata
575 atom.type = sym_t;492 atom.type = sym_t;
576 // write the symbol493 // write the symbol
...@@ -578,7 +495,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {...@@ -578,7 +495,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
578 const sym: aout.Sym = .{495 const sym: aout.Sym = .{
579 .value = undefined, // the value of stuff gets filled in in flushModule496 .value = undefined, // the value of stuff gets filled in in flushModule
580 .type = atom.type,497 .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)),
582 };499 };
583500
584 if (atom.sym_index) |s| {501 if (atom.sym_index) |s| {
...@@ -643,29 +560,24 @@ fn externCount(self: *Plan9) usize {...@@ -643,29 +560,24 @@ fn externCount(self: *Plan9) usize {
643 }560 }
644 return extern_atom_count;561 return extern_atom_count;
645}562}
646// counts decls, unnamed consts, and lazy syms563// counts decls, and lazy syms
647fn atomCount(self: *Plan9) usize {564fn atomCount(self: *Plan9) usize {
648 var fn_decl_count: usize = 0;565 var fn_nav_count: usize = 0;
649 var itf_files = self.fn_decl_table.iterator();566 var itf_files = self.fn_nav_table.iterator();
650 while (itf_files.next()) |ent| {567 while (itf_files.next()) |ent| {
651 // get the submap568 // get the submap
652 var submap = ent.value_ptr.functions;569 var submap = ent.value_ptr.functions;
653 fn_decl_count += submap.count();570 fn_nav_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;
660 }571 }
572 const data_nav_count = self.data_nav_table.count();
661 var lazy_atom_count: usize = 0;573 var lazy_atom_count: usize = 0;
662 var it_lazy = self.lazy_syms.iterator();574 var it_lazy = self.lazy_syms.iterator();
663 while (it_lazy.next()) |kv| {575 while (it_lazy.next()) |kv| {
664 lazy_atom_count += kv.value_ptr.numberOfAtoms();576 lazy_atom_count += kv.value_ptr.numberOfAtoms();
665 }577 }
666 const anon_atom_count = self.anon_decls.count();578 const uav_atom_count = self.uavs.count();
667 const extern_atom_count = self.externCount();579 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;
669}581}
670582
671pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {583pub 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...@@ -700,7 +612,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
700 // anyerror needs to wait for everything to be flushed.612 // anyerror needs to wait for everything to be flushed.
701 if (metadata.text_state != .unused) self.updateLazySymbolAtom(613 if (metadata.text_state != .unused) self.updateLazySymbolAtom(
702 pt,614 pt,
703 File.LazySymbol.initDecl(.code, null, pt.zcu),615 .{ .kind = .code, .ty = .anyerror_type },
704 metadata.text_atom,616 metadata.text_atom,
705 ) catch |err| return switch (err) {617 ) catch |err| return switch (err) {
706 error.CodegenFail => error.FlushFailure,618 error.CodegenFail => error.FlushFailure,
...@@ -708,7 +620,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -708,7 +620,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
708 };620 };
709 if (metadata.rodata_state != .unused) self.updateLazySymbolAtom(621 if (metadata.rodata_state != .unused) self.updateLazySymbolAtom(
710 pt,622 pt,
711 File.LazySymbol.initDecl(.const_data, null, pt.zcu),623 .{ .kind = .const_data, .ty = .anyerror_type },
712 metadata.rodata_atom,624 metadata.rodata_atom,
713 ) catch |err| return switch (err) {625 ) catch |err| return switch (err) {
714 error.CodegenFail => error.FlushFailure,626 error.CodegenFail => error.FlushFailure,
...@@ -734,7 +646,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -734,7 +646,7 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
734646
735 var hdr_buf: [40]u8 = undefined;647 var hdr_buf: [40]u8 = undefined;
736 // account for the fat header648 // 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;
738 const hdr_slice: []u8 = hdr_buf[0..hdr_size];650 const hdr_slice: []u8 = hdr_buf[0..hdr_size];
739 var foff = hdr_size;651 var foff = hdr_size;
740 iovecs[0] = .{ .base = hdr_slice.ptr, .len = hdr_slice.len };652 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...@@ -746,13 +658,13 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
746 // text658 // text
747 {659 {
748 var linecount: i64 = -1;660 var linecount: i64 = -1;
749 var it_file = self.fn_decl_table.iterator();661 var it_file = self.fn_nav_table.iterator();
750 while (it_file.next()) |fentry| {662 while (it_file.next()) |fentry| {
751 var it = fentry.value_ptr.functions.iterator();663 var it = fentry.value_ptr.functions.iterator();
752 while (it.next()) |entry| {664 while (it.next()) |entry| {
753 const decl_index = entry.key_ptr.*;665 const nav_index = entry.key_ptr.*;
754 const decl = pt.zcu.declPtr(decl_index);666 const nav = pt.zcu.intern_pool.getNav(nav_index);
755 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);667 const atom = self.getAtomPtr(self.navs.get(nav_index).?.index);
756 const out = entry.value_ptr.*;668 const out = entry.value_ptr.*;
757 {669 {
758 // connect the previous decl to the next670 // connect the previous decl to the next
...@@ -771,15 +683,15 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -771,15 +683,15 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
771 const off = self.getAddr(text_i, .t);683 const off = self.getAddr(text_i, .t);
772 text_i += out.code.len;684 text_i += out.code.len;
773 atom.offset = off;685 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 });
775 if (!self.sixtyfour_bit) {687 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());
777 } else {689 } else {
778 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());690 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
779 }691 }
780 self.syms.items[atom.sym_index.?].value = off;692 self.syms.items[atom.sym_index.?].value = off;
781 if (self.decl_exports.get(decl_index)) |export_indices| {693 if (self.nav_exports.get(nav_index)) |export_indices| {
782 try self.addDeclExports(pt.zcu, decl_index, export_indices);694 try self.addNavExports(pt.zcu, nav_index, export_indices);
783 }695 }
784 }696 }
785 }697 }
...@@ -826,10 +738,10 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -826,10 +738,10 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
826 // data738 // data
827 var data_i: u64 = got_size;739 var data_i: u64 = got_size;
828 {740 {
829 var it = self.data_decl_table.iterator();741 var it = self.data_nav_table.iterator();
830 while (it.next()) |entry| {742 while (it.next()) |entry| {
831 const decl_index = entry.key_ptr.*;743 const nav_index = entry.key_ptr.*;
832 const atom = self.getAtomPtr(self.decls.get(decl_index).?.index);744 const atom = self.getAtomPtr(self.navs.get(nav_index).?.index);
833 const code = entry.value_ptr.*;745 const code = entry.value_ptr.*;
834746
835 foff += code.len;747 foff += code.len;
...@@ -844,35 +756,13 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -844,35 +756,13 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
844 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());756 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
845 }757 }
846 self.syms.items[atom.sym_index.?].value = off;758 self.syms.items[atom.sym_index.?].value = off;
847 if (self.decl_exports.get(decl_index)) |export_indices| {759 if (self.nav_exports.get(nav_index)) |export_indices| {
848 try self.addDeclExports(pt.zcu, decl_index, export_indices);760 try self.addNavExports(pt.zcu, nav_index, export_indices);
849 }761 }
850 }762 }
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
873 {763 {
874 var it_anon = self.anon_decls.iterator();764 var it_uav = self.uavs.iterator();
875 while (it_anon.next()) |kv| {765 while (it_uav.next()) |kv| {
876 const atom = self.getAtomPtr(kv.value_ptr.*);766 const atom = self.getAtomPtr(kv.value_ptr.*);
877 const code = atom.code.getOwnedCode().?;767 const code = atom.code.getOwnedCode().?;
878 log.debug("write anon decl: {s}", .{self.syms.items[atom.sym_index.?].name});768 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...@@ -1011,14 +901,14 @@ pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
1011 // write it all!901 // write it all!
1012 try file.pwritevAll(iovecs, 0);902 try file.pwritevAll(iovecs, 0);
1013}903}
1014fn addDeclExports(904fn addNavExports(
1015 self: *Plan9,905 self: *Plan9,
1016 mod: *Zcu,906 mod: *Zcu,
1017 decl_index: InternPool.DeclIndex,907 nav_index: InternPool.Nav.Index,
1018 export_indices: []const u32,908 export_indices: []const u32,
1019) !void {909) !void {
1020 const gpa = self.base.comp.gpa;910 const gpa = self.base.comp.gpa;
1021 const metadata = self.decls.getPtr(decl_index).?;911 const metadata = self.navs.getPtr(nav_index).?;
1022 const atom = self.getAtom(metadata.index);912 const atom = self.getAtom(metadata.index);
1023913
1024 for (export_indices) |export_idx| {914 for (export_indices) |export_idx| {
...@@ -1031,7 +921,7 @@ fn addDeclExports(...@@ -1031,7 +921,7 @@ fn addDeclExports(
1031 {921 {
1032 try mod.failed_exports.put(mod.gpa, export_idx, try Zcu.ErrorMsg.create(922 try mod.failed_exports.put(mod.gpa, export_idx, try Zcu.ErrorMsg.create(
1033 gpa,923 gpa,
1034 mod.declPtr(decl_index).navSrcLoc(mod),924 mod.navSrcLoc(nav_index),
1035 "plan9 does not support extra sections",925 "plan9 does not support extra sections",
1036 .{},926 .{},
1037 ));927 ));
...@@ -1090,7 +980,6 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {...@@ -1090,7 +980,6 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1090 }980 }
1091 kv.value.exports.deinit(gpa);981 kv.value.exports.deinit(gpa);
1092 }982 }
1093 self.freeUnnamedConsts(decl_index);
1094 {983 {
1095 const atom_index = self.decls.get(decl_index).?.index;984 const atom_index = self.decls.get(decl_index).?.index;
1096 const relocs = self.relocs.getPtr(atom_index) orelse return;985 const relocs = self.relocs.getPtr(atom_index) orelse return;
...@@ -1098,18 +987,6 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {...@@ -1098,18 +987,6 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1098 assert(self.relocs.remove(atom_index));987 assert(self.relocs.remove(atom_index));
1099 }988 }
1100}989}
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
1113fn createAtom(self: *Plan9) !Atom.Index {990fn createAtom(self: *Plan9) !Atom.Index {
1114 const gpa = self.base.comp.gpa;991 const gpa = self.base.comp.gpa;
1115 const index = @as(Atom.Index, @intCast(self.atoms.items.len));992 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
...@@ -1124,9 +1001,11 @@ fn createAtom(self: *Plan9) !Atom.Index {...@@ -1124,9 +1001,11 @@ fn createAtom(self: *Plan9) !Atom.Index {
1124 return index;1001 return index;
1125}1002}
11261003
1127pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {1004pub fn seeNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !Atom.Index {
1128 const gpa = self.base.comp.gpa;1005 const zcu = pt.zcu;
1129 const gop = try self.decls.getOrPut(gpa, decl_index);1006 const ip = &zcu.intern_pool;
1007 const gpa = zcu.gpa;
1008 const gop = try self.navs.getOrPut(gpa, nav_index);
1130 if (!gop.found_existing) {1009 if (!gop.found_existing) {
1131 const index = try self.createAtom();1010 const index = try self.createAtom();
1132 self.getAtomPtr(index).got_index = self.allocateGotIndex();1011 self.getAtomPtr(index).got_index = self.allocateGotIndex();
...@@ -1137,23 +1016,22 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {...@@ -1137,23 +1016,22 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {
1137 }1016 }
1138 const atom_idx = gop.value_ptr.index;1017 const atom_idx = gop.value_ptr.index;
1139 // handle externs here because they might not get updateDecl called on them1018 // handle externs here because they might not get updateDecl called on them
1140 const mod = self.base.comp.module.?;1019 const nav = ip.getNav(nav_index);
1141 const decl = mod.declPtr(decl_index);1020 if (ip.indexToKey(nav.status.resolved.val) == .@"extern") {
1142 if (decl.isExtern(mod)) {
1143 // this is a "phantom atom" - it is never actually written to disk, just convenient for us to store stuff about externs1021 // 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)) {
1145 self.etext_edata_end_atom_indices[0] = atom_idx;1023 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)) {
1147 self.etext_edata_end_atom_indices[1] = atom_idx;1025 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)) {
1149 self.etext_edata_end_atom_indices[2] = atom_idx;1027 self.etext_edata_end_atom_indices[2] = atom_idx;
1150 }1028 }
1151 try self.updateFinish(decl_index);1029 try self.updateFinish(pt, nav_index);
1152 log.debug("seeDecl(extern) for {} (got_addr=0x{x})", .{1030 log.debug("seeNav(extern) for {} (got_addr=0x{x})", .{
1153 decl.name.fmt(&mod.intern_pool),1031 nav.name.fmt(ip),
1154 self.getAtom(atom_idx).getOffsetTableAddress(self),1032 self.getAtom(atom_idx).getOffsetTableAddress(self),
1155 });1033 });
1156 } else log.debug("seeDecl for {}", .{decl.name.fmt(&mod.intern_pool)});1034 } else log.debug("seeNav for {}", .{nav.name.fmt(ip)});
1157 return atom_idx;1035 return atom_idx;
1158}1036}
11591037
...@@ -1165,45 +1043,41 @@ pub fn updateExports(...@@ -1165,45 +1043,41 @@ pub fn updateExports(
1165) !void {1043) !void {
1166 const gpa = self.base.comp.gpa;1044 const gpa = self.base.comp.gpa;
1167 switch (exported) {1045 switch (exported) {
1168 .value => @panic("TODO: plan9 updateExports handling values"),1046 .uav => @panic("TODO: plan9 updateExports handling values"),
1169 .decl_index => |decl_index| {1047 .nav => |nav| {
1170 _ = try self.seeDecl(decl_index);1048 _ = try self.seeNav(pt, nav);
1171 if (self.decl_exports.fetchSwapRemove(decl_index)) |kv| {1049 if (self.nav_exports.fetchSwapRemove(nav)) |kv| {
1172 gpa.free(kv.value);1050 gpa.free(kv.value);
1173 }1051 }
1174 try self.decl_exports.ensureUnusedCapacity(gpa, 1);1052 try self.nav_exports.ensureUnusedCapacity(gpa, 1);
1175 const duped_indices = try gpa.dupe(u32, export_indices);1053 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);
1177 },1055 },
1178 }1056 }
1179 // all proper work is done in flush1057 // all proper work is done in flush
1180 _ = pt;
1181}1058}
11821059
1183pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol) !Atom.Index {1060pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, lazy_sym: File.LazySymbol) !Atom.Index {
1184 const gpa = pt.zcu.gpa;1061 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
1185 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?));
1186 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();1062 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
11871063
1188 if (!gop.found_existing) gop.value_ptr.* = .{};1064 if (!gop.found_existing) gop.value_ptr.* = .{};
11891065
1190 const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {1066 const atom_ptr, const state_ptr = switch (lazy_sym.kind) {
1191 .code => .{ .atom = &gop.value_ptr.text_atom, .state = &gop.value_ptr.text_state },1067 .code => .{ &gop.value_ptr.text_atom, &gop.value_ptr.text_state },
1192 .const_data => .{ .atom = &gop.value_ptr.rodata_atom, .state = &gop.value_ptr.rodata_state },1068 .const_data => .{ &gop.value_ptr.rodata_atom, &gop.value_ptr.rodata_state },
1193 };1069 };
1194 switch (metadata.state.*) {1070 switch (state_ptr.*) {
1195 .unused => metadata.atom.* = try self.createAtom(),1071 .unused => atom_ptr.* = try self.createAtom(),
1196 .pending_flush => return metadata.atom.*,1072 .pending_flush => return atom_ptr.*,
1197 .flushed => {},1073 .flushed => {},
1198 }1074 }
1199 metadata.state.* = .pending_flush;1075 state_ptr.* = .pending_flush;
1200 const atom = metadata.atom.*;1076 const atom = atom_ptr.*;
1201 _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self);1077 _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self);
1202 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);1078 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);
1203 // anyerror needs to be deferred until flushModule1079 // anyerror needs to be deferred until flushModule
1204 if (sym.getDecl(self.base.comp.module.?) != .none) {1080 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbolAtom(pt, lazy_sym, atom);
1205 try self.updateLazySymbolAtom(pt, sym, atom);
1206 }
1207 return atom;1081 return atom;
1208}1082}
12091083
...@@ -1217,7 +1091,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a...@@ -1217,7 +1091,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a
1217 // create the symbol for the name1091 // create the symbol for the name
1218 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1092 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1219 @tagName(sym.kind),1093 @tagName(sym.kind),
1220 sym.ty.fmt(pt),1094 Type.fromInterned(sym.ty).fmt(pt),
1221 });1095 });
12221096
1223 const symbol: aout.Sym = .{1097 const symbol: aout.Sym = .{
...@@ -1228,7 +1102,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a...@@ -1228,7 +1102,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a
1228 self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;1102 self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;
12291103
1230 // generate the code1104 // 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;
1232 const res = try codegen.generateLazySymbol(1106 const res = try codegen.generateLazySymbol(
1233 &self.base,1107 &self.base,
1234 pt,1108 pt,
...@@ -1264,12 +1138,6 @@ pub fn deinit(self: *Plan9) void {...@@ -1264,12 +1138,6 @@ pub fn deinit(self: *Plan9) void {
1264 }1138 }
1265 self.relocs.deinit(gpa);1139 self.relocs.deinit(gpa);
1266 }1140 }
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);
1273 var it_lzc = self.lazy_syms.iterator();1141 var it_lzc = self.lazy_syms.iterator();
1274 while (it_lzc.next()) |kv| {1142 while (it_lzc.next()) |kv| {
1275 if (kv.value_ptr.text_state != .unused)1143 if (kv.value_ptr.text_state != .unused)
...@@ -1278,7 +1146,7 @@ pub fn deinit(self: *Plan9) void {...@@ -1278,7 +1146,7 @@ pub fn deinit(self: *Plan9) void {
1278 gpa.free(self.syms.items[self.getAtom(kv.value_ptr.rodata_atom).sym_index.?].name);1146 gpa.free(self.syms.items[self.getAtom(kv.value_ptr.rodata_atom).sym_index.?].name);
1279 }1147 }
1280 self.lazy_syms.deinit(gpa);1148 self.lazy_syms.deinit(gpa);
1281 var itf_files = self.fn_decl_table.iterator();1149 var itf_files = self.fn_nav_table.iterator();
1282 while (itf_files.next()) |ent| {1150 while (itf_files.next()) |ent| {
1283 // get the submap1151 // get the submap
1284 var submap = ent.value_ptr.functions;1152 var submap = ent.value_ptr.functions;
...@@ -1289,21 +1157,21 @@ pub fn deinit(self: *Plan9) void {...@@ -1289,21 +1157,21 @@ pub fn deinit(self: *Plan9) void {
1289 gpa.free(entry.value_ptr.lineinfo);1157 gpa.free(entry.value_ptr.lineinfo);
1290 }1158 }
1291 }1159 }
1292 self.fn_decl_table.deinit(gpa);1160 self.fn_nav_table.deinit(gpa);
1293 var itd = self.data_decl_table.iterator();1161 var itd = self.data_nav_table.iterator();
1294 while (itd.next()) |entry| {1162 while (itd.next()) |entry| {
1295 gpa.free(entry.value_ptr.*);1163 gpa.free(entry.value_ptr.*);
1296 }1164 }
1297 var it_anon = self.anon_decls.iterator();1165 var it_uav = self.uavs.iterator();
1298 while (it_anon.next()) |entry| {1166 while (it_uav.next()) |entry| {
1299 const sym_index = self.getAtom(entry.value_ptr.*).sym_index.?;1167 const sym_index = self.getAtom(entry.value_ptr.*).sym_index.?;
1300 gpa.free(self.syms.items[sym_index].name);1168 gpa.free(self.syms.items[sym_index].name);
1301 }1169 }
1302 self.data_decl_table.deinit(gpa);1170 self.data_nav_table.deinit(gpa);
1303 for (self.decl_exports.values()) |export_indices| {1171 for (self.nav_exports.values()) |export_indices| {
1304 gpa.free(export_indices);1172 gpa.free(export_indices);
1305 }1173 }
1306 self.decl_exports.deinit(gpa);1174 self.nav_exports.deinit(gpa);
1307 self.syms.deinit(gpa);1175 self.syms.deinit(gpa);
1308 self.got_index_free_list.deinit(gpa);1176 self.got_index_free_list.deinit(gpa);
1309 self.syms_index_free_list.deinit(gpa);1177 self.syms_index_free_list.deinit(gpa);
...@@ -1317,11 +1185,11 @@ pub fn deinit(self: *Plan9) void {...@@ -1317,11 +1185,11 @@ pub fn deinit(self: *Plan9) void {
1317 self.atoms.deinit(gpa);1185 self.atoms.deinit(gpa);
13181186
1319 {1187 {
1320 var it = self.decls.iterator();1188 var it = self.navs.iterator();
1321 while (it.next()) |entry| {1189 while (it.next()) |entry| {
1322 entry.value_ptr.exports.deinit(gpa);1190 entry.value_ptr.exports.deinit(gpa);
1323 }1191 }
1324 self.decls.deinit(gpa);1192 self.navs.deinit(gpa);
1325 }1193 }
1326}1194}
13271195
...@@ -1402,17 +1270,17 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -1402,17 +1270,17 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
14021270
1403 // write the data symbols1271 // write the data symbols
1404 {1272 {
1405 var it = self.data_decl_table.iterator();1273 var it = self.data_nav_table.iterator();
1406 while (it.next()) |entry| {1274 while (it.next()) |entry| {
1407 const decl_index = entry.key_ptr.*;1275 const nav_index = entry.key_ptr.*;
1408 const decl_metadata = self.decls.get(decl_index).?;1276 const nav_metadata = self.navs.get(nav_index).?;
1409 const atom = self.getAtom(decl_metadata.index);1277 const atom = self.getAtom(nav_metadata.index);
1410 const sym = self.syms.items[atom.sym_index.?];1278 const sym = self.syms.items[atom.sym_index.?];
1411 try self.writeSym(writer, sym);1279 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| {
1413 for (export_indices) |export_idx| {1281 for (export_indices) |export_idx| {
1414 const exp = mod.all_exports.items[export_idx];1282 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| {
1416 try self.writeSym(writer, self.syms.items[exp_i]);1284 try self.writeSym(writer, self.syms.items[exp_i]);
1417 }1285 }
1418 }1286 }
...@@ -1429,22 +1297,11 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -1429,22 +1297,11 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1429 try self.writeSym(writer, sym);1297 try self.writeSym(writer, sym);
1430 }1298 }
1431 }1299 }
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 }
1443 // text symbols are the hardest:1300 // text symbols are the hardest:
1444 // the file of a text symbol is the .z symbol before it1301 // the file of a text symbol is the .z symbol before it
1445 // so we have to write everything in the right order1302 // so we have to write everything in the right order
1446 {1303 {
1447 var it_file = self.fn_decl_table.iterator();1304 var it_file = self.fn_nav_table.iterator();
1448 while (it_file.next()) |fentry| {1305 while (it_file.next()) |fentry| {
1449 var symidx_and_submap = fentry.value_ptr;1306 var symidx_and_submap = fentry.value_ptr;
1450 // write the z symbols1307 // write the z symbols
...@@ -1454,15 +1311,15 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -1454,15 +1311,15 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1454 // write all the decls come from the file of the z symbol1311 // write all the decls come from the file of the z symbol
1455 var submap_it = symidx_and_submap.functions.iterator();1312 var submap_it = symidx_and_submap.functions.iterator();
1456 while (submap_it.next()) |entry| {1313 while (submap_it.next()) |entry| {
1457 const decl_index = entry.key_ptr.*;1314 const nav_index = entry.key_ptr.*;
1458 const decl_metadata = self.decls.get(decl_index).?;1315 const nav_metadata = self.navs.get(nav_index).?;
1459 const atom = self.getAtom(decl_metadata.index);1316 const atom = self.getAtom(nav_metadata.index);
1460 const sym = self.syms.items[atom.sym_index.?];1317 const sym = self.syms.items[atom.sym_index.?];
1461 try self.writeSym(writer, sym);1318 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| {
1463 for (export_indices) |export_idx| {1320 for (export_indices) |export_idx| {
1464 const exp = mod.all_exports.items[export_idx];1321 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| {
1466 const s = self.syms.items[exp_i];1323 const s = self.syms.items[exp_i];
1467 if (mem.eql(u8, s.name, "_start"))1324 if (mem.eql(u8, s.name, "_start"))
1468 self.entry_val = s.value;1325 self.entry_val = s.value;
...@@ -1500,31 +1357,31 @@ pub fn updateDeclLineNumber(self: *Plan9, pt: Zcu.PerThread, decl_index: InternP...@@ -1500,31 +1357,31 @@ pub fn updateDeclLineNumber(self: *Plan9, pt: Zcu.PerThread, decl_index: InternP
1500 _ = decl_index;1357 _ = decl_index;
1501}1358}
15021359
1503pub fn getDeclVAddr(1360pub fn getNavVAddr(
1504 self: *Plan9,1361 self: *Plan9,
1505 pt: Zcu.PerThread,1362 pt: Zcu.PerThread,
1506 decl_index: InternPool.DeclIndex,1363 nav_index: InternPool.Nav.Index,
1507 reloc_info: link.File.RelocInfo,1364 reloc_info: link.File.RelocInfo,
1508) !u64 {1365) !u64 {
1509 const ip = &pt.zcu.intern_pool;1366 const ip = &pt.zcu.intern_pool;
1510 const decl = pt.zcu.declPtr(decl_index);1367 const nav = ip.getNav(nav_index);
1511 log.debug("getDeclVAddr for {}", .{decl.name.fmt(ip)});1368 log.debug("getDeclVAddr for {}", .{nav.name.fmt(ip)});
1512 if (decl.isExtern(pt.zcu)) {1369 if (ip.indexToKey(nav.status.resolved.val) == .@"extern") {
1513 if (decl.name.eqlSlice("etext", ip)) {1370 if (nav.name.eqlSlice("etext", ip)) {
1514 try self.addReloc(reloc_info.parent_atom_index, .{1371 try self.addReloc(reloc_info.parent_atom_index, .{
1515 .target = undefined,1372 .target = undefined,
1516 .offset = reloc_info.offset,1373 .offset = reloc_info.offset,
1517 .addend = reloc_info.addend,1374 .addend = reloc_info.addend,
1518 .type = .special_etext,1375 .type = .special_etext,
1519 });1376 });
1520 } else if (decl.name.eqlSlice("edata", ip)) {1377 } else if (nav.name.eqlSlice("edata", ip)) {
1521 try self.addReloc(reloc_info.parent_atom_index, .{1378 try self.addReloc(reloc_info.parent_atom_index, .{
1522 .target = undefined,1379 .target = undefined,
1523 .offset = reloc_info.offset,1380 .offset = reloc_info.offset,
1524 .addend = reloc_info.addend,1381 .addend = reloc_info.addend,
1525 .type = .special_edata,1382 .type = .special_edata,
1526 });1383 });
1527 } else if (decl.name.eqlSlice("end", ip)) {1384 } else if (nav.name.eqlSlice("end", ip)) {
1528 try self.addReloc(reloc_info.parent_atom_index, .{1385 try self.addReloc(reloc_info.parent_atom_index, .{
1529 .target = undefined,1386 .target = undefined,
1530 .offset = reloc_info.offset,1387 .offset = reloc_info.offset,
...@@ -1536,7 +1393,7 @@ pub fn getDeclVAddr(...@@ -1536,7 +1393,7 @@ pub fn getDeclVAddr(
1536 return undefined;1393 return undefined;
1537 }1394 }
1538 // otherwise, we just add a relocation1395 // 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);
1540 // the parent_atom_index in this case is just the decl_index of the parent1397 // the parent_atom_index in this case is just the decl_index of the parent
1541 try self.addReloc(reloc_info.parent_atom_index, .{1398 try self.addReloc(reloc_info.parent_atom_index, .{
1542 .target = atom_index,1399 .target = atom_index,
...@@ -1546,15 +1403,14 @@ pub fn getDeclVAddr(...@@ -1546,15 +1403,14 @@ pub fn getDeclVAddr(
1546 return undefined;1403 return undefined;
1547}1404}
15481405
1549pub fn lowerAnonDecl(1406pub fn lowerUav(
1550 self: *Plan9,1407 self: *Plan9,
1551 pt: Zcu.PerThread,1408 pt: Zcu.PerThread,
1552 decl_val: InternPool.Index,1409 uav: InternPool.Index,
1553 explicit_alignment: InternPool.Alignment,1410 explicit_alignment: InternPool.Alignment,
1554 src_loc: Zcu.LazySrcLoc,1411 src_loc: Zcu.LazySrcLoc,
1555) !codegen.Result {1412) !codegen.GenResult {
1556 _ = explicit_alignment;1413 _ = explicit_alignment;
1557 // This is basically the same as lowerUnnamedConst.
1558 // example:1414 // example:
1559 // const ty = mod.intern_pool.typeOf(decl_val).toType();1415 // const ty = mod.intern_pool.typeOf(decl_val).toType();
1560 // const val = decl_val.toValue();1416 // const val = decl_val.toValue();
...@@ -1564,41 +1420,40 @@ pub fn lowerAnonDecl(...@@ -1564,41 +1420,40 @@ pub fn lowerAnonDecl(
1564 // to put it in some location.1420 // to put it in some location.
1565 // ...1421 // ...
1566 const gpa = self.base.comp.gpa;1422 const gpa = self.base.comp.gpa;
1567 const gop = try self.anon_decls.getOrPut(gpa, decl_val);1423 const gop = try self.uavs.getOrPut(gpa, uav);
1568 if (!gop.found_existing) {1424 if (gop.found_existing) return .{ .mcv = .{ .load_direct = gop.value_ptr.* } };
1569 const val = Value.fromInterned(decl_val);1425 const val = Value.fromInterned(uav);
1570 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});1426 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(uav)});
15711427
1572 const index = try self.createAtom();1428 const index = try self.createAtom();
1573 const got_index = self.allocateGotIndex();1429 const got_index = self.allocateGotIndex();
1574 gop.value_ptr.* = index;1430 gop.value_ptr.* = index;
1575 // we need to free name latex1431 // we need to free name latex
1576 var code_buffer = std.ArrayList(u8).init(gpa);1432 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 });1433 const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
1578 const code = switch (res) {1434 const code = switch (res) {
1579 .ok => code_buffer.items,1435 .ok => code_buffer.items,
1580 .fail => |em| return .{ .fail = em },1436 .fail => |em| return .{ .fail = em },
1581 };1437 };
1582 const atom_ptr = self.getAtomPtr(index);1438 const atom_ptr = self.getAtomPtr(index);
1583 atom_ptr.* = .{1439 atom_ptr.* = .{
1584 .type = .d,1440 .type = .d,
1585 .offset = undefined,1441 .offset = undefined,
1586 .sym_index = null,1442 .sym_index = null,
1587 .got_index = got_index,1443 .got_index = got_index,
1588 .code = Atom.CodePtr.fromSlice(code),1444 .code = Atom.CodePtr.fromSlice(code),
1589 };1445 };
1590 _ = try atom_ptr.getOrCreateSymbolTableEntry(self);1446 _ = try atom_ptr.getOrCreateSymbolTableEntry(self);
1591 self.syms.items[atom_ptr.sym_index.?] = .{1447 self.syms.items[atom_ptr.sym_index.?] = .{
1592 .type = .d,1448 .type = .d,
1593 .value = undefined,1449 .value = undefined,
1594 .name = name,1450 .name = name,
1595 };1451 };
1596 }1452 return .{ .mcv = .{ .load_direct = index } };
1597 return .ok;
1598}1453}
15991454
1600pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1455pub fn getUavVAddr(self: *Plan9, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1601 const atom_index = self.anon_decls.get(decl_val).?;1456 const atom_index = self.uavs.get(uav).?;
1602 try self.addReloc(reloc_info.parent_atom_index, .{1457 try self.addReloc(reloc_info.parent_atom_index, .{
1603 .target = atom_index,1458 .target = atom_index,
1604 .offset = reloc_info.offset,1459 .offset = reloc_info.offset,
src/link/SpirV.zig+20-20
...@@ -36,6 +36,7 @@ const trace = @import("../tracy.zig").trace;...@@ -36,6 +36,7 @@ const trace = @import("../tracy.zig").trace;
36const build_options = @import("build_options");36const build_options = @import("build_options");
37const Air = @import("../Air.zig");37const Air = @import("../Air.zig");
38const Liveness = @import("../Liveness.zig");38const Liveness = @import("../Liveness.zig");
39const Type = @import("../Type.zig");
39const Value = @import("../Value.zig");40const Value = @import("../Value.zig");
4041
41const SpvModule = @import("../codegen/spirv/Module.zig");42const SpvModule = @import("../codegen/spirv/Module.zig");
...@@ -50,8 +51,6 @@ base: link.File,...@@ -50,8 +51,6 @@ base: link.File,
5051
51object: codegen.Object,52object: codegen.Object,
5253
53pub const base_tag: link.File.Tag = .spirv;
54
55pub fn createEmpty(54pub fn createEmpty(
56 arena: Allocator,55 arena: Allocator,
57 comp: *Compilation,56 comp: *Compilation,
...@@ -128,22 +127,22 @@ pub fn updateFunc(self: *SpirV, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -128,22 +127,22 @@ pub fn updateFunc(self: *SpirV, pt: Zcu.PerThread, func_index: InternPool.Index,
128 @panic("Attempted to compile for architecture that was disabled by build configuration");127 @panic("Attempted to compile for architecture that was disabled by build configuration");
129 }128 }
130129
130 const ip = &pt.zcu.intern_pool;
131 const func = pt.zcu.funcInfo(func_index);131 const func = pt.zcu.funcInfo(func_index);
132 const decl = pt.zcu.declPtr(func.owner_decl);132 log.debug("lowering function {}", .{ip.getNav(func.owner_nav).name.fmt(ip)});
133 log.debug("lowering function {}", .{decl.name.fmt(&pt.zcu.intern_pool)});
134133
135 try self.object.updateFunc(pt, func_index, air, liveness);134 try self.object.updateFunc(pt, func_index, air, liveness);
136}135}
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 {
139 if (build_options.skip_non_native) {138 if (build_options.skip_non_native) {
140 @panic("Attempted to compile for architecture that was disabled by build configuration");139 @panic("Attempted to compile for architecture that was disabled by build configuration");
141 }140 }
142141
143 const decl = pt.zcu.declPtr(decl_index);142 const ip = &pt.zcu.intern_pool;
144 log.debug("lowering declaration {}", .{decl.name.fmt(&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);
147}146}
148147
149pub fn updateExports(148pub fn updateExports(
...@@ -152,19 +151,20 @@ pub fn updateExports(...@@ -152,19 +151,20 @@ pub fn updateExports(
152 exported: Zcu.Exported,151 exported: Zcu.Exported,
153 export_indices: []const u32,152 export_indices: []const u32,
154) !void {153) !void {
155 const mod = pt.zcu;154 const zcu = pt.zcu;
156 const decl_index = switch (exported) {155 const ip = &zcu.intern_pool;
157 .decl_index => |i| i,156 const nav_index = switch (exported) {
158 .value => |val| {157 .nav => |nav| nav,
159 _ = val;158 .uav => |uav| {
159 _ = uav;
160 @panic("TODO: implement SpirV linker code for exporting a constant value");160 @panic("TODO: implement SpirV linker code for exporting a constant value");
161 },161 },
162 };162 };
163 const decl = mod.declPtr(decl_index);163 const nav_ty = ip.getNav(nav_index).typeOf(ip);
164 if (decl.val.isFuncBody(mod)) {164 if (ip.isFunctionType(nav_ty)) {
165 const target = mod.getTarget();165 const target = zcu.getTarget();
166 const spv_decl_index = try self.object.resolveDecl(mod, decl_index);166 const spv_decl_index = try self.object.resolveNav(zcu, nav_index);
167 const execution_model = switch (decl.typeOf(mod).fnCallingConvention(mod)) {167 const execution_model = switch (Type.fromInterned(nav_ty).fnCallingConvention(zcu)) {
168 .Vertex => spec.ExecutionModel.Vertex,168 .Vertex => spec.ExecutionModel.Vertex,
169 .Fragment => spec.ExecutionModel.Fragment,169 .Fragment => spec.ExecutionModel.Fragment,
170 .Kernel => spec.ExecutionModel.Kernel,170 .Kernel => spec.ExecutionModel.Kernel,
...@@ -177,10 +177,10 @@ pub fn updateExports(...@@ -177,10 +177,10 @@ pub fn updateExports(
177 (is_vulkan and (execution_model == .Fragment or execution_model == .Vertex)))177 (is_vulkan and (execution_model == .Fragment or execution_model == .Vertex)))
178 {178 {
179 for (export_indices) |export_idx| {179 for (export_indices) |export_idx| {
180 const exp = mod.all_exports.items[export_idx];180 const exp = zcu.all_exports.items[export_idx];
181 try self.object.spv.declareEntryPoint(181 try self.object.spv.declareEntryPoint(
182 spv_decl_index,182 spv_decl_index,
183 exp.opts.name.toSlice(&mod.intern_pool),183 exp.opts.name.toSlice(ip),
184 execution_model,184 execution_model,
185 );185 );
186 }186 }
src/link/Wasm.zig+21-30
...@@ -39,8 +39,6 @@ const ZigObject = @import("Wasm/ZigObject.zig");...@@ -39,8 +39,6 @@ const ZigObject = @import("Wasm/ZigObject.zig");
39pub const Atom = @import("Wasm/Atom.zig");39pub const Atom = @import("Wasm/Atom.zig");
40pub const Relocation = types.Relocation;40pub const Relocation = types.Relocation;
4141
42pub const base_tag: link.File.Tag = .wasm;
43
44base: link.File,42base: link.File,
45/// Symbol name of the entry function to export43/// Symbol name of the entry function to export
46entry_name: ?[]const u8,44entry_name: ?[]const u8,
...@@ -1451,19 +1449,19 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index,...@@ -1451,19 +1449,19 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index,
1451 try wasm.zigObjectPtr().?.updateFunc(wasm, pt, func_index, air, liveness);1449 try wasm.zigObjectPtr().?.updateFunc(wasm, pt, func_index, air, liveness);
1452}1450}
14531451
1454// Generate code for the Decl, storing it in memory to be later written to1452// Generate code for the "Nav", storing it in memory to be later written to
1455// the file on flush().1453// 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 {
1457 if (build_options.skip_non_native and builtin.object_format != .wasm) {1455 if (build_options.skip_non_native and builtin.object_format != .wasm) {
1458 @panic("Attempted to compile for object format that was disabled by build configuration");1456 @panic("Attempted to compile for object format that was disabled by build configuration");
1459 }1457 }
1460 if (wasm.llvm_object) |llvm_object| return llvm_object.updateDecl(pt, decl_index);1458 if (wasm.llvm_object) |llvm_object| return llvm_object.updateNav(pt, nav);
1461 try wasm.zigObjectPtr().?.updateDecl(wasm, pt, decl_index);1459 try wasm.zigObjectPtr().?.updateNav(wasm, pt, nav);
1462}1460}
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 {
1465 if (wasm.llvm_object) |_| return;1463 if (wasm.llvm_object) |_| return;
1466 try wasm.zigObjectPtr().?.updateDeclLineNumber(pt, decl_index);1464 try wasm.zigObjectPtr().?.updateNavLineNumber(pt, nav);
1467}1465}
14681466
1469/// From a given symbol location, returns its `wasm.GlobalType`.1467/// From a given symbol location, returns its `wasm.GlobalType`.
...@@ -1505,13 +1503,6 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {...@@ -1505,13 +1503,6 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
1505 return wasm.func_types.items[wasm.functions.get(.{ .file = loc.file, .index = symbol.index }).?.func.type_index];1503 return wasm.func_types.items[wasm.functions.get(.{ .file = loc.file, .index = symbol.index }).?.func.type_index];
1506}1504}
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
1515/// Returns the symbol index from a symbol of which its flag is set global,1506/// Returns the symbol index from a symbol of which its flag is set global,
1516/// such as an exported or imported symbol.1507/// such as an exported or imported symbol.
1517/// If the symbol does not yet exist, creates a new one symbol instead1508/// 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...@@ -1521,29 +1512,29 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !Sy
1521 return wasm.zigObjectPtr().?.getGlobalSymbol(wasm.base.comp.gpa, name);1512 return wasm.zigObjectPtr().?.getGlobalSymbol(wasm.base.comp.gpa, name);
1522}1513}
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.
1525/// Returns the given pointer address1516/// Returns the given pointer address
1526pub fn getDeclVAddr(1517pub fn getNavVAddr(
1527 wasm: *Wasm,1518 wasm: *Wasm,
1528 pt: Zcu.PerThread,1519 pt: Zcu.PerThread,
1529 decl_index: InternPool.DeclIndex,1520 nav: InternPool.Nav.Index,
1530 reloc_info: link.File.RelocInfo,1521 reloc_info: link.File.RelocInfo,
1531) !u64 {1522) !u64 {
1532 return wasm.zigObjectPtr().?.getDeclVAddr(wasm, pt, decl_index, reloc_info);1523 return wasm.zigObjectPtr().?.getNavVAddr(wasm, pt, nav, reloc_info);
1533}1524}
15341525
1535pub fn lowerAnonDecl(1526pub fn lowerUav(
1536 wasm: *Wasm,1527 wasm: *Wasm,
1537 pt: Zcu.PerThread,1528 pt: Zcu.PerThread,
1538 decl_val: InternPool.Index,1529 uav: InternPool.Index,
1539 explicit_alignment: Alignment,1530 explicit_alignment: Alignment,
1540 src_loc: Zcu.LazySrcLoc,1531 src_loc: Zcu.LazySrcLoc,
1541) !codegen.Result {1532) !codegen.GenResult {
1542 return wasm.zigObjectPtr().?.lowerAnonDecl(wasm, pt, decl_val, explicit_alignment, src_loc);1533 return wasm.zigObjectPtr().?.lowerUav(wasm, pt, uav, explicit_alignment, src_loc);
1543}1534}
15441535
1545pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1536pub fn getUavVAddr(wasm: *Wasm, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1546 return wasm.zigObjectPtr().?.getAnonDeclVAddr(wasm, decl_val, reloc_info);1537 return wasm.zigObjectPtr().?.getUavVAddr(wasm, uav, reloc_info);
1547}1538}
15481539
1549pub fn deleteExport(1540pub fn deleteExport(
...@@ -4018,11 +4009,11 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {...@@ -4018,11 +4009,11 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
4018 return index;4009 return index;
4019}4010}
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.
4022/// Asserts declaration has an associated `Atom`.4013/// Asserts declaration has an associated `Atom`.
4023/// Returns the index into the list of types.4014/// Returns the index into the list of types.
4024pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {4015pub fn storeNavType(wasm: *Wasm, nav: InternPool.Nav.Index, func_type: std.wasm.Type) !u32 {
4025 return wasm.zigObjectPtr().?.storeDeclType(wasm.base.comp.gpa, decl_index, func_type);4016 return wasm.zigObjectPtr().?.storeDeclType(wasm.base.comp.gpa, nav, func_type);
4026}4017}
40274018
4028/// Returns the symbol index of the error name table.4019/// Returns the symbol index of the error name table.
...@@ -4036,8 +4027,8 @@ pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 {...@@ -4036,8 +4027,8 @@ pub fn getErrorTableSymbol(wasm_file: *Wasm, pt: Zcu.PerThread) !u32 {
4036/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.4027/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.
4037/// When the index was not found, a new `Atom` will be created, and its index will be returned.4028/// When the index was not found, a new `Atom` will be created, and its index will be returned.
4038/// The newly created Atom is empty with default fields as specified by `Atom.empty`.4029/// 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 {4030pub fn getOrCreateAtomForNav(wasm_file: *Wasm, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !Atom.Index {
4040 return wasm_file.zigObjectPtr().?.getOrCreateAtomForDecl(wasm_file, pt, decl_index);4031 return wasm_file.zigObjectPtr().?.getOrCreateAtomForNav(wasm_file, pt, nav);
4041}4032}
40424033
4043/// Verifies all resolved symbols and checks whether itself needs to be marked alive,4034/// Verifies all resolved symbols and checks whether itself needs to be marked alive,
src/link/Wasm/ZigObject.zig+174-223
...@@ -6,9 +6,9 @@...@@ -6,9 +6,9 @@
6path: []const u8,6path: []const u8,
7/// Index within the list of relocatable objects of the linker driver.7/// Index within the list of relocatable objects of the linker driver.
8index: File.Index,8index: File.Index,
9/// Map of all `Decl` that are currently alive.9/// Map of all `Nav` that are currently alive.
10/// Each index maps to the corresponding `DeclInfo`.10/// Each index maps to the corresponding `NavInfo`.
11decls_map: std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclInfo) = .{},11navs: std.AutoHashMapUnmanaged(InternPool.Nav.Index, NavInfo) = .{},
12/// List of function type signatures for this Zig module.12/// List of function type signatures for this Zig module.
13func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},13func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{},
14/// List of `std.wasm.Func`. Each entry contains the function signature,14/// List of `std.wasm.Func`. Each entry contains the function signature,
...@@ -36,7 +36,7 @@ segment_free_list: std.ArrayListUnmanaged(u32) = .{},...@@ -36,7 +36,7 @@ segment_free_list: std.ArrayListUnmanaged(u32) = .{},
36/// File encapsulated string table, used to deduplicate strings within the generated file.36/// File encapsulated string table, used to deduplicate strings within the generated file.
37string_table: StringTable = .{},37string_table: StringTable = .{},
38/// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index.38/// 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) = .{},
40/// List of atom indexes of functions that are generated by the backend.40/// List of atom indexes of functions that are generated by the backend.
41synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{},41synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{},
42/// Represents the symbol index of the error name table42/// Represents the symbol index of the error name table
...@@ -86,12 +86,12 @@ debug_str_index: ?u32 = null,...@@ -86,12 +86,12 @@ debug_str_index: ?u32 = null,
86/// The index of the segment representing the custom '.debug_pubtypes' section.86/// The index of the segment representing the custom '.debug_pubtypes' section.
87debug_abbrev_index: ?u32 = null,87debug_abbrev_index: ?u32 = null,
8888
89const DeclInfo = struct {89const NavInfo = struct {
90 atom: Atom.Index = .null,90 atom: Atom.Index = .null,
91 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},91 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
9292
93 fn @"export"(di: DeclInfo, zig_object: *const ZigObject, name: []const u8) ?Symbol.Index {93 fn @"export"(ni: NavInfo, zig_object: *const ZigObject, name: []const u8) ?Symbol.Index {
94 for (di.exports.items) |sym_index| {94 for (ni.exports.items) |sym_index| {
95 const sym_name_index = zig_object.symbol(sym_index).name;95 const sym_name_index = zig_object.symbol(sym_index).name;
96 const sym_name = zig_object.string_table.getAssumeExists(sym_name_index);96 const sym_name = zig_object.string_table.getAssumeExists(sym_name_index);
97 if (std.mem.eql(u8, name, sym_name)) {97 if (std.mem.eql(u8, name, sym_name)) {
...@@ -101,14 +101,14 @@ const DeclInfo = struct {...@@ -101,14 +101,14 @@ const DeclInfo = struct {
101 return null;101 return null;
102 }102 }
103103
104 fn appendExport(di: *DeclInfo, gpa: std.mem.Allocator, sym_index: Symbol.Index) !void {104 fn appendExport(ni: *NavInfo, gpa: std.mem.Allocator, sym_index: Symbol.Index) !void {
105 return di.exports.append(gpa, sym_index);105 return ni.exports.append(gpa, sym_index);
106 }106 }
107107
108 fn deleteExport(di: *DeclInfo, sym_index: Symbol.Index) void {108 fn deleteExport(ni: *NavInfo, sym_index: Symbol.Index) void {
109 for (di.exports.items, 0..) |idx, index| {109 for (ni.exports.items, 0..) |idx, index| {
110 if (idx == sym_index) {110 if (idx == sym_index) {
111 _ = di.exports.swapRemove(index);111 _ = ni.exports.swapRemove(index);
112 return;112 return;
113 }113 }
114 }114 }
...@@ -155,19 +155,19 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {...@@ -155,19 +155,19 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
155 }155 }
156156
157 {157 {
158 var it = zig_object.decls_map.valueIterator();158 var it = zig_object.navs.valueIterator();
159 while (it.next()) |decl_info| {159 while (it.next()) |nav_info| {
160 const atom = wasm_file.getAtomPtr(decl_info.atom);160 const atom = wasm_file.getAtomPtr(nav_info.atom);
161 for (atom.locals.items) |local_index| {161 for (atom.locals.items) |local_index| {
162 const local_atom = wasm_file.getAtomPtr(local_index);162 const local_atom = wasm_file.getAtomPtr(local_index);
163 local_atom.deinit(gpa);163 local_atom.deinit(gpa);
164 }164 }
165 atom.deinit(gpa);165 atom.deinit(gpa);
166 decl_info.exports.deinit(gpa);166 nav_info.exports.deinit(gpa);
167 }167 }
168 }168 }
169 {169 {
170 for (zig_object.anon_decls.values()) |atom_index| {170 for (zig_object.uavs.values()) |atom_index| {
171 const atom = wasm_file.getAtomPtr(atom_index);171 const atom = wasm_file.getAtomPtr(atom_index);
172 for (atom.locals.items) |local_index| {172 for (atom.locals.items) |local_index| {
173 const local_atom = wasm_file.getAtomPtr(local_index);173 const local_atom = wasm_file.getAtomPtr(local_index);
...@@ -201,8 +201,8 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {...@@ -201,8 +201,8 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
201 zig_object.atom_types.deinit(gpa);201 zig_object.atom_types.deinit(gpa);
202 zig_object.functions.deinit(gpa);202 zig_object.functions.deinit(gpa);
203 zig_object.imports.deinit(gpa);203 zig_object.imports.deinit(gpa);
204 zig_object.decls_map.deinit(gpa);204 zig_object.navs.deinit(gpa);
205 zig_object.anon_decls.deinit(gpa);205 zig_object.uavs.deinit(gpa);
206 zig_object.symbols.deinit(gpa);206 zig_object.symbols.deinit(gpa);
207 zig_object.symbols_free_list.deinit(gpa);207 zig_object.symbols_free_list.deinit(gpa);
208 zig_object.segment_info.deinit(gpa);208 zig_object.segment_info.deinit(gpa);
...@@ -236,34 +236,35 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In...@@ -236,34 +236,35 @@ pub fn allocateSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator) !Symbol.In
236 return index;236 return index;
237}237}
238238
239// Generate code for the Decl, storing it in memory to be later written to239// Generate code for the `Nav`, storing it in memory to be later written to
240// the file on flush().240// the file on flush().
241pub fn updateDecl(241pub fn updateNav(
242 zig_object: *ZigObject,242 zig_object: *ZigObject,
243 wasm_file: *Wasm,243 wasm_file: *Wasm,
244 pt: Zcu.PerThread,244 pt: Zcu.PerThread,
245 decl_index: InternPool.DeclIndex,245 nav_index: InternPool.Nav.Index,
246) !void {246) !void {
247 const mod = pt.zcu;247 const zcu = pt.zcu;
248 const decl = mod.declPtr(decl_index);248 const ip = &zcu.intern_pool;
249 if (decl.val.getFunction(mod)) |_| {249 const nav = ip.getNav(nav_index);
250 return;250
251 } else if (decl.val.getExternFunc(mod)) |_| {251 const is_extern, const lib_name, const nav_init = switch (ip.indexToKey(nav.status.resolved.val)) {
252 return;252 .variable => |variable| .{ false, variable.lib_name, variable.init },
253 }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
255 const gpa = wasm_file.base.comp.gpa;261 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);
257 const atom = wasm_file.getAtomPtr(atom_index);263 const atom = wasm_file.getAtomPtr(atom_index);
258 atom.clear();264 atom.clear();
259265
260 if (decl.isExtern(mod)) {266 if (is_extern)
261 const variable = decl.getOwnedVariable(mod).?;267 return zig_object.addOrUpdateImport(wasm_file, nav.name.toSlice(ip), atom.sym_index, lib_name.toSlice(ip), null);
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;
267268
268 var code_writer = std.ArrayList(u8).init(gpa);269 var code_writer = std.ArrayList(u8).init(gpa);
269 defer code_writer.deinit();270 defer code_writer.deinit();
...@@ -271,8 +272,8 @@ pub fn updateDecl(...@@ -271,8 +272,8 @@ pub fn updateDecl(
271 const res = try codegen.generateSymbol(272 const res = try codegen.generateSymbol(
272 &wasm_file.base,273 &wasm_file.base,
273 pt,274 pt,
274 decl.navSrcLoc(mod),275 zcu.navSrcLoc(nav_index),
275 val,276 Value.fromInterned(nav_init),
276 &code_writer,277 &code_writer,
277 .none,278 .none,
278 .{ .parent_atom_index = @intFromEnum(atom.sym_index) },279 .{ .parent_atom_index = @intFromEnum(atom.sym_index) },
...@@ -281,13 +282,12 @@ pub fn updateDecl(...@@ -281,13 +282,12 @@ pub fn updateDecl(
281 const code = switch (res) {282 const code = switch (res) {
282 .ok => code_writer.items,283 .ok => code_writer.items,
283 .fail => |em| {284 .fail => |em| {
284 decl.analysis = .codegen_failure;285 try zcu.failed_codegen.put(zcu.gpa, nav_index, em);
285 try mod.failed_analysis.put(mod.gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
286 return;286 return;
287 },287 },
288 };288 };
289289
290 return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code);290 return zig_object.finishUpdateNav(wasm_file, pt, nav_index, code);
291}291}
292292
293pub fn updateFunc(293pub fn updateFunc(
...@@ -298,11 +298,10 @@ pub fn updateFunc(...@@ -298,11 +298,10 @@ pub fn updateFunc(
298 air: Air,298 air: Air,
299 liveness: Liveness,299 liveness: Liveness,
300) !void {300) !void {
301 const gpa = wasm_file.base.comp.gpa;301 const zcu = pt.zcu;
302 const gpa = zcu.gpa;
302 const func = pt.zcu.funcInfo(func_index);303 const func = pt.zcu.funcInfo(func_index);
303 const decl_index = func.owner_decl;304 const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, func.owner_nav);
304 const decl = pt.zcu.declPtr(decl_index);
305 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
306 const atom = wasm_file.getAtomPtr(atom_index);305 const atom = wasm_file.getAtomPtr(atom_index);
307 atom.clear();306 atom.clear();
308307
...@@ -311,7 +310,7 @@ pub fn updateFunc(...@@ -311,7 +310,7 @@ pub fn updateFunc(
311 const result = try codegen.generateFunction(310 const result = try codegen.generateFunction(
312 &wasm_file.base,311 &wasm_file.base,
313 pt,312 pt,
314 decl.navSrcLoc(pt.zcu),313 zcu.navSrcLoc(func.owner_nav),
315 func_index,314 func_index,
316 air,315 air,
317 liveness,316 liveness,
...@@ -322,79 +321,75 @@ pub fn updateFunc(...@@ -322,79 +321,75 @@ pub fn updateFunc(
322 const code = switch (result) {321 const code = switch (result) {
323 .ok => code_writer.items,322 .ok => code_writer.items,
324 .fail => |em| {323 .fail => |em| {
325 decl.analysis = .codegen_failure;324 try pt.zcu.failed_codegen.put(gpa, func.owner_nav, em);
326 try pt.zcu.failed_analysis.put(gpa, AnalUnit.wrap(.{ .decl = decl_index }), em);
327 return;325 return;
328 },326 },
329 };327 };
330328
331 return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code);329 return zig_object.finishUpdateNav(wasm_file, pt, func.owner_nav, code);
332}330}
333331
334fn finishUpdateDecl(332fn finishUpdateNav(
335 zig_object: *ZigObject,333 zig_object: *ZigObject,
336 wasm_file: *Wasm,334 wasm_file: *Wasm,
337 pt: Zcu.PerThread,335 pt: Zcu.PerThread,
338 decl_index: InternPool.DeclIndex,336 nav_index: InternPool.Nav.Index,
339 code: []const u8,337 code: []const u8,
340) !void {338) !void {
341 const zcu = pt.zcu;339 const zcu = pt.zcu;
342 const ip = &zcu.intern_pool;340 const ip = &zcu.intern_pool;
343 const gpa = zcu.gpa;341 const gpa = zcu.gpa;
344 const decl = zcu.declPtr(decl_index);342 const nav = ip.getNav(nav_index);
345 const decl_info = zig_object.decls_map.get(decl_index).?;343 const nav_val = zcu.navValue(nav_index);
346 const atom_index = decl_info.atom;344 const nav_info = zig_object.navs.get(nav_index).?;
345 const atom_index = nav_info.atom;
347 const atom = wasm_file.getAtomPtr(atom_index);346 const atom = wasm_file.getAtomPtr(atom_index);
348 const sym = zig_object.symbol(atom.sym_index);347 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));
350 try atom.code.appendSlice(gpa, code);349 try atom.code.appendSlice(gpa, code);
351 atom.size = @intCast(code.len);350 atom.size = @intCast(code.len);
352351
353 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {352 if (ip.isFunctionType(nav.typeOf(ip))) {
354 .Fn => {353 sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? });
355 sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? });354 sym.tag = .function;
356 sym.tag = .function;355 } else {
357 },356 const is_const, const nav_init = switch (ip.indexToKey(nav_val.toIntern())) {
358 else => {357 .variable => |variable| .{ false, variable.init },
359 const segment_name: []const u8 = if (decl.getOwnedVariable(zcu)) |variable| name: {358 .@"extern" => |@"extern"| .{ @"extern".is_const, .none },
360 if (variable.is_const) {359 else => .{ true, nav_val.toIntern() },
361 break :name ".rodata.";360 };
362 } else if (Value.fromInterned(variable.init).isUndefDeep(zcu)) {361 const segment_name = name: {
363 const decl_namespace = zcu.namespacePtr(decl.src_namespace);362 if (is_const) break :name ".rodata.";
364 const optimize_mode = decl_namespace.fileScope(zcu).mod.optimize_mode;363
365 const is_initialized = switch (optimize_mode) {364 if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) {
366 .Debug, .ReleaseSafe => true,365 break :name switch (zcu.navFileScope(nav_index).mod.optimize_mode) {
367 .ReleaseFast, .ReleaseSmall => false,366 .Debug, .ReleaseSafe => ".data.",
368 };367 .ReleaseFast, .ReleaseSmall => ".bss.",
369 if (is_initialized) {368 };
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);
385 }369 }
386 // Will be freed upon freeing of decl or after cleanup of Wasm binary.370 // when the decl is all zeroes, we store the atom in the bss segment,
387 const full_segment_name = try std.mem.concat(gpa, u8, &.{371 // in all other cases it will be in the data segment.
388 segment_name,372 for (atom.code.items) |byte| {
389 decl.fqn.toSlice(ip),373 if (byte != 0) break :name ".data.";
390 });374 }
391 errdefer gpa.free(full_segment_name);375 break :name ".bss.";
392 sym.tag = .data;376 };
393 sym.index = try zig_object.createDataSegment(gpa, full_segment_name, decl.alignment);377 if ((wasm_file.base.isObject() or wasm_file.base.comp.config.import_memory) and
394 },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));
395 }390 }
396 if (code.len == 0) return;391 if (code.len == 0) return;
397 atom.alignment = decl.getAlignment(pt);392 atom.alignment = pt.navAlignment(nav_index);
398}393}
399394
400/// Creates and initializes a new segment in the 'Data' section.395/// Creates and initializes a new segment in the 'Data' section.
...@@ -420,50 +415,51 @@ fn createDataSegment(...@@ -420,50 +415,51 @@ fn createDataSegment(
420 return segment_index;415 return segment_index;
421}416}
422417
423/// For a given `InternPool.DeclIndex` returns its corresponding `Atom.Index`.418/// For a given `InternPool.Nav.Index` returns its corresponding `Atom.Index`.
424/// When the index was not found, a new `Atom` will be created, and its index will be returned.419/// When the index was not found, a new `Atom` will be created, and its index will be returned.
425/// The newly created Atom is empty with default fields as specified by `Atom.empty`.420/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
426pub fn getOrCreateAtomForDecl(421pub fn getOrCreateAtomForNav(
427 zig_object: *ZigObject,422 zig_object: *ZigObject,
428 wasm_file: *Wasm,423 wasm_file: *Wasm,
429 pt: Zcu.PerThread,424 pt: Zcu.PerThread,
430 decl_index: InternPool.DeclIndex,425 nav_index: InternPool.Nav.Index,
431) !Atom.Index {426) !Atom.Index {
427 const ip = &pt.zcu.intern_pool;
432 const gpa = pt.zcu.gpa;428 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);
434 if (!gop.found_existing) {430 if (!gop.found_existing) {
435 const sym_index = try zig_object.allocateSymbol(gpa);431 const sym_index = try zig_object.allocateSymbol(gpa);
436 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };432 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);
438 const sym = zig_object.symbol(sym_index);434 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));
440 }436 }
441 return gop.value_ptr.atom;437 return gop.value_ptr.atom;
442}438}
443439
444pub fn lowerAnonDecl(440pub fn lowerUav(
445 zig_object: *ZigObject,441 zig_object: *ZigObject,
446 wasm_file: *Wasm,442 wasm_file: *Wasm,
447 pt: Zcu.PerThread,443 pt: Zcu.PerThread,
448 decl_val: InternPool.Index,444 uav: InternPool.Index,
449 explicit_alignment: InternPool.Alignment,445 explicit_alignment: InternPool.Alignment,
450 src_loc: Zcu.LazySrcLoc,446 src_loc: Zcu.LazySrcLoc,
451) !codegen.Result {447) !codegen.GenResult {
452 const gpa = wasm_file.base.comp.gpa;448 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);
454 if (!gop.found_existing) {450 if (!gop.found_existing) {
455 var name_buf: [32]u8 = undefined;451 var name_buf: [32]u8 = undefined;
456 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{452 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
457 @intFromEnum(decl_val),453 @intFromEnum(uav),
458 }) catch unreachable;454 }) catch unreachable;
459455
460 switch (try zig_object.lowerConst(wasm_file, pt, name, Value.fromInterned(decl_val), src_loc)) {456 switch (try zig_object.lowerConst(wasm_file, pt, name, Value.fromInterned(uav), src_loc)) {
461 .ok => |atom_index| zig_object.anon_decls.values()[gop.index] = atom_index,457 .ok => |atom_index| zig_object.uavs.values()[gop.index] = atom_index,
462 .fail => |em| return .{ .fail = em },458 .fail => |em| return .{ .fail = em },
463 }459 }
464 }460 }
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]);
467 atom.alignment = switch (atom.alignment) {463 atom.alignment = switch (atom.alignment) {
468 .none => explicit_alignment,464 .none => explicit_alignment,
469 else => switch (explicit_alignment) {465 else => switch (explicit_alignment) {
...@@ -471,53 +467,7 @@ pub fn lowerAnonDecl(...@@ -471,53 +467,7 @@ pub fn lowerAnonDecl(
471 else => atom.alignment.maxStrict(explicit_alignment),467 else => atom.alignment.maxStrict(explicit_alignment),
472 },468 },
473 };469 };
474 return .ok;470 return .{ .mcv = .{ .load_symbol = @intFromEnum(atom.sym_index) } };
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 }
521}471}
522472
523const LowerConstResult = union(enum) {473const LowerConstResult = union(enum) {
...@@ -782,36 +732,38 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c...@@ -782,36 +732,38 @@ pub fn getGlobalSymbol(zig_object: *ZigObject, gpa: std.mem.Allocator, name: []c
782732
783/// For a given decl, find the given symbol index's atom, and create a relocation for the type.733/// For a given decl, find the given symbol index's atom, and create a relocation for the type.
784/// Returns the given pointer address734/// Returns the given pointer address
785pub fn getDeclVAddr(735pub fn getNavVAddr(
786 zig_object: *ZigObject,736 zig_object: *ZigObject,
787 wasm_file: *Wasm,737 wasm_file: *Wasm,
788 pt: Zcu.PerThread,738 pt: Zcu.PerThread,
789 decl_index: InternPool.DeclIndex,739 nav_index: InternPool.Nav.Index,
790 reloc_info: link.File.RelocInfo,740 reloc_info: link.File.RelocInfo,
791) !u64 {741) !u64 {
792 const target = wasm_file.base.comp.root_mod.resolved_target.result;
793 const zcu = pt.zcu;742 const zcu = pt.zcu;
794 const ip = &zcu.intern_pool;743 const ip = &zcu.intern_pool;
795 const gpa = zcu.gpa;744 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);
799 const target_atom = wasm_file.getAtom(target_atom_index);749 const target_atom = wasm_file.getAtom(target_atom_index);
800 const target_symbol_index = @intFromEnum(target_atom.sym_index);750 const target_symbol_index = @intFromEnum(target_atom.sym_index);
801 if (decl.isExtern(zcu)) {751 switch (ip.indexToKey(nav.status.resolved.val)) {
802 const name = decl.name.toSlice(ip);752 .@"extern" => |@"extern"| try zig_object.addOrUpdateImport(
803 const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn|753 wasm_file,
804 ext_fn.lib_name.toSlice(ip)754 nav.name.toSlice(ip),
805 else755 target_atom.sym_index,
806 decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip);756 @"extern".lib_name.toSlice(ip),
807 try zig_object.addOrUpdateImport(wasm_file, name, target_atom.sym_index, lib_name, null);757 null,
758 ),
759 else => {},
808 }760 }
809761
810 std.debug.assert(reloc_info.parent_atom_index != 0);762 std.debug.assert(reloc_info.parent_atom_index != 0);
811 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;763 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
812 const atom = wasm_file.getAtomPtr(atom_index);764 const atom = wasm_file.getAtomPtr(atom_index);
813 const is_wasm32 = target.cpu.arch == .wasm32;765 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))) {
815 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations767 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
816 try atom.relocs.append(gpa, .{768 try atom.relocs.append(gpa, .{
817 .index = target_symbol_index,769 .index = target_symbol_index,
...@@ -834,22 +786,22 @@ pub fn getDeclVAddr(...@@ -834,22 +786,22 @@ pub fn getDeclVAddr(
834 return target_symbol_index;786 return target_symbol_index;
835}787}
836788
837pub fn getAnonDeclVAddr(789pub fn getUavVAddr(
838 zig_object: *ZigObject,790 zig_object: *ZigObject,
839 wasm_file: *Wasm,791 wasm_file: *Wasm,
840 decl_val: InternPool.Index,792 uav: InternPool.Index,
841 reloc_info: link.File.RelocInfo,793 reloc_info: link.File.RelocInfo,
842) !u64 {794) !u64 {
843 const gpa = wasm_file.base.comp.gpa;795 const gpa = wasm_file.base.comp.gpa;
844 const target = wasm_file.base.comp.root_mod.resolved_target.result;796 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).?;
846 const target_symbol_index = @intFromEnum(wasm_file.getAtom(atom_index).sym_index);798 const target_symbol_index = @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
847799
848 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;800 const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;
849 const parent_atom = wasm_file.getAtomPtr(parent_atom_index);801 const parent_atom = wasm_file.getAtomPtr(parent_atom_index);
850 const is_wasm32 = target.cpu.arch == .wasm32;802 const is_wasm32 = target.cpu.arch == .wasm32;
851 const mod = wasm_file.base.comp.module.?;803 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));
853 if (ty.zigTypeTag(mod) == .Fn) {805 if (ty.zigTypeTag(mod) == .Fn) {
854 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations806 std.debug.assert(reloc_info.addend == 0); // addend not allowed for function relocations
855 try parent_atom.relocs.append(gpa, .{807 try parent_atom.relocs.append(gpa, .{
...@@ -880,14 +832,14 @@ pub fn deleteExport(...@@ -880,14 +832,14 @@ pub fn deleteExport(
880 name: InternPool.NullTerminatedString,832 name: InternPool.NullTerminatedString,
881) void {833) void {
882 const mod = wasm_file.base.comp.module.?;834 const mod = wasm_file.base.comp.module.?;
883 const decl_index = switch (exported) {835 const nav_index = switch (exported) {
884 .decl_index => |decl_index| decl_index,836 .nav => |nav_index| nav_index,
885 .value => @panic("TODO: implement Wasm linker code for exporting a constant value"),837 .uav => @panic("TODO: implement Wasm linker code for exporting a constant value"),
886 };838 };
887 const decl_info = zig_object.decls_map.getPtr(decl_index) orelse return;839 const nav_info = zig_object.navs.getPtr(nav_index) orelse return;
888 if (decl_info.@"export"(zig_object, name.toSlice(&mod.intern_pool))) |sym_index| {840 if (nav_info.@"export"(zig_object, name.toSlice(&mod.intern_pool))) |sym_index| {
889 const sym = zig_object.symbol(sym_index);841 const sym = zig_object.symbol(sym_index);
890 decl_info.deleteExport(sym_index);842 nav_info.deleteExport(sym_index);
891 std.debug.assert(zig_object.global_syms.remove(sym.name));843 std.debug.assert(zig_object.global_syms.remove(sym.name));
892 std.debug.assert(wasm_file.symbol_atom.remove(.{ .file = zig_object.index, .index = sym_index }));844 std.debug.assert(wasm_file.symbol_atom.remove(.{ .file = zig_object.index, .index = sym_index }));
893 zig_object.symbols_free_list.append(wasm_file.base.comp.gpa, sym_index) catch {};845 zig_object.symbols_free_list.append(wasm_file.base.comp.gpa, sym_index) catch {};
...@@ -902,38 +854,39 @@ pub fn updateExports(...@@ -902,38 +854,39 @@ pub fn updateExports(
902 exported: Zcu.Exported,854 exported: Zcu.Exported,
903 export_indices: []const u32,855 export_indices: []const u32,
904) !void {856) !void {
905 const mod = pt.zcu;857 const zcu = pt.zcu;
906 const decl_index = switch (exported) {858 const ip = &zcu.intern_pool;
907 .decl_index => |i| i,859 const nav_index = switch (exported) {
908 .value => |val| {860 .nav => |nav| nav,
909 _ = val;861 .uav => |uav| {
862 _ = uav;
910 @panic("TODO: implement Wasm linker code for exporting a constant value");863 @panic("TODO: implement Wasm linker code for exporting a constant value");
911 },864 },
912 };865 };
913 const decl = mod.declPtr(decl_index);866 const nav = ip.getNav(nav_index);
914 const atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);867 const atom_index = try zig_object.getOrCreateAtomForNav(wasm_file, pt, nav_index);
915 const decl_info = zig_object.decls_map.getPtr(decl_index).?;868 const nav_info = zig_object.navs.getPtr(nav_index).?;
916 const atom = wasm_file.getAtom(atom_index);869 const atom = wasm_file.getAtom(atom_index);
917 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;870 const atom_sym = atom.symbolLoc().getSymbol(wasm_file).*;
918 const gpa = mod.gpa;871 const gpa = zcu.gpa;
919 log.debug("Updating exports for decl '{}'", .{decl.name.fmt(&mod.intern_pool)});872 log.debug("Updating exports for decl '{}'", .{nav.name.fmt(ip)});
920873
921 for (export_indices) |export_idx| {874 for (export_indices) |export_idx| {
922 const exp = mod.all_exports.items[export_idx];875 const exp = zcu.all_exports.items[export_idx];
923 if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {876 if (exp.opts.section.toSlice(ip)) |section| {
924 try mod.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(877 try zcu.failed_exports.putNoClobber(gpa, export_idx, try Zcu.ErrorMsg.create(
925 gpa,878 gpa,
926 decl.navSrcLoc(mod),879 zcu.navSrcLoc(nav_index),
927 "Unimplemented: ExportOptions.section '{s}'",880 "Unimplemented: ExportOptions.section '{s}'",
928 .{section},881 .{section},
929 ));882 ));
930 continue;883 continue;
931 }884 }
932885
933 const export_string = exp.opts.name.toSlice(&mod.intern_pool);886 const export_string = exp.opts.name.toSlice(ip);
934 const sym_index = if (decl_info.@"export"(zig_object, export_string)) |idx| idx else index: {887 const sym_index = if (nav_info.@"export"(zig_object, export_string)) |idx| idx else index: {
935 const sym_index = try zig_object.allocateSymbol(gpa);888 const sym_index = try zig_object.allocateSymbol(gpa);
936 try decl_info.appendExport(gpa, sym_index);889 try nav_info.appendExport(gpa, sym_index);
937 break :index sym_index;890 break :index sym_index;
938 };891 };
939892
...@@ -954,9 +907,9 @@ pub fn updateExports(...@@ -954,9 +907,9 @@ pub fn updateExports(
954 },907 },
955 .strong => {}, // symbols are strong by default908 .strong => {}, // symbols are strong by default
956 .link_once => {909 .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(
958 gpa,911 gpa,
959 decl.navSrcLoc(mod),912 zcu.navSrcLoc(nav_index),
960 "Unimplemented: LinkOnce",913 "Unimplemented: LinkOnce",
961 .{},914 .{},
962 ));915 ));
...@@ -972,21 +925,21 @@ pub fn updateExports(...@@ -972,21 +925,21 @@ pub fn updateExports(
972 }925 }
973}926}
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 {
976 const gpa = wasm_file.base.comp.gpa;929 const gpa = wasm_file.base.comp.gpa;
977 const mod = wasm_file.base.comp.module.?;930 const mod = wasm_file.base.comp.module.?;
978 const decl = mod.declPtr(decl_index);931 const ip = &mod.intern_pool;
979 const decl_info = zig_object.decls_map.getPtr(decl_index).?;932 const nav_info = zig_object.navs.getPtr(nav_index).?;
980 const atom_index = decl_info.atom;933 const atom_index = nav_info.atom;
981 const atom = wasm_file.getAtomPtr(atom_index);934 const atom = wasm_file.getAtomPtr(atom_index);
982 zig_object.symbols_free_list.append(gpa, atom.sym_index) catch {};935 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| {
984 const exp_sym = zig_object.symbol(exp_sym_index);937 const exp_sym = zig_object.symbol(exp_sym_index);
985 exp_sym.tag = .dead;938 exp_sym.tag = .dead;
986 zig_object.symbols_free_list.append(exp_sym_index) catch {};939 zig_object.symbols_free_list.append(exp_sym_index) catch {};
987 }940 }
988 decl_info.exports.deinit(gpa);941 nav_info.exports.deinit(gpa);
989 std.debug.assert(zig_object.decls_map.remove(decl_index));942 std.debug.assert(zig_object.navs.remove(nav_index));
990 const sym = &zig_object.symbols.items[atom.sym_index];943 const sym = &zig_object.symbols.items[atom.sym_index];
991 for (atom.locals.items) |local_atom_index| {944 for (atom.locals.items) |local_atom_index| {
992 const local_atom = wasm_file.getAtom(local_atom_index);945 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...@@ -1000,7 +953,8 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
1000 segment.name = &.{}; // Ensure no accidental double free953 segment.name = &.{}; // Ensure no accidental double free
1001 }954 }
1002955
1003 if (decl.isExtern(mod)) {956 const nav_val = mod.navValue(nav_index).toIntern();
957 if (ip.indexToKey(nav_val) == .@"extern") {
1004 std.debug.assert(zig_object.imports.remove(atom.sym_index));958 std.debug.assert(zig_object.imports.remove(atom.sym_index));
1005 }959 }
1006 std.debug.assert(wasm_file.symbol_atom.remove(atom.symbolLoc()));960 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...@@ -1014,17 +968,14 @@ pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool
1014 if (sym.isGlobal()) {968 if (sym.isGlobal()) {
1015 std.debug.assert(zig_object.global_syms.remove(atom.sym_index));969 std.debug.assert(zig_object.global_syms.remove(atom.sym_index));
1016 }970 }
1017 switch (decl.typeOf(mod).zigTypeTag(mod)) {971 if (ip.isFunctionType(ip.typeOf(nav_val))) {
1018 .Fn => {972 zig_object.functions_free_list.append(gpa, sym.index) catch {};
1019 zig_object.functions_free_list.append(gpa, sym.index) catch {};973 std.debug.assert(zig_object.atom_types.remove(atom_index));
1020 std.debug.assert(zig_object.atom_types.remove(atom_index));974 } else {
1021 },975 zig_object.segment_free_list.append(gpa, sym.index) catch {};
1022 else => {976 const segment = &zig_object.segment_info.items[sym.index];
1023 zig_object.segment_free_list.append(gpa, sym.index) catch {};977 gpa.free(segment.name);
1024 const segment = &zig_object.segment_info.items[sym.index];978 segment.name = &.{}; // Prevent accidental double free
1025 gpa.free(segment.name);
1026 segment.name = &.{}; // Prevent accidental double free
1027 },
1028 }979 }
1029}980}
1030981
...@@ -1182,10 +1133,10 @@ fn allocateDebugAtoms(zig_object: *ZigObject) !void {...@@ -1182,10 +1133,10 @@ fn allocateDebugAtoms(zig_object: *ZigObject) !void {
1182/// For the given `decl_index`, stores the corresponding type representing the function signature.1133/// For the given `decl_index`, stores the corresponding type representing the function signature.
1183/// Asserts declaration has an associated `Atom`.1134/// Asserts declaration has an associated `Atom`.
1184/// Returns the index into the list of types.1135/// 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 {1136pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, nav_index: InternPool.Nav.Index, func_type: std.wasm.Type) !u32 {
1186 const decl_info = zig_object.decls_map.get(decl_index).?;1137 const nav_info = zig_object.navs.get(nav_index).?;
1187 const index = try zig_object.putOrGetFuncType(gpa, func_type);1138 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);
1189 return index;1140 return index;
1190}1141}
11911142
src/print_air.zig+1-1
...@@ -675,7 +675,7 @@ const Writer = struct {...@@ -675,7 +675,7 @@ const Writer = struct {
675 }675 }
676 }676 }
677 const asm_source = std.mem.sliceAsBytes(w.air.extra[extra_i..])[0..extra.data.source_len];677 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)});
679 }679 }
680680
681 fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {681 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(...@@ -90,12 +90,8 @@ pub fn print(
90 else => try writer.writeAll(@tagName(simple_value)),90 else => try writer.writeAll(@tagName(simple_value)),
91 },91 },
92 .variable => try writer.writeAll("(variable)"),92 .variable => try writer.writeAll("(variable)"),
93 .extern_func => |extern_func| try writer.print("(extern function '{}')", .{93 .@"extern" => |e| try writer.print("(extern '{}')", .{e.name.fmt(ip)}),
94 mod.declPtr(extern_func.decl).name.fmt(ip),94 .func => |func| try writer.print("(function '{}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}),
95 }),
96 .func => |func| try writer.print("(function '{}')", .{
97 mod.declPtr(func.owner_decl).name.fmt(ip),
98 }),
99 .int => |int| switch (int.storage) {95 .int => |int| switch (int.storage) {
100 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),96 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
101 .lazy_align => |ty| if (have_sema) {97 .lazy_align => |ty| if (have_sema) {
...@@ -138,8 +134,8 @@ pub fn print(...@@ -138,8 +134,8 @@ pub fn print(
138 .slice => |slice| {134 .slice => |slice| {
139 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {135 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
140 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,136 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
141 .anon_decl, .comptime_alloc, .comptime_field => true,137 .uav, .comptime_alloc, .comptime_field => true,
142 .decl, .int => false,138 .nav, .int => false,
143 };139 };
144 if (print_contents) {140 if (print_contents) {
145 // TODO: eventually we want to load the slice as an array with `sema`, but that's141 // TODO: eventually we want to load the slice as an array with `sema`, but that's
...@@ -157,8 +153,8 @@ pub fn print(...@@ -157,8 +153,8 @@ pub fn print(
157 .ptr => {153 .ptr => {
158 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {154 const print_contents = switch (ip.getBackingAddrTag(val.toIntern()).?) {
159 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,155 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
160 .anon_decl, .comptime_alloc, .comptime_field => true,156 .uav, .comptime_alloc, .comptime_field => true,
161 .decl, .int => false,157 .nav, .int => false,
162 };158 };
163 if (print_contents) {159 if (print_contents) {
164 // TODO: eventually we want to load the pointer with `sema`, but that's160 // TODO: eventually we want to load the pointer with `sema`, but that's
...@@ -294,11 +290,11 @@ fn printPtr(...@@ -294,11 +290,11 @@ fn printPtr(
294 else => unreachable,290 else => unreachable,
295 };291 };
296292
297 if (ptr.base_addr == .anon_decl) {293 if (ptr.base_addr == .uav) {
298 // If the value is an aggregate, we can potentially print it more nicely.294 // 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)) {
300 .aggregate => |agg| return printAggregate(296 .aggregate => |agg| return printAggregate(
301 Value.fromInterned(ptr.base_addr.anon_decl.val),297 Value.fromInterned(ptr.base_addr.uav.val),
302 agg,298 agg,
303 true,299 true,
304 writer,300 writer,
...@@ -333,13 +329,13 @@ fn printPtrDerivation(...@@ -333,13 +329,13 @@ fn printPtrDerivation(
333 int.ptr_ty.fmt(pt),329 int.ptr_ty.fmt(pt),
334 int.addr,330 int.addr,
335 }),331 }),
336 .decl_ptr => |decl_index| {332 .nav_ptr => |nav| {
337 try writer.print("{}", .{zcu.declPtr(decl_index).fqn.fmt(ip)});333 try writer.print("{}", .{ip.getNav(nav).fqn.fmt(ip)});
338 },334 },
339 .anon_decl_ptr => |anon| {335 .uav_ptr => |uav| {
340 const ty = Value.fromInterned(anon.val).typeOf(zcu);336 const ty = Value.fromInterned(uav.val).typeOf(zcu);
341 try writer.print("@as({}, ", .{ty.fmt(pt)});337 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);
343 try writer.writeByte(')');339 try writer.writeByte(')');
344 },340 },
345 .comptime_alloc_ptr => |info| {341 .comptime_alloc_ptr => |info| {
test/behavior/type_info.zig+3-3
...@@ -605,9 +605,9 @@ test "@typeInfo decls and usingnamespace" {...@@ -605,9 +605,9 @@ test "@typeInfo decls and usingnamespace" {
605 };605 };
606 const decls = @typeInfo(B).Struct.decls;606 const decls = @typeInfo(B).Struct.decls;
607 try expect(decls.len == 3);607 try expect(decls.len == 3);
608 try expectEqualStrings(decls[0].name, "x");608 try expectEqualStrings(decls[0].name, "z");
609 try expectEqualStrings(decls[1].name, "y");609 try expectEqualStrings(decls[1].name, "x");
610 try expectEqualStrings(decls[2].name, "z");610 try expectEqualStrings(decls[2].name, "y");
611}611}
612612
613test "@typeInfo decls ignore dependency loops" {613test "@typeInfo decls ignore dependency loops" {
test/behavior/usingnamespace.zig-4
...@@ -90,10 +90,6 @@ test {...@@ -90,10 +90,6 @@ test {
90 try expect(a.x == AA.c().expected);90 try expect(a.x == AA.c().expected);
91}91}
9292
93comptime {
94 _ = @import("usingnamespace/file_1.zig");
95}
96
97const Bar = struct {93const Bar = struct {
98 usingnamespace Mixin;94 usingnamespace Mixin;
99};95};
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" {...@@ -8,5 +8,5 @@ test "enum" {
8// target=native8// target=native
9// is_test=true9// is_test=true
10//10//
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'
12// :2:15: note: declared here12// :2:15: note: declared here