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

compiler: split Decl into Nav and Cau

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

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

src/Compilation.zig+76-151
...@@ -354,28 +354,25 @@ pub const RcIncludes = enum {...@@ -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+921-459
...@@ -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:
840 /// * Stable memory so that one thread can access a Decl object while another
841 /// thread allocates additional Decl objects from this list.
842 /// * It allows us to use u32 indexes to reference Decl objects rather than
843 /// pointers, saving memory in Type, Value, and dependency sets.
844 /// * Using integers to reference Decl objects rather than pointers makes
845 /// serialization trivial.
846 /// * It provides a unique integer to be used for anonymous symbol names, avoiding
847 /// multi-threaded contention on an atomic counter.
848 pub fn getMutableDecls(local: *Local, gpa: Allocator) Decls.Mutable {
849 return .{1103 return .{
850 .gpa = gpa,1104 .gpa = gpa,
851 .arena = &local.mutate.arena,1105 .arena = &local.mutate.arena,
852 .mutate = &local.mutate.decls.buckets_list,1106 .mutate = &local.mutate.caus,
853 .list = &local.shared.decls,1107 .list = &local.shared.caus,
854 };1108 };
855 }1109 }
8561110
857 /// Same pattern as with `getMutableDecls`.1111 pub fn getMutableNavs(local: *Local, gpa: Allocator) Navs.Mutable {
1112 return .{
1113 .gpa = gpa,
1114 .arena = &local.mutate.arena,
1115 .mutate = &local.mutate.navs,
1116 .list = &local.shared.navs,
1117 };
1118 }
1119
1120 /// Rather than allocating Namespace objects with an Allocator, we instead allocate
1121 /// them with this BucketList. This provides four advantages:
1122 /// * Stable memory so that one thread can access a Namespace object while another
1123 /// thread allocates additional Namespace objects from this list.
1124 /// * It allows us to use u32 indexes to reference Namespace objects rather than
1125 /// pointers, saving memory in types.
1126 /// * Using integers to reference Namespace objects rather than pointers makes
1127 /// serialization trivial.
1128 /// * It provides a unique integer to be used for anonymous symbol names, avoiding
1129 /// multi-threaded contention on an atomic counter.
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,8 +2879,11 @@ pub const LoadedUnionType = struct {...@@ -2632,8 +2879,11 @@ 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: OptionalNamespaceIndex,
2639 /// The enum tag type.2889 /// The enum tag type.
...@@ -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,8 +3214,11 @@ pub const LoadedStructType = struct {...@@ -2963,8 +3214,11 @@ 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.
3219 name: NullTerminatedString,
3220 /// The `Cau` within which type resolution occurs. `none` when the struct is `@TypeOf(.{})`.
3221 cau: Cau.Index.Optional,
2968 /// `none` when the struct has no declarations.3222 /// `none` when the struct has no declarations.
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.
...@@ -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,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3577,7 +3832,8 @@ 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").?]);
3581 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);3837 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").?];3838 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));3839 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
...@@ -3667,7 +3923,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3667,7 +3923,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3667 return .{3923 return .{
3668 .tid = unwrapped_index.tid,3924 .tid = unwrapped_index.tid,
3669 .extra_index = item.data,3925 .extra_index = item.data,
3670 .decl = decl.toOptional(),3926 .name = name,
3927 .cau = cau.toOptional(),
3671 .namespace = namespace,3928 .namespace = namespace,
3672 .zir_index = zir_index.toOptional(),3929 .zir_index = zir_index.toOptional(),
3673 .layout = if (flags.is_extern) .@"extern" else .auto,3930 .layout = if (flags.is_extern) .@"extern" else .auto,
...@@ -3683,7 +3940,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3683,7 +3940,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3683 };3940 };
3684 },3941 },
3685 .type_struct_packed, .type_struct_packed_inits => {3942 .type_struct_packed, .type_struct_packed_inits => {
3686 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]);3943 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]);
3944 const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?]);
3687 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);3945 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").?];3946 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").?]);3947 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
...@@ -3729,7 +3987,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3729,7 +3987,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3729 return .{3987 return .{
3730 .tid = unwrapped_index.tid,3988 .tid = unwrapped_index.tid,
3731 .extra_index = item.data,3989 .extra_index = item.data,
3732 .decl = decl.toOptional(),3990 .name = name,
3991 .cau = cau.toOptional(),
3733 .namespace = namespace,3992 .namespace = namespace,
3734 .zir_index = zir_index.toOptional(),3993 .zir_index = zir_index.toOptional(),
3735 .layout = .@"packed",3994 .layout = .@"packed",
...@@ -3749,8 +4008,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3749,8 +4008,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3749}4008}
37504009
3751const LoadedEnumType = struct {4010const LoadedEnumType = struct {
3752 /// The Decl that corresponds to the enum itself.4011 // TODO: the non-fqn will be needed by the new dwarf structure
3753 decl: DeclIndex,4012 /// The name of this enum type.
4013 name: NullTerminatedString,
4014 /// The `Cau` within which type resolution occurs.
4015 /// `null` if this is a generated tag type.
4016 cau: Cau.Index.Optional,
3754 /// Represents the declarations inside this enum.4017 /// Represents the declarations inside this enum.
3755 namespace: OptionalNamespaceIndex,4018 namespace: OptionalNamespaceIndex,
3756 /// An integer type which is used for the numerical value of the enum.4019 /// An integer type which is used for the numerical value of the enum.
...@@ -3827,15 +4090,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3827,15 +4090,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3827 .type_enum_auto => {4090 .type_enum_auto => {
3828 const extra = extraDataTrail(extra_list, EnumAuto, item.data);4091 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
3829 var extra_index: u32 = @intCast(extra.end);4092 var extra_index: u32 = @intCast(extra.end);
3830 if (extra.data.zir_index == .none) {4093 const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: {
3831 extra_index += 1; // owner_union4094 extra_index += 1; // owner_union
3832 }4095 break :cau .none;
4096 } else cau: {
4097 const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4098 extra_index += 1; // cau
4099 break :cau cau.toOptional();
4100 };
3833 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {4101 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
3834 extra_index += 2; // type_hash: PackedU644102 extra_index += 2; // type_hash: PackedU64
3835 break :c 0;4103 break :c 0;
3836 } else extra.data.captures_len;4104 } else extra.data.captures_len;
3837 return .{4105 return .{
3838 .decl = extra.data.decl,4106 .name = extra.data.name,
4107 .cau = cau,
3839 .namespace = extra.data.namespace,4108 .namespace = extra.data.namespace,
3840 .tag_ty = extra.data.int_tag_type,4109 .tag_ty = extra.data.int_tag_type,
3841 .names = .{4110 .names = .{
...@@ -3861,15 +4130,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3861,15 +4130,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3861 };4130 };
3862 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);4131 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
3863 var extra_index: u32 = @intCast(extra.end);4132 var extra_index: u32 = @intCast(extra.end);
3864 if (extra.data.zir_index == .none) {4133 const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: {
3865 extra_index += 1; // owner_union4134 extra_index += 1; // owner_union
3866 }4135 break :cau .none;
4136 } else cau: {
4137 const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4138 extra_index += 1; // cau
4139 break :cau cau.toOptional();
4140 };
3867 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {4141 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
3868 extra_index += 2; // type_hash: PackedU644142 extra_index += 2; // type_hash: PackedU64
3869 break :c 0;4143 break :c 0;
3870 } else extra.data.captures_len;4144 } else extra.data.captures_len;
3871 return .{4145 return .{
3872 .decl = extra.data.decl,4146 .name = extra.data.name,
4147 .cau = cau,
3873 .namespace = extra.data.namespace,4148 .namespace = extra.data.namespace,
3874 .tag_ty = extra.data.int_tag_type,4149 .tag_ty = extra.data.int_tag_type,
3875 .names = .{4150 .names = .{
...@@ -3896,10 +4171,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3896,10 +4171,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
38964171
3897/// Note that this type doubles as the payload for `Tag.type_opaque`.4172/// Note that this type doubles as the payload for `Tag.type_opaque`.
3898pub const LoadedOpaqueType = struct {4173pub const LoadedOpaqueType = struct {
3899 /// The opaque's owner Decl.
3900 decl: DeclIndex,
3901 /// Contains the declarations inside this opaque.4174 /// Contains the declarations inside this opaque.
3902 namespace: OptionalNamespaceIndex,4175 namespace: OptionalNamespaceIndex,
4176 // TODO: the non-fqn will be needed by the new dwarf structure
4177 /// The name of this opaque type.
4178 name: NullTerminatedString,
3903 /// Index of the `opaque_decl` or `reify` instruction.4179 /// Index of the `opaque_decl` or `reify` instruction.
3904 zir_index: TrackedInst.Index,4180 zir_index: TrackedInst.Index,
3905 captures: CaptureValue.Slice,4181 captures: CaptureValue.Slice,
...@@ -3915,7 +4191,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {...@@ -3915,7 +4191,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
3915 else4191 else
3916 extra.data.captures_len;4192 extra.data.captures_len;
3917 return .{4193 return .{
3918 .decl = extra.data.decl,4194 .name = extra.data.name,
3919 .namespace = extra.data.namespace,4195 .namespace = extra.data.namespace,
3920 .zir_index = extra.data.zir_index,4196 .zir_index = extra.data.zir_index,
3921 .captures = .{4197 .captures = .{
...@@ -4216,10 +4492,10 @@ pub const Index = enum(u32) {...@@ -4216,10 +4492,10 @@ pub const Index = enum(u32) {
42164492
4217 undef: DataIsIndex,4493 undef: DataIsIndex,
4218 simple_value: void,4494 simple_value: void,
4219 ptr_decl: struct { data: *PtrDecl },4495 ptr_nav: struct { data: *PtrNav },
4220 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },4496 ptr_comptime_alloc: struct { data: *PtrComptimeAlloc },
4221 ptr_anon_decl: struct { data: *PtrAnonDecl },4497 ptr_uav: struct { data: *PtrUav },
4222 ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned },4498 ptr_uav_aligned: struct { data: *PtrUavAligned },
4223 ptr_comptime_field: struct { data: *PtrComptimeField },4499 ptr_comptime_field: struct { data: *PtrComptimeField },
4224 ptr_int: struct { data: *PtrInt },4500 ptr_int: struct { data: *PtrInt },
4225 ptr_eu_payload: struct { data: *PtrBase },4501 ptr_eu_payload: struct { data: *PtrBase },
...@@ -4255,7 +4531,7 @@ pub const Index = enum(u32) {...@@ -4255,7 +4531,7 @@ pub const Index = enum(u32) {
4255 float_c_longdouble_f128: struct { data: *Float128 },4531 float_c_longdouble_f128: struct { data: *Float128 },
4256 float_comptime_float: struct { data: *Float128 },4532 float_comptime_float: struct { data: *Float128 },
4257 variable: struct { data: *Tag.Variable },4533 variable: struct { data: *Tag.Variable },
4258 extern_func: struct { data: *Key.ExternFunc },4534 @"extern": struct { data: *Tag.Extern },
4259 func_decl: struct {4535 func_decl: struct {
4260 const @"data.analysis.inferred_error_set" = opaque {};4536 const @"data.analysis.inferred_error_set" = opaque {};
4261 data: *Tag.FuncDecl,4537 data: *Tag.FuncDecl,
...@@ -4669,23 +4945,23 @@ pub const Tag = enum(u8) {...@@ -4669,23 +4945,23 @@ pub const Tag = enum(u8) {
4669 /// A value that can be represented with only an enum tag.4945 /// A value that can be represented with only an enum tag.
4670 /// data is SimpleValue enum value.4946 /// data is SimpleValue enum value.
4671 simple_value,4947 simple_value,
4672 /// A pointer to a decl.4948 /// A pointer to a `Nav`.
4673 /// data is extra index of `PtrDecl`, which contains the type and address.4949 /// data is extra index of `PtrNav`, which contains the type and address.
4674 ptr_decl,4950 ptr_nav,
4675 /// A pointer to a decl that can be mutated at comptime.4951 /// A pointer to a decl that can be mutated at comptime.
4676 /// data is extra index of `PtrComptimeAlloc`, which contains the type and address.4952 /// data is extra index of `PtrComptimeAlloc`, which contains the type and address.
4677 ptr_comptime_alloc,4953 ptr_comptime_alloc,
4678 /// A pointer to an anonymous decl.4954 /// A pointer to an anonymous addressable value.
4679 /// data is extra index of `PtrAnonDecl`, which contains the pointer type and decl value.4955 /// 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.4956 /// The alignment of the uav is communicated via the pointer type.
4681 ptr_anon_decl,4957 ptr_uav,
4682 /// A pointer to an anonymous decl.4958 /// A pointer to an unnamed addressable value.
4683 /// data is extra index of `PtrAnonDeclAligned`, which contains the pointer4959 /// data is extra index of `PtrUavAligned`, which contains the pointer
4684 /// type and decl value.4960 /// type and decl value.
4685 /// The original pointer type is also provided, which will be different than `ty`.4961 /// 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 is4962 /// This encoding is only used when a pointer to a Uav is
4687 /// coerced to a different pointer type with a different alignment.4963 /// coerced to a different pointer type with a different alignment.
4688 ptr_anon_decl_aligned,4964 ptr_uav_aligned,
4689 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.4965 /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value.
4690 ptr_comptime_field,4966 ptr_comptime_field,
4691 /// A pointer with an integer value.4967 /// A pointer with an integer value.
...@@ -4800,9 +5076,10 @@ pub const Tag = enum(u8) {...@@ -4800,9 +5076,10 @@ pub const Tag = enum(u8) {
4800 /// A global variable.5076 /// A global variable.
4801 /// data is extra index to Variable.5077 /// data is extra index to Variable.
4802 variable,5078 variable,
4803 /// An extern function.5079 /// An extern function or variable.
4804 /// data is extra index to ExternFunc.5080 /// data is extra index to Extern.
4805 extern_func,5081 /// Some parts of the key are stored in `owner_nav`.
5082 @"extern",
4806 /// A non-extern function corresponding directly to the AST node from whence it originated.5083 /// A non-extern function corresponding directly to the AST node from whence it originated.
4807 /// data is extra index to `FuncDecl`.5084 /// data is extra index to `FuncDecl`.
4808 /// Only the owner Decl is used for hashing and equality because the other5085 /// Only the owner Decl is used for hashing and equality because the other
...@@ -4843,7 +5120,6 @@ pub const Tag = enum(u8) {...@@ -4843,7 +5120,6 @@ pub const Tag = enum(u8) {
4843 const TypeValue = Key.TypeValue;5120 const TypeValue = Key.TypeValue;
4844 const Error = Key.Error;5121 const Error = Key.Error;
4845 const EnumTag = Key.EnumTag;5122 const EnumTag = Key.EnumTag;
4846 const ExternFunc = Key.ExternFunc;
4847 const Union = Key.Union;5123 const Union = Key.Union;
4848 const TypePointer = Key.PtrType;5124 const TypePointer = Key.PtrType;
48495125
...@@ -4877,10 +5153,10 @@ pub const Tag = enum(u8) {...@@ -4877,10 +5153,10 @@ pub const Tag = enum(u8) {
48775153
4878 .undef => unreachable,5154 .undef => unreachable,
4879 .simple_value => unreachable,5155 .simple_value => unreachable,
4880 .ptr_decl => PtrDecl,5156 .ptr_nav => PtrNav,
4881 .ptr_comptime_alloc => PtrComptimeAlloc,5157 .ptr_comptime_alloc => PtrComptimeAlloc,
4882 .ptr_anon_decl => PtrAnonDecl,5158 .ptr_uav => PtrUav,
4883 .ptr_anon_decl_aligned => PtrAnonDeclAligned,5159 .ptr_uav_aligned => PtrUavAligned,
4884 .ptr_comptime_field => PtrComptimeField,5160 .ptr_comptime_field => PtrComptimeField,
4885 .ptr_int => PtrInt,5161 .ptr_int => PtrInt,
4886 .ptr_eu_payload => PtrBase,5162 .ptr_eu_payload => PtrBase,
...@@ -4916,7 +5192,7 @@ pub const Tag = enum(u8) {...@@ -4916,7 +5192,7 @@ pub const Tag = enum(u8) {
4916 .float_c_longdouble_f128 => unreachable,5192 .float_c_longdouble_f128 => unreachable,
4917 .float_comptime_float => unreachable,5193 .float_comptime_float => unreachable,
4918 .variable => Variable,5194 .variable => Variable,
4919 .extern_func => ExternFunc,5195 .@"extern" => Extern,
4920 .func_decl => FuncDecl,5196 .func_decl => FuncDecl,
4921 .func_instance => FuncInstance,5197 .func_instance => FuncInstance,
4922 .func_coerced => FuncCoerced,5198 .func_coerced => FuncCoerced,
...@@ -4933,21 +5209,29 @@ pub const Tag = enum(u8) {...@@ -4933,21 +5209,29 @@ pub const Tag = enum(u8) {
4933 ty: Index,5209 ty: Index,
4934 /// May be `none`.5210 /// May be `none`.
4935 init: Index,5211 init: Index,
4936 decl: DeclIndex,5212 owner_nav: Nav.Index,
4937 /// Library name if specified.5213 /// Library name if specified.
4938 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.5214 /// For example `extern "c" var stderrp = ...` would have 'c' as library name.
4939 lib_name: OptionalNullTerminatedString,5215 lib_name: OptionalNullTerminatedString,
4940 flags: Flags,5216 flags: Flags,
49415217
4942 pub const Flags = packed struct(u32) {5218 pub const Flags = packed struct(u32) {
4943 is_extern: bool,
4944 is_const: bool,5219 is_const: bool,
4945 is_threadlocal: bool,5220 is_threadlocal: bool,
4946 is_weak_linkage: bool,5221 is_weak_linkage: bool,
4947 _: u28 = 0,5222 _: u29 = 0,
4948 };5223 };
4949 };5224 };
49505225
5226 pub const Extern = struct {
5227 // name, alignment, addrspace come from `owner_nav`.
5228 ty: Index,
5229 lib_name: OptionalNullTerminatedString,
5230 flags: Variable.Flags,
5231 owner_nav: Nav.Index,
5232 zir_index: TrackedInst.Index,
5233 };
5234
4951 /// Trailing:5235 /// Trailing:
4952 /// 0. element: Index for each len5236 /// 0. element: Index for each len
4953 /// len is determined by the aggregate type.5237 /// len is determined by the aggregate type.
...@@ -4962,7 +5246,7 @@ pub const Tag = enum(u8) {...@@ -4962,7 +5246,7 @@ pub const Tag = enum(u8) {
4962 /// A `none` value marks that the inferred error set is not resolved yet.5246 /// A `none` value marks that the inferred error set is not resolved yet.
4963 pub const FuncDecl = struct {5247 pub const FuncDecl = struct {
4964 analysis: FuncAnalysis,5248 analysis: FuncAnalysis,
4965 owner_decl: DeclIndex,5249 owner_nav: Nav.Index,
4966 ty: Index,5250 ty: Index,
4967 zir_body_inst: TrackedInst.Index,5251 zir_body_inst: TrackedInst.Index,
4968 lbrace_line: u32,5252 lbrace_line: u32,
...@@ -4979,7 +5263,7 @@ pub const Tag = enum(u8) {...@@ -4979,7 +5263,7 @@ pub const Tag = enum(u8) {
4979 pub const FuncInstance = struct {5263 pub const FuncInstance = struct {
4980 analysis: FuncAnalysis,5264 analysis: FuncAnalysis,
4981 // Needed by the linker for codegen. Not part of hashing or equality.5265 // Needed by the linker for codegen. Not part of hashing or equality.
4982 owner_decl: DeclIndex,5266 owner_nav: Nav.Index,
4983 ty: Index,5267 ty: Index,
4984 branch_quota: u32,5268 branch_quota: u32,
4985 /// Points to a `FuncDecl`.5269 /// Points to a `FuncDecl`.
...@@ -5029,6 +5313,7 @@ pub const Tag = enum(u8) {...@@ -5029,6 +5313,7 @@ pub const Tag = enum(u8) {
5029 /// 3. field type: Index for each field; declaration order5313 /// 3. field type: Index for each field; declaration order
5030 /// 4. field align: Alignment for each field; declaration order5314 /// 4. field align: Alignment for each field; declaration order
5031 pub const TypeUnion = struct {5315 pub const TypeUnion = struct {
5316 name: NullTerminatedString,
5032 flags: Flags,5317 flags: Flags,
5033 /// This could be provided through the tag type, but it is more convenient5318 /// This could be provided through the tag type, but it is more convenient
5034 /// to store it directly. This is also necessary for `dumpStatsFallible` to5319 /// to store it directly. This is also necessary for `dumpStatsFallible` to
...@@ -5038,7 +5323,7 @@ pub const Tag = enum(u8) {...@@ -5038,7 +5323,7 @@ pub const Tag = enum(u8) {
5038 size: u32,5323 size: u32,
5039 /// Only valid after .have_layout5324 /// Only valid after .have_layout
5040 padding: u32,5325 padding: u32,
5041 decl: DeclIndex,5326 cau: Cau.Index,
5042 namespace: OptionalNamespaceIndex,5327 namespace: OptionalNamespaceIndex,
5043 /// The enum that provides the list of field names and values.5328 /// The enum that provides the list of field names and values.
5044 tag_ty: Index,5329 tag_ty: Index,
...@@ -5068,7 +5353,8 @@ pub const Tag = enum(u8) {...@@ -5068,7 +5353,8 @@ pub const Tag = enum(u8) {
5068 /// 4. name: NullTerminatedString for each fields_len5353 /// 4. name: NullTerminatedString for each fields_len
5069 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits5354 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits
5070 pub const TypeStructPacked = struct {5355 pub const TypeStructPacked = struct {
5071 decl: DeclIndex,5356 name: NullTerminatedString,
5357 cau: Cau.Index,
5072 zir_index: TrackedInst.Index,5358 zir_index: TrackedInst.Index,
5073 fields_len: u32,5359 fields_len: u32,
5074 namespace: OptionalNamespaceIndex,5360 namespace: OptionalNamespaceIndex,
...@@ -5120,7 +5406,8 @@ pub const Tag = enum(u8) {...@@ -5120,7 +5406,8 @@ pub const Tag = enum(u8) {
5120 /// field_index: RuntimeOrder // for each field in runtime order5406 /// field_index: RuntimeOrder // for each field in runtime order
5121 /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved5407 /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved
5122 pub const TypeStruct = struct {5408 pub const TypeStruct = struct {
5123 decl: DeclIndex,5409 name: NullTerminatedString,
5410 cau: Cau.Index,
5124 zir_index: TrackedInst.Index,5411 zir_index: TrackedInst.Index,
5125 fields_len: u32,5412 fields_len: u32,
5126 flags: Flags,5413 flags: Flags,
...@@ -5164,8 +5451,7 @@ pub const Tag = enum(u8) {...@@ -5164,8 +5451,7 @@ pub const Tag = enum(u8) {
5164 /// Trailing:5451 /// Trailing:
5165 /// 0. capture: CaptureValue // for each `captures_len`5452 /// 0. capture: CaptureValue // for each `captures_len`
5166 pub const TypeOpaque = struct {5453 pub const TypeOpaque = struct {
5167 /// The opaque's owner Decl.5454 name: NullTerminatedString,
5168 decl: DeclIndex,
5169 /// Contains the declarations inside this opaque.5455 /// Contains the declarations inside this opaque.
5170 namespace: OptionalNamespaceIndex,5456 namespace: OptionalNamespaceIndex,
5171 /// The index of the `opaque_decl` instruction.5457 /// The index of the `opaque_decl` instruction.
...@@ -5188,29 +5474,19 @@ pub const FuncAnalysis = packed struct(u32) {...@@ -5188,29 +5474,19 @@ pub const FuncAnalysis = packed struct(u32) {
5188 inferred_error_set: bool,5474 inferred_error_set: bool,
5189 disable_instrumentation: bool,5475 disable_instrumentation: bool,
51905476
5191 _: u13 = 0,5477 _: u19 = 0,
51925478
5193 pub const State = enum(u8) {5479 pub const State = enum(u2) {
5194 /// This function has not yet undergone analysis, because we have not5480 /// The runtime function has never been referenced.
5195 /// seen a potential runtime call. It may be analyzed in future.5481 /// As such, it has never been analyzed, nor is it queued for analysis.
5196 none,5482 unreferenced,
5197 /// Analysis for this function has been queued, but not yet completed.5483 /// The runtime function has been referenced, but has not yet been analyzed.
5484 /// Its semantic analysis is queued.
5198 queued,5485 queued,
5199 /// This function intentionally only has ZIR generated because it is marked5486 /// The runtime function has been (or is currently being) semantically analyzed.
5200 /// inline, which means no runtime version of the function will be generated.5487 /// To know if analysis succeeded, consult `zcu.[transitive_]failed_analysis`.
5201 inline_only,5488 /// To know if analysis is up-to-date, consult `zcu.[potentially_]outdated`.
5202 in_progress,5489 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 };5490 };
5215};5491};
52165492
...@@ -5477,13 +5753,13 @@ pub const Array = struct {...@@ -5477,13 +5753,13 @@ pub const Array = struct {
54775753
5478/// Trailing:5754/// Trailing:
5479/// 0. owner_union: Index // if `zir_index == .none`5755/// 0. owner_union: Index // if `zir_index == .none`
5480/// 1. capture: CaptureValue // for each `captures_len`5756/// 1. cau: Cau.Index // if `zir_index != .none`
5481/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)5757/// 2. capture: CaptureValue // for each `captures_len`
5482/// 3. field name: NullTerminatedString for each fields_len; declaration order5758/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5483/// 4. tag value: Index for each fields_len; declaration order5759/// 4. field name: NullTerminatedString for each fields_len; declaration order
5760/// 5. tag value: Index for each fields_len; declaration order
5484pub const EnumExplicit = struct {5761pub const EnumExplicit = struct {
5485 /// The Decl that corresponds to the enum itself.5762 name: NullTerminatedString,
5486 decl: DeclIndex,
5487 /// `std.math.maxInt(u32)` indicates this type is reified.5763 /// `std.math.maxInt(u32)` indicates this type is reified.
5488 captures_len: u32,5764 captures_len: u32,
5489 /// This may be `none` if there are no declarations.5765 /// This may be `none` if there are no declarations.
...@@ -5505,12 +5781,12 @@ pub const EnumExplicit = struct {...@@ -5505,12 +5781,12 @@ pub const EnumExplicit = struct {
55055781
5506/// Trailing:5782/// Trailing:
5507/// 0. owner_union: Index // if `zir_index == .none`5783/// 0. owner_union: Index // if `zir_index == .none`
5508/// 1. capture: CaptureValue // for each `captures_len`5784/// 1. cau: Cau.Index // if `zir_index != .none`
5509/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)5785/// 2. capture: CaptureValue // for each `captures_len`
5510/// 3. field name: NullTerminatedString for each fields_len; declaration order5786/// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
5787/// 4. field name: NullTerminatedString for each fields_len; declaration order
5511pub const EnumAuto = struct {5788pub const EnumAuto = struct {
5512 /// The Decl that corresponds to the enum itself.5789 name: NullTerminatedString,
5513 decl: DeclIndex,
5514 /// `std.math.maxInt(u32)` indicates this type is reified.5790 /// `std.math.maxInt(u32)` indicates this type is reified.
5515 captures_len: u32,5791 captures_len: u32,
5516 /// This may be `none` if there are no declarations.5792 /// This may be `none` if there are no declarations.
...@@ -5539,15 +5815,15 @@ pub const PackedU64 = packed struct(u64) {...@@ -5539,15 +5815,15 @@ pub const PackedU64 = packed struct(u64) {
5539 }5815 }
5540};5816};
55415817
5542pub const PtrDecl = struct {5818pub const PtrNav = struct {
5543 ty: Index,5819 ty: Index,
5544 decl: DeclIndex,5820 nav: Nav.Index,
5545 byte_offset_a: u32,5821 byte_offset_a: u32,
5546 byte_offset_b: u32,5822 byte_offset_b: u32,
5547 fn init(ty: Index, decl: DeclIndex, byte_offset: u64) @This() {5823 fn init(ty: Index, nav: Nav.Index, byte_offset: u64) @This() {
5548 return .{5824 return .{
5549 .ty = ty,5825 .ty = ty,
5550 .decl = decl,5826 .nav = nav,
5551 .byte_offset_a = @intCast(byte_offset >> 32),5827 .byte_offset_a = @intCast(byte_offset >> 32),
5552 .byte_offset_b = @truncate(byte_offset),5828 .byte_offset_b = @truncate(byte_offset),
5553 };5829 };
...@@ -5557,7 +5833,7 @@ pub const PtrDecl = struct {...@@ -5557,7 +5833,7 @@ pub const PtrDecl = struct {
5557 }5833 }
5558};5834};
55595835
5560pub const PtrAnonDecl = struct {5836pub const PtrUav = struct {
5561 ty: Index,5837 ty: Index,
5562 val: Index,5838 val: Index,
5563 byte_offset_a: u32,5839 byte_offset_a: u32,
...@@ -5575,7 +5851,7 @@ pub const PtrAnonDecl = struct {...@@ -5575,7 +5851,7 @@ pub const PtrAnonDecl = struct {
5575 }5851 }
5576};5852};
55775853
5578pub const PtrAnonDeclAligned = struct {5854pub const PtrUavAligned = struct {
5579 ty: Index,5855 ty: Index,
5580 val: Index,5856 val: Index,
5581 /// Must be nonequal to `ty`. Only the alignment from this value is important.5857 /// Must be nonequal to `ty`. Only the alignment from this value is important.
...@@ -5805,8 +6081,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5805,8 +6081,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5805 .tracked_insts = Local.TrackedInsts.empty,6081 .tracked_insts = Local.TrackedInsts.empty,
5806 .files = Local.List(File).empty,6082 .files = Local.List(File).empty,
5807 .maps = Local.Maps.empty,6083 .maps = Local.Maps.empty,
6084 .caus = Local.Caus.empty,
6085 .navs = Local.Navs.empty,
58086086
5809 .decls = Local.Decls.empty,
5810 .namespaces = Local.Namespaces.empty,6087 .namespaces = Local.Namespaces.empty,
5811 },6088 },
5812 .mutate = .{6089 .mutate = .{
...@@ -5819,8 +6096,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5819,8 +6096,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5819 .tracked_insts = Local.ListMutate.empty,6096 .tracked_insts = Local.ListMutate.empty,
5820 .files = Local.ListMutate.empty,6097 .files = Local.ListMutate.empty,
5821 .maps = Local.ListMutate.empty,6098 .maps = Local.ListMutate.empty,
6099 .caus = Local.ListMutate.empty,
6100 .navs = Local.ListMutate.empty,
58226101
5823 .decls = Local.BucketListMutate.empty,
5824 .namespaces = Local.BucketListMutate.empty,6102 .namespaces = Local.BucketListMutate.empty,
5825 },6103 },
5826 });6104 });
...@@ -5878,8 +6156,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5878,8 +6156,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
58786156
5879pub fn deinit(ip: *InternPool, gpa: Allocator) void {6157pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5880 ip.src_hash_deps.deinit(gpa);6158 ip.src_hash_deps.deinit(gpa);
5881 ip.decl_val_deps.deinit(gpa);6159 ip.nav_val_deps.deinit(gpa);
5882 ip.func_ies_deps.deinit(gpa);6160 ip.interned_deps.deinit(gpa);
5883 ip.namespace_deps.deinit(gpa);6161 ip.namespace_deps.deinit(gpa);
5884 ip.namespace_name_deps.deinit(gpa);6162 ip.namespace_name_deps.deinit(gpa);
58856163
...@@ -5900,8 +6178,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -5900,8 +6178,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5900 else6178 else
5901 local.mutate.namespaces.last_bucket_len]) |*namespace|6179 local.mutate.namespaces.last_bucket_len]) |*namespace|
5902 {6180 {
5903 namespace.decls.deinit(gpa);6181 namespace.pub_decls.deinit(gpa);
5904 namespace.usingnamespace_set.deinit(gpa);6182 namespace.priv_decls.deinit(gpa);
6183 namespace.pub_usingnamespace.deinit(gpa);
6184 namespace.priv_usingnamespace.deinit(gpa);
6185 namespace.other_decls.deinit(gpa);
5905 }6186 }
5906 };6187 };
5907 const maps = local.getMutableMaps(gpa);6188 const maps = local.getMutableMaps(gpa);
...@@ -6082,14 +6363,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6082,14 +6363,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6082 if (extra.data.captures_len == std.math.maxInt(u32)) {6363 if (extra.data.captures_len == std.math.maxInt(u32)) {
6083 break :ns .{ .reified = .{6364 break :ns .{ .reified = .{
6084 .zir_index = zir_index,6365 .zir_index = zir_index,
6085 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),6366 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
6086 } };6367 } };
6087 }6368 }
6088 break :ns .{ .declared = .{6369 break :ns .{ .declared = .{
6089 .zir_index = zir_index,6370 .zir_index = zir_index,
6090 .captures = .{ .owned = .{6371 .captures = .{ .owned = .{
6091 .tid = unwrapped_index.tid,6372 .tid = unwrapped_index.tid,
6092 .start = extra.end,6373 .start = extra.end + 1,
6093 .len = extra.data.captures_len,6374 .len = extra.data.captures_len,
6094 } },6375 } },
6095 } };6376 } };
...@@ -6106,14 +6387,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6106,14 +6387,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6106 if (extra.data.captures_len == std.math.maxInt(u32)) {6387 if (extra.data.captures_len == std.math.maxInt(u32)) {
6107 break :ns .{ .reified = .{6388 break :ns .{ .reified = .{
6108 .zir_index = zir_index,6389 .zir_index = zir_index,
6109 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),6390 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
6110 } };6391 } };
6111 }6392 }
6112 break :ns .{ .declared = .{6393 break :ns .{ .declared = .{
6113 .zir_index = zir_index,6394 .zir_index = zir_index,
6114 .captures = .{ .owned = .{6395 .captures = .{ .owned = .{
6115 .tid = unwrapped_index.tid,6396 .tid = unwrapped_index.tid,
6116 .start = extra.end,6397 .start = extra.end + 1,
6117 .len = extra.data.captures_len,6398 .len = extra.data.captures_len,
6118 } },6399 } },
6119 } };6400 } };
...@@ -6132,24 +6413,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6132,24 +6413,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6132 .val = extra.val,6413 .val = extra.val,
6133 } };6414 } };
6134 },6415 },
6135 .ptr_decl => {6416 .ptr_nav => {
6136 const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data);6417 const info = extraData(unwrapped_index.getExtra(ip), PtrNav, data);
6137 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };6418 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .nav = info.nav }, .byte_offset = info.byteOffset() } };
6138 },6419 },
6139 .ptr_comptime_alloc => {6420 .ptr_comptime_alloc => {
6140 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);6421 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() } };6422 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
6142 },6423 },
6143 .ptr_anon_decl => {6424 .ptr_uav => {
6144 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);6425 const info = extraData(unwrapped_index.getExtra(ip), PtrUav, data);
6145 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{6426 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
6146 .val = info.val,6427 .val = info.val,
6147 .orig_ty = info.ty,6428 .orig_ty = info.ty,
6148 } }, .byte_offset = info.byteOffset() } };6429 } }, .byte_offset = info.byteOffset() } };
6149 },6430 },
6150 .ptr_anon_decl_aligned => {6431 .ptr_uav_aligned => {
6151 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data);6432 const info = extraData(unwrapped_index.getExtra(ip), PtrUavAligned, data);
6152 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{6433 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{
6153 .val = info.val,6434 .val = info.val,
6154 .orig_ty = info.orig_ty,6435 .orig_ty = info.orig_ty,
6155 } }, .byte_offset = info.byteOffset() } };6436 } }, .byte_offset = info.byteOffset() } };
...@@ -6293,15 +6574,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -6293,15 +6574,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
6293 return .{ .variable = .{6574 return .{ .variable = .{
6294 .ty = extra.ty,6575 .ty = extra.ty,
6295 .init = extra.init,6576 .init = extra.init,
6296 .decl = extra.decl,6577 .owner_nav = extra.owner_nav,
6578 .lib_name = extra.lib_name,
6579 .is_threadlocal = extra.flags.is_threadlocal,
6580 .is_weak_linkage = extra.flags.is_weak_linkage,
6581 } };
6582 },
6583 .@"extern" => {
6584 const extra = extraData(unwrapped_index.getExtra(ip), Tag.Extern, data);
6585 const nav = ip.getNav(extra.owner_nav);
6586 return .{ .@"extern" = .{
6587 .name = nav.name,
6588 .ty = extra.ty,
6297 .lib_name = extra.lib_name,6589 .lib_name = extra.lib_name,
6298 .is_extern = extra.flags.is_extern,
6299 .is_const = extra.flags.is_const,6590 .is_const = extra.flags.is_const,
6300 .is_threadlocal = extra.flags.is_threadlocal,6591 .is_threadlocal = extra.flags.is_threadlocal,
6301 .is_weak_linkage = extra.flags.is_weak_linkage,6592 .is_weak_linkage = extra.flags.is_weak_linkage,
6593 .alignment = nav.status.resolved.alignment,
6594 .@"addrspace" = nav.status.resolved.@"addrspace",
6595 .zir_index = extra.zir_index,
6596 .owner_nav = extra.owner_nav,
6302 } };6597 } };
6303 },6598 },
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) },6599 .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) },6600 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6307 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },6601 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },
...@@ -6513,7 +6807,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke...@@ -6513,7 +6807,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").?,6807 .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,6808 .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0,
6515 .branch_quota_extra_index = 0,6809 .branch_quota_extra_index = 0,
6516 .owner_decl = func_decl.data.owner_decl,6810 .owner_nav = func_decl.data.owner_nav,
6517 .zir_body_inst = func_decl.data.zir_body_inst,6811 .zir_body_inst = func_decl.data.zir_body_inst,
6518 .lbrace_line = func_decl.data.lbrace_line,6812 .lbrace_line = func_decl.data.lbrace_line,
6519 .rbrace_line = func_decl.data.rbrace_line,6813 .rbrace_line = func_decl.data.rbrace_line,
...@@ -6528,7 +6822,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local....@@ -6528,7 +6822,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.
6528 const extra_items = extra.view().items(.@"0");6822 const extra_items = extra.view().items(.@"0");
6529 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;6823 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));6824 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .unordered));
6531 const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]);6825 const owner_nav: Nav.Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?]);
6532 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);6826 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").?]);6827 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
6534 const func_decl = ip.funcDeclInfo(generic_owner);6828 const func_decl = ip.funcDeclInfo(generic_owner);
...@@ -6541,7 +6835,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local....@@ -6541,7 +6835,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,6835 .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,6836 .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").?,6837 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,
6544 .owner_decl = owner_decl,6838 .owner_nav = owner_nav,
6545 .zir_body_inst = func_decl.zir_body_inst,6839 .zir_body_inst = func_decl.zir_body_inst,
6546 .lbrace_line = func_decl.lbrace_line,6840 .lbrace_line = func_decl.lbrace_line,
6547 .rbrace_line = func_decl.rbrace_line,6841 .rbrace_line = func_decl.rbrace_line,
...@@ -6905,7 +7199,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6905,7 +7199,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
69057199
6906 .enum_type => unreachable, // use getEnumType() instead7200 .enum_type => unreachable, // use getEnumType() instead
6907 .func_type => unreachable, // use getFuncType() instead7201 .func_type => unreachable, // use getFuncType() instead
6908 .extern_func => unreachable, // use getExternFunc() instead7202 .@"extern" => unreachable, // use getExtern() instead
6909 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead7203 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead
69107204
6911 .variable => |variable| {7205 .variable => |variable| {
...@@ -6916,11 +7210,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6916,11 +7210,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6916 .data = try addExtra(extra, Tag.Variable{7210 .data = try addExtra(extra, Tag.Variable{
6917 .ty = variable.ty,7211 .ty = variable.ty,
6918 .init = variable.init,7212 .init = variable.init,
6919 .decl = variable.decl,7213 .owner_nav = variable.owner_nav,
6920 .lib_name = variable.lib_name,7214 .lib_name = variable.lib_name,
6921 .flags = .{7215 .flags = .{
6922 .is_extern = variable.is_extern,7216 .is_const = false,
6923 .is_const = variable.is_const,
6924 .is_threadlocal = variable.is_threadlocal,7217 .is_threadlocal = variable.is_threadlocal,
6925 .is_weak_linkage = variable.is_weak_linkage,7218 .is_weak_linkage = variable.is_weak_linkage,
6926 },7219 },
...@@ -6945,29 +7238,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6945,29 +7238,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;7238 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
6946 assert(ptr_type.flags.size != .Slice);7239 assert(ptr_type.flags.size != .Slice);
6947 items.appendAssumeCapacity(switch (ptr.base_addr) {7240 items.appendAssumeCapacity(switch (ptr.base_addr) {
6948 .decl => |decl| .{7241 .nav => |nav| .{
6949 .tag = .ptr_decl,7242 .tag = .ptr_nav,
6950 .data = try addExtra(extra, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),7243 .data = try addExtra(extra, PtrNav.init(ptr.ty, nav, ptr.byte_offset)),
6951 },7244 },
6952 .comptime_alloc => |alloc_index| .{7245 .comptime_alloc => |alloc_index| .{
6953 .tag = .ptr_comptime_alloc,7246 .tag = .ptr_comptime_alloc,
6954 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),7247 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
6955 },7248 },
6956 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {7249 .uav => |uav| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, uav.orig_ty)) item: {
6957 if (ptr.ty != anon_decl.orig_ty) {7250 if (ptr.ty != uav.orig_ty) {
6958 gop.cancel();7251 gop.cancel();
6959 var new_key = key;7252 var new_key = key;
6960 new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty;7253 new_key.ptr.base_addr.uav.orig_ty = ptr.ty;
6961 gop = try ip.getOrPutKey(gpa, tid, new_key);7254 gop = try ip.getOrPutKey(gpa, tid, new_key);
6962 if (gop == .existing) return gop.existing;7255 if (gop == .existing) return gop.existing;
6963 }7256 }
6964 break :item .{7257 break :item .{
6965 .tag = .ptr_anon_decl,7258 .tag = .ptr_uav,
6966 .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),7259 .data = try addExtra(extra, PtrUav.init(ptr.ty, uav.val, ptr.byte_offset)),
6967 };7260 };
6968 } else .{7261 } else .{
6969 .tag = .ptr_anon_decl_aligned,7262 .tag = .ptr_uav_aligned,
6970 .data = try addExtra(extra, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),7263 .data = try addExtra(extra, PtrUavAligned.init(ptr.ty, uav.val, uav.orig_ty, ptr.byte_offset)),
6971 },7264 },
6972 .comptime_field => |field_val| item: {7265 .comptime_field => |field_val| item: {
6973 assert(field_val != .none);7266 assert(field_val != .none);
...@@ -7635,7 +7928,8 @@ pub fn getUnionType(...@@ -7635,7 +7928,8 @@ pub fn getUnionType(
7635 .fields_len = ini.fields_len,7928 .fields_len = ini.fields_len,
7636 .size = std.math.maxInt(u32),7929 .size = std.math.maxInt(u32),
7637 .padding = std.math.maxInt(u32),7930 .padding = std.math.maxInt(u32),
7638 .decl = undefined, // set by `finish`7931 .name = undefined, // set by `finish`
7932 .cau = undefined, // set by `finish`
7639 .namespace = .none, // set by `finish`7933 .namespace = .none, // set by `finish`
7640 .tag_ty = ini.enum_tag_ty,7934 .tag_ty = ini.enum_tag_ty,
7641 .zir_index = switch (ini.key) {7935 .zir_index = switch (ini.key) {
...@@ -7682,7 +7976,8 @@ pub fn getUnionType(...@@ -7682,7 +7976,8 @@ pub fn getUnionType(
7682 return .{ .wip = .{7976 return .{ .wip = .{
7683 .tid = tid,7977 .tid = tid,
7684 .index = gop.put(),7978 .index = gop.put(),
7685 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,7979 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
7980 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "cau").?,
7686 .namespace_extra_index = if (ini.has_namespace)7981 .namespace_extra_index = if (ini.has_namespace)
7687 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?7982 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?
7688 else7983 else
...@@ -7693,18 +7988,44 @@ pub fn getUnionType(...@@ -7693,18 +7988,44 @@ pub fn getUnionType(
7693pub const WipNamespaceType = struct {7988pub const WipNamespaceType = struct {
7694 tid: Zcu.PerThread.Id,7989 tid: Zcu.PerThread.Id,
7695 index: Index,7990 index: Index,
7696 decl_extra_index: u32,7991 type_name_extra_index: u32,
7992 cau_extra_index: ?u32,
7697 namespace_extra_index: ?u32,7993 namespace_extra_index: ?u32,
7698 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {7994
7699 const extra_items = ip.getLocalShared(wip.tid).extra.acquire().view().items(.@"0");7995 pub fn setName(
7700 extra_items[wip.decl_extra_index] = @intFromEnum(decl);7996 wip: WipNamespaceType,
7997 ip: *InternPool,
7998 type_name: NullTerminatedString,
7999 ) void {
8000 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8001 const extra_items = extra.view().items(.@"0");
8002 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
8003 }
8004
8005 pub fn finish(
8006 wip: WipNamespaceType,
8007 ip: *InternPool,
8008 analysis_owner: Cau.Index.Optional,
8009 namespace: OptionalNamespaceIndex,
8010 ) Index {
8011 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8012 const extra_items = extra.view().items(.@"0");
8013
8014 if (wip.cau_extra_index) |i| {
8015 extra_items[i] = @intFromEnum(analysis_owner.unwrap().?);
8016 } else {
8017 assert(analysis_owner == .none);
8018 }
8019
7701 if (wip.namespace_extra_index) |i| {8020 if (wip.namespace_extra_index) |i| {
7702 extra_items[i] = @intFromEnum(namespace.unwrap().?);8021 extra_items[i] = @intFromEnum(namespace.unwrap().?);
7703 } else {8022 } else {
7704 assert(namespace == .none);8023 assert(namespace == .none);
7705 }8024 }
8025
7706 return wip.index;8026 return wip.index;
7707 }8027 }
8028
7708 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {8029 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
7709 ip.remove(tid, wip.index);8030 ip.remove(tid, wip.index);
7710 }8031 }
...@@ -7784,7 +8105,8 @@ pub fn getStructType(...@@ -7784,7 +8105,8 @@ pub fn getStructType(
7784 ini.fields_len + // names8105 ini.fields_len + // names
7785 ini.fields_len); // inits8106 ini.fields_len); // inits
7786 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{8107 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
7787 .decl = undefined, // set by `finish`8108 .name = undefined, // set by `finish`
8109 .cau = undefined, // set by `finish`
7788 .zir_index = zir_index,8110 .zir_index = zir_index,
7789 .fields_len = ini.fields_len,8111 .fields_len = ini.fields_len,
7790 .namespace = .none,8112 .namespace = .none,
...@@ -7818,7 +8140,8 @@ pub fn getStructType(...@@ -7818,7 +8140,8 @@ pub fn getStructType(
7818 return .{ .wip = .{8140 return .{ .wip = .{
7819 .tid = tid,8141 .tid = tid,
7820 .index = gop.put(),8142 .index = gop.put(),
7821 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,8143 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
8144 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?,
7822 .namespace_extra_index = if (ini.has_namespace)8145 .namespace_extra_index = if (ini.has_namespace)
7823 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?8146 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?
7824 else8147 else
...@@ -7843,7 +8166,8 @@ pub fn getStructType(...@@ -7843,7 +8166,8 @@ pub fn getStructType(
7843 align_elements_len + comptime_elements_len +8166 align_elements_len + comptime_elements_len +
7844 2); // names_map + namespace8167 2); // names_map + namespace
7845 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{8168 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
7846 .decl = undefined, // set by `finish`8169 .name = undefined, // set by `finish`
8170 .cau = undefined, // set by `finish`
7847 .zir_index = zir_index,8171 .zir_index = zir_index,
7848 .fields_len = ini.fields_len,8172 .fields_len = ini.fields_len,
7849 .size = std.math.maxInt(u32),8173 .size = std.math.maxInt(u32),
...@@ -7908,7 +8232,8 @@ pub fn getStructType(...@@ -7908,7 +8232,8 @@ pub fn getStructType(
7908 return .{ .wip = .{8232 return .{ .wip = .{
7909 .tid = tid,8233 .tid = tid,
7910 .index = gop.put(),8234 .index = gop.put(),
7911 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,8235 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
8236 .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "cau").?,
7912 .namespace_extra_index = namespace_extra_index,8237 .namespace_extra_index = namespace_extra_index,
7913 } };8238 } };
7914}8239}
...@@ -8047,34 +8372,71 @@ pub fn getFuncType(...@@ -8047,34 +8372,71 @@ pub fn getFuncType(
8047 return gop.put();8372 return gop.put();
8048}8373}
80498374
8050pub fn getExternFunc(8375/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
8376/// This will *not* queue the extern for codegen: see `Zcu.PerThread.getExtern` for a wrapper which does.
8377pub fn getExtern(
8051 ip: *InternPool,8378 ip: *InternPool,
8052 gpa: Allocator,8379 gpa: Allocator,
8053 tid: Zcu.PerThread.Id,8380 tid: Zcu.PerThread.Id,
8054 key: Key.ExternFunc,8381 /// `key.owner_nav` is ignored.
8055) Allocator.Error!Index {8382 key: Key.Extern,
8056 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });8383) Allocator.Error!struct {
8384 index: Index,
8385 /// Only set if the `Nav` was newly created.
8386 new_nav: Nav.Index.Optional,
8387} {
8388 var gop = try ip.getOrPutKey(gpa, tid, .{ .@"extern" = key });
8057 defer gop.deinit();8389 defer gop.deinit();
8058 if (gop == .existing) return gop.existing;8390 if (gop == .existing) return .{
8391 .index = gop.existing,
8392 .new_nav = .none,
8393 };
80598394
8060 const local = ip.getLocal(tid);8395 const local = ip.getLocal(tid);
8061 const items = local.getMutableItems(gpa);8396 const items = local.getMutableItems(gpa);
8062 try items.ensureUnusedCapacity(1);
8063 const extra = local.getMutableExtra(gpa);8397 const extra = local.getMutableExtra(gpa);
8398 try items.ensureUnusedCapacity(1);
8399 try extra.ensureUnusedCapacity(@typeInfo(Tag.Extern).Struct.fields.len);
8400 try local.getMutableNavs(gpa).ensureUnusedCapacity(1);
80648401
8065 const prev_extra_len = extra.mutate.len;8402 // 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));8403 const extern_index = Index.Unwrapped.wrap(.{
8067 errdefer extra.mutate.len = prev_extra_len;8404 .tid = tid,
8405 .index = items.mutate.len,
8406 }, ip);
8407 const owner_nav = ip.createNav(gpa, tid, .{
8408 .name = key.name,
8409 .fqn = key.name,
8410 .val = extern_index,
8411 .alignment = key.alignment,
8412 .@"linksection" = .none,
8413 .@"addrspace" = key.@"addrspace",
8414 }) catch unreachable; // capacity asserted above
8415 const extra_index = addExtraAssumeCapacity(extra, Tag.Extern{
8416 .ty = key.ty,
8417 .lib_name = key.lib_name,
8418 .flags = .{
8419 .is_const = key.is_const,
8420 .is_threadlocal = key.is_threadlocal,
8421 .is_weak_linkage = key.is_weak_linkage,
8422 },
8423 .zir_index = key.zir_index,
8424 .owner_nav = owner_nav,
8425 });
8068 items.appendAssumeCapacity(.{8426 items.appendAssumeCapacity(.{
8069 .tag = .extern_func,8427 .tag = .@"extern",
8070 .data = extra_index,8428 .data = extra_index,
8071 });8429 });
8072 errdefer items.mutate.len -= 1;8430 assert(gop.put() == extern_index);
8073 return gop.put();8431
8432 return .{
8433 .index = extern_index,
8434 .new_nav = owner_nav.toOptional(),
8435 };
8074}8436}
80758437
8076pub const GetFuncDeclKey = struct {8438pub const GetFuncDeclKey = struct {
8077 owner_decl: DeclIndex,8439 owner_nav: Nav.Index,
8078 ty: Index,8440 ty: Index,
8079 zir_body_inst: TrackedInst.Index,8441 zir_body_inst: TrackedInst.Index,
8080 lbrace_line: u32,8442 lbrace_line: u32,
...@@ -8105,7 +8467,7 @@ pub fn getFuncDecl(...@@ -8105,7 +8467,7 @@ pub fn getFuncDecl(
81058467
8106 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{8468 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
8107 .analysis = .{8469 .analysis = .{
8108 .state = if (key.cc == .Inline) .inline_only else .none,8470 .state = .unreferenced,
8109 .is_cold = false,8471 .is_cold = false,
8110 .is_noinline = key.is_noinline,8472 .is_noinline = key.is_noinline,
8111 .calls_or_awaits_errorable_fn = false,8473 .calls_or_awaits_errorable_fn = false,
...@@ -8113,7 +8475,7 @@ pub fn getFuncDecl(...@@ -8113,7 +8475,7 @@ pub fn getFuncDecl(
8113 .inferred_error_set = false,8475 .inferred_error_set = false,
8114 .disable_instrumentation = false,8476 .disable_instrumentation = false,
8115 },8477 },
8116 .owner_decl = key.owner_decl,8478 .owner_nav = key.owner_nav,
8117 .ty = key.ty,8479 .ty = key.ty,
8118 .zir_body_inst = key.zir_body_inst,8480 .zir_body_inst = key.zir_body_inst,
8119 .lbrace_line = key.lbrace_line,8481 .lbrace_line = key.lbrace_line,
...@@ -8140,7 +8502,7 @@ pub fn getFuncDecl(...@@ -8140,7 +8502,7 @@ pub fn getFuncDecl(
8140}8502}
81418503
8142pub const GetFuncDeclIesKey = struct {8504pub const GetFuncDeclIesKey = struct {
8143 owner_decl: DeclIndex,8505 owner_nav: Nav.Index,
8144 param_types: []Index,8506 param_types: []Index,
8145 noalias_bits: u32,8507 noalias_bits: u32,
8146 comptime_bits: u32,8508 comptime_bits: u32,
...@@ -8209,7 +8571,7 @@ pub fn getFuncDeclIes(...@@ -8209,7 +8571,7 @@ pub fn getFuncDeclIes(
82098571
8210 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{8572 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
8211 .analysis = .{8573 .analysis = .{
8212 .state = if (key.cc == .Inline) .inline_only else .none,8574 .state = .unreferenced,
8213 .is_cold = false,8575 .is_cold = false,
8214 .is_noinline = key.is_noinline,8576 .is_noinline = key.is_noinline,
8215 .calls_or_awaits_errorable_fn = false,8577 .calls_or_awaits_errorable_fn = false,
...@@ -8217,7 +8579,7 @@ pub fn getFuncDeclIes(...@@ -8217,7 +8579,7 @@ pub fn getFuncDeclIes(
8217 .inferred_error_set = true,8579 .inferred_error_set = true,
8218 .disable_instrumentation = false,8580 .disable_instrumentation = false,
8219 },8581 },
8220 .owner_decl = key.owner_decl,8582 .owner_nav = key.owner_nav,
8221 .ty = func_ty,8583 .ty = func_ty,
8222 .zir_body_inst = key.zir_body_inst,8584 .zir_body_inst = key.zir_body_inst,
8223 .lbrace_line = key.lbrace_line,8585 .lbrace_line = key.lbrace_line,
...@@ -8401,7 +8763,7 @@ pub fn getFuncInstance(...@@ -8401,7 +8763,7 @@ pub fn getFuncInstance(
84018763
8402 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{8764 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
8403 .analysis = .{8765 .analysis = .{
8404 .state = if (arg.cc == .Inline) .inline_only else .none,8766 .state = .unreferenced,
8405 .is_cold = false,8767 .is_cold = false,
8406 .is_noinline = arg.is_noinline,8768 .is_noinline = arg.is_noinline,
8407 .calls_or_awaits_errorable_fn = false,8769 .calls_or_awaits_errorable_fn = false,
...@@ -8409,9 +8771,9 @@ pub fn getFuncInstance(...@@ -8409,9 +8771,9 @@ pub fn getFuncInstance(
8409 .inferred_error_set = false,8771 .inferred_error_set = false,
8410 .disable_instrumentation = false,8772 .disable_instrumentation = false,
8411 },8773 },
8412 // This is populated after we create the Decl below. It is not read8774 // This is populated after we create the Nav below. It is not read
8413 // by equality or hashing functions.8775 // by equality or hashing functions.
8414 .owner_decl = undefined,8776 .owner_nav = undefined,
8415 .ty = func_ty,8777 .ty = func_ty,
8416 .branch_quota = 0,8778 .branch_quota = 0,
8417 .generic_owner = generic_owner,8779 .generic_owner = generic_owner,
...@@ -8501,7 +8863,7 @@ pub fn getFuncInstanceIes(...@@ -8501,7 +8863,7 @@ pub fn getFuncInstanceIes(
85018863
8502 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{8864 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
8503 .analysis = .{8865 .analysis = .{
8504 .state = if (arg.cc == .Inline) .inline_only else .none,8866 .state = .unreferenced,
8505 .is_cold = false,8867 .is_cold = false,
8506 .is_noinline = arg.is_noinline,8868 .is_noinline = arg.is_noinline,
8507 .calls_or_awaits_errorable_fn = false,8869 .calls_or_awaits_errorable_fn = false,
...@@ -8509,9 +8871,9 @@ pub fn getFuncInstanceIes(...@@ -8509,9 +8871,9 @@ pub fn getFuncInstanceIes(
8509 .inferred_error_set = true,8871 .inferred_error_set = true,
8510 .disable_instrumentation = false,8872 .disable_instrumentation = false,
8511 },8873 },
8512 // This is populated after we create the Decl below. It is not read8874 // This is populated after we create the Nav below. It is not read
8513 // by equality or hashing functions.8875 // by equality or hashing functions.
8514 .owner_decl = undefined,8876 .owner_nav = undefined,
8515 .ty = func_ty,8877 .ty = func_ty,
8516 .branch_quota = 0,8878 .branch_quota = 0,
8517 .generic_owner = generic_owner,8879 .generic_owner = generic_owner,
...@@ -8617,37 +8979,26 @@ fn finishFuncInstance(...@@ -8617,37 +8979,26 @@ fn finishFuncInstance(
8617 alignment: Alignment,8979 alignment: Alignment,
8618 section: OptionalNullTerminatedString,8980 section: OptionalNullTerminatedString,
8619) Allocator.Error!void {8981) Allocator.Error!void {
8620 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));8982 const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav);
8621 const decl_index = try ip.createDecl(gpa, tid, .{8983 const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace;
8622 .name = undefined,8984
8623 .fqn = undefined,8985 // TODO: improve this name
8624 .src_namespace = fn_owner_decl.src_namespace,8986 const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
8625 .has_tv = true,8987 fn_owner_nav.name.fmt(ip), @intFromEnum(func_index),
8626 .owns_tv = true,8988 }, .no_embedded_nulls);
8627 .val = @import("Value.zig").fromInterned(func_index),8989 const nav_index = try ip.createNav(gpa, tid, .{
8990 .name = nav_name,
8991 .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name),
8992 .val = func_index,
8628 .alignment = alignment,8993 .alignment = alignment,
8629 .@"linksection" = section,8994 .@"linksection" = section,
8630 .@"addrspace" = fn_owner_decl.@"addrspace",8995 .@"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 });8996 });
8637 errdefer ip.destroyDecl(tid, decl_index);
86388997
8639 // Populate the owner_decl field which was left undefined until now.8998 // Populate the owner_nav field which was left undefined until now.
8640 extra.view().items(.@"0")[8999 extra.view().items(.@"0")[
8641 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?9000 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?
8642 ] = @intFromEnum(decl_index);9001 ] = @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}9002}
86529003
8653pub const EnumTypeInit = struct {9004pub const EnumTypeInit = struct {
...@@ -8671,23 +9022,36 @@ pub const WipEnumType = struct {...@@ -8671,23 +9022,36 @@ pub const WipEnumType = struct {
8671 tid: Zcu.PerThread.Id,9022 tid: Zcu.PerThread.Id,
8672 index: Index,9023 index: Index,
8673 tag_ty_index: u32,9024 tag_ty_index: u32,
8674 decl_index: u32,9025 type_name_extra_index: u32,
8675 namespace_index: ?u32,9026 cau_extra_index: u32,
9027 namespace_extra_index: ?u32,
8676 names_map: MapIndex,9028 names_map: MapIndex,
8677 names_start: u32,9029 names_start: u32,
8678 values_map: OptionalMapIndex,9030 values_map: OptionalMapIndex,
8679 values_start: u32,9031 values_start: u32,
86809032
9033 pub fn setName(
9034 wip: WipEnumType,
9035 ip: *InternPool,
9036 type_name: NullTerminatedString,
9037 ) void {
9038 const extra = ip.getLocalShared(wip.tid).extra.acquire();
9039 const extra_items = extra.view().items(.@"0");
9040 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
9041 }
9042
8681 pub fn prepare(9043 pub fn prepare(
8682 wip: WipEnumType,9044 wip: WipEnumType,
8683 ip: *InternPool,9045 ip: *InternPool,
8684 decl: DeclIndex,9046 analysis_owner: Cau.Index,
8685 namespace: OptionalNamespaceIndex,9047 namespace: OptionalNamespaceIndex,
8686 ) void {9048 ) void {
8687 const extra = ip.getLocalShared(wip.tid).extra.acquire();9049 const extra = ip.getLocalShared(wip.tid).extra.acquire();
8688 const extra_items = extra.view().items(.@"0");9050 const extra_items = extra.view().items(.@"0");
8689 extra_items[wip.decl_index] = @intFromEnum(decl);9051
8690 if (wip.namespace_index) |i| {9052 extra_items[wip.cau_extra_index] = @intFromEnum(analysis_owner);
9053
9054 if (wip.namespace_extra_index) |i| {
8691 extra_items[i] = @intFromEnum(namespace.unwrap().?);9055 extra_items[i] = @intFromEnum(namespace.unwrap().?);
8692 } else {9056 } else {
8693 assert(namespace == .none);9057 assert(namespace == .none);
...@@ -8780,10 +9144,11 @@ pub fn getEnumType(...@@ -8780,10 +9144,11 @@ pub fn getEnumType(
8780 .reified => 2, // type_hash: PackedU649144 .reified => 2, // type_hash: PackedU64
8781 } +9145 } +
8782 // zig fmt: on9146 // zig fmt: on
9147 1 + // cau
8783 ini.fields_len); // field types9148 ini.fields_len); // field types
87849149
8785 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{9150 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
8786 .decl = undefined, // set by `prepare`9151 .name = undefined, // set by `prepare`
8787 .captures_len = switch (ini.key) {9152 .captures_len = switch (ini.key) {
8788 .declared => |d| @intCast(d.captures.len),9153 .declared => |d| @intCast(d.captures.len),
8789 .reified => std.math.maxInt(u32),9154 .reified => std.math.maxInt(u32),
...@@ -8800,6 +9165,8 @@ pub fn getEnumType(...@@ -8800,6 +9165,8 @@ pub fn getEnumType(
8800 .tag = .type_enum_auto,9165 .tag = .type_enum_auto,
8801 .data = extra_index,9166 .data = extra_index,
8802 });9167 });
9168 const cau_extra_index = extra.view().len;
9169 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
8803 switch (ini.key) {9170 switch (ini.key) {
8804 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),9171 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8805 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),9172 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
...@@ -8810,8 +9177,9 @@ pub fn getEnumType(...@@ -8810,8 +9177,9 @@ pub fn getEnumType(
8810 .tid = tid,9177 .tid = tid,
8811 .index = gop.put(),9178 .index = gop.put(),
8812 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,9179 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
8813 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,9180 .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,9181 .cau_extra_index = @intCast(cau_extra_index),
9182 .namespace_extra_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
8815 .names_map = names_map,9183 .names_map = names_map,
8816 .names_start = @intCast(names_start),9184 .names_start = @intCast(names_start),
8817 .values_map = .none,9185 .values_map = .none,
...@@ -8835,11 +9203,12 @@ pub fn getEnumType(...@@ -8835,11 +9203,12 @@ pub fn getEnumType(
8835 .reified => 2, // type_hash: PackedU649203 .reified => 2, // type_hash: PackedU64
8836 } +9204 } +
8837 // zig fmt: on9205 // zig fmt: on
9206 1 + // cau
8838 ini.fields_len + // field types9207 ini.fields_len + // field types
8839 ini.fields_len * @intFromBool(ini.has_values)); // field values9208 ini.fields_len * @intFromBool(ini.has_values)); // field values
88409209
8841 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{9210 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
8842 .decl = undefined, // set by `prepare`9211 .name = undefined, // set by `prepare`
8843 .captures_len = switch (ini.key) {9212 .captures_len = switch (ini.key) {
8844 .declared => |d| @intCast(d.captures.len),9213 .declared => |d| @intCast(d.captures.len),
8845 .reified => std.math.maxInt(u32),9214 .reified => std.math.maxInt(u32),
...@@ -8861,6 +9230,8 @@ pub fn getEnumType(...@@ -8861,6 +9230,8 @@ pub fn getEnumType(
8861 },9230 },
8862 .data = extra_index,9231 .data = extra_index,
8863 });9232 });
9233 const cau_extra_index = extra.view().len;
9234 extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish`
8864 switch (ini.key) {9235 switch (ini.key) {
8865 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),9236 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8866 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),9237 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
...@@ -8874,9 +9245,10 @@ pub fn getEnumType(...@@ -8874,9 +9245,10 @@ pub fn getEnumType(
8874 return .{ .wip = .{9245 return .{ .wip = .{
8875 .tid = tid,9246 .tid = tid,
8876 .index = gop.put(),9247 .index = gop.put(),
8877 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,9248 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,
8878 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,9249 .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,9250 .cau_extra_index = @intCast(cau_extra_index),
9251 .namespace_extra_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").? else null,
8880 .names_map = names_map,9252 .names_map = names_map,
8881 .names_start = @intCast(names_start),9253 .names_start = @intCast(names_start),
8882 .values_map = values_map,9254 .values_map = values_map,
...@@ -8887,7 +9259,7 @@ pub fn getEnumType(...@@ -8887,7 +9259,7 @@ pub fn getEnumType(
8887}9259}
88889260
8889const GeneratedTagEnumTypeInit = struct {9261const GeneratedTagEnumTypeInit = struct {
8890 decl: DeclIndex,9262 name: NullTerminatedString,
8891 owner_union_ty: Index,9263 owner_union_ty: Index,
8892 tag_ty: Index,9264 tag_ty: Index,
8893 names: []const NullTerminatedString,9265 names: []const NullTerminatedString,
...@@ -8928,7 +9300,7 @@ pub fn getGeneratedTagEnumType(...@@ -8928,7 +9300,7 @@ pub fn getGeneratedTagEnumType(
8928 items.appendAssumeCapacity(.{9300 items.appendAssumeCapacity(.{
8929 .tag = .type_enum_auto,9301 .tag = .type_enum_auto,
8930 .data = addExtraAssumeCapacity(extra, EnumAuto{9302 .data = addExtraAssumeCapacity(extra, EnumAuto{
8931 .decl = ini.decl,9303 .name = ini.name,
8932 .captures_len = 0,9304 .captures_len = 0,
8933 .namespace = .none,9305 .namespace = .none,
8934 .int_tag_type = ini.tag_ty,9306 .int_tag_type = ini.tag_ty,
...@@ -8961,7 +9333,7 @@ pub fn getGeneratedTagEnumType(...@@ -8961,7 +9333,7 @@ pub fn getGeneratedTagEnumType(
8961 .auto => unreachable,9333 .auto => unreachable,
8962 },9334 },
8963 .data = addExtraAssumeCapacity(extra, EnumExplicit{9335 .data = addExtraAssumeCapacity(extra, EnumExplicit{
8964 .decl = ini.decl,9336 .name = ini.name,
8965 .captures_len = 0,9337 .captures_len = 0,
8966 .namespace = .none,9338 .namespace = .none,
8967 .int_tag_type = ini.tag_ty,9339 .int_tag_type = ini.tag_ty,
...@@ -9034,7 +9406,7 @@ pub fn getOpaqueType(...@@ -9034,7 +9406,7 @@ pub fn getOpaqueType(
9034 .reified => 0,9406 .reified => 0,
9035 });9407 });
9036 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{9408 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
9037 .decl = undefined, // set by `finish`9409 .name = undefined, // set by `finish`
9038 .namespace = .none,9410 .namespace = .none,
9039 .zir_index = switch (ini.key) {9411 .zir_index = switch (ini.key) {
9040 inline else => |x| x.zir_index,9412 inline else => |x| x.zir_index,
...@@ -9052,15 +9424,18 @@ pub fn getOpaqueType(...@@ -9052,15 +9424,18 @@ pub fn getOpaqueType(
9052 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),9424 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
9053 .reified => {},9425 .reified => {},
9054 }9426 }
9055 return .{ .wip = .{9427 return .{
9056 .tid = tid,9428 .wip = .{
9057 .index = gop.put(),9429 .tid = tid,
9058 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,9430 .index = gop.put(),
9059 .namespace_extra_index = if (ini.has_namespace)9431 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
9060 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?9432 .cau_extra_index = null, // opaques do not undergo type resolution
9061 else9433 .namespace_extra_index = if (ini.has_namespace)
9062 null,9434 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?
9063 } };9435 else
9436 null,
9437 },
9438 };
9064}9439}
90659440
9066pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {9441pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
...@@ -9181,7 +9556,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {...@@ -9181,7 +9556,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
9181 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {9556 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
9182 extra.appendAssumeCapacity(.{switch (field.type) {9557 extra.appendAssumeCapacity(.{switch (field.type) {
9183 Index,9558 Index,
9184 DeclIndex,9559 Cau.Index,
9560 Nav.Index,
9185 NamespaceIndex,9561 NamespaceIndex,
9186 OptionalNamespaceIndex,9562 OptionalNamespaceIndex,
9187 MapIndex,9563 MapIndex,
...@@ -9244,7 +9620,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat...@@ -9244,7 +9620,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
9244 const extra_item = extra_items[extra_index];9620 const extra_item = extra_items[extra_index];
9245 @field(result, field.name) = switch (field.type) {9621 @field(result, field.name) = switch (field.type) {
9246 Index,9622 Index,
9247 DeclIndex,9623 Cau.Index,
9624 Nav.Index,
9248 NamespaceIndex,9625 NamespaceIndex,
9249 OptionalNamespaceIndex,9626 OptionalNamespaceIndex,
9250 MapIndex,9627 MapIndex,
...@@ -9436,12 +9813,6 @@ pub fn getCoerced(...@@ -9436,12 +9813,6 @@ pub fn getCoerced(
94369813
9437 switch (ip.indexToKey(val)) {9814 switch (ip.indexToKey(val)) {
9438 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),9815 .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,9816 .func => unreachable,
94469817
9447 .int => |int| switch (ip.indexToKey(new_ty)) {9818 .int => |int| switch (ip.indexToKey(new_ty)) {
...@@ -9858,27 +10229,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9858,27 +10229,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9858 var items_len: usize = 0;10229 var items_len: usize = 0;
9859 var extra_len: usize = 0;10230 var extra_len: usize = 0;
9860 var limbs_len: usize = 0;10231 var limbs_len: usize = 0;
9861 var decls_len: usize = 0;
9862 for (ip.locals) |*local| {10232 for (ip.locals) |*local| {
9863 items_len += local.mutate.items.len;10233 items_len += local.mutate.items.len;
9864 extra_len += local.mutate.extra.len;10234 extra_len += local.mutate.extra.len;
9865 limbs_len += local.mutate.limbs.len;10235 limbs_len += local.mutate.limbs.len;
9866 decls_len += local.mutate.decls.buckets_list.len;
9867 }10236 }
9868 const items_size = (1 + 4) * items_len;10237 const items_size = (1 + 4) * items_len;
9869 const extra_size = 4 * extra_len;10238 const extra_size = 4 * extra_len;
9870 const limbs_size = 8 * limbs_len;10239 const limbs_size = 8 * limbs_len;
9871 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
987210240
9873 // TODO: map overhead size is not taken into account10241 // TODO: map overhead size is not taken into account
9874 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;10242 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size;
987510243
9876 std.debug.print(10244 std.debug.print(
9877 \\InternPool size: {d} bytes10245 \\InternPool size: {d} bytes
9878 \\ {d} items: {d} bytes10246 \\ {d} items: {d} bytes
9879 \\ {d} extra: {d} bytes10247 \\ {d} extra: {d} bytes
9880 \\ {d} limbs: {d} bytes10248 \\ {d} limbs: {d} bytes
9881 \\ {d} decls: {d} bytes
9882 \\10249 \\
9883 , .{10250 , .{
9884 total_size,10251 total_size,
...@@ -9888,8 +10255,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9888,8 +10255,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9888 extra_size,10255 extra_size,
9889 limbs_len,10256 limbs_len,
9890 limbs_size,10257 limbs_size,
9891 decls_len,
9892 decls_size,
9893 });10258 });
989410259
9895 const TagStats = struct {10260 const TagStats = struct {
...@@ -10034,10 +10399,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10034,10 +10399,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10034 .undef => 0,10399 .undef => 0,
10035 .simple_type => 0,10400 .simple_type => 0,
10036 .simple_value => 0,10401 .simple_value => 0,
10037 .ptr_decl => @sizeOf(PtrDecl),10402 .ptr_nav => @sizeOf(PtrNav),
10038 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),10403 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
10039 .ptr_anon_decl => @sizeOf(PtrAnonDecl),10404 .ptr_uav => @sizeOf(PtrUav),
10040 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),10405 .ptr_uav_aligned => @sizeOf(PtrUavAligned),
10041 .ptr_comptime_field => @sizeOf(PtrComptimeField),10406 .ptr_comptime_field => @sizeOf(PtrComptimeField),
10042 .ptr_int => @sizeOf(PtrInt),10407 .ptr_int => @sizeOf(PtrInt),
10043 .ptr_eu_payload => @sizeOf(PtrBase),10408 .ptr_eu_payload => @sizeOf(PtrBase),
...@@ -10092,7 +10457,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -10092,7 +10457,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
10092 .float_c_longdouble_f128 => @sizeOf(Float128),10457 .float_c_longdouble_f128 => @sizeOf(Float128),
10093 .float_comptime_float => @sizeOf(Float128),10458 .float_comptime_float => @sizeOf(Float128),
10094 .variable => @sizeOf(Tag.Variable),10459 .variable => @sizeOf(Tag.Variable),
10095 .extern_func => @sizeOf(Tag.ExternFunc),10460 .@"extern" => @sizeOf(Tag.Extern),
10096 .func_decl => @sizeOf(Tag.FuncDecl),10461 .func_decl => @sizeOf(Tag.FuncDecl),
10097 .func_instance => b: {10462 .func_instance => b: {
10098 const info = extraData(extra_list, Tag.FuncInstance, data);10463 const info = extraData(extra_list, Tag.FuncInstance, data);
...@@ -10171,10 +10536,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -10171,10 +10536,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
10171 .type_union,10536 .type_union,
10172 .type_function,10537 .type_function,
10173 .undef,10538 .undef,
10174 .ptr_decl,10539 .ptr_nav,
10175 .ptr_comptime_alloc,10540 .ptr_comptime_alloc,
10176 .ptr_anon_decl,10541 .ptr_uav,
10177 .ptr_anon_decl_aligned,10542 .ptr_uav_aligned,
10178 .ptr_comptime_field,10543 .ptr_comptime_field,
10179 .ptr_int,10544 .ptr_int,
10180 .ptr_eu_payload,10545 .ptr_eu_payload,
...@@ -10212,7 +10577,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {...@@ -10212,7 +10577,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void {
10212 .float_c_longdouble_f128,10577 .float_c_longdouble_f128,
10213 .float_comptime_float,10578 .float_comptime_float,
10214 .variable,10579 .variable,
10215 .extern_func,10580 .@"extern",
10216 .func_decl,10581 .func_decl,
10217 .func_instance,10582 .func_instance,
10218 .func_coerced,10583 .func_coerced,
...@@ -10275,13 +10640,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -10275,13 +10640,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
10275 instances.sort(SortContext{ .values = instances.values() });10640 instances.sort(SortContext{ .values = instances.values() });
10276 var it = instances.iterator();10641 var it = instances.iterator();
10277 while (it.next()) |entry| {10642 while (it.next()) |entry| {
10278 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));10643 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 });10644 try w.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len });
10280 for (entry.value_ptr.items) |index| {10645 for (entry.value_ptr.items) |index| {
10281 const unwrapped_index = index.unwrap(ip);10646 const unwrapped_index = index.unwrap(ip);
10282 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));10647 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
10283 const owner_decl = ip.declPtrConst(func.owner_decl);10648 const owner_nav = ip.getNav(func.owner_nav);
10284 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});10649 try w.print(" {}: (", .{owner_nav.name.fmt(ip)});
10285 for (func.comptime_args.get(ip)) |arg| {10650 for (func.comptime_args.get(ip)) |arg| {
10286 if (arg != .none) {10651 if (arg != .none) {
10287 const key = ip.indexToKey(arg);10652 const key = ip.indexToKey(arg);
...@@ -10295,66 +10660,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -10295,66 +10660,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
10295 try bw.flush();10660 try bw.flush();
10296}10661}
1029710662
10298pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {10663pub fn getCau(ip: *const InternPool, index: Cau.Index) Cau {
10299 return @constCast(ip.declPtrConst(decl_index));10664 const unwrapped = index.unwrap(ip);
10665 const caus = ip.getLocalShared(unwrapped.tid).caus.acquire();
10666 return caus.view().items(.@"0")[unwrapped.index];
10667}
10668
10669pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav {
10670 const unwrapped = index.unwrap(ip);
10671 const navs = ip.getLocalShared(unwrapped.tid).navs.acquire();
10672 return navs.view().get(unwrapped.index).unpack();
10300}10673}
1030110674
10302pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl {10675pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
10303 const unwrapped_decl_index = decl_index.unwrap(ip);10676 const unwrapped_namespace_index = namespace_index.unwrap(ip);
10304 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();10677 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
10305 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];10678 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
10306 return &decls_bucket[unwrapped_decl_index.index];10679 return &namespaces_bucket[unwrapped_namespace_index.index];
10307}10680}
1030810681
10309pub fn createDecl(10682/// Create a `Cau` associated with the type at the given `InternPool.Index`.
10683pub fn createTypeCau(
10310 ip: *InternPool,10684 ip: *InternPool,
10311 gpa: Allocator,10685 gpa: Allocator,
10312 tid: Zcu.PerThread.Id,10686 tid: Zcu.PerThread.Id,
10313 initialization: Zcu.Decl,10687 zir_index: TrackedInst.Index,
10314) Allocator.Error!DeclIndex {10688 namespace: NamespaceIndex,
10315 const local = ip.getLocal(tid);10689 owner_type: InternPool.Index,
10316 const free_list_next = local.mutate.decls.free_list;10690) Allocator.Error!Cau.Index {
10317 if (free_list_next != Local.BucketListMutate.free_list_sentinel) {10691 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10318 const reused_decl_index: DeclIndex = @enumFromInt(free_list_next);10692 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,10693 .tid = tid,
10335 .bucket_index = decls.mutate.len - 1,10694 .index = caus.mutate.len,
10336 .index = local.mutate.decls.last_bucket_len,
10337 };10695 };
10338 local.mutate.decls.last_bucket_len =10696 try caus.append(.{.{
10339 (unwrapped_decl_index.index + 1) & Local.namespaces_bucket_mask;10697 .zir_index = zir_index,
10340 const decl_index = unwrapped_decl_index.wrap(ip);10698 .namespace = namespace,
10341 ip.declPtr(decl_index).* = initialization;10699 .owner = Cau.Owner.wrap(.{ .type = owner_type }),
10342 return decl_index;10700 }});
10701 return index_unwrapped.wrap(ip);
10343}10702}
1034410703
10345pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex) void {10704/// Create a `Cau` for a `comptime` declaration.
10346 const local = ip.getLocal(tid);10705pub fn createComptimeCau(
10347 const decl = ip.declPtr(decl_index);10706 ip: *InternPool,
10348 decl.* = undefined;10707 gpa: Allocator,
10349 @field(decl, Local.decl_next_free_field) = @enumFromInt(local.mutate.decls.free_list);10708 tid: Zcu.PerThread.Id,
10350 local.mutate.decls.free_list = @intFromEnum(decl_index);10709 zir_index: TrackedInst.Index,
10710 namespace: NamespaceIndex,
10711) Allocator.Error!Cau.Index {
10712 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10713 const index_unwrapped: Cau.Index.Unwrapped = .{
10714 .tid = tid,
10715 .index = caus.mutate.len,
10716 };
10717 try caus.append(.{.{
10718 .zir_index = zir_index,
10719 .namespace = namespace,
10720 .owner = Cau.Owner.wrap(.none),
10721 }});
10722 return index_unwrapped.wrap(ip);
10351}10723}
1035210724
10353pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {10725/// Create a `Nav` not associated with any `Cau`.
10354 const unwrapped_namespace_index = namespace_index.unwrap(ip);10726/// 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();10727pub fn createNav(
10356 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];10728 ip: *InternPool,
10357 return &namespaces_bucket[unwrapped_namespace_index.index];10729 gpa: Allocator,
10730 tid: Zcu.PerThread.Id,
10731 opts: struct {
10732 name: NullTerminatedString,
10733 fqn: NullTerminatedString,
10734 val: InternPool.Index,
10735 alignment: Alignment,
10736 @"linksection": OptionalNullTerminatedString,
10737 @"addrspace": std.builtin.AddressSpace,
10738 },
10739) Allocator.Error!Nav.Index {
10740 const navs = ip.getLocal(tid).getMutableNavs(gpa);
10741 const index_unwrapped: Nav.Index.Unwrapped = .{
10742 .tid = tid,
10743 .index = navs.mutate.len,
10744 };
10745 try navs.append(Nav.pack(.{
10746 .name = opts.name,
10747 .fqn = opts.fqn,
10748 .analysis_owner = .none,
10749 .status = .{ .resolved = .{
10750 .val = opts.val,
10751 .alignment = opts.alignment,
10752 .@"linksection" = opts.@"linksection",
10753 .@"addrspace" = opts.@"addrspace",
10754 } },
10755 .is_usingnamespace = false,
10756 }));
10757 return index_unwrapped.wrap(ip);
10758}
10759
10760/// Create a `Cau` and `Nav` which are paired. The value of the `Nav` is
10761/// determined by semantic analysis of the `Cau`. The value of the `Nav`
10762/// is initially unresolved.
10763pub fn createPairedCauNav(
10764 ip: *InternPool,
10765 gpa: Allocator,
10766 tid: Zcu.PerThread.Id,
10767 name: NullTerminatedString,
10768 fqn: NullTerminatedString,
10769 zir_index: TrackedInst.Index,
10770 namespace: NamespaceIndex,
10771 /// TODO: this is hacky! See `Nav.is_usingnamespace`.
10772 is_usingnamespace: bool,
10773) Allocator.Error!struct { Cau.Index, Nav.Index } {
10774 const caus = ip.getLocal(tid).getMutableCaus(gpa);
10775 const navs = ip.getLocal(tid).getMutableNavs(gpa);
10776
10777 try caus.ensureUnusedCapacity(1);
10778 try navs.ensureUnusedCapacity(1);
10779
10780 const cau = Cau.Index.Unwrapped.wrap(.{
10781 .tid = tid,
10782 .index = caus.mutate.len,
10783 }, ip);
10784 const nav = Nav.Index.Unwrapped.wrap(.{
10785 .tid = tid,
10786 .index = navs.mutate.len,
10787 }, ip);
10788
10789 caus.appendAssumeCapacity(.{.{
10790 .zir_index = zir_index,
10791 .namespace = namespace,
10792 .owner = Cau.Owner.wrap(.{ .nav = nav }),
10793 }});
10794 navs.appendAssumeCapacity(Nav.pack(.{
10795 .name = name,
10796 .fqn = fqn,
10797 .analysis_owner = cau.toOptional(),
10798 .status = .unresolved,
10799 .is_usingnamespace = is_usingnamespace,
10800 }));
10801
10802 return .{ cau, nav };
10803}
10804
10805/// Resolve the value of a `Nav` with an analysis owner.
10806/// If its status is already `resolved`, the old value is discarded.
10807pub fn resolveNavValue(
10808 ip: *InternPool,
10809 nav: Nav.Index,
10810 resolved: struct {
10811 val: InternPool.Index,
10812 alignment: Alignment,
10813 @"linksection": OptionalNullTerminatedString,
10814 @"addrspace": std.builtin.AddressSpace,
10815 },
10816) void {
10817 const unwrapped = nav.unwrap(ip);
10818
10819 const local = ip.getLocal(unwrapped.tid);
10820 local.mutate.extra.mutex.lock();
10821 defer local.mutate.extra.mutex.unlock();
10822
10823 const navs = local.shared.navs.view();
10824
10825 const nav_analysis_owners = navs.items(.analysis_owner);
10826 const nav_vals = navs.items(.val);
10827 const nav_linksections = navs.items(.@"linksection");
10828 const nav_bits = navs.items(.bits);
10829
10830 assert(nav_analysis_owners[unwrapped.index] != .none);
10831
10832 @atomicStore(InternPool.Index, &nav_vals[unwrapped.index], resolved.val, .release);
10833 @atomicStore(OptionalNullTerminatedString, &nav_linksections[unwrapped.index], resolved.@"linksection", .release);
10834
10835 var bits = nav_bits[unwrapped.index];
10836 bits.status = .resolved;
10837 bits.alignment = resolved.alignment;
10838 bits.@"addrspace" = resolved.@"addrspace";
10839 @atomicStore(Nav.Repr.Bits, &nav_bits[unwrapped.index], bits, .release);
10358}10840}
1035910841
10360pub fn createNamespace(10842pub fn createNamespace(
...@@ -10404,7 +10886,7 @@ pub fn destroyNamespace(...@@ -10404,7 +10886,7 @@ pub fn destroyNamespace(
10404 namespace.* = .{10886 namespace.* = .{
10405 .parent = undefined,10887 .parent = undefined,
10406 .file_scope = undefined,10888 .file_scope = undefined,
10407 .decl_index = undefined,10889 .owner_type = undefined,
10408 };10890 };
10409 @field(namespace, Local.namespace_next_free_field) =10891 @field(namespace, Local.namespace_next_free_field) =
10410 @enumFromInt(local.mutate.namespaces.free_list);10892 @enumFromInt(local.mutate.namespaces.free_list);
...@@ -10750,10 +11232,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -10750,10 +11232,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1075011232
10751 .simple_type, .simple_value => unreachable, // handled via Index above11233 .simple_type, .simple_value => unreachable, // handled via Index above
1075211234
10753 inline .ptr_decl,11235 inline .ptr_nav,
10754 .ptr_comptime_alloc,11236 .ptr_comptime_alloc,
10755 .ptr_anon_decl,11237 .ptr_uav,
10756 .ptr_anon_decl_aligned,11238 .ptr_uav_aligned,
10757 .ptr_comptime_field,11239 .ptr_comptime_field,
10758 .ptr_int,11240 .ptr_int,
10759 .ptr_eu_payload,11241 .ptr_eu_payload,
...@@ -10770,7 +11252,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -10770,7 +11252,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
10770 .error_union_error,11252 .error_union_error,
10771 .enum_tag,11253 .enum_tag,
10772 .variable,11254 .variable,
10773 .extern_func,11255 .@"extern",
10774 .func_decl,11256 .func_decl,
10775 .func_instance,11257 .func_instance,
10776 .func_coerced,11258 .func_coerced,
...@@ -10892,14 +11374,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool {...@@ -10892,14 +11374,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool {
10892 return val.unwrap(ip).getTag(ip) == .variable;11374 return val.unwrap(ip).getTag(ip) == .variable;
10893}11375}
1089411376
10895pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {11377pub fn getBackingNav(ip: *const InternPool, val: Index) Nav.Index.Optional {
10896 var base = val;11378 var base = val;
10897 while (true) {11379 while (true) {
10898 const unwrapped_base = base.unwrap(ip);11380 const unwrapped_base = base.unwrap(ip);
10899 const base_item = unwrapped_base.getItem(ip);11381 const base_item = unwrapped_base.getItem(ip);
10900 switch (base_item.tag) {11382 switch (base_item.tag) {
10901 .ptr_decl => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[11383 .ptr_nav => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
10902 base_item.data + std.meta.fieldIndex(PtrDecl, "decl").?11384 base_item.data + std.meta.fieldIndex(PtrNav, "nav").?
10903 ]),11385 ]),
10904 inline .ptr_eu_payload,11386 inline .ptr_eu_payload,
10905 .ptr_opt_payload,11387 .ptr_opt_payload,
...@@ -10922,11 +11404,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta...@@ -10922,11 +11404,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
10922 const unwrapped_base = base.unwrap(ip);11404 const unwrapped_base = base.unwrap(ip);
10923 const base_item = unwrapped_base.getItem(ip);11405 const base_item = unwrapped_base.getItem(ip);
10924 switch (base_item.tag) {11406 switch (base_item.tag) {
10925 .ptr_decl => return .decl,11407 .ptr_nav => return .nav,
10926 .ptr_comptime_alloc => return .comptime_alloc,11408 .ptr_comptime_alloc => return .comptime_alloc,
10927 .ptr_anon_decl,11409 .ptr_uav,
10928 .ptr_anon_decl_aligned,11410 .ptr_uav_aligned,
10929 => return .anon_decl,11411 => return .uav,
10930 .ptr_comptime_field => return .comptime_field,11412 .ptr_comptime_field => return .comptime_field,
10931 .ptr_int => return .int,11413 .ptr_int => return .int,
10932 inline .ptr_eu_payload,11414 inline .ptr_eu_payload,
...@@ -11098,10 +11580,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11098,10 +11580,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
11098 // values, not types11580 // values, not types
11099 .undef,11581 .undef,
11100 .simple_value,11582 .simple_value,
11101 .ptr_decl,11583 .ptr_nav,
11102 .ptr_comptime_alloc,11584 .ptr_comptime_alloc,
11103 .ptr_anon_decl,11585 .ptr_uav,
11104 .ptr_anon_decl_aligned,11586 .ptr_uav_aligned,
11105 .ptr_comptime_field,11587 .ptr_comptime_field,
11106 .ptr_int,11588 .ptr_int,
11107 .ptr_eu_payload,11589 .ptr_eu_payload,
...@@ -11137,7 +11619,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -11137,7 +11619,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
11137 .float_c_longdouble_f128,11619 .float_c_longdouble_f128,
11138 .float_comptime_float,11620 .float_comptime_float,
11139 .variable,11621 .variable,
11140 .extern_func,11622 .@"extern",
11141 .func_decl,11623 .func_decl,
11142 .func_instance,11624 .func_instance,
11143 .func_coerced,11625 .func_coerced,
...@@ -11190,18 +11672,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {...@@ -11190,18 +11672,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis {
11190 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);11672 return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered);
11191}11673}
1119211674
11193pub fn funcSetAnalysisState(ip: *InternPool, func: Index, state: FuncAnalysis.State) void {
11194 const unwrapped_func = func.unwrap(ip);
11195 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
11196 extra_mutex.lock();
11197 defer extra_mutex.unlock();
11198
11199 const analysis_ptr = ip.funcAnalysisPtr(func);
11200 var analysis = analysis_ptr.*;
11201 analysis.state = state;
11202 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
11203}
11204
11205pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {11675pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void {
11206 const unwrapped_func = func.unwrap(ip);11676 const unwrapped_func = func.unwrap(ip);
11207 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;11677 const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex;
...@@ -11349,10 +11819,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {...@@ -11349,10 +11819,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
11349 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);11819 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
11350}11820}
1135111821
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 {11822pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
11357 const unwrapped_index = index.unwrap(ip);11823 const unwrapped_index = index.unwrap(ip);
11358 const extra_list = unwrapped_index.getExtra(ip);11824 const extra_list = unwrapped_index.getExtra(ip);
...@@ -11409,14 +11875,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {...@@ -11409,14 +11875,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 {
11409 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);11875 return @intCast(ip.indexToKey(i).anon_struct_type.types.len);
11410}11876}
1141111877
11412/// Asserts the type is a struct.
11413pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {
11414 return switch (ip.indexToKey(i)) {
11415 .struct_type => |t| t.decl,
11416 else => unreachable,
11417 };
11418}
11419
11420/// Returns the already-existing field with the same name, if any.11878/// Returns the already-existing field with the same name, if any.
11421pub fn addFieldName(11879pub fn addFieldName(
11422 ip: *InternPool,11880 ip: *InternPool,
...@@ -11436,8 +11894,8 @@ pub fn addFieldName(...@@ -11436,8 +11894,8 @@ pub fn addFieldName(
11436 return null;11894 return null;
11437}11895}
1143811896
11439/// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_anon_decl`11897/// 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.11898/// encoding instead of `Tag.ptr_uav_aligned` when possible.
11441fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {11899fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
11442 if (a_ty == b_ty) return true;11900 if (a_ty == b_ty) return true;
11443 const b_info = ip.indexToKey(b_ty).ptr_type;11901 const b_info = ip.indexToKey(b_ty).ptr_type;
...@@ -11607,3 +12065,7 @@ pub fn getErrorValue(...@@ -11607,3 +12065,7 @@ pub fn getErrorValue(
11607pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {12065pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
11608 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);12066 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
11609}12067}
12068
12069pub fn isRemoved(ip: *const InternPool, ty: Index) bool {
12070 return ty.unwrap(ip).getTag(ip) == .removed;
12071}
src/Sema.zig+1014-1056
...@@ -16,16 +16,14 @@ air_instructions: std.MultiArrayList(Air.Inst) = .{},...@@ -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
...@@ -2831,73 +2817,68 @@ fn zirStructDecl(...@@ -2831,73 +2817,68 @@ fn zirStructDecl(
2831 });2817 });
2832 errdefer wip_ty.cancel(ip, pt.tid);2818 errdefer wip_ty.cancel(ip, pt.tid);
28332819
2834 const new_decl_index = try sema.createAnonymousDeclTypeNamed(2820 wip_ty.setName(ip, try sema.createTypeName(
2835 block,2821 block,
2836 Value.fromInterned(wip_ty.index),
2837 small.name_strategy,2822 small.name_strategy,
2838 "struct",2823 "struct",
2839 inst,2824 inst,
2840 );2825 wip_ty.index,
2841 mod.declPtr(new_decl_index).owns_tv = true;2826 ));
2842 errdefer pt.abortAnonDecl(new_decl_index);
2843
2844 if (pt.zcu.comp.incremental) {
2845 try ip.addDependency(
2846 sema.gpa,
2847 AnalUnit.wrap(.{ .decl = new_decl_index }),
2848 .{ .src_hash = try block.trackZir(inst) },
2849 );
2850 }
28512827
2852 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.2828 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
2853 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{2829 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
2854 .parent = block.namespace.toOptional(),2830 .parent = block.namespace.toOptional(),
2855 .decl_index = new_decl_index,2831 .owner_type = wip_ty.index,
2856 .file_scope = block.getFileScopeIndex(mod),2832 .file_scope = block.getFileScopeIndex(mod),
2857 })).toOptional() else .none;2833 })).toOptional() else .none;
2858 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);2834 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
28592835
2836 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index.unwrap() orelse block.namespace, wip_ty.index);
2837
2838 if (pt.zcu.comp.incremental) {
2839 try ip.addDependency(
2840 sema.gpa,
2841 AnalUnit.wrap(.{ .cau = new_cau_index }),
2842 .{ .src_hash = tracked_inst },
2843 );
2844 }
2845
2860 if (new_namespace_index.unwrap()) |ns| {2846 if (new_namespace_index.unwrap()) |ns| {
2861 const decls = sema.code.bodySlice(extra_index, decls_len);2847 const decls = sema.code.bodySlice(extra_index, decls_len);
2862 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));2848 try pt.scanNamespace(ns, decls);
2863 }2849 }
28642850
2865 try pt.finalizeAnonDecl(new_decl_index);
2866 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });2851 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
2867 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));2852 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
2868 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));2853 try sema.declareDependency(.{ .interned = wip_ty.index });
2854 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
2869}2855}
28702856
2871fn createAnonymousDeclTypeNamed(2857fn createTypeName(
2872 sema: *Sema,2858 sema: *Sema,
2873 block: *Block,2859 block: *Block,
2874 val: Value,
2875 name_strategy: Zir.Inst.NameStrategy,2860 name_strategy: Zir.Inst.NameStrategy,
2876 anon_prefix: []const u8,2861 anon_prefix: []const u8,
2877 inst: ?Zir.Inst.Index,2862 inst: ?Zir.Inst.Index,
2878) !InternPool.DeclIndex {2863 /// This is used purely to give the type a unique name in the `anon` case.
2864 type_index: InternPool.Index,
2865) !InternPool.NullTerminatedString {
2879 const pt = sema.pt;2866 const pt = sema.pt;
2880 const zcu = pt.zcu;2867 const zcu = pt.zcu;
2868 const gpa = zcu.gpa;
2881 const ip = &zcu.intern_pool;2869 const ip = &zcu.intern_pool;
2882 const gpa = sema.gpa;
2883 const namespace = block.namespace;
2884 const new_decl_index = try pt.allocateNewDecl(namespace);
2885 errdefer pt.destroyDecl(new_decl_index);
28862870
2887 switch (name_strategy) {2871 switch (name_strategy) {
2888 .anon => {}, // handled after switch2872 .anon => {}, // handled after switch
2889 .parent => {2873 .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: {2874 .func => func_strat: {
2894 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));2875 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip));
2895 const zir_tags = sema.code.instructions.items(.tag);2876 const zir_tags = sema.code.instructions.items(.tag);
28962877
2897 var buf = std.ArrayList(u8).init(gpa);2878 var buf: std.ArrayListUnmanaged(u8) = .{};
2898 defer buf.deinit();2879 defer buf.deinit(gpa);
28992880
2900 const writer = buf.writer();2881 const writer = buf.writer(gpa);
2901 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});2882 try writer.print("{}(", .{block.type_name_ctx.fmt(ip)});
29022883
2903 var arg_i: usize = 0;2884 var arg_i: usize = 0;
...@@ -2931,23 +2912,18 @@ fn createAnonymousDeclTypeNamed(...@@ -2931,23 +2912,18 @@ fn createAnonymousDeclTypeNamed(
2931 };2912 };
29322913
2933 try writer.writeByte(')');2914 try writer.writeByte(')');
2934 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);2915 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 },2916 },
2938 .dbg_var => {2917 .dbg_var => {
2918 // 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();2919 const ref = inst.?.toRef();
2940 const zir_tags = sema.code.instructions.items(.tag);2920 const zir_tags = sema.code.instructions.items(.tag);
2941 const zir_data = sema.code.instructions.items(.data);2921 const zir_data = sema.code.instructions.items(.data);
2942 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {2922 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
2943 .dbg_var_ptr, .dbg_var_val => {2923 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
2944 if (zir_data[i].str_op.operand != ref) continue;2924 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),2925 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
2948 }, .no_embedded_nulls);2926 }, .no_embedded_nulls);
2949 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2950 return new_decl_index;
2951 },2927 },
2952 else => {},2928 else => {},
2953 };2929 };
...@@ -2955,20 +2931,19 @@ fn createAnonymousDeclTypeNamed(...@@ -2955,20 +2931,19 @@ fn createAnonymousDeclTypeNamed(
2955 },2931 },
2956 }2932 }
29572933
2958 // anon strat handling.2934 // anon strat handling
29592935
2960 // It would be neat to have "struct:line:column" but this name has2936 // It would be neat to have "struct:line:column" but this name has
2961 // to survive incremental updates, where it may have been shifted down2937 // to survive incremental updates, where it may have been shifted down
2962 // or up to a different line, but unchanged, and thus not unnecessarily2938 // or up to a different line, but unchanged, and thus not unnecessarily
2963 // semantically analyzed.2939 // semantically analyzed.
2964 // This name is also used as the key in the parent namespace so it cannot be2940 // TODO: that would be possible, by detecting line number changes and renaming
2965 // renamed.2941 // types appropriately. However, `@typeName` becomes a problem then. If we remove
2942 // that builtin from the language, we can consider this.
29662943
2967 const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{2944 return ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2968 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),2945 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
2969 }, .no_embedded_nulls) catch unreachable;2946 }, .no_embedded_nulls);
2970 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2971 return new_decl_index;
2972}2947}
29732948
2974fn zirEnumDecl(2949fn zirEnumDecl(
...@@ -3068,60 +3043,53 @@ fn zirEnumDecl(...@@ -3068,60 +3043,53 @@ fn zirEnumDecl(
30683043
3069 errdefer if (!done) wip_ty.cancel(ip, pt.tid);3044 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
30703045
3071 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3046 const type_name = try sema.createTypeName(
3072 block,3047 block,
3073 Value.fromInterned(wip_ty.index),
3074 small.name_strategy,3048 small.name_strategy,
3075 "enum",3049 "enum",
3076 inst,3050 inst,
3051 wip_ty.index,
3077 );3052 );
3078 const new_decl = mod.declPtr(new_decl_index);3053 wip_ty.setName(ip, type_name);
3079 new_decl.owns_tv = true;
3080 errdefer if (!done) pt.abortAnonDecl(new_decl_index);
3081
3082 if (pt.zcu.comp.incremental) {
3083 try mod.intern_pool.addDependency(
3084 gpa,
3085 AnalUnit.wrap(.{ .decl = new_decl_index }),
3086 .{ .src_hash = try block.trackZir(inst) },
3087 );
3088 }
30893054
3090 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.3055 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
3091 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{3056 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
3092 .parent = block.namespace.toOptional(),3057 .parent = block.namespace.toOptional(),
3093 .decl_index = new_decl_index,3058 .owner_type = wip_ty.index,
3094 .file_scope = block.getFileScopeIndex(mod),3059 .file_scope = block.getFileScopeIndex(mod),
3095 })).toOptional() else .none;3060 })).toOptional() else .none;
3096 errdefer if (!done) if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);3061 errdefer if (!done) if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
30973062
3063 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index.unwrap() orelse block.namespace, wip_ty.index);
3064
3065 if (pt.zcu.comp.incremental) {
3066 try mod.intern_pool.addDependency(
3067 gpa,
3068 AnalUnit.wrap(.{ .cau = new_cau_index }),
3069 .{ .src_hash = try block.trackZir(inst) },
3070 );
3071 }
3072
3098 if (new_namespace_index.unwrap()) |ns| {3073 if (new_namespace_index.unwrap()) |ns| {
3099 try pt.scanNamespace(ns, decls, new_decl);3074 try pt.scanNamespace(ns, decls);
3100 }3075 }
31013076
3077 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3078 try sema.declareDependency(.{ .interned = wip_ty.index });
3079
3102 // We've finished the initial construction of this type, and are about to perform analysis.3080 // 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.3081 // Set the Cau and namespace appropriately, and don't destroy anything on failure.
3104 wip_ty.prepare(ip, new_decl_index, new_namespace_index);3082 wip_ty.prepare(ip, new_cau_index, new_namespace_index);
3105 done = true;3083 done = true;
31063084
3107 const int_tag_ty = ty: {3085 const int_tag_ty = ty: {
3108 // We create a block for the field type instructions because they3086 // We create a block for the field type instructions because they
3109 // may need to reference Decls from inside the enum namespace.3087 // may need to reference Decls from inside the enum namespace.
3110 // Within the field type, default value, and alignment expressions, the "owner decl"3088 // Within the field type, default value, and alignment expressions, the owner should be the enum's `Cau`.
3111 // should be the enum itself.
31123089
3113 const prev_owner_decl = sema.owner_decl;3090 const prev_owner = sema.owner;
3114 const prev_owner_decl_index = sema.owner_decl_index;3091 sema.owner = AnalUnit.wrap(.{ .cau = new_cau_index });
3115 sema.owner_decl = new_decl;3092 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;
31253093
3126 const prev_func_index = sema.func_index;3094 const prev_func_index = sema.func_index;
3127 sema.func_index = .none;3095 sema.func_index = .none;
...@@ -3135,7 +3103,7 @@ fn zirEnumDecl(...@@ -3135,7 +3103,7 @@ fn zirEnumDecl(
3135 .inlining = null,3103 .inlining = null,
3136 .is_comptime = true,3104 .is_comptime = true,
3137 .src_base_inst = tracked_inst,3105 .src_base_inst = tracked_inst,
3138 .type_name_ctx = new_decl.name,3106 .type_name_ctx = type_name,
3139 };3107 };
3140 defer enum_block.instructions.deinit(sema.gpa);3108 defer enum_block.instructions.deinit(sema.gpa);
31413109
...@@ -3253,7 +3221,6 @@ fn zirEnumDecl(...@@ -3253,7 +3221,6 @@ fn zirEnumDecl(
3253 }3221 }
3254 }3222 }
32553223
3256 try pt.finalizeAnonDecl(new_decl_index);
3257 return Air.internedToRef(wip_ty.index);3224 return Air.internedToRef(wip_ty.index);
3258}3225}
32593226
...@@ -3336,41 +3303,41 @@ fn zirUnionDecl(...@@ -3336,41 +3303,41 @@ fn zirUnionDecl(
3336 });3303 });
3337 errdefer wip_ty.cancel(ip, pt.tid);3304 errdefer wip_ty.cancel(ip, pt.tid);
33383305
3339 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3306 wip_ty.setName(ip, try sema.createTypeName(
3340 block,3307 block,
3341 Value.fromInterned(wip_ty.index),
3342 small.name_strategy,3308 small.name_strategy,
3343 "union",3309 "union",
3344 inst,3310 inst,
3345 );3311 wip_ty.index,
3346 mod.declPtr(new_decl_index).owns_tv = true;3312 ));
3347 errdefer pt.abortAnonDecl(new_decl_index);
3348
3349 if (pt.zcu.comp.incremental) {
3350 try mod.intern_pool.addDependency(
3351 gpa,
3352 AnalUnit.wrap(.{ .decl = new_decl_index }),
3353 .{ .src_hash = try block.trackZir(inst) },
3354 );
3355 }
33563313
3357 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.3314 // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace.
3358 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{3315 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{
3359 .parent = block.namespace.toOptional(),3316 .parent = block.namespace.toOptional(),
3360 .decl_index = new_decl_index,3317 .owner_type = wip_ty.index,
3361 .file_scope = block.getFileScopeIndex(mod),3318 .file_scope = block.getFileScopeIndex(mod),
3362 })).toOptional() else .none;3319 })).toOptional() else .none;
3363 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);3320 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
33643321
3322 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index.unwrap() orelse block.namespace, wip_ty.index);
3323
3324 if (pt.zcu.comp.incremental) {
3325 try mod.intern_pool.addDependency(
3326 gpa,
3327 AnalUnit.wrap(.{ .cau = new_cau_index }),
3328 .{ .src_hash = try block.trackZir(inst) },
3329 );
3330 }
3331
3365 if (new_namespace_index.unwrap()) |ns| {3332 if (new_namespace_index.unwrap()) |ns| {
3366 const decls = sema.code.bodySlice(extra_index, decls_len);3333 const decls = sema.code.bodySlice(extra_index, decls_len);
3367 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));3334 try pt.scanNamespace(ns, decls);
3368 }3335 }
33693336
3370 try pt.finalizeAnonDecl(new_decl_index);
3371 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });3337 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
3372 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));3338 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
3373 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3339 try sema.declareDependency(.{ .interned = wip_ty.index });
3340 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index));
3374}3341}
33753342
3376fn zirOpaqueDecl(3343fn zirOpaqueDecl(
...@@ -3418,47 +3385,33 @@ fn zirOpaqueDecl(...@@ -3418,47 +3385,33 @@ fn zirOpaqueDecl(
3418 };3385 };
3419 // No `wrapWipTy` needed as no std.builtin types are opaque.3386 // No `wrapWipTy` needed as no std.builtin types are opaque.
3420 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {3387 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {
3421 .existing => |ty| wip: {3388 // No `maybeRemoveOutdatedType` as opaque types are never outdated.
3422 if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty);3389 .existing => |ty| return Air.internedToRef(ty),
3423 break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip;
3424 },
3425 .wip => |wip| wip,3390 .wip => |wip| wip,
3426 };3391 };
3427 errdefer wip_ty.cancel(ip, pt.tid);3392 errdefer wip_ty.cancel(ip, pt.tid);
34283393
3429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3394 wip_ty.setName(ip, try sema.createTypeName(
3430 block,3395 block,
3431 Value.fromInterned(wip_ty.index),
3432 small.name_strategy,3396 small.name_strategy,
3433 "opaque",3397 "opaque",
3434 inst,3398 inst,
3435 );3399 wip_ty.index,
3436 mod.declPtr(new_decl_index).owns_tv = true;3400 ));
3437 errdefer pt.abortAnonDecl(new_decl_index);
3438
3439 if (pt.zcu.comp.incremental) {
3440 try ip.addDependency(
3441 gpa,
3442 AnalUnit.wrap(.{ .decl = new_decl_index }),
3443 .{ .src_hash = try block.trackZir(inst) },
3444 );
3445 }
34463401
3447 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try pt.createNamespace(.{3402 const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try pt.createNamespace(.{
3448 .parent = block.namespace.toOptional(),3403 .parent = block.namespace.toOptional(),
3449 .decl_index = new_decl_index,3404 .owner_type = wip_ty.index,
3450 .file_scope = block.getFileScopeIndex(mod),3405 .file_scope = block.getFileScopeIndex(mod),
3451 })).toOptional() else .none;3406 })).toOptional() else .none;
3452 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);3407 errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns);
34533408
3454 if (new_namespace_index.unwrap()) |ns| {3409 if (new_namespace_index.unwrap()) |ns| {
3455 const decls = sema.code.bodySlice(extra_index, decls_len);3410 const decls = sema.code.bodySlice(extra_index, decls_len);
3456 try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index));3411 try pt.scanNamespace(ns, decls);
3457 }3412 }
34583413
3459 try pt.finalizeAnonDecl(new_decl_index);3414 return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index));
3460
3461 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3462}3415}
34633416
3464fn zirErrorSetDecl(3417fn zirErrorSetDecl(
...@@ -3774,7 +3727,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3774,7 +3727,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.3727 // might have already done our job and created an anon decl ref.
3775 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {3728 switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) {
3776 .ptr => |ptr| switch (ptr.base_addr) {3729 .ptr => |ptr| switch (ptr.base_addr) {
3777 .anon_decl => {3730 .uav => {
3778 // The comptime-ification was already done for us.3731 // The comptime-ification was already done for us.
3779 // Just make sure the pointer is const.3732 // Just make sure the pointer is const.
3780 return sema.makePtrConst(block, alloc);3733 return sema.makePtrConst(block, alloc);
...@@ -3799,7 +3752,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3799,7 +3752,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3799 // Promote the constant to an anon decl.3752 // Promote the constant to an anon decl.
3800 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{3753 const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{
3801 .ty = alloc_ty.toIntern(),3754 .ty = alloc_ty.toIntern(),
3802 .base_addr = .{ .anon_decl = .{3755 .base_addr = .{ .uav = .{
3803 .val = interned.toIntern(),3756 .val = interned.toIntern(),
3804 .orig_ty = alloc_ty.toIntern(),3757 .orig_ty = alloc_ty.toIntern(),
3805 } },3758 } },
...@@ -4097,7 +4050,7 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4097,7 +4050,7 @@ fn finishResolveComptimeKnownAllocPtr(
4097 } else {4050 } else {
4098 return try pt.intern(.{ .ptr = .{4051 return try pt.intern(.{ .ptr = .{
4099 .ty = alloc_ty.toIntern(),4052 .ty = alloc_ty.toIntern(),
4100 .base_addr = .{ .anon_decl = .{4053 .base_addr = .{ .uav = .{
4101 .orig_ty = alloc_ty.toIntern(),4054 .orig_ty = alloc_ty.toIntern(),
4102 .val = result_val,4055 .val = result_val,
4103 } },4056 } },
...@@ -4250,7 +4203,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4250,7 +4203,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4250 }4203 }
42514204
4252 const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) {4205 const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) {
4253 .anon_decl => |a| a.val,4206 .uav => |a| a.val,
4254 .comptime_alloc => |i| val: {4207 .comptime_alloc => |i| val: {
4255 const alloc = sema.getComptimeAlloc(i);4208 const alloc = sema.getComptimeAlloc(i);
4256 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();4209 break :val (try alloc.val.intern(pt, sema.arena)).toIntern();
...@@ -5505,22 +5458,23 @@ fn failWithBadMemberAccess(...@@ -5505,22 +5458,23 @@ fn failWithBadMemberAccess(
5505 field_name: InternPool.NullTerminatedString,5458 field_name: InternPool.NullTerminatedString,
5506) CompileError {5459) CompileError {
5507 const pt = sema.pt;5460 const pt = sema.pt;
5508 const mod = pt.zcu;5461 const zcu = pt.zcu;
5509 const kw_name = switch (agg_ty.zigTypeTag(mod)) {5462 const ip = &zcu.intern_pool;
5463 const kw_name = switch (agg_ty.zigTypeTag(zcu)) {
5510 .Union => "union",5464 .Union => "union",
5511 .Struct => "struct",5465 .Struct => "struct",
5512 .Opaque => "opaque",5466 .Opaque => "opaque",
5513 .Enum => "enum",5467 .Enum => "enum",
5514 else => unreachable,5468 else => unreachable,
5515 };5469 };
5516 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {5470 if (agg_ty.typeDeclInst(zcu)) |inst| if (inst.resolve(ip) == .main_struct_inst) {
5517 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{5471 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{
5518 agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),5472 agg_ty.fmt(pt), field_name.fmt(ip),
5519 });5473 });
5520 };5474 };
55215475
5522 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{5476 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5523 kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool),5477 kw_name, agg_ty.fmt(pt), field_name.fmt(ip),
5524 });5478 });
5525}5479}
55265480
...@@ -5535,13 +5489,12 @@ fn failWithBadStructFieldAccess(...@@ -5535,13 +5489,12 @@ fn failWithBadStructFieldAccess(
5535 const pt = sema.pt;5489 const pt = sema.pt;
5536 const zcu = pt.zcu;5490 const zcu = pt.zcu;
5537 const ip = &zcu.intern_pool;5491 const ip = &zcu.intern_pool;
5538 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
55395492
5540 const msg = msg: {5493 const msg = msg: {
5541 const msg = try sema.errMsg(5494 const msg = try sema.errMsg(
5542 field_src,5495 field_src,
5543 "no field named '{}' in struct '{}'",5496 "no field named '{}' in struct '{}'",
5544 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },5497 .{ field_name.fmt(ip), struct_type.name.fmt(ip) },
5545 );5498 );
5546 errdefer msg.destroy(sema.gpa);5499 errdefer msg.destroy(sema.gpa);
5547 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});5500 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
...@@ -5562,13 +5515,12 @@ fn failWithBadUnionFieldAccess(...@@ -5562,13 +5515,12 @@ fn failWithBadUnionFieldAccess(
5562 const zcu = pt.zcu;5515 const zcu = pt.zcu;
5563 const ip = &zcu.intern_pool;5516 const ip = &zcu.intern_pool;
5564 const gpa = sema.gpa;5517 const gpa = sema.gpa;
5565 const decl = zcu.declPtr(union_obj.decl);
55665518
5567 const msg = msg: {5519 const msg = msg: {
5568 const msg = try sema.errMsg(5520 const msg = try sema.errMsg(
5569 field_src,5521 field_src,
5570 "no field named '{}' in union '{}'",5522 "no field named '{}' in union '{}'",
5571 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },5523 .{ field_name.fmt(ip), union_obj.name.fmt(ip) },
5572 );5524 );
5573 errdefer msg.destroy(gpa);5525 errdefer msg.destroy(gpa);
5574 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});5526 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
...@@ -5659,7 +5611,7 @@ fn storeToInferredAllocComptime(...@@ -5659,7 +5611,7 @@ fn storeToInferredAllocComptime(
5659 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {5611 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
5660 iac.ptr = try pt.intern(.{ .ptr = .{5612 iac.ptr = try pt.intern(.{ .ptr = .{
5661 .ty = alloc_ty.toIntern(),5613 .ty = alloc_ty.toIntern(),
5662 .base_addr = .{ .anon_decl = .{5614 .base_addr = .{ .uav = .{
5663 .val = operand_val.toIntern(),5615 .val = operand_val.toIntern(),
5664 .orig_ty = alloc_ty.toIntern(),5616 .orig_ty = alloc_ty.toIntern(),
5665 } },5617 } },
...@@ -5748,11 +5700,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air....@@ -5748,11 +5700,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.
5748 .ty = array_ty.toIntern(),5700 .ty = array_ty.toIntern(),
5749 .storage = .{ .bytes = string },5701 .storage = .{ .bytes = string },
5750 } });5702 } });
5751 return anonDeclRef(sema, val);5703 return sema.uavRef(val);
5752}5704}
57535705
5754fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {5706fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5755 return Air.internedToRef(try refValue(sema, val));5707 return Air.internedToRef(try sema.refValue(val));
5756}5708}
57575709
5758fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {5710fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
...@@ -5767,7 +5719,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {...@@ -5767,7 +5719,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5767 })).toIntern();5719 })).toIntern();
5768 return pt.intern(.{ .ptr = .{5720 return pt.intern(.{ .ptr = .{
5769 .ty = ptr_ty,5721 .ty = ptr_ty,
5770 .base_addr = .{ .anon_decl = .{5722 .base_addr = .{ .uav = .{
5771 .val = val,5723 .val = val,
5772 .orig_ty = ptr_ty,5724 .orig_ty = ptr_ty,
5773 } },5725 } },
...@@ -5866,7 +5818,7 @@ fn zirCompileLog(...@@ -5866,7 +5818,7 @@ fn zirCompileLog(
5866 }5818 }
5867 try writer.print("\n", .{});5819 try writer.print("\n", .{});
58685820
5869 const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.ownerUnit());5821 const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.owner);
5870 if (!gop.found_existing) gop.value_ptr.* = .{5822 if (!gop.found_existing) gop.value_ptr.* = .{
5871 .base_node_inst = block.src_base_inst,5823 .base_node_inst = block.src_base_inst,
5872 .node_offset = src_node,5824 .node_offset = src_node,
...@@ -6021,7 +5973,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6021,7 +5973,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
6021 if (!comp.config.link_libc)5973 if (!comp.config.link_libc)
6022 try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});5974 try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});
60235975
6024 const gop = try zcu.cimport_errors.getOrPut(gpa, sema.ownerUnit());5976 const gop = try zcu.cimport_errors.getOrPut(gpa, sema.owner);
6025 if (!gop.found_existing) {5977 if (!gop.found_existing) {
6026 gop.value_ptr.* = c_import_res.errors;5978 gop.value_ptr.* = c_import_res.errors;
6027 c_import_res.errors = std.zig.ErrorBundle.empty;5979 c_import_res.errors = std.zig.ErrorBundle.empty;
...@@ -6069,13 +6021,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6069,13 +6021,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)});6021 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60706022
6071 const path_digest = zcu.filePathDigest(result.file_index);6023 const path_digest = zcu.filePathDigest(result.file_index);
6072 const root_decl = zcu.fileRootDecl(result.file_index);6024 const old_root_type = zcu.fileRootType(result.file_index);
6073 pt.astGenFile(result.file, path_digest, root_decl) catch |err|6025 pt.astGenFile(result.file, path_digest, old_root_type) catch |err|
6074 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6026 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60756027
6028 // TODO: register some kind of dependency on the file.
6029 // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to
6030 // trigger re-analysis later.
6076 try pt.ensureFileAnalyzed(result.file_index);6031 try pt.ensureFileAnalyzed(result.file_index);
6077 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;6032 return Air.internedToRef(zcu.fileRootType(result.file_index));
6078 return sema.analyzeDeclVal(parent_block, src, file_root_decl_index);
6079}6033}
60806034
6081fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6035fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -6423,36 +6377,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -6423,36 +6377,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
6423 defer tracy.end();6377 defer tracy.end();
64246378
6425 const pt = sema.pt;6379 const pt = sema.pt;
6426 const mod = pt.zcu;6380 const zcu = pt.zcu;
6381 const ip = &zcu.intern_pool;
6427 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6382 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;6383 const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
6429 const src = block.nodeOffset(inst_data.src_node);6384 const src = block.nodeOffset(inst_data.src_node);
6430 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);6385 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
6431 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);6386 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
6432 const decl_name = try mod.intern_pool.getOrPutString(6387 const decl_name = try ip.getOrPutString(
6433 mod.gpa,6388 zcu.gpa,
6434 pt.tid,6389 pt.tid,
6435 sema.code.nullTerminatedString(extra.decl_name),6390 sema.code.nullTerminatedString(extra.decl_name),
6436 .no_embedded_nulls,6391 .no_embedded_nulls,
6437 );6392 );
6438 const decl_index = if (extra.namespace != .none) index_blk: {6393 const nav_index = if (extra.namespace != .none) index_blk: {
6439 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);6394 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);
6440 const container_namespace = container_ty.getNamespaceIndex(mod);6395 const container_namespace = container_ty.getNamespaceIndex(zcu);
64416396
6442 const maybe_index = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false);6397 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);6398 return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name);
6399
6400 break :index_blk lookup.nav;
6445 } else try sema.lookupIdentifier(block, operand_src, decl_name);6401 } else try sema.lookupIdentifier(block, operand_src, decl_name);
6446 const options = try sema.resolveExportOptions(block, options_src, extra.options);6402 const options = try sema.resolveExportOptions(block, options_src, extra.options);
6447 {6403
6448 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));6404 try sema.ensureNavResolved(src, nav_index);
6449 try sema.ensureDeclAnalyzed(decl_index);6405
6450 const exported_decl = mod.declPtr(decl_index);6406 // Make sure to export the owner Nav if applicable.
6451 if (exported_decl.val.getFunction(mod)) |function| {6407 const exported_nav = switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) {
6452 return sema.analyzeExport(block, src, options, function.owner_decl);6408 .variable => |v| v.owner_nav,
6453 }6409 .@"extern" => |e| e.owner_nav,
6454 }6410 .func => |f| f.owner_nav,
6455 try sema.analyzeExport(block, src, options, decl_index);6411 else => nav_index,
6412 };
6413 try sema.analyzeExport(block, src, options, exported_nav);
6456}6414}
64576415
6458fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {6416fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
...@@ -6460,7 +6418,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6460,7 +6418,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6460 defer tracy.end();6418 defer tracy.end();
64616419
6462 const pt = sema.pt;6420 const pt = sema.pt;
6463 const mod = pt.zcu;6421 const zcu = pt.zcu;
6422 const ip = &zcu.intern_pool;
6464 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;6423 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;6424 const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
6466 const src = block.nodeOffset(inst_data.src_node);6425 const src = block.nodeOffset(inst_data.src_node);
...@@ -6472,17 +6431,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6472,17 +6431,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6472 const options = try sema.resolveExportOptions(block, options_src, extra.options);6431 const options = try sema.resolveExportOptions(block, options_src, extra.options);
6473 if (options.linkage == .internal)6432 if (options.linkage == .internal)
6474 return;6433 return;
6475 if (operand.getFunction(mod)) |function| {
6476 const decl_index = function.owner_decl;
6477 return sema.analyzeExport(block, src, options, decl_index);
6478 }
64796434
6480 try sema.exports.append(mod.gpa, .{6435 // If the value has an owner Nav, export that instead.
6481 .opts = options,6436 const maybe_owner_nav = switch (ip.indexToKey(operand.toIntern())) {
6482 .src = src,6437 .variable => |v| v.owner_nav,
6483 .exported = .{ .value = operand.toIntern() },6438 .@"extern" => |e| e.owner_nav,
6484 .status = .in_progress,6439 .func => |f| f.owner_nav,
6485 });6440 else => null,
6441 };
6442 if (maybe_owner_nav) |owner_nav| {
6443 return sema.analyzeExport(block, src, options, owner_nav);
6444 } else {
6445 try sema.exports.append(zcu.gpa, .{
6446 .opts = options,
6447 .src = src,
6448 .exported = .{ .uav = operand.toIntern() },
6449 .status = .in_progress,
6450 });
6451 }
6486}6452}
64876453
6488pub fn analyzeExport(6454pub fn analyzeExport(
...@@ -6490,22 +6456,22 @@ pub fn analyzeExport(...@@ -6490,22 +6456,22 @@ pub fn analyzeExport(
6490 block: *Block,6456 block: *Block,
6491 src: LazySrcLoc,6457 src: LazySrcLoc,
6492 options: Module.Export.Options,6458 options: Module.Export.Options,
6493 exported_decl_index: InternPool.DeclIndex,6459 exported_nav_index: InternPool.Nav.Index,
6494) !void {6460) !void {
6495 const gpa = sema.gpa;6461 const gpa = sema.gpa;
6496 const pt = sema.pt;6462 const pt = sema.pt;
6497 const mod = pt.zcu;6463 const zcu = pt.zcu;
6464 const ip = &zcu.intern_pool;
64986465
6499 if (options.linkage == .internal)6466 if (options.linkage == .internal)
6500 return;6467 return;
65016468
6502 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = exported_decl_index }));6469 try sema.ensureNavResolved(src, exported_nav_index);
6503 try sema.ensureDeclAnalyzed(exported_decl_index);6470 const exported_nav = ip.getNav(exported_nav_index);
6504 const exported_decl = mod.declPtr(exported_decl_index);6471 const export_ty = Type.fromInterned(exported_nav.typeOf(ip));
6505 const export_ty = exported_decl.typeOf(mod);
65066472
6507 if (!try sema.validateExternType(export_ty, .other)) {6473 if (!try sema.validateExternType(export_ty, .other)) {
6508 const msg = msg: {6474 return sema.failWithOwnedErrorMsg(block, msg: {
6509 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});6475 const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)});
6510 errdefer msg.destroy(gpa);6476 errdefer msg.destroy(gpa);
65116477
...@@ -6513,59 +6479,50 @@ pub fn analyzeExport(...@@ -6513,59 +6479,50 @@ pub fn analyzeExport(
65136479
6514 try sema.addDeclaredHereNote(msg, export_ty);6480 try sema.addDeclaredHereNote(msg, export_ty);
6515 break :msg msg;6481 break :msg msg;
6516 };6482 });
6517 return sema.failWithOwnedErrorMsg(block, msg);
6518 }6483 }
65196484
6520 // TODO: some backends might support re-exporting extern decls6485 // TODO: some backends might support re-exporting extern decls
6521 if (exported_decl.isExtern(mod)) {6486 if (exported_nav.isExtern(ip)) {
6522 return sema.fail(block, src, "export target cannot be extern", .{});6487 return sema.fail(block, src, "export target cannot be extern", .{});
6523 }6488 }
65246489
6525 try sema.maybeQueueFuncBodyAnalysis(src, exported_decl_index);6490 try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index);
65266491
6527 try sema.exports.append(gpa, .{6492 try sema.exports.append(gpa, .{
6528 .opts = options,6493 .opts = options,
6529 .src = src,6494 .src = src,
6530 .exported = .{ .decl_index = exported_decl_index },6495 .exported = .{ .nav = exported_nav_index },
6531 .status = .in_progress,6496 .status = .in_progress,
6532 });6497 });
6533}6498}
65346499
6535fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6500fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
6536 const pt = sema.pt;6501 const pt = sema.pt;
6537 const mod = pt.zcu;6502 const zcu = pt.zcu;
6538 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;6503 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
6539 const operand_src = block.builtinCallArgSrc(extra.node, 0);6504 const operand_src = block.builtinCallArgSrc(extra.node, 0);
6540 const src = block.nodeOffset(extra.node);6505 const src = block.nodeOffset(extra.node);
6541 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);6506 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
6507
6508 const func = switch (sema.owner.unwrap()) {
6509 .func => |func| func,
6510 .cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}),
6511 };
6512
6542 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {6513 if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
6543 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{6514 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
6544 alignment.toByteUnits().?,6515 alignment.toByteUnits().?,
6545 });6516 });
6546 }6517 }
65476518
6548 const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);6519 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", .{}),6520 .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}),
6551 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),6521 .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}),
6552 else => if (block.inlining != null) {6522 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 }6523 }
6566 sema.prev_stack_alignment_src = src;
65676524
6568 mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);6525 zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment);
6569}6526}
65706527
6571fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6528fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
...@@ -6577,16 +6534,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -6577,16 +6534,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
6577 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{6534 const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{
6578 .needed_comptime_reason = "operand to @setCold must be comptime-known",6535 .needed_comptime_reason = "operand to @setCold must be comptime-known",
6579 });6536 });
6580 if (sema.func_index == .none) return; // does nothing outside a function6537 // TODO: should `@setCold` apply to the parent in an inline call?
6581 ip.funcSetCold(sema.func_index, is_cold);6538 // See also #20642 and friends.
6539 const func = switch (sema.owner.unwrap()) {
6540 .func => |func| func,
6541 .cau => return, // does nothing outside a function
6542 };
6543 ip.funcSetCold(func, is_cold);
6582}6544}
65836545
6584fn zirDisableInstrumentation(sema: *Sema) CompileError!void {6546fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
6585 const pt = sema.pt;6547 const pt = sema.pt;
6586 const mod = pt.zcu;6548 const mod = pt.zcu;
6587 const ip = &mod.intern_pool;6549 const ip = &mod.intern_pool;
6588 if (sema.func_index == .none) return; // does nothing outside a function6550 const func = switch (sema.owner.unwrap()) {
6589 ip.funcSetDisableInstrumentation(sema.func_index);6551 .func => |func| func,
6552 .cau => return, // does nothing outside a function
6553 };
6554 ip.funcSetDisableInstrumentation(func);
6590}6555}
65916556
6592fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {6557fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
...@@ -6760,8 +6725,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6760,8 +6725,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6760 inst_data.get(sema.code),6725 inst_data.get(sema.code),
6761 .no_embedded_nulls,6726 .no_embedded_nulls,
6762 );6727 );
6763 const decl_index = try sema.lookupIdentifier(block, src, decl_name);6728 const nav_index = try sema.lookupIdentifier(block, src, decl_name);
6764 return sema.analyzeDeclRef(src, decl_index);6729 return sema.analyzeNavRef(src, nav_index);
6765}6730}
67666731
6767fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6732fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -6775,17 +6740,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6775,17 +6740,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6775 inst_data.get(sema.code),6740 inst_data.get(sema.code),
6776 .no_embedded_nulls,6741 .no_embedded_nulls,
6777 );6742 );
6778 const decl = try sema.lookupIdentifier(block, src, decl_name);6743 const nav = try sema.lookupIdentifier(block, src, decl_name);
6779 return sema.analyzeDeclVal(block, src, decl);6744 return sema.analyzeNavVal(block, src, nav);
6780}6745}
67816746
6782fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex {6747fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.Nav.Index {
6783 const pt = sema.pt;6748 const pt = sema.pt;
6784 const mod = pt.zcu;6749 const mod = pt.zcu;
6785 var namespace = block.namespace;6750 var namespace = block.namespace;
6786 while (true) {6751 while (true) {
6787 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| {6752 if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |lookup| {
6788 return decl_index;6753 assert(lookup.accessible);
6754 return lookup.nav;
6789 }6755 }
6790 namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break;6756 namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break;
6791 }6757 }
...@@ -6801,66 +6767,72 @@ fn lookupInNamespace(...@@ -6801,66 +6767,72 @@ fn lookupInNamespace(
6801 opt_namespace_index: InternPool.OptionalNamespaceIndex,6767 opt_namespace_index: InternPool.OptionalNamespaceIndex,
6802 ident_name: InternPool.NullTerminatedString,6768 ident_name: InternPool.NullTerminatedString,
6803 observe_usingnamespace: bool,6769 observe_usingnamespace: bool,
6804) CompileError!?InternPool.DeclIndex {6770) CompileError!?struct {
6771 nav: InternPool.Nav.Index,
6772 /// If `false`, the declaration is in a different file and is not `pub`.
6773 /// We still return the declaration for better error reporting.
6774 accessible: bool,
6775} {
6805 const pt = sema.pt;6776 const pt = sema.pt;
6806 const mod = pt.zcu;6777 const zcu = pt.zcu;
6778 const ip = &zcu.intern_pool;
68076779
6808 const namespace_index = opt_namespace_index.unwrap() orelse return null;6780 const namespace_index = opt_namespace_index.unwrap() orelse return null;
6809 const namespace = mod.namespacePtr(namespace_index);6781 const namespace = zcu.namespacePtr(namespace_index);
6810 const namespace_decl = mod.declPtr(namespace.decl_index);6782
6811 if (namespace_decl.analysis == .file_failure) {6783 const adapter: Zcu.Namespace.NameAdapter = .{ .zcu = zcu };
6812 return error.AnalysisFail;
6813 }
68146784
6815 if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) {6785 const src_file = zcu.namespacePtr(block.namespace).file_scope;
6816 const src_file = mod.namespacePtr(block.namespace).file_scope;
68176786
6787 if (observe_usingnamespace and (namespace.pub_usingnamespace.items.len != 0 or namespace.priv_usingnamespace.items.len != 0)) {
6818 const gpa = sema.gpa;6788 const gpa = sema.gpa;
6819 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{};6789 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{};
6820 defer checked_namespaces.deinit(gpa);6790 defer checked_namespaces.deinit(gpa);
68216791
6822 // Keep track of name conflicts for error notes.6792 // Keep track of name conflicts for error notes.
6823 var candidates: std.ArrayListUnmanaged(InternPool.DeclIndex) = .{};6793 var candidates: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{};
6824 defer candidates.deinit(gpa);6794 defer candidates.deinit(gpa);
68256795
6826 try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file);6796 try checked_namespaces.put(gpa, namespace, {});
6827 var check_i: usize = 0;6797 var check_i: usize = 0;
68286798
6829 while (check_i < checked_namespaces.count()) : (check_i += 1) {6799 while (check_i < checked_namespaces.count()) : (check_i += 1) {
6830 const check_ns = checked_namespaces.keys()[check_i];6800 const check_ns = checked_namespaces.keys()[check_i];
6831 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {6801 const Pass = enum { @"pub", priv };
6832 // Skip decls which are not marked pub, which are in a different6802 for ([2]Pass{ .@"pub", .priv }) |pass| {
6833 // file than the `a.b`/`@hasDecl` syntax.6803 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;6804 continue;
6852 }6805 }
6853 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index);6806
6854 const ns_ty = sub_usingnamespace_decl.val.toType();6807 const decls, const usingnamespaces = switch (pass) {
6855 const sub_ns = mod.namespacePtrUnwrap(ns_ty.getNamespaceIndex(mod)) orelse continue;6808 .@"pub" => .{ &check_ns.pub_decls, &check_ns.pub_usingnamespace },
6856 try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScopeIndex(mod));6809 .priv => .{ &check_ns.priv_decls, &check_ns.priv_usingnamespace },
6810 };
6811
6812 if (decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6813 try candidates.append(gpa, nav_index);
6814 }
6815
6816 for (usingnamespaces.items) |sub_ns_nav| {
6817 try sema.ensureNavResolved(src, sub_ns_nav);
6818 const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.resolved.val);
6819 const sub_ns = zcu.namespacePtrUnwrap(sub_ns_ty.getNamespaceIndex(zcu)) orelse continue;
6820 try checked_namespaces.put(gpa, sub_ns, {});
6821 }
6857 }6822 }
6858 }6823 }
68596824
6860 {6825 ignore_self: {
6826 const skip_nav = switch (sema.owner.unwrap()) {
6827 .func => break :ignore_self,
6828 .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) {
6829 .none, .type => break :ignore_self,
6830 .nav => |nav| nav,
6831 },
6832 };
6861 var i: usize = 0;6833 var i: usize = 0;
6862 while (i < candidates.items.len) {6834 while (i < candidates.items.len) {
6863 if (candidates.items[i] == sema.owner_decl_index) {6835 if (candidates.items[i] == skip_nav) {
6864 _ = candidates.orderedRemove(i);6836 _ = candidates.orderedRemove(i);
6865 } else {6837 } else {
6866 i += 1;6838 i += 1;
...@@ -6870,48 +6842,50 @@ fn lookupInNamespace(...@@ -6870,48 +6842,50 @@ fn lookupInNamespace(
68706842
6871 switch (candidates.items.len) {6843 switch (candidates.items.len) {
6872 0 => {},6844 0 => {},
6873 1 => {6845 1 => return .{
6874 const decl_index = candidates.items[0];6846 .nav = candidates.items[0],
6875 return decl_index;6847 .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 },6848 },
6849 else => return sema.failWithOwnedErrorMsg(block, msg: {
6850 const msg = try sema.errMsg(src, "ambiguous reference", .{});
6851 errdefer msg.destroy(gpa);
6852 for (candidates.items) |candidate| {
6853 try sema.errNote(zcu.navSrcLoc(candidate), msg, "declared here", .{});
6854 }
6855 break :msg msg;
6856 }),
6892 }6857 }
6893 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {6858 } else if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6894 return decl_index;6859 return .{
6860 .nav = nav_index,
6861 .accessible = true,
6862 };
6863 } else if (namespace.priv_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6864 return .{
6865 .nav = nav_index,
6866 .accessible = src_file == namespace.file_scope,
6867 };
6895 }6868 }
68966869
6897 return null;6870 return null;
6898}6871}
68996872
6900fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {6873fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedInst.Index {
6901 const pt = sema.pt;6874 const pt = sema.pt;
6902 const mod = pt.zcu;6875 const zcu = pt.zcu;
6903 const func_val = (try sema.resolveValue(func_inst)) orelse return null;6876 const ip = &zcu.intern_pool;
6904 if (func_val.isUndef(mod)) return null;6877 const func_val = try sema.resolveValue(func_inst) orelse return null;
6905 const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {6878 if (func_val.isUndef(zcu)) return null;
6906 .extern_func => |extern_func| extern_func.decl,6879 const nav = switch (ip.indexToKey(func_val.toIntern())) {
6907 .func => |func| func.owner_decl,6880 .@"extern" => |e| e.owner_nav,
6881 .func => |f| f.owner_nav,
6908 .ptr => |ptr| switch (ptr.base_addr) {6882 .ptr => |ptr| switch (ptr.base_addr) {
6909 .decl => |decl| if (ptr.byte_offset == 0) mod.declPtr(decl).val.getFunction(mod).?.owner_decl else return null,6883 .nav => |nav| if (ptr.byte_offset == 0) nav else return null,
6910 else => return null,6884 else => return null,
6911 },6885 },
6912 else => return null,6886 else => return null,
6913 };6887 };
6914 return mod.declPtr(owner_decl_index);6888 return ip.getNav(nav).srcInst(ip);
6915}6889}
69166890
6917pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {6891pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
...@@ -7100,11 +7074,12 @@ fn zirCall(...@@ -7100,11 +7074,12 @@ fn zirCall(
7100 const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1);7074 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);7075 const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
71027076
7103 if (sema.owner_func_index == .none or7077 switch (sema.owner.unwrap()) {
7104 !mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn)7078 .cau => input_is_error = false,
7105 {7079 .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 trace7080 // No errorable fn actually called; we have no error return trace
7107 input_is_error = false;7081 input_is_error = false;
7082 },
7108 }7083 }
71097084
7110 if (block.ownerModule().error_tracing and7085 if (block.ownerModule().error_tracing and
...@@ -7199,7 +7174,7 @@ fn checkCallArgumentCount(...@@ -7199,7 +7174,7 @@ fn checkCallArgumentCount(
7199 return func_ty;7174 return func_ty;
7200 }7175 }
72017176
7202 const maybe_decl = try sema.funcDeclSrc(func);7177 const maybe_func_inst = try sema.funcDeclSrcInst(func);
7203 const member_str = if (member_fn) "member function " else "";7178 const member_str = if (member_fn) "member function " else "";
7204 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";7179 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
7205 const msg = msg: {7180 const msg = msg: {
...@@ -7215,9 +7190,9 @@ fn checkCallArgumentCount(...@@ -7215,9 +7190,9 @@ fn checkCallArgumentCount(
7215 );7190 );
7216 errdefer msg.destroy(sema.gpa);7191 errdefer msg.destroy(sema.gpa);
72177192
7218 if (maybe_decl) |fn_decl| {7193 if (maybe_func_inst) |func_inst| {
7219 try sema.errNote(.{7194 try sema.errNote(.{
7220 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,7195 .base_node_inst = func_inst,
7221 .offset = LazySrcLoc.Offset.nodeOffset(0),7196 .offset = LazySrcLoc.Offset.nodeOffset(0),
7222 }, msg, "function declared here", .{});7197 }, msg, "function declared here", .{});
7223 }7198 }
...@@ -7544,7 +7519,7 @@ fn analyzeCall(...@@ -7544,7 +7519,7 @@ fn analyzeCall(
7544 if (func_val.isUndef(mod))7519 if (func_val.isUndef(mod))
7545 return sema.failWithUseOfUndef(block, call_src);7520 return sema.failWithUseOfUndef(block, call_src);
7546 if (cc == .Naked) {7521 if (cc == .Naked) {
7547 const maybe_decl = try sema.funcDeclSrc(func);7522 const maybe_func_inst = try sema.funcDeclSrcInst(func);
7548 const msg = msg: {7523 const msg = msg: {
7549 const msg = try sema.errMsg(7524 const msg = try sema.errMsg(
7550 func_src,7525 func_src,
...@@ -7553,8 +7528,8 @@ fn analyzeCall(...@@ -7553,8 +7528,8 @@ fn analyzeCall(
7553 );7528 );
7554 errdefer msg.destroy(sema.gpa);7529 errdefer msg.destroy(sema.gpa);
75557530
7556 if (maybe_decl) |fn_decl| try sema.errNote(.{7531 if (maybe_func_inst) |func_inst| try sema.errNote(.{
7557 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,7532 .base_node_inst = func_inst,
7558 .offset = LazySrcLoc.Offset.nodeOffset(0),7533 .offset = LazySrcLoc.Offset.nodeOffset(0),
7559 }, msg, "function declared here", .{});7534 }, msg, "function declared here", .{});
7560 break :msg msg;7535 break :msg msg;
...@@ -7654,33 +7629,32 @@ fn analyzeCall(...@@ -7654,33 +7629,32 @@ fn analyzeCall(
7654 .block_comptime_reason = comptime_reason,7629 .block_comptime_reason = comptime_reason,
7655 });7630 });
7656 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {7631 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
7657 .extern_func => return sema.fail(block, call_src, "{s} call of extern function", .{7632 .@"extern" => return sema.fail(block, call_src, "{s} call of extern function", .{
7658 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7633 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7659 }),7634 }),
7660 .func => func_val.toIntern(),7635 .func => func_val.toIntern(),
7661 .ptr => |ptr| blk: {7636 .ptr => |ptr| blk: {
7662 switch (ptr.base_addr) {7637 switch (ptr.base_addr) {
7663 .decl => |decl| if (ptr.byte_offset == 0) {7638 .nav => |nav_index| if (ptr.byte_offset == 0) {
7664 const func_val_ptr = mod.declPtr(decl).val.toIntern();7639 const nav = ip.getNav(nav_index);
7665 const intern_index = mod.intern_pool.indexToKey(func_val_ptr);7640 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", .{7641 return sema.fail(block, call_src, "{s} call of extern function pointer", .{
7668 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7642 if (is_comptime_call) "comptime" else "inline",
7669 });7643 });
7670 break :blk func_val_ptr;7644 break :blk nav.status.resolved.val;
7671 },7645 },
7672 else => {},7646 else => {},
7673 }7647 }
7674 assert(callee_ty.isPtrAtRuntime(mod));7648 assert(callee_ty.isPtrAtRuntime(mod));
7675 return sema.fail(block, call_src, "{s} call of function pointer", .{7649 return sema.fail(block, call_src, "{s} call of function pointer", .{
7676 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7650 if (is_comptime_call) "comptime" else "inline",
7677 });7651 });
7678 },7652 },
7679 else => unreachable,7653 else => unreachable,
7680 };7654 };
7681 if (func_ty_info.is_var_args) {7655 if (func_ty_info.is_var_args) {
7682 return sema.fail(block, call_src, "{s} call of variadic function", .{7656 return sema.fail(block, call_src, "{s} call of variadic function", .{
7683 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7657 if (is_comptime_call) "comptime" else "inline",
7684 });7658 });
7685 }7659 }
76867660
...@@ -7712,7 +7686,12 @@ fn analyzeCall(...@@ -7712,7 +7686,12 @@ fn analyzeCall(
7712 };7686 };
77137687
7714 const module_fn = mod.funcInfo(module_fn_index);7688 const module_fn = mod.funcInfo(module_fn_index);
7715 const fn_owner_decl = mod.declPtr(module_fn.owner_decl);7689
7690 // This is not a function instance, so the function's `Nav` has a
7691 // `Cau` -- we don't need to check `generic_owner`.
7692 const fn_nav = ip.getNav(module_fn.owner_nav);
7693 const fn_cau_index = fn_nav.analysis_owner.unwrap().?;
7694 const fn_cau = ip.getCau(fn_cau_index);
77167695
7717 // We effectively want a child Sema here, but can't literally do that, because we need AIR7696 // 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 in7697 // to be shared. InlineCallSema is a wrapper which handles this for us. While `ics` is in
...@@ -7720,7 +7699,7 @@ fn analyzeCall(...@@ -7720,7 +7699,7 @@ fn analyzeCall(
7720 // whenever performing an operation where the difference matters.7699 // whenever performing an operation where the difference matters.
7721 var ics = InlineCallSema.init(7700 var ics = InlineCallSema.init(
7722 sema,7701 sema,
7723 fn_owner_decl.getFileScope(mod).zir,7702 mod.cauFileScope(fn_cau_index).zir,
7724 module_fn_index,7703 module_fn_index,
7725 block.error_return_trace_index,7704 block.error_return_trace_index,
7726 );7705 );
...@@ -7729,7 +7708,8 @@ fn analyzeCall(...@@ -7729,7 +7708,8 @@ fn analyzeCall(
7729 var child_block: Block = .{7708 var child_block: Block = .{
7730 .parent = null,7709 .parent = null,
7731 .sema = sema,7710 .sema = sema,
7732 .namespace = fn_owner_decl.src_namespace,7711 // The function body exists in the same namespace as the corresponding function declaration.
7712 .namespace = fn_cau.namespace,
7733 .instructions = .{},7713 .instructions = .{},
7734 .label = null,7714 .label = null,
7735 .inlining = &inlining,7715 .inlining = &inlining,
...@@ -7740,8 +7720,8 @@ fn analyzeCall(...@@ -7740,8 +7720,8 @@ fn analyzeCall(
7740 .runtime_cond = block.runtime_cond,7720 .runtime_cond = block.runtime_cond,
7741 .runtime_loop = block.runtime_loop,7721 .runtime_loop = block.runtime_loop,
7742 .runtime_index = block.runtime_index,7722 .runtime_index = block.runtime_index,
7743 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,7723 .src_base_inst = fn_cau.zir_index,
7744 .type_name_ctx = fn_owner_decl.name,7724 .type_name_ctx = fn_nav.fqn,
7745 };7725 };
77467726
7747 const merges = &child_block.inlining.?.merges;7727 const merges = &child_block.inlining.?.merges;
...@@ -7759,7 +7739,7 @@ fn analyzeCall(...@@ -7759,7 +7739,7 @@ fn analyzeCall(
7759 // comptime memory is mutated.7739 // comptime memory is mutated.
7760 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);7740 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
77617741
7762 const owner_info = mod.typeToFunc(fn_owner_decl.typeOf(mod)).?;7742 const owner_info = mod.typeToFunc(Type.fromInterned(module_fn.ty)).?;
7763 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);7743 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);
7764 var new_fn_info: InternPool.GetFuncTypeKey = .{7744 var new_fn_info: InternPool.GetFuncTypeKey = .{
7765 .param_types = new_param_types,7745 .param_types = new_param_types,
...@@ -7809,9 +7789,6 @@ fn analyzeCall(...@@ -7809,9 +7789,6 @@ fn analyzeCall(
7809 _ = ics.callee();7789 _ = ics.callee();
78107790
7811 if (!inlining.has_comptime_args) {7791 if (!inlining.has_comptime_args) {
7812 if (module_fn.analysisUnordered(ip).state == .sema_failure)
7813 return error.AnalysisFail;
7814
7815 var block_it = block;7792 var block_it = block;
7816 while (block_it.inlining) |parent_inlining| {7793 while (block_it.inlining) |parent_inlining| {
7817 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {7794 if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {
...@@ -7957,8 +7934,11 @@ fn analyzeCall(...@@ -7957,8 +7934,11 @@ fn analyzeCall(
79577934
7958 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);7935 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
79597936
7960 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {7937 switch (sema.owner.unwrap()) {
7961 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);7938 .cau => {},
7939 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7940 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
7941 },
7962 }7942 }
79637943
7964 if (try sema.resolveValue(func)) |func_val| {7944 if (try sema.resolveValue(func)) |func_val| {
...@@ -7994,7 +7974,7 @@ fn analyzeCall(...@@ -7994,7 +7974,7 @@ fn analyzeCall(
7994 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {7974 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
7995 .func => break :skip_safety,7975 .func => break :skip_safety,
7996 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {7976 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
7997 .decl => |decl| if (!mod.declPtr(decl).isExtern(mod)) break :skip_safety,7977 .nav => |nav| if (!ip.getNav(nav).isExtern(ip)) break :skip_safety,
7998 else => {},7978 else => {},
7999 },7979 },
8000 else => {},7980 else => {},
...@@ -8018,18 +7998,18 @@ fn analyzeCall(...@@ -8018,18 +7998,18 @@ fn analyzeCall(
80187998
8019fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {7999fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {
8020 const pt = sema.pt;8000 const pt = sema.pt;
8021 const mod = pt.zcu;8001 const zcu = pt.zcu;
8022 const target = mod.getTarget();8002 const target = zcu.getTarget();
8023 const backend = mod.comp.getZigBackend();8003 const backend = zcu.comp.getZigBackend();
8024 if (!target_util.supportsTailCall(target, backend)) {8004 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", .{8005 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),8006 @tagName(backend), @tagName(target.cpu.arch),
8027 });8007 });
8028 }8008 }
8029 const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index);8009 const owner_func_ty = Type.fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty);
8030 if (!func_ty.eql(func_decl.typeOf(mod), mod)) {8010 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 '{}'", .{8011 return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{
8032 func_ty.fmt(pt), func_decl.typeOf(mod).fmt(pt),8012 func_ty.fmt(pt), owner_func_ty.fmt(pt),
8033 });8013 });
8034 }8014 }
8035 _ = try block.addUnOp(.ret, result);8015 _ = try block.addUnOp(.ret, result);
...@@ -8191,7 +8171,7 @@ fn instantiateGenericCall(...@@ -8191,7 +8171,7 @@ fn instantiateGenericCall(
8191 });8171 });
8192 const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {8172 const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {
8193 .func => func_val.toIntern(),8173 .func => func_val.toIntern(),
8194 .ptr => |ptr| zcu.declPtr(ptr.base_addr.decl).val.toIntern(),8174 .ptr => |ptr| ip.getNav(ptr.base_addr.nav).status.resolved.val,
8195 else => unreachable,8175 else => unreachable,
8196 };8176 };
8197 const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func;8177 const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func;
...@@ -8207,10 +8187,10 @@ fn instantiateGenericCall(...@@ -8207,10 +8187,10 @@ fn instantiateGenericCall(
8207 // The actual monomorphization happens via adding `func_instance` to8187 // The actual monomorphization happens via adding `func_instance` to
8208 // `InternPool`.8188 // `InternPool`.
82098189
8210 const fn_owner_decl = zcu.declPtr(generic_owner_func.owner_decl);8190 // Since we are looking at the generic owner here, it has a `Cau`.
8211 const namespace_index = fn_owner_decl.src_namespace;8191 const fn_nav = ip.getNav(generic_owner_func.owner_nav);
8212 const namespace = zcu.namespacePtr(namespace_index);8192 const fn_cau = ip.getCau(fn_nav.analysis_owner.unwrap().?);
8213 const fn_zir = namespace.fileScope(zcu).zir;8193 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));8194 const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip));
82158195
8216 const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());8196 const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count());
...@@ -8232,15 +8212,13 @@ fn instantiateGenericCall(...@@ -8232,15 +8212,13 @@ fn instantiateGenericCall(
8232 // We pass the generic callsite's owner decl here because whatever `Decl`8212 // We pass the generic callsite's owner decl here because whatever `Decl`
8233 // dependencies are chased at this point should be attached to the8213 // dependencies are chased at this point should be attached to the
8234 // callsite, not the `Decl` associated with the `func_instance`.8214 // callsite, not the `Decl` associated with the `func_instance`.
8235 .owner_decl = sema.owner_decl,8215 .owner = sema.owner,
8236 .owner_decl_index = sema.owner_decl_index,8216 .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 there8217 // 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.8218 // should be no illegal instructions encountered while creating the function anyway.
8240 .func_is_naked = false,8219 .func_is_naked = false,
8241 .fn_ret_ty = Type.void,8220 .fn_ret_ty = Type.void,
8242 .fn_ret_ty_ies = null,8221 .fn_ret_ty_ies = null,
8243 .owner_func_index = .none,
8244 .comptime_args = comptime_args,8222 .comptime_args = comptime_args,
8245 .generic_owner = generic_owner,8223 .generic_owner = generic_owner,
8246 .generic_call_src = call_src,8224 .generic_call_src = call_src,
...@@ -8253,12 +8231,12 @@ fn instantiateGenericCall(...@@ -8253,12 +8231,12 @@ fn instantiateGenericCall(
8253 var child_block: Block = .{8231 var child_block: Block = .{
8254 .parent = null,8232 .parent = null,
8255 .sema = &child_sema,8233 .sema = &child_sema,
8256 .namespace = namespace_index,8234 .namespace = fn_cau.namespace,
8257 .instructions = .{},8235 .instructions = .{},
8258 .inlining = null,8236 .inlining = null,
8259 .is_comptime = true,8237 .is_comptime = true,
8260 .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,8238 .src_base_inst = fn_cau.zir_index,
8261 .type_name_ctx = fn_owner_decl.name,8239 .type_name_ctx = fn_nav.fqn,
8262 };8240 };
8263 defer child_block.instructions.deinit(gpa);8241 defer child_block.instructions.deinit(gpa);
82648242
...@@ -8421,10 +8399,11 @@ fn instantiateGenericCall(...@@ -8421,10 +8399,11 @@ fn instantiateGenericCall(
84218399
8422 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);8400 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
84238401
8424 if (sema.owner_func_index != .none and8402 switch (sema.owner.unwrap()) {
8425 Type.fromInterned(func_ty_info.return_type).isError(zcu))8403 .cau => {},
8426 {8404 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
8427 ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index);8405 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
8406 },
8428 }8407 }
84298408
8430 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));8409 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index }));
...@@ -9366,10 +9345,11 @@ fn zirFunc(...@@ -9366,10 +9345,11 @@ fn zirFunc(
9366 inferred_error_set: bool,9345 inferred_error_set: bool,
9367) CompileError!Air.Inst.Ref {9346) CompileError!Air.Inst.Ref {
9368 const pt = sema.pt;9347 const pt = sema.pt;
9369 const mod = pt.zcu;9348 const zcu = pt.zcu;
9349 const ip = &zcu.intern_pool;
9370 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;9350 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);9351 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
9372 const target = mod.getTarget();9352 const target = zcu.getTarget();
9373 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });9353 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
93749354
9375 var extra_index = extra.end;9355 var extra_index = extra.end;
...@@ -9410,11 +9390,17 @@ fn zirFunc(...@@ -9410,11 +9390,17 @@ fn zirFunc(
9410 // the callconv based on whether it is exported. Otherwise, the callconv defaults9390 // the callconv based on whether it is exported. Otherwise, the callconv defaults
9411 // to `.Unspecified`.9391 // to `.Unspecified`.
9412 const cc: std.builtin.CallingConvention = if (has_body) cc: {9392 const cc: std.builtin.CallingConvention = if (has_body) cc: {
9413 const fn_is_exported = if (sema.generic_owner != .none) exported: {9393 const func_decl_cau = if (sema.generic_owner != .none) cau: {
9414 const generic_owner_fn = mod.funcInfo(sema.generic_owner);9394 const generic_owner_fn = zcu.funcInfo(sema.generic_owner);
9415 const generic_owner_decl = mod.declPtr(generic_owner_fn.owner_decl);9395 // The generic owner definitely has a `Cau` for the corresponding function declaration.
9416 break :exported generic_owner_decl.is_exported;9396 const generic_owner_nav = ip.getNav(generic_owner_fn.owner_nav);
9417 } else sema.owner_decl.is_exported;9397 break :cau generic_owner_nav.analysis_owner.unwrap().?;
9398 } else sema.owner.unwrap().cau;
9399 const fn_is_exported = exported: {
9400 const decl_inst = ip.getCau(func_decl_cau).zir_index.resolve(ip);
9401 const zir_decl = sema.code.getDeclaration(decl_inst)[0];
9402 break :exported zir_decl.flags.is_export;
9403 };
9418 break :cc if (fn_is_exported) .C else .Unspecified;9404 break :cc if (fn_is_exported) .C else .Unspecified;
9419 } else .Unspecified;9405 } else .Unspecified;
94209406
...@@ -9613,10 +9599,10 @@ fn funcCommon(...@@ -9613,10 +9599,10 @@ fn funcCommon(
9613 is_noinline: bool,9599 is_noinline: bool,
9614) CompileError!Air.Inst.Ref {9600) CompileError!Air.Inst.Ref {
9615 const pt = sema.pt;9601 const pt = sema.pt;
9616 const mod = pt.zcu;9602 const zcu = pt.zcu;
9617 const gpa = sema.gpa;9603 const gpa = sema.gpa;
9618 const target = mod.getTarget();9604 const target = zcu.getTarget();
9619 const ip = &mod.intern_pool;9605 const ip = &zcu.intern_pool;
9620 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });9606 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 });9607 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
9622 const func_src = block.nodeOffset(src_node_offset);9608 const func_src = block.nodeOffset(src_node_offset);
...@@ -9664,8 +9650,8 @@ fn funcCommon(...@@ -9664,8 +9650,8 @@ fn funcCommon(
9664 if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) {9650 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)});9651 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)});
9666 }9652 }
9667 if (!param_ty.isValidParamType(mod)) {9653 if (!param_ty.isValidParamType(zcu)) {
9668 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";9654 const opaque_str = if (param_ty.zigTypeTag(zcu) == .Opaque) "opaque " else "";
9669 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{9655 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
9670 opaque_str, param_ty.fmt(pt),9656 opaque_str, param_ty.fmt(pt),
9671 });9657 });
...@@ -9699,7 +9685,7 @@ fn funcCommon(...@@ -9699,7 +9685,7 @@ fn funcCommon(
9699 return sema.failWithOwnedErrorMsg(block, msg);9685 return sema.failWithOwnedErrorMsg(block, msg);
9700 }9686 }
9701 if (is_source_decl and !this_generic and is_noalias and9687 if (is_source_decl and !this_generic and is_noalias and
9702 !(param_ty.zigTypeTag(mod) == .Pointer or param_ty.isPtrLikeOptional(mod)))9688 !(param_ty.zigTypeTag(zcu) == .Pointer or param_ty.isPtrLikeOptional(zcu)))
9703 {9689 {
9704 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});9690 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
9705 }9691 }
...@@ -9707,7 +9693,7 @@ fn funcCommon(...@@ -9707,7 +9693,7 @@ fn funcCommon(
9707 .Interrupt => if (target.cpu.arch.isX86()) {9693 .Interrupt => if (target.cpu.arch.isX86()) {
9708 const err_code_size = target.ptrBitWidth();9694 const err_code_size = target.ptrBitWidth();
9709 switch (i) {9695 switch (i) {
9710 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}),9696 0 => if (param_ty.zigTypeTag(zcu) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}),
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}),9697 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}),9698 else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}),
9713 }9699 }
...@@ -9769,14 +9755,11 @@ fn funcCommon(...@@ -9769,14 +9755,11 @@ fn funcCommon(
9769 );9755 );
9770 }9756 }
97719757
9772 // extern_func and func_decl functions take ownership of `sema.owner_decl`.9758 const section_name: InternPool.OptionalNullTerminatedString = switch (section) {
9773 sema.owner_decl.@"linksection" = switch (section) {
9774 .generic => .none,9759 .generic => .none,
9775 .default => .none,9760 .default => .none,
9776 .explicit => |section_name| section_name.toOptional(),9761 .explicit => |name| name.toOptional(),
9777 };9762 };
9778 sema.owner_decl.alignment = alignment orelse .none;
9779 sema.owner_decl.@"addrspace" = address_space orelse .generic;
97809763
9781 if (inferred_error_set) {9764 if (inferred_error_set) {
9782 assert(!is_extern);9765 assert(!is_extern);
...@@ -9784,7 +9767,7 @@ fn funcCommon(...@@ -9784,7 +9767,7 @@ fn funcCommon(
9784 if (!ret_poison)9767 if (!ret_poison)
9785 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);9768 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9786 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{9769 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9787 .owner_decl = sema.owner_decl_index,9770 .owner_nav = sema.getOwnerCauNav(),
97889771
9789 .param_types = param_types,9772 .param_types = param_types,
9790 .noalias_bits = noalias_bits,9773 .noalias_bits = noalias_bits,
...@@ -9804,6 +9787,13 @@ fn funcCommon(...@@ -9804,6 +9787,13 @@ fn funcCommon(
9804 .lbrace_column = @as(u16, @truncate(src_locs.columns)),9787 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9805 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),9788 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9806 });9789 });
9790 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
9791 ip.resolveNavValue(sema.getOwnerCauNav(), .{
9792 .val = func_index,
9793 .alignment = alignment orelse .none,
9794 .@"linksection" = section_name,
9795 .@"addrspace" = address_space orelse .generic,
9796 });
9807 return finishFunc(9797 return finishFunc(
9808 sema,9798 sema,
9809 block,9799 block,
...@@ -9846,11 +9836,20 @@ fn funcCommon(...@@ -9846,11 +9836,20 @@ fn funcCommon(
9846 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{9836 if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
9847 .node_offset_lib_name = src_node_offset,9837 .node_offset_lib_name = src_node_offset,
9848 }), lib_name);9838 }), lib_name);
9849 const func_index = try ip.getExternFunc(gpa, pt.tid, .{9839 const func_index = try pt.getExtern(.{
9840 .name = sema.getOwnerCauNavName(),
9850 .ty = func_ty,9841 .ty = func_ty,
9851 .decl = sema.owner_decl_index,9842 .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),9843 .is_const = true,
9844 .is_threadlocal = false,
9845 .is_weak_linkage = false,
9846 .alignment = alignment orelse .none,
9847 .@"addrspace" = address_space orelse .generic,
9848 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
9849 .owner_nav = undefined, // ignored by `getExtern`
9853 });9850 });
9851 // Note that unlike function declaration, extern functions don't touch the
9852 // Sema's owner Cau's owner Nav. The alignment etc were passed above.
9854 return finishFunc(9853 return finishFunc(
9855 sema,9854 sema,
9856 block,9855 block,
...@@ -9872,7 +9871,7 @@ fn funcCommon(...@@ -9872,7 +9871,7 @@ fn funcCommon(
98729871
9873 if (has_body) {9872 if (has_body) {
9874 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{9873 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9875 .owner_decl = sema.owner_decl_index,9874 .owner_nav = sema.getOwnerCauNav(),
9876 .ty = func_ty,9875 .ty = func_ty,
9877 .cc = cc,9876 .cc = cc,
9878 .is_noinline = is_noinline,9877 .is_noinline = is_noinline,
...@@ -9882,6 +9881,13 @@ fn funcCommon(...@@ -9882,6 +9881,13 @@ fn funcCommon(
9882 .lbrace_column = @as(u16, @truncate(src_locs.columns)),9881 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9883 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),9882 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9884 });9883 });
9884 // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`.
9885 ip.resolveNavValue(sema.getOwnerCauNav(), .{
9886 .val = func_index,
9887 .alignment = alignment orelse .none,
9888 .@"linksection" = section_name,
9889 .@"addrspace" = address_space orelse .generic,
9890 });
9885 return finishFunc(9891 return finishFunc(
9886 sema,9892 sema,
9887 block,9893 block,
...@@ -11179,7 +11185,7 @@ const SwitchProngAnalysis = struct {...@@ -11179,7 +11185,7 @@ const SwitchProngAnalysis = struct {
11179 return block.addStructFieldVal(spa.operand, field_index, field_ty);11185 return block.addStructFieldVal(spa.operand, field_index, field_ty);
11180 }11186 }
11181 } else if (capture_byref) {11187 } else if (capture_byref) {
11182 return anonDeclRef(sema, item_val.toIntern());11188 return sema.uavRef(item_val.toIntern());
11183 } else {11189 } else {
11184 return inline_case_capture;11190 return inline_case_capture;
11185 }11191 }
...@@ -13947,9 +13953,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13947,9 +13953,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13947 }13953 }
1394813954
13949 const namespace = container_type.getNamespaceIndex(mod);13955 const namespace = container_type.getNamespaceIndex(mod);
13950 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl_index| {13956 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {
13951 const decl = mod.declPtr(decl_index);13957 if (lookup.accessible) {
13952 if (decl.is_pub or decl.getFileScope(mod) == block.getFileScope(mod)) {
13953 return .bool_true;13958 return .bool_true;
13954 }13959 }
13955 }13960 }
...@@ -13981,9 +13986,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13981,9 +13986,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) });13986 return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
13982 },13987 },
13983 };13988 };
13989 // TODO: register some kind of dependency on the file.
13990 // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to
13991 // trigger re-analysis later.
13984 try pt.ensureFileAnalyzed(result.file_index);13992 try pt.ensureFileAnalyzed(result.file_index);
13985 const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?;13993 return Air.internedToRef(zcu.fileRootType(result.file_index));
13986 return sema.analyzeDeclVal(block, operand_src, file_root_decl_index);
13987}13994}
1398813995
13989fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {13996fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -16970,7 +16977,7 @@ fn analyzeArithmetic(...@@ -16970,7 +16977,7 @@ fn analyzeArithmetic(
16970 if (block.wantSafety() and want_safety and scalar_tag == .Int) {16977 if (block.wantSafety() and want_safety and scalar_tag == .Int) {
16971 if (mod.backendSupportsFeature(.safety_checked_instructions)) {16978 if (mod.backendSupportsFeature(.safety_checked_instructions)) {
16972 if (air_tag != air_tag_safe) {16979 if (air_tag != air_tag_safe) {
16973 _ = try sema.preparePanicId(block, .integer_overflow);16980 _ = try sema.preparePanicId(block, src, .integer_overflow);
16974 }16981 }
16975 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);16982 return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs);
16976 } else {16983 } else {
...@@ -17158,13 +17165,11 @@ fn zirAsm(...@@ -17158,13 +17165,11 @@ fn zirAsm(
17158 if (is_volatile) {17165 if (is_volatile) {
17159 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});17166 return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{});
17160 }17167 }
17161 try mod.addGlobalAssembly(sema.owner_decl_index, asm_source);17168 try mod.addGlobalAssembly(sema.owner.unwrap().cau, asm_source);
17162 return .void_value;17169 return .void_value;
17163 }17170 }
1716417171
17165 if (block.is_comptime) {17172 try sema.requireRuntimeBlock(block, src, null);
17166 try sema.requireRuntimeBlock(block, src, null);
17167 }
1716817173
17169 var extra_i = extra.end;17174 var extra_i = extra.end;
17170 var output_type_bits = extra.data.output_type_bits;17175 var output_type_bits = extra.data.output_type_bits;
...@@ -17646,18 +17651,17 @@ fn zirThis(...@@ -17646,18 +17651,17 @@ fn zirThis(
17646 block: *Block,17651 block: *Block,
17647 extended: Zir.Inst.Extended.InstData,17652 extended: Zir.Inst.Extended.InstData,
17648) CompileError!Air.Inst.Ref {17653) CompileError!Air.Inst.Ref {
17654 _ = extended;
17649 const pt = sema.pt;17655 const pt = sema.pt;
17650 const mod = pt.zcu;17656 const namespace = pt.zcu.namespacePtr(block.namespace);
17651 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;17657 return Air.internedToRef(namespace.owner_type);
17652 const src = block.nodeOffset(@bitCast(extended.operand));
17653 return sema.analyzeDeclVal(block, src, this_decl_index);
17654}17658}
1765517659
17656fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17660fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
17657 const pt = sema.pt;17661 const pt = sema.pt;
17658 const mod = pt.zcu;17662 const mod = pt.zcu;
17659 const ip = &mod.intern_pool;17663 const ip = &mod.intern_pool;
17660 const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);17664 const captures = Type.fromInterned(mod.namespacePtr(block.namespace).owner_type).getCaptures(mod);
1766117665
17662 const src_node: i32 = @bitCast(extended.operand);17666 const src_node: i32 = @bitCast(extended.operand);
17663 const src = block.nodeOffset(src_node);17667 const src = block.nodeOffset(src_node);
...@@ -17665,8 +17669,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -17665,8 +17669,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
17665 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {17669 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {
17666 .@"comptime" => |index| return Air.internedToRef(index),17670 .@"comptime" => |index| return Air.internedToRef(index),
17667 .runtime => |index| index,17671 .runtime => |index| index,
17668 .decl_val => |decl_index| return sema.analyzeDeclVal(block, src, decl_index),17672 .nav_val => |nav| return sema.analyzeNavVal(block, src, nav),
17669 .decl_ref => |decl_index| return sema.analyzeDeclRef(src, decl_index),17673 .nav_ref => |nav| return sema.analyzeNavRef(src, nav),
17670 };17674 };
1767117675
17672 // The comptime case is handled already above. Runtime case below.17676 // The comptime case is handled already above. Runtime case below.
...@@ -17764,20 +17768,19 @@ fn zirBuiltinSrc(...@@ -17764,20 +17768,19 @@ fn zirBuiltinSrc(
17764 block: *Block,17768 block: *Block,
17765 extended: Zir.Inst.Extended.InstData,17769 extended: Zir.Inst.Extended.InstData,
17766) CompileError!Air.Inst.Ref {17770) CompileError!Air.Inst.Ref {
17767 _ = block;
17768 const tracy = trace(@src());17771 const tracy = trace(@src());
17769 defer tracy.end();17772 defer tracy.end();
1777017773
17771 const pt = sema.pt;17774 const pt = sema.pt;
17772 const zcu = pt.zcu;17775 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;17776 const ip = &zcu.intern_pool;
17777 const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
17778 const fn_name = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).name;
17776 const gpa = sema.gpa;17779 const gpa = sema.gpa;
17777 const file_scope = fn_owner_decl.getFileScope(zcu);17780 const file_scope = block.getFileScope(zcu);
1777817781
17779 const func_name_val = v: {17782 const func_name_val = v: {
17780 const func_name_len = fn_owner_decl.name.length(ip);17783 const func_name_len = fn_name.length(ip);
17781 const array_ty = try pt.intern(.{ .array_type = .{17784 const array_ty = try pt.intern(.{ .array_type = .{
17782 .len = func_name_len,17785 .len = func_name_len,
17783 .sentinel = .zero_u8,17786 .sentinel = .zero_u8,
...@@ -17787,11 +17790,11 @@ fn zirBuiltinSrc(...@@ -17787,11 +17790,11 @@ fn zirBuiltinSrc(
17787 .ty = .slice_const_u8_sentinel_0_type,17790 .ty = .slice_const_u8_sentinel_0_type,
17788 .ptr = try pt.intern(.{ .ptr = .{17791 .ptr = try pt.intern(.{ .ptr = .{
17789 .ty = .manyptr_const_u8_sentinel_0_type,17792 .ty = .manyptr_const_u8_sentinel_0_type,
17790 .base_addr = .{ .anon_decl = .{17793 .base_addr = .{ .uav = .{
17791 .orig_ty = .slice_const_u8_sentinel_0_type,17794 .orig_ty = .slice_const_u8_sentinel_0_type,
17792 .val = try pt.intern(.{ .aggregate = .{17795 .val = try pt.intern(.{ .aggregate = .{
17793 .ty = array_ty,17796 .ty = array_ty,
17794 .storage = .{ .bytes = fn_owner_decl.name.toString() },17797 .storage = .{ .bytes = fn_name.toString() },
17795 } }),17798 } }),
17796 } },17799 } },
17797 .byte_offset = 0,17800 .byte_offset = 0,
...@@ -17811,7 +17814,7 @@ fn zirBuiltinSrc(...@@ -17811,7 +17814,7 @@ fn zirBuiltinSrc(
17811 .ty = .slice_const_u8_sentinel_0_type,17814 .ty = .slice_const_u8_sentinel_0_type,
17812 .ptr = try pt.intern(.{ .ptr = .{17815 .ptr = try pt.intern(.{ .ptr = .{
17813 .ty = .manyptr_const_u8_sentinel_0_type,17816 .ty = .manyptr_const_u8_sentinel_0_type,
17814 .base_addr = .{ .anon_decl = .{17817 .base_addr = .{ .uav = .{
17815 .orig_ty = .slice_const_u8_sentinel_0_type,17818 .orig_ty = .slice_const_u8_sentinel_0_type,
17816 .val = try pt.intern(.{ .aggregate = .{17819 .val = try pt.intern(.{ .aggregate = .{
17817 .ty = array_ty,17820 .ty = array_ty,
...@@ -17837,7 +17840,7 @@ fn zirBuiltinSrc(...@@ -17837,7 +17840,7 @@ fn zirBuiltinSrc(
17837 .ty = .slice_const_u8_sentinel_0_type,17840 .ty = .slice_const_u8_sentinel_0_type,
17838 .ptr = try pt.intern(.{ .ptr = .{17841 .ptr = try pt.intern(.{ .ptr = .{
17839 .ty = .manyptr_const_u8_sentinel_0_type,17842 .ty = .manyptr_const_u8_sentinel_0_type,
17840 .base_addr = .{ .anon_decl = .{17843 .base_addr = .{ .uav = .{
17841 .orig_ty = .slice_const_u8_sentinel_0_type,17844 .orig_ty = .slice_const_u8_sentinel_0_type,
17842 .val = try pt.intern(.{ .aggregate = .{17845 .val = try pt.intern(.{ .aggregate = .{
17843 .ty = array_ty,17846 .ty = array_ty,
...@@ -17902,25 +17905,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17902,25 +17905,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17902 .val = .void_value,17905 .val = .void_value,
17903 } }))),17906 } }))),
17904 .Fn => {17907 .Fn => {
17905 const fn_info_decl_index = (try sema.namespaceLookup(17908 const fn_info_nav = try sema.namespaceLookup(
17906 block,17909 block,
17907 src,17910 src,
17908 type_info_ty.getNamespaceIndex(mod),17911 type_info_ty.getNamespaceIndex(mod),
17909 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),17912 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),
17910 )).?;17913 ) orelse @panic("std.builtin.Type is corrupt");
17911 try sema.ensureDeclAnalyzed(fn_info_decl_index);17914 try sema.ensureNavResolved(src, fn_info_nav);
17912 const fn_info_decl = mod.declPtr(fn_info_decl_index);17915 const fn_info_ty = Type.fromInterned(ip.getNav(fn_info_nav).status.resolved.val);
17913 const fn_info_ty = fn_info_decl.val.toType();
1791417916
17915 const param_info_decl_index = (try sema.namespaceLookup(17917 const param_info_nav = try sema.namespaceLookup(
17916 block,17918 block,
17917 src,17919 src,
17918 fn_info_ty.getNamespaceIndex(mod),17920 fn_info_ty.getNamespaceIndex(mod),
17919 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),17921 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),
17920 )).?;17922 ) orelse @panic("std.builtin.Type is corrupt");
17921 try sema.ensureDeclAnalyzed(param_info_decl_index);17923 try sema.ensureNavResolved(src, param_info_nav);
17922 const param_info_decl = mod.declPtr(param_info_decl_index);17924 const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val);
17923 const param_info_ty = param_info_decl.val.toType();
1792417925
17925 const func_ty_info = mod.typeToFunc(ty).?;17926 const func_ty_info = mod.typeToFunc(ty).?;
17926 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);17927 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
...@@ -17972,7 +17973,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17972,7 +17973,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17972 .ty = slice_ty,17973 .ty = slice_ty,
17973 .ptr = try pt.intern(.{ .ptr = .{17974 .ptr = try pt.intern(.{ .ptr = .{
17974 .ty = manyptr_ty,17975 .ty = manyptr_ty,
17975 .base_addr = .{ .anon_decl = .{17976 .base_addr = .{ .uav = .{
17976 .orig_ty = manyptr_ty,17977 .orig_ty = manyptr_ty,
17977 .val = new_decl_val,17978 .val = new_decl_val,
17978 } },17979 } },
...@@ -18014,15 +18015,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18014,15 +18015,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18014 } })));18015 } })));
18015 },18016 },
18016 .Int => {18017 .Int => {
18017 const int_info_decl_index = (try sema.namespaceLookup(18018 const int_info_nav = try sema.namespaceLookup(
18018 block,18019 block,
18019 src,18020 src,
18020 type_info_ty.getNamespaceIndex(mod),18021 type_info_ty.getNamespaceIndex(mod),
18021 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),18022 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),
18022 )).?;18023 ) orelse @panic("std.builtin.Type is corrupt");
18023 try sema.ensureDeclAnalyzed(int_info_decl_index);18024 try sema.ensureNavResolved(src, int_info_nav);
18024 const int_info_decl = mod.declPtr(int_info_decl_index);18025 const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val);
18025 const int_info_ty = int_info_decl.val.toType();
1802618026
18027 const signedness_ty = try pt.getBuiltinType("Signedness");18027 const signedness_ty = try pt.getBuiltinType("Signedness");
18028 const info = ty.intInfo(mod);18028 const info = ty.intInfo(mod);
...@@ -18042,15 +18042,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18042,15 +18042,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18042 } })));18042 } })));
18043 },18043 },
18044 .Float => {18044 .Float => {
18045 const float_info_decl_index = (try sema.namespaceLookup(18045 const float_info_nav = try sema.namespaceLookup(
18046 block,18046 block,
18047 src,18047 src,
18048 type_info_ty.getNamespaceIndex(mod),18048 type_info_ty.getNamespaceIndex(mod),
18049 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),18049 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),
18050 )).?;18050 ) orelse @panic("std.builtin.Type is corrupt");
18051 try sema.ensureDeclAnalyzed(float_info_decl_index);18051 try sema.ensureNavResolved(src, float_info_nav);
18052 const float_info_decl = mod.declPtr(float_info_decl_index);18052 const float_info_ty = Type.fromInterned(ip.getNav(float_info_nav).status.resolved.val);
18053 const float_info_ty = float_info_decl.val.toType();
1805418053
18055 const field_vals = .{18054 const field_vals = .{
18056 // bits: u16,18055 // bits: u16,
...@@ -18074,26 +18073,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18074,26 +18073,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1807418073
18075 const addrspace_ty = try pt.getBuiltinType("AddressSpace");18074 const addrspace_ty = try pt.getBuiltinType("AddressSpace");
18076 const pointer_ty = t: {18075 const pointer_ty = t: {
18077 const decl_index = (try sema.namespaceLookup(18076 const nav = try sema.namespaceLookup(
18078 block,18077 block,
18079 src,18078 src,
18080 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),18079 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18081 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),18080 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),
18082 )).?;18081 ) orelse @panic("std.builtin.Type is corrupt");
18083 try sema.ensureDeclAnalyzed(decl_index);18082 try sema.ensureNavResolved(src, nav);
18084 const decl = mod.declPtr(decl_index);18083 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18085 break :t decl.val.toType();
18086 };18084 };
18087 const ptr_size_ty = t: {18085 const ptr_size_ty = t: {
18088 const decl_index = (try sema.namespaceLookup(18086 const nav = try sema.namespaceLookup(
18089 block,18087 block,
18090 src,18088 src,
18091 pointer_ty.getNamespaceIndex(mod),18089 pointer_ty.getNamespaceIndex(mod),
18092 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),18090 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),
18093 )).?;18091 ) orelse @panic("std.builtin.Type is corrupt");
18094 try sema.ensureDeclAnalyzed(decl_index);18092 try sema.ensureNavResolved(src, nav);
18095 const decl = mod.declPtr(decl_index);18093 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18096 break :t decl.val.toType();
18097 };18094 };
1809818095
18099 const field_values = .{18096 const field_values = .{
...@@ -18128,15 +18125,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18128,15 +18125,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18128 },18125 },
18129 .Array => {18126 .Array => {
18130 const array_field_ty = t: {18127 const array_field_ty = t: {
18131 const array_field_ty_decl_index = (try sema.namespaceLookup(18128 const nav = try sema.namespaceLookup(
18132 block,18129 block,
18133 src,18130 src,
18134 type_info_ty.getNamespaceIndex(mod),18131 type_info_ty.getNamespaceIndex(mod),
18135 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),18132 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),
18136 )).?;18133 ) orelse @panic("std.builtin.Type is corrupt");
18137 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);18134 try sema.ensureNavResolved(src, nav);
18138 const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index);18135 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18139 break :t array_field_ty_decl.val.toType();
18140 };18136 };
1814118137
18142 const info = ty.arrayInfo(mod);18138 const info = ty.arrayInfo(mod);
...@@ -18159,15 +18155,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18159,15 +18155,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18159 },18155 },
18160 .Vector => {18156 .Vector => {
18161 const vector_field_ty = t: {18157 const vector_field_ty = t: {
18162 const vector_field_ty_decl_index = (try sema.namespaceLookup(18158 const nav = try sema.namespaceLookup(
18163 block,18159 block,
18164 src,18160 src,
18165 type_info_ty.getNamespaceIndex(mod),18161 type_info_ty.getNamespaceIndex(mod),
18166 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),18162 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),
18167 )).?;18163 ) orelse @panic("std.builtin.Type is corrupt");
18168 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);18164 try sema.ensureNavResolved(src, nav);
18169 const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index);18165 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18170 break :t vector_field_ty_decl.val.toType();
18171 };18166 };
1817218167
18173 const info = ty.arrayInfo(mod);18168 const info = ty.arrayInfo(mod);
...@@ -18188,15 +18183,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18188,15 +18183,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18188 },18183 },
18189 .Optional => {18184 .Optional => {
18190 const optional_field_ty = t: {18185 const optional_field_ty = t: {
18191 const optional_field_ty_decl_index = (try sema.namespaceLookup(18186 const nav = try sema.namespaceLookup(
18192 block,18187 block,
18193 src,18188 src,
18194 type_info_ty.getNamespaceIndex(mod),18189 type_info_ty.getNamespaceIndex(mod),
18195 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),18190 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),
18196 )).?;18191 ) orelse @panic("std.builtin.Type is corrupt");
18197 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);18192 try sema.ensureNavResolved(src, nav);
18198 const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index);18193 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18199 break :t optional_field_ty_decl.val.toType();
18200 };18194 };
1820118195
18202 const field_values = .{18196 const field_values = .{
...@@ -18215,15 +18209,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18215,15 +18209,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18215 .ErrorSet => {18209 .ErrorSet => {
18216 // Get the Error type18210 // Get the Error type
18217 const error_field_ty = t: {18211 const error_field_ty = t: {
18218 const set_field_ty_decl_index = (try sema.namespaceLookup(18212 const nav = try sema.namespaceLookup(
18219 block,18213 block,
18220 src,18214 src,
18221 type_info_ty.getNamespaceIndex(mod),18215 type_info_ty.getNamespaceIndex(mod),
18222 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),18216 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),
18223 )).?;18217 ) orelse @panic("std.builtin.Type is corrupt");
18224 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);18218 try sema.ensureNavResolved(src, nav);
18225 const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index);18219 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18226 break :t set_field_ty_decl.val.toType();
18227 };18220 };
1822818221
18229 // Build our list of Error values18222 // Build our list of Error values
...@@ -18251,7 +18244,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18251,7 +18244,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18251 .ty = .slice_const_u8_sentinel_0_type,18244 .ty = .slice_const_u8_sentinel_0_type,
18252 .ptr = try pt.intern(.{ .ptr = .{18245 .ptr = try pt.intern(.{ .ptr = .{
18253 .ty = .manyptr_const_u8_sentinel_0_type,18246 .ty = .manyptr_const_u8_sentinel_0_type,
18254 .base_addr = .{ .anon_decl = .{18247 .base_addr = .{ .uav = .{
18255 .val = new_decl_val,18248 .val = new_decl_val,
18256 .orig_ty = .slice_const_u8_sentinel_0_type,18249 .orig_ty = .slice_const_u8_sentinel_0_type,
18257 } },18250 } },
...@@ -18298,7 +18291,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18298,7 +18291,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18298 .ty = slice_errors_ty.toIntern(),18291 .ty = slice_errors_ty.toIntern(),
18299 .ptr = try pt.intern(.{ .ptr = .{18292 .ptr = try pt.intern(.{ .ptr = .{
18300 .ty = manyptr_errors_ty,18293 .ty = manyptr_errors_ty,
18301 .base_addr = .{ .anon_decl = .{18294 .base_addr = .{ .uav = .{
18302 .orig_ty = manyptr_errors_ty,18295 .orig_ty = manyptr_errors_ty,
18303 .val = new_decl_val,18296 .val = new_decl_val,
18304 } },18297 } },
...@@ -18321,15 +18314,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18321,15 +18314,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18321 },18314 },
18322 .ErrorUnion => {18315 .ErrorUnion => {
18323 const error_union_field_ty = t: {18316 const error_union_field_ty = t: {
18324 const error_union_field_ty_decl_index = (try sema.namespaceLookup(18317 const nav = try sema.namespaceLookup(
18325 block,18318 block,
18326 src,18319 src,
18327 type_info_ty.getNamespaceIndex(mod),18320 type_info_ty.getNamespaceIndex(mod),
18328 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),18321 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),
18329 )).?;18322 ) orelse @panic("std.builtin.Type is corrupt");
18330 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);18323 try sema.ensureNavResolved(src, nav);
18331 const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index);18324 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18332 break :t error_union_field_ty_decl.val.toType();
18333 };18325 };
1833418326
18335 const field_values = .{18327 const field_values = .{
...@@ -18351,15 +18343,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18351,15 +18343,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);18343 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1835218344
18353 const enum_field_ty = t: {18345 const enum_field_ty = t: {
18354 const enum_field_ty_decl_index = (try sema.namespaceLookup(18346 const nav = try sema.namespaceLookup(
18355 block,18347 block,
18356 src,18348 src,
18357 type_info_ty.getNamespaceIndex(mod),18349 type_info_ty.getNamespaceIndex(mod),
18358 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),18350 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),
18359 )).?;18351 ) orelse @panic("std.builtin.Type is corrupt");
18360 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);18352 try sema.ensureNavResolved(src, nav);
18361 const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index);18353 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18362 break :t enum_field_ty_decl.val.toType();
18363 };18354 };
1836418355
18365 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);18356 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
...@@ -18392,7 +18383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18392,7 +18383,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18392 .ty = .slice_const_u8_sentinel_0_type,18383 .ty = .slice_const_u8_sentinel_0_type,
18393 .ptr = try pt.intern(.{ .ptr = .{18384 .ptr = try pt.intern(.{ .ptr = .{
18394 .ty = .manyptr_const_u8_sentinel_0_type,18385 .ty = .manyptr_const_u8_sentinel_0_type,
18395 .base_addr = .{ .anon_decl = .{18386 .base_addr = .{ .uav = .{
18396 .val = new_decl_val,18387 .val = new_decl_val,
18397 .orig_ty = .slice_const_u8_sentinel_0_type,18388 .orig_ty = .slice_const_u8_sentinel_0_type,
18398 } },18389 } },
...@@ -18435,7 +18426,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18435,7 +18426,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18435 .ty = slice_ty,18426 .ty = slice_ty,
18436 .ptr = try pt.intern(.{ .ptr = .{18427 .ptr = try pt.intern(.{ .ptr = .{
18437 .ty = manyptr_ty,18428 .ty = manyptr_ty,
18438 .base_addr = .{ .anon_decl = .{18429 .base_addr = .{ .uav = .{
18439 .val = new_decl_val,18430 .val = new_decl_val,
18440 .orig_ty = manyptr_ty,18431 .orig_ty = manyptr_ty,
18441 } },18432 } },
...@@ -18448,15 +18439,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18448,15 +18439,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18448 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace);18439 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace);
1844918440
18450 const type_enum_ty = t: {18441 const type_enum_ty = t: {
18451 const type_enum_ty_decl_index = (try sema.namespaceLookup(18442 const nav = try sema.namespaceLookup(
18452 block,18443 block,
18453 src,18444 src,
18454 type_info_ty.getNamespaceIndex(mod),18445 type_info_ty.getNamespaceIndex(mod),
18455 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),18446 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),
18456 )).?;18447 ) orelse @panic("std.builtin.Type is corrupt");
18457 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);18448 try sema.ensureNavResolved(src, nav);
18458 const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index);18449 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18459 break :t type_enum_ty_decl.val.toType();
18460 };18450 };
1846118451
18462 const field_values = .{18452 const field_values = .{
...@@ -18480,27 +18470,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18480,27 +18470,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18480 },18470 },
18481 .Union => {18471 .Union => {
18482 const type_union_ty = t: {18472 const type_union_ty = t: {
18483 const type_union_ty_decl_index = (try sema.namespaceLookup(18473 const nav = try sema.namespaceLookup(
18484 block,18474 block,
18485 src,18475 src,
18486 type_info_ty.getNamespaceIndex(mod),18476 type_info_ty.getNamespaceIndex(mod),
18487 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),18477 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),
18488 )).?;18478 ) orelse @panic("std.builtin.Type is corrupt");
18489 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);18479 try sema.ensureNavResolved(src, nav);
18490 const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index);18480 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18491 break :t type_union_ty_decl.val.toType();
18492 };18481 };
1849318482
18494 const union_field_ty = t: {18483 const union_field_ty = t: {
18495 const union_field_ty_decl_index = (try sema.namespaceLookup(18484 const nav = try sema.namespaceLookup(
18496 block,18485 block,
18497 src,18486 src,
18498 type_info_ty.getNamespaceIndex(mod),18487 type_info_ty.getNamespaceIndex(mod),
18499 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),18488 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),
18500 )).?;18489 ) orelse @panic("std.builtin.Type is corrupt");
18501 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);18490 try sema.ensureNavResolved(src, nav);
18502 const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index);18491 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18503 break :t union_field_ty_decl.val.toType();
18504 };18492 };
1850518493
18506 try ty.resolveLayout(pt); // Getting alignment requires type layout18494 try ty.resolveLayout(pt); // Getting alignment requires type layout
...@@ -18528,7 +18516,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18528,7 +18516,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18528 .ty = .slice_const_u8_sentinel_0_type,18516 .ty = .slice_const_u8_sentinel_0_type,
18529 .ptr = try pt.intern(.{ .ptr = .{18517 .ptr = try pt.intern(.{ .ptr = .{
18530 .ty = .manyptr_const_u8_sentinel_0_type,18518 .ty = .manyptr_const_u8_sentinel_0_type,
18531 .base_addr = .{ .anon_decl = .{18519 .base_addr = .{ .uav = .{
18532 .val = new_decl_val,18520 .val = new_decl_val,
18533 .orig_ty = .slice_const_u8_sentinel_0_type,18521 .orig_ty = .slice_const_u8_sentinel_0_type,
18534 } },18522 } },
...@@ -18579,7 +18567,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18579,7 +18567,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18579 .ty = slice_ty,18567 .ty = slice_ty,
18580 .ptr = try pt.intern(.{ .ptr = .{18568 .ptr = try pt.intern(.{ .ptr = .{
18581 .ty = manyptr_ty,18569 .ty = manyptr_ty,
18582 .base_addr = .{ .anon_decl = .{18570 .base_addr = .{ .uav = .{
18583 .orig_ty = manyptr_ty,18571 .orig_ty = manyptr_ty,
18584 .val = new_decl_val,18572 .val = new_decl_val,
18585 } },18573 } },
...@@ -18597,15 +18585,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18597,15 +18585,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18597 } });18585 } });
1859818586
18599 const container_layout_ty = t: {18587 const container_layout_ty = t: {
18600 const decl_index = (try sema.namespaceLookup(18588 const nav = try sema.namespaceLookup(
18601 block,18589 block,
18602 src,18590 src,
18603 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),18591 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18604 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),18592 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18605 )).?;18593 ) orelse @panic("std.builtin.Type is corrupt");
18606 try sema.ensureDeclAnalyzed(decl_index);18594 try sema.ensureNavResolved(src, nav);
18607 const decl = mod.declPtr(decl_index);18595 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18608 break :t decl.val.toType();
18609 };18596 };
1861018597
18611 const field_values = .{18598 const field_values = .{
...@@ -18630,27 +18617,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18630,27 +18617,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18630 },18617 },
18631 .Struct => {18618 .Struct => {
18632 const type_struct_ty = t: {18619 const type_struct_ty = t: {
18633 const type_struct_ty_decl_index = (try sema.namespaceLookup(18620 const nav = try sema.namespaceLookup(
18634 block,18621 block,
18635 src,18622 src,
18636 type_info_ty.getNamespaceIndex(mod),18623 type_info_ty.getNamespaceIndex(mod),
18637 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),18624 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),
18638 )).?;18625 ) orelse @panic("std.builtin.Type is corrupt");
18639 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);18626 try sema.ensureNavResolved(src, nav);
18640 const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index);18627 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18641 break :t type_struct_ty_decl.val.toType();
18642 };18628 };
1864318629
18644 const struct_field_ty = t: {18630 const struct_field_ty = t: {
18645 const struct_field_ty_decl_index = (try sema.namespaceLookup(18631 const nav = try sema.namespaceLookup(
18646 block,18632 block,
18647 src,18633 src,
18648 type_info_ty.getNamespaceIndex(mod),18634 type_info_ty.getNamespaceIndex(mod),
18649 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),18635 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),
18650 )).?;18636 ) orelse @panic("std.builtin.Type is corrupt");
18651 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);18637 try sema.ensureNavResolved(src, nav);
18652 const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index);18638 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18653 break :t struct_field_ty_decl.val.toType();
18654 };18639 };
1865518640
18656 try ty.resolveLayout(pt); // Getting alignment requires type layout18641 try ty.resolveLayout(pt); // Getting alignment requires type layout
...@@ -18683,7 +18668,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18683,7 +18668,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18683 .ty = .slice_const_u8_sentinel_0_type,18668 .ty = .slice_const_u8_sentinel_0_type,
18684 .ptr = try pt.intern(.{ .ptr = .{18669 .ptr = try pt.intern(.{ .ptr = .{
18685 .ty = .manyptr_const_u8_sentinel_0_type,18670 .ty = .manyptr_const_u8_sentinel_0_type,
18686 .base_addr = .{ .anon_decl = .{18671 .base_addr = .{ .uav = .{
18687 .val = new_decl_val,18672 .val = new_decl_val,
18688 .orig_ty = .slice_const_u8_sentinel_0_type,18673 .orig_ty = .slice_const_u8_sentinel_0_type,
18689 } },18674 } },
...@@ -18747,7 +18732,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18747,7 +18732,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18747 .ty = .slice_const_u8_sentinel_0_type,18732 .ty = .slice_const_u8_sentinel_0_type,
18748 .ptr = try pt.intern(.{ .ptr = .{18733 .ptr = try pt.intern(.{ .ptr = .{
18749 .ty = .manyptr_const_u8_sentinel_0_type,18734 .ty = .manyptr_const_u8_sentinel_0_type,
18750 .base_addr = .{ .anon_decl = .{18735 .base_addr = .{ .uav = .{
18751 .val = new_decl_val,18736 .val = new_decl_val,
18752 .orig_ty = .slice_const_u8_sentinel_0_type,18737 .orig_ty = .slice_const_u8_sentinel_0_type,
18753 } },18738 } },
...@@ -18809,7 +18794,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18809,7 +18794,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18809 .ty = slice_ty,18794 .ty = slice_ty,
18810 .ptr = try pt.intern(.{ .ptr = .{18795 .ptr = try pt.intern(.{ .ptr = .{
18811 .ty = manyptr_ty,18796 .ty = manyptr_ty,
18812 .base_addr = .{ .anon_decl = .{18797 .base_addr = .{ .uav = .{
18813 .orig_ty = manyptr_ty,18798 .orig_ty = manyptr_ty,
18814 .val = new_decl_val,18799 .val = new_decl_val,
18815 } },18800 } },
...@@ -18830,15 +18815,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18830,15 +18815,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18830 } });18815 } });
1883118816
18832 const container_layout_ty = t: {18817 const container_layout_ty = t: {
18833 const decl_index = (try sema.namespaceLookup(18818 const nav = try sema.namespaceLookup(
18834 block,18819 block,
18835 src,18820 src,
18836 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),18821 (try pt.getBuiltinType("Type")).getNamespaceIndex(mod),
18837 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),18822 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
18838 )).?;18823 ) orelse @panic("std.builtin.Type is corrupt");
18839 try sema.ensureDeclAnalyzed(decl_index);18824 try sema.ensureNavResolved(src, nav);
18840 const decl = mod.declPtr(decl_index);18825 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18841 break :t decl.val.toType();
18842 };18826 };
1884318827
18844 const layout = ty.containerLayout(mod);18828 const layout = ty.containerLayout(mod);
...@@ -18866,15 +18850,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18866,15 +18850,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18866 },18850 },
18867 .Opaque => {18851 .Opaque => {
18868 const type_opaque_ty = t: {18852 const type_opaque_ty = t: {
18869 const type_opaque_ty_decl_index = (try sema.namespaceLookup(18853 const nav = try sema.namespaceLookup(
18870 block,18854 block,
18871 src,18855 src,
18872 type_info_ty.getNamespaceIndex(mod),18856 type_info_ty.getNamespaceIndex(mod),
18873 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),18857 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),
18874 )).?;18858 ) orelse @panic("std.builtin.Type is corrupt");
18875 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);18859 try sema.ensureNavResolved(src, nav);
18876 const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index);18860 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18877 break :t type_opaque_ty_decl.val.toType();
18878 };18861 };
1887918862
18880 try ty.resolveFields(pt);18863 try ty.resolveFields(pt);
...@@ -18906,19 +18889,19 @@ fn typeInfoDecls(...@@ -18906,19 +18889,19 @@ fn typeInfoDecls(
18906 opt_namespace: InternPool.OptionalNamespaceIndex,18889 opt_namespace: InternPool.OptionalNamespaceIndex,
18907) CompileError!InternPool.Index {18890) CompileError!InternPool.Index {
18908 const pt = sema.pt;18891 const pt = sema.pt;
18909 const mod = pt.zcu;18892 const zcu = pt.zcu;
18893 const ip = &zcu.intern_pool;
18910 const gpa = sema.gpa;18894 const gpa = sema.gpa;
1891118895
18912 const declaration_ty = t: {18896 const declaration_ty = t: {
18913 const declaration_ty_decl_index = (try sema.namespaceLookup(18897 const nav = try sema.namespaceLookup(
18914 block,18898 block,
18915 src,18899 src,
18916 type_info_ty.getNamespaceIndex(mod),18900 type_info_ty.getNamespaceIndex(zcu),
18917 try mod.intern_pool.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),18901 try ip.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
18918 )).?;18902 ) orelse @panic("std.builtin.Type is corrupt");
18919 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);18903 try sema.ensureNavResolved(src, nav);
18920 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);18904 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18921 break :t declaration_ty_decl.val.toType();
18922 };18905 };
1892318906
18924 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);18907 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
...@@ -18927,7 +18910,7 @@ fn typeInfoDecls(...@@ -18927,7 +18910,7 @@ fn typeInfoDecls(
18927 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);18910 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
18928 defer seen_namespaces.deinit();18911 defer seen_namespaces.deinit();
1892918912
18930 try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);18913 try sema.typeInfoNamespaceDecls(block, src, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
1893118914
18932 const array_decl_ty = try pt.arrayType(.{18915 const array_decl_ty = try pt.arrayType(.{
18933 .len = decl_vals.items.len,18916 .len = decl_vals.items.len,
...@@ -18944,12 +18927,12 @@ fn typeInfoDecls(...@@ -18944,12 +18927,12 @@ fn typeInfoDecls(
18944 .is_const = true,18927 .is_const = true,
18945 },18928 },
18946 })).toIntern();18929 })).toIntern();
18947 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern();18930 const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern();
18948 return try pt.intern(.{ .slice = .{18931 return try pt.intern(.{ .slice = .{
18949 .ty = slice_ty,18932 .ty = slice_ty,
18950 .ptr = try pt.intern(.{ .ptr = .{18933 .ptr = try pt.intern(.{ .ptr = .{
18951 .ty = manyptr_ty,18934 .ty = manyptr_ty,
18952 .base_addr = .{ .anon_decl = .{18935 .base_addr = .{ .uav = .{
18953 .orig_ty = manyptr_ty,18936 .orig_ty = manyptr_ty,
18954 .val = new_decl_val,18937 .val = new_decl_val,
18955 } },18938 } },
...@@ -18962,59 +18945,54 @@ fn typeInfoDecls(...@@ -18962,59 +18945,54 @@ fn typeInfoDecls(
18962fn typeInfoNamespaceDecls(18945fn typeInfoNamespaceDecls(
18963 sema: *Sema,18946 sema: *Sema,
18964 block: *Block,18947 block: *Block,
18948 src: LazySrcLoc,
18965 opt_namespace_index: InternPool.OptionalNamespaceIndex,18949 opt_namespace_index: InternPool.OptionalNamespaceIndex,
18966 declaration_ty: Type,18950 declaration_ty: Type,
18967 decl_vals: *std.ArrayList(InternPool.Index),18951 decl_vals: *std.ArrayList(InternPool.Index),
18968 seen_namespaces: *std.AutoHashMap(*Namespace, void),18952 seen_namespaces: *std.AutoHashMap(*Namespace, void),
18969) !void {18953) !void {
18970 const pt = sema.pt;18954 const pt = sema.pt;
18971 const mod = pt.zcu;18955 const zcu = pt.zcu;
18972 const ip = &mod.intern_pool;18956 const ip = &zcu.intern_pool;
1897318957
18974 const namespace_index = opt_namespace_index.unwrap() orelse return;18958 const namespace_index = opt_namespace_index.unwrap() orelse return;
18975 const namespace = mod.namespacePtr(namespace_index);18959 const namespace = zcu.namespacePtr(namespace_index);
1897618960
18977 const gop = try seen_namespaces.getOrPut(namespace);18961 const gop = try seen_namespaces.getOrPut(namespace);
18978 if (gop.found_existing) return;18962 if (gop.found_existing) return;
1897918963
18980 const decls = namespace.decls.keys();18964 for (namespace.pub_decls.keys()) |nav| {
18981 for (decls) |decl_index| {18965 const name = ip.getNav(nav).name;
18982 const decl = mod.declPtr(decl_index);18966 const name_val = name_val: {
18983 if (!decl.is_pub) continue;18967 const name_len = name.length(ip);
18984 if (decl.kind == .@"usingnamespace") {18968 const array_ty = try pt.arrayType(.{
18985 if (decl.analysis == .in_progress) continue;18969 .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,18970 .sentinel = .zero_u8,
18996 .child = .u8_type,18971 .child = .u8_type,
18997 });18972 });
18998 const new_decl_val = try pt.intern(.{ .aggregate = .{18973 const array_val = try pt.intern(.{ .aggregate = .{
18999 .ty = new_decl_ty.toIntern(),18974 .ty = array_ty.toIntern(),
19000 .storage = .{ .bytes = decl.name.toString() },18975 .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 } });18976 } });
18977 break :name_val try pt.intern(.{
18978 .slice = .{
18979 .ty = .slice_const_u8_sentinel_0_type, // [:0]const u8
18980 .ptr = try pt.intern(.{
18981 .ptr = .{
18982 .ty = .manyptr_const_u8_sentinel_0_type, // [*:0]const u8
18983 .base_addr = .{ .uav = .{
18984 .orig_ty = .slice_const_u8_sentinel_0_type,
18985 .val = array_val,
18986 } },
18987 .byte_offset = 0,
18988 },
18989 }),
18990 .len = (try pt.intValue(Type.usize, name_len)).toIntern(),
18991 },
18992 });
19014 };18993 };
1901518994 const fields = [_]InternPool.Index{
19016 const fields = .{18995 // name: [:0]const u8,
19017 //name: [:0]const u8,
19018 name_val,18996 name_val,
19019 };18997 };
19020 try decl_vals.append(try pt.intern(.{ .aggregate = .{18998 try decl_vals.append(try pt.intern(.{ .aggregate = .{
...@@ -19022,6 +19000,17 @@ fn typeInfoNamespaceDecls(...@@ -19022,6 +19000,17 @@ fn typeInfoNamespaceDecls(
19022 .storage = .{ .elems = &fields },19000 .storage = .{ .elems = &fields },
19023 } }));19001 } }));
19024 }19002 }
19003
19004 for (namespace.pub_usingnamespace.items) |nav| {
19005 if (ip.getNav(nav).analysis_owner.unwrap()) |cau| {
19006 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .cau = cau }))) {
19007 continue;
19008 }
19009 }
19010 try sema.ensureNavResolved(src, nav);
19011 const namespace_ty = Type.fromInterned(ip.getNav(nav).status.resolved.val);
19012 try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu), declaration_ty, decl_vals, seen_namespaces);
19013 }
19025}19014}
1902619015
19027fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19016fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -19906,7 +19895,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -19906,7 +19895,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
19906 return;19895 return;
19907 }19896 }
1990819897
19909 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) return;19898 if (!mod.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return;
19910 if (!start_block.ownerModule().error_tracing) return;19899 if (!start_block.ownerModule().error_tracing) return;
1991119900
19912 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere19901 assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere
...@@ -19928,7 +19917,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {...@@ -19928,7 +19917,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
19928 },19917 },
19929 else => if (ip.isInferredErrorSetType(err_set_ty)) {19918 else => if (ip.isInferredErrorSetType(err_set_ty)) {
19930 const ies = sema.fn_ret_ty_ies.?;19919 const ies = sema.fn_ret_ty_ies.?;
19931 assert(ies.func == sema.func_index);19920 assert(ies.func == sema.owner.unwrap().func);
19932 try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand));19921 try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand));
19933 },19922 },
19934 }19923 }
...@@ -20232,7 +20221,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is...@@ -20232,7 +20221,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
2023220221
20233 if (is_byref) {20222 if (is_byref) {
20234 const init_val = (try sema.resolveValue(init_ref)).?;20223 const init_val = (try sema.resolveValue(init_ref)).?;
20235 return anonDeclRef(sema, init_val.toIntern());20224 return sema.uavRef(init_val.toIntern());
20236 } else {20225 } else {
20237 return init_ref;20226 return init_ref;
20238 }20227 }
...@@ -21056,7 +21045,7 @@ fn arrayInitAnon(...@@ -21056,7 +21045,7 @@ fn arrayInitAnon(
21056}21045}
2105721046
21058fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {21047fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
21059 return if (is_ref) anonDeclRef(sema, val) else Air.internedToRef(val);21048 return if (is_ref) sema.uavRef(val) else Air.internedToRef(val);
21060}21049}
2106121050
21062fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21051fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -21163,16 +21152,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21163,16 +21152,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21163 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);21152 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());21153 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2116521154
21166 if (sema.owner_func_index != .none and21155 switch (sema.owner.unwrap()) {
21167 ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and21156 .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) {
21168 block.ownerModule().error_tracing)21157 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
21169 {21158 },
21170 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);21159 .cau => {},
21171 }21160 }
21172 return Air.internedToRef((try pt.intern(.{ .opt = .{21161 return Air.internedToRef(try pt.intern(.{ .opt = .{
21173 .ty = opt_ptr_stack_trace_ty.toIntern(),21162 .ty = opt_ptr_stack_trace_ty.toIntern(),
21174 .val = .none,21163 .val = .none,
21175 } })));21164 } }));
21176}21165}
2117721166
21178fn zirFrame(21167fn zirFrame(
...@@ -21369,24 +21358,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21369,24 +21358,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21369 const operand = try sema.resolveInst(inst_data.operand);21358 const operand = try sema.resolveInst(inst_data.operand);
21370 const operand_ty = sema.typeOf(operand);21359 const operand_ty = sema.typeOf(operand);
21371 const pt = sema.pt;21360 const pt = sema.pt;
21372 const mod = pt.zcu;21361 const zcu = pt.zcu;
21373 const ip = &mod.intern_pool;21362 const ip = &zcu.intern_pool;
2137421363
21375 try operand_ty.resolveLayout(pt);21364 try operand_ty.resolveLayout(pt);
21376 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {21365 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
21377 .EnumLiteral => {21366 .EnumLiteral => {
21378 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);21367 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
21379 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;21368 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
21380 return sema.addNullTerminatedStrLit(tag_name);21369 return sema.addNullTerminatedStrLit(tag_name);
21381 },21370 },
21382 .Enum => operand_ty,21371 .Enum => operand_ty,
21383 .Union => operand_ty.unionTagType(mod) orelse21372 .Union => operand_ty.unionTagType(zcu) orelse
21384 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}),21373 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 '{}'", .{21374 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
21386 operand_ty.fmt(pt),21375 operand_ty.fmt(pt),
21387 }),21376 }),
21388 };21377 };
21389 if (enum_ty.enumFieldCount(mod) == 0) {21378 if (enum_ty.enumFieldCount(zcu) == 0) {
21390 // TODO I don't think this is the correct way to handle this but21379 // TODO I don't think this is the correct way to handle this but
21391 // it prevents a crash.21380 // it prevents a crash.
21392 // https://github.com/ziglang/zig/issues/1590921381 // https://github.com/ziglang/zig/issues/15909
...@@ -21394,26 +21383,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21394,26 +21383,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21394 enum_ty.fmt(pt),21383 enum_ty.fmt(pt),
21395 });21384 });
21396 }21385 }
21397 const enum_decl_index = enum_ty.getOwnerDecl(mod);
21398 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);21386 const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
21399 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {21387 if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
21400 const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {21388 const field_index = enum_ty.enumTagFieldIndex(val, zcu) orelse {
21401 const msg = msg: {21389 const msg = msg: {
21402 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{21390 const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{
21403 val.fmtValueSema(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip),21391 val.fmtValueSema(pt, sema), enum_ty.fmt(pt),
21404 });21392 });
21405 errdefer msg.destroy(sema.gpa);21393 errdefer msg.destroy(sema.gpa);
21406 try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});21394 try sema.errNote(enum_ty.srcLoc(zcu), msg, "declared here", .{});
21407 break :msg msg;21395 break :msg msg;
21408 };21396 };
21409 return sema.failWithOwnedErrorMsg(block, msg);21397 return sema.failWithOwnedErrorMsg(block, msg);
21410 };21398 };
21411 // TODO: write something like getCoercedInts to avoid needing to dupe21399 // TODO: write something like getCoercedInts to avoid needing to dupe
21412 const field_name = enum_ty.enumFieldName(field_index, mod);21400 const field_name = enum_ty.enumFieldName(field_index, zcu);
21413 return sema.addNullTerminatedStrLit(field_name);21401 return sema.addNullTerminatedStrLit(field_name);
21414 }21402 }
21415 try sema.requireRuntimeBlock(block, src, operand_src);21403 try sema.requireRuntimeBlock(block, src, operand_src);
21416 if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) {21404 if (block.wantSafety() and zcu.backendSupportsFeature(.is_named_enum_value)) {
21417 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);21405 const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
21418 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);21406 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
21419 }21407 }
...@@ -21820,19 +21808,15 @@ fn zirReify(...@@ -21820,19 +21808,15 @@ fn zirReify(
21820 };21808 };
21821 errdefer wip_ty.cancel(ip, pt.tid);21809 errdefer wip_ty.cancel(ip, pt.tid);
2182221810
21823 const new_decl_index = try sema.createAnonymousDeclTypeNamed(21811 wip_ty.setName(ip, try sema.createTypeName(
21824 block,21812 block,
21825 Value.fromInterned(wip_ty.index),
21826 name_strategy,21813 name_strategy,
21827 "opaque",21814 "opaque",
21828 inst,21815 inst,
21829 );21816 wip_ty.index,
21830 mod.declPtr(new_decl_index).owns_tv = true;21817 ));
21831 errdefer pt.abortAnonDecl(new_decl_index);
21832
21833 try pt.finalizeAnonDecl(new_decl_index);
2183421818
21835 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));21819 return Air.internedToRef(wip_ty.finish(ip, .none, .none));
21836 },21820 },
21837 .Union => {21821 .Union => {
21838 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));21822 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
...@@ -22001,13 +21985,15 @@ fn reifyEnum(...@@ -22001,13 +21985,15 @@ fn reifyEnum(
22001 });21985 });
22002 }21986 }
2200321987
21988 const tracked_inst = try block.trackZir(inst);
21989
22004 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{21990 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
22005 .has_namespace = false,21991 .has_namespace = false,
22006 .has_values = true,21992 .has_values = true,
22007 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,21993 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
22008 .fields_len = fields_len,21994 .fields_len = fields_len,
22009 .key = .{ .reified = .{21995 .key = .{ .reified = .{
22010 .zir_index = try block.trackZir(inst),21996 .zir_index = tracked_inst,
22011 .type_hash = hasher.final(),21997 .type_hash = hasher.final(),
22012 } },21998 } },
22013 })) {21999 })) {
...@@ -22020,17 +22006,17 @@ fn reifyEnum(...@@ -22020,17 +22006,17 @@ fn reifyEnum(
22020 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});22006 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
22021 }22007 }
2202222008
22023 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22009 wip_ty.setName(ip, try sema.createTypeName(
22024 block,22010 block,
22025 Value.fromInterned(wip_ty.index),
22026 name_strategy,22011 name_strategy,
22027 "enum",22012 "enum",
22028 inst,22013 inst,
22029 );22014 wip_ty.index,
22030 mod.declPtr(new_decl_index).owns_tv = true;22015 ));
22031 errdefer pt.abortAnonDecl(new_decl_index);22016
22017 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, block.namespace, wip_ty.index);
2203222018
22033 wip_ty.prepare(ip, new_decl_index, .none);22019 wip_ty.prepare(ip, new_cau_index, .none);
22034 wip_ty.setTagTy(ip, tag_ty.toIntern());22020 wip_ty.setTagTy(ip, tag_ty.toIntern());
2203522021
22036 for (0..fields_len) |field_idx| {22022 for (0..fields_len) |field_idx| {
...@@ -22076,7 +22062,6 @@ fn reifyEnum(...@@ -22076,7 +22062,6 @@ fn reifyEnum(
22076 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});22062 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
22077 }22063 }
2207822064
22079 try pt.finalizeAnonDecl(new_decl_index);
22080 return Air.internedToRef(wip_ty.index);22065 return Air.internedToRef(wip_ty.index);
22081}22066}
2208222067
...@@ -22134,6 +22119,8 @@ fn reifyUnion(...@@ -22134,6 +22119,8 @@ fn reifyUnion(
22134 }22119 }
22135 }22120 }
2213622121
22122 const tracked_inst = try block.trackZir(inst);
22123
22137 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{22124 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
22138 .flags = .{22125 .flags = .{
22139 .layout = layout,22126 .layout = layout,
...@@ -22158,7 +22145,7 @@ fn reifyUnion(...@@ -22158,7 +22145,7 @@ fn reifyUnion(
22158 .field_types = &.{}, // set later22145 .field_types = &.{}, // set later
22159 .field_aligns = &.{}, // set later22146 .field_aligns = &.{}, // set later
22160 .key = .{ .reified = .{22147 .key = .{ .reified = .{
22161 .zir_index = try block.trackZir(inst),22148 .zir_index = tracked_inst,
22162 .type_hash = hasher.final(),22149 .type_hash = hasher.final(),
22163 } },22150 } },
22164 })) {22151 })) {
...@@ -22167,15 +22154,14 @@ fn reifyUnion(...@@ -22167,15 +22154,14 @@ fn reifyUnion(
22167 };22154 };
22168 errdefer wip_ty.cancel(ip, pt.tid);22155 errdefer wip_ty.cancel(ip, pt.tid);
2216922156
22170 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22157 const type_name = try sema.createTypeName(
22171 block,22158 block,
22172 Value.fromInterned(wip_ty.index),
22173 name_strategy,22159 name_strategy,
22174 "union",22160 "union",
22175 inst,22161 inst,
22162 wip_ty.index,
22176 );22163 );
22177 mod.declPtr(new_decl_index).owns_tv = true;22164 wip_ty.setName(ip, type_name);
22178 errdefer pt.abortAnonDecl(new_decl_index);
2217922165
22180 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);22166 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;22167 const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined;
...@@ -22268,7 +22254,7 @@ fn reifyUnion(...@@ -22268,7 +22254,7 @@ fn reifyUnion(
22268 }22254 }
22269 }22255 }
2227022256
22271 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));22257 const enum_tag_ty = try sema.generateUnionTagTypeSimple(field_names.keys(), wip_ty.index, type_name);
22272 break :tag_ty .{ enum_tag_ty, false };22258 break :tag_ty .{ enum_tag_ty, false };
22273 };22259 };
22274 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error22260 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
...@@ -22315,10 +22301,11 @@ fn reifyUnion(...@@ -22315,10 +22301,11 @@ fn reifyUnion(
22315 loaded_union.setTagType(ip, enum_tag_ty);22301 loaded_union.setTagType(ip, enum_tag_ty);
22316 loaded_union.setStatus(ip, .have_field_types);22302 loaded_union.setStatus(ip, .have_field_types);
2231722303
22318 try pt.finalizeAnonDecl(new_decl_index);22304 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, block.namespace, wip_ty.index);
22305
22319 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });22306 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22320 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22307 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22321 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22308 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), .none));
22322}22309}
2232322310
22324fn reifyStruct(22311fn reifyStruct(
...@@ -22399,6 +22386,8 @@ fn reifyStruct(...@@ -22399,6 +22386,8 @@ fn reifyStruct(
22399 }22386 }
22400 }22387 }
2240122388
22389 const tracked_inst = try block.trackZir(inst);
22390
22402 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{22391 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
22403 .layout = layout,22392 .layout = layout,
22404 .fields_len = fields_len,22393 .fields_len = fields_len,
...@@ -22411,7 +22400,7 @@ fn reifyStruct(...@@ -22411,7 +22400,7 @@ fn reifyStruct(
22411 .inits_resolved = true,22400 .inits_resolved = true,
22412 .has_namespace = false,22401 .has_namespace = false,
22413 .key = .{ .reified = .{22402 .key = .{ .reified = .{
22414 .zir_index = try block.trackZir(inst),22403 .zir_index = tracked_inst,
22415 .type_hash = hasher.final(),22404 .type_hash = hasher.final(),
22416 } },22405 } },
22417 })) {22406 })) {
...@@ -22426,15 +22415,13 @@ fn reifyStruct(...@@ -22426,15 +22415,13 @@ fn reifyStruct(
22426 .auto => {},22415 .auto => {},
22427 };22416 };
2242822417
22429 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22418 wip_ty.setName(ip, try sema.createTypeName(
22430 block,22419 block,
22431 Value.fromInterned(wip_ty.index),
22432 name_strategy,22420 name_strategy,
22433 "struct",22421 "struct",
22434 inst,22422 inst,
22435 );22423 wip_ty.index,
22436 mod.declPtr(new_decl_index).owns_tv = true;22424 ));
22437 errdefer pt.abortAnonDecl(new_decl_index);
2243822425
22439 const struct_type = ip.loadStructType(wip_ty.index);22426 const struct_type = ip.loadStructType(wip_ty.index);
2244022427
...@@ -22582,10 +22569,11 @@ fn reifyStruct(...@@ -22582,10 +22569,11 @@ fn reifyStruct(
22582 }22569 }
22583 }22570 }
2258422571
22585 try pt.finalizeAnonDecl(new_decl_index);22572 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, block.namespace, wip_ty.index);
22573
22586 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });22574 try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
22587 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index }));22575 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index }));
22588 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22576 return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), .none));
22589}22577}
2259022578
22591fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {22579fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
...@@ -26028,7 +26016,8 @@ fn zirVarExtended(...@@ -26028,7 +26016,8 @@ fn zirVarExtended(
26028 extended: Zir.Inst.Extended.InstData,26016 extended: Zir.Inst.Extended.InstData,
26029) CompileError!Air.Inst.Ref {26017) CompileError!Air.Inst.Ref {
26030 const pt = sema.pt;26018 const pt = sema.pt;
26031 const mod = pt.zcu;26019 const zcu = pt.zcu;
26020 const ip = &zcu.intern_pool;
26032 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);26021 const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
26033 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });26022 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
26034 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });26023 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
...@@ -26075,16 +26064,62 @@ fn zirVarExtended(...@@ -26075,16 +26064,62 @@ fn zirVarExtended(
2607526064
26076 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);26065 try sema.validateVarType(block, ty_src, var_ty, small.is_extern);
2607726066
26078 return Air.internedToRef((try pt.intern(.{ .variable = .{26067 if (small.is_extern) {
26068 // We need to resolve the alignment and addrspace early.
26069 // Keep in sync with logic in `Zcu.PerThread.semaCau`.
26070 const align_src = block.src(.{ .node_offset_var_decl_align = 0 });
26071 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
26072
26073 const decl_inst, const decl_bodies = decl: {
26074 const decl_inst = sema.getOwnerCauDeclInst().resolve(ip);
26075 const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst);
26076 break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) };
26077 };
26078
26079 const alignment: InternPool.Alignment = a: {
26080 const align_body = decl_bodies.align_body orelse break :a .none;
26081 const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst);
26082 break :a try sema.analyzeAsAlign(block, align_src, align_ref);
26083 };
26084
26085 const @"addrspace": std.builtin.AddressSpace = as: {
26086 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(var_ty.toIntern())) {
26087 .func_type => .function,
26088 else => .variable,
26089 };
26090 const target = zcu.getTarget();
26091 const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) {
26092 .function => target_util.defaultAddressSpace(target, .function),
26093 .variable => target_util.defaultAddressSpace(target, .global_mutable),
26094 .constant => target_util.defaultAddressSpace(target, .global_constant),
26095 else => unreachable,
26096 };
26097 const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst);
26098 break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx);
26099 };
26100
26101 return Air.internedToRef(try pt.getExtern(.{
26102 .name = sema.getOwnerCauNavName(),
26103 .ty = var_ty.toIntern(),
26104 .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),
26105 .is_const = small.is_const,
26106 .is_threadlocal = small.is_threadlocal,
26107 .is_weak_linkage = false,
26108 .alignment = alignment,
26109 .@"addrspace" = @"addrspace",
26110 .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction
26111 .owner_nav = undefined, // ignored by `getExtern`
26112 }));
26113 }
26114 assert(!small.is_const); // non-const non-extern variable is not legal
26115 return Air.internedToRef(try pt.intern(.{ .variable = .{
26079 .ty = var_ty.toIntern(),26116 .ty = var_ty.toIntern(),
26080 .init = init_val,26117 .init = init_val,
26081 .decl = sema.owner_decl_index,26118 .owner_nav = sema.getOwnerCauNav(),
26082 .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls),26119 .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,26120 .is_threadlocal = small.is_threadlocal,
26086 .is_weak_linkage = false,26121 .is_weak_linkage = false,
26087 } })));26122 } }));
26088}26123}
2608926124
26090fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {26125fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -26255,10 +26290,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26255,10 +26290,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26255 else => |e| return e,26290 else => |e| return e,
26256 };26291 };
26257 break :blk mod.toEnum(std.builtin.CallingConvention, cc_val);26292 break :blk mod.toEnum(std.builtin.CallingConvention, cc_val);
26258 } else if (sema.owner_decl.is_exported and has_body)26293 } else cc: {
26259 .C26294 if (has_body) {
26260 else26295 const decl_inst = if (sema.generic_owner != .none) decl_inst: {
26261 .Unspecified;26296 // Generic instance -- use the original function declaration to
26297 // look for the `export` syntax.
26298 const nav = mod.intern_pool.getNav(mod.funcInfo(sema.generic_owner).owner_nav);
26299 const cau = mod.intern_pool.getCau(nav.analysis_owner.unwrap().?);
26300 break :decl_inst cau.zir_index;
26301 } else sema.getOwnerCauDeclInst(); // not an instantiation so we're analyzing a function declaration Cau
26302
26303 const zir_decl = sema.code.getDeclaration(decl_inst.resolve(&mod.intern_pool))[0];
26304 if (zir_decl.flags.is_export) {
26305 break :cc .C;
26306 }
26307 }
26308 break :cc .Unspecified;
26309 };
2626226310
26263 const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: {26311 const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: {
26264 const body_len = sema.code.extra[extra_index];26312 const body_len = sema.code.extra[extra_index];
...@@ -26600,42 +26648,32 @@ fn zirBuiltinExtern(...@@ -26600,42 +26648,32 @@ fn zirBuiltinExtern(
2660026648
26601 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);26649 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
2660226650
26651 // TODO: error for threadlocal functions, non-const functions, etc
26652
26603 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {26653 if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
26604 ty = try pt.optionalType(ty.toIntern());26654 ty = try pt.optionalType(ty.toIntern());
26605 }26655 }
26606 const ptr_info = ty.ptrInfo(mod);26656 const ptr_info = ty.ptrInfo(mod);
2660726657
26608 const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);26658 const extern_val = try pt.getExtern(.{
26609 errdefer pt.destroyDecl(new_decl_index);26659 .name = options.name,
26610 const new_decl = mod.declPtr(new_decl_index);26660 .ty = ptr_info.child,
26611 try pt.initNewAnonDecl(26661 .lib_name = options.library_name,
26612 new_decl_index,26662 .is_const = ptr_info.flags.is_const,
26613 Value.fromInterned(26663 .is_threadlocal = options.is_thread_local,
26614 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)26664 .is_weak_linkage = options.linkage == .weak,
26615 try ip.getExternFunc(sema.gpa, pt.tid, .{26665 .alignment = ptr_info.flags.alignment,
26616 .ty = ptr_info.child,26666 .@"addrspace" = ptr_info.flags.address_space,
26617 .decl = new_decl_index,26667 // This instruction is just for source locations.
26618 .lib_name = options.library_name,26668 // `builtin_extern` doesn't provide enough information, and isn't currently tracked.
26619 })26669 // So, for now, just use our containing `declaration`.
26620 else26670 .zir_index = switch (sema.owner.unwrap()) {
26621 try pt.intern(.{ .variable = .{26671 .cau => sema.getOwnerCauDeclInst(),
26622 .ty = ptr_info.child,26672 .func => sema.getOwnerFuncDeclInst(),
26623 .init = .none,26673 },
26624 .decl = new_decl_index,26674 .owner_nav = undefined, // ignored by `getExtern`
26625 .lib_name = options.library_name,26675 });
26626 .is_extern = true,26676 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);
2663926677
26640 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{26678 return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{
26641 .ty = switch (ip.indexToKey(ty.toIntern())) {26679 .ty = switch (ip.indexToKey(ty.toIntern())) {
...@@ -26643,7 +26681,7 @@ fn zirBuiltinExtern(...@@ -26643,7 +26681,7 @@ fn zirBuiltinExtern(
26643 .opt_type => |child_type| child_type,26681 .opt_type => |child_type| child_type,
26644 else => unreachable,26682 else => unreachable,
26645 },26683 },
26646 .base_addr = .{ .decl = new_decl_index },26684 .base_addr = .{ .nav = extern_nav },
26647 .byte_offset = 0,26685 .byte_offset = 0,
26648 } })), ty)).toIntern());26686 } })), ty)).toIntern());
26649}26687}
...@@ -27129,17 +27167,15 @@ fn explainWhyTypeIsNotPacked(...@@ -27129,17 +27167,15 @@ fn explainWhyTypeIsNotPacked(
27129 }27167 }
27130}27168}
2713127169
27132fn prepareSimplePanic(sema: *Sema) !void {27170fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27133 const pt = sema.pt;27171 const pt = sema.pt;
27134 const mod = pt.zcu;27172 const mod = pt.zcu;
2713527173
27136 if (mod.panic_func_index == .none) {27174 if (mod.panic_func_index == .none) {
27137 const decl_index = (try pt.getBuiltinDecl("panic"));27175 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 actually27176 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{
27139 // owns the function.27177 .needed_comptime_reason = "panic handler must be comptime-known",
27140 try sema.ensureDeclAnalyzed(decl_index);27178 });
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);27179 assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn);
27144 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));27180 assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod)));
27145 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());27181 try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern());
...@@ -27167,16 +27203,16 @@ fn prepareSimplePanic(sema: *Sema) !void {...@@ -27167,16 +27203,16 @@ fn prepareSimplePanic(sema: *Sema) !void {
27167/// Backends depend on panic decls being available when lowering safety-checked27203/// Backends depend on panic decls being available when lowering safety-checked
27168/// instructions. This function ensures the panic function will be available to27204/// instructions. This function ensures the panic function will be available to
27169/// be called during that time.27205/// be called during that time.
27170fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex {27206fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) !InternPool.Nav.Index {
27171 const pt = sema.pt;27207 const pt = sema.pt;
27172 const mod = pt.zcu;27208 const mod = pt.zcu;
27173 const gpa = sema.gpa;27209 const gpa = sema.gpa;
27174 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;27210 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2717527211
27176 try sema.prepareSimplePanic();27212 try sema.prepareSimplePanic(block, src);
2717727213
27178 const panic_messages_ty = try pt.getBuiltinType("panic_messages");27214 const panic_messages_ty = try pt.getBuiltinType("panic_messages");
27179 const msg_decl_index = (sema.namespaceLookup(27215 const msg_nav_index = (sema.namespaceLookup(
27180 block,27216 block,
27181 LazySrcLoc.unneeded,27217 LazySrcLoc.unneeded,
27182 panic_messages_ty.getNamespaceIndex(mod),27218 panic_messages_ty.getNamespaceIndex(mod),
...@@ -27186,9 +27222,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP...@@ -27186,9 +27222,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
27186 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,27222 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27187 error.OutOfMemory => |e| return e,27223 error.OutOfMemory => |e| return e,
27188 }).?;27224 }).?;
27189 try sema.ensureDeclAnalyzed(msg_decl_index);27225 try sema.ensureNavResolved(src, msg_nav_index);
27190 mod.panic_messages[@intFromEnum(panic_id)] = msg_decl_index.toOptional();27226 mod.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional();
27191 return msg_decl_index;27227 return msg_nav_index;
27192}27228}
2719327229
27194fn addSafetyCheck(27230fn addSafetyCheck(
...@@ -27282,10 +27318,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -27282,10 +27318,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
27282 return;27318 return;
27283 }27319 }
2728427320
27285 try sema.prepareSimplePanic();27321 try sema.prepareSimplePanic(block, src);
2728627322
27287 const panic_func = mod.funcInfo(mod.panic_func_index);27323 const panic_func = mod.funcInfo(mod.panic_func_index);
27288 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);27324 const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav);
27289 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);27325 const null_stack_trace = Air.internedToRef(mod.null_stack_trace);
2729027326
27291 const opt_usize_ty = try pt.optionalType(.usize_type);27327 const opt_usize_ty = try pt.optionalType(.usize_type);
...@@ -27455,8 +27491,8 @@ fn safetyCheckFormatted(...@@ -27455,8 +27491,8 @@ fn safetyCheckFormatted(
27455}27491}
2745627492
27457fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void {27493fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void {
27458 const msg_decl_index = try sema.preparePanicId(block, panic_id);27494 const msg_nav_index = try sema.preparePanicId(block, src, panic_id);
27459 const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index);27495 const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index);
27460 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");27496 try sema.panicWithMsg(block, src, msg_inst, .@"safety check");
27461}27497}
2746227498
...@@ -27628,21 +27664,21 @@ fn fieldVal(...@@ -27628,21 +27664,21 @@ fn fieldVal(
27628 return Air.internedToRef(enum_val.toIntern());27664 return Air.internedToRef(enum_val.toIntern());
27629 },27665 },
27630 .Struct, .Opaque => {27666 .Struct, .Opaque => {
27631 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27667 switch (child_type.toIntern()) {
27632 return inst;27668 .empty_struct_type, .anyopaque_type => {}, // no namespace
27669 else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27670 return inst;
27671 },
27633 }27672 }
27634 return sema.failWithBadMemberAccess(block, child_type, src, field_name);27673 return sema.failWithBadMemberAccess(block, child_type, src, field_name);
27635 },27674 },
27636 else => {27675 else => return sema.failWithOwnedErrorMsg(block, msg: {
27637 const msg = msg: {27676 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)});27677 errdefer msg.destroy(sema.gpa);
27639 errdefer msg.destroy(sema.gpa);27678 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", .{});27679 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", .{});27680 break :msg msg;
27642 break :msg msg;27681 }),
27643 };
27644 return sema.failWithOwnedErrorMsg(block, msg);
27645 },
27646 }27682 }
27647 },27683 },
27648 .Struct => if (is_pointer_to) {27684 .Struct => if (is_pointer_to) {
...@@ -27700,7 +27736,7 @@ fn fieldPtr(...@@ -27700,7 +27736,7 @@ fn fieldPtr(
27700 .Array => {27736 .Array => {
27701 if (field_name.eqlSlice("len", ip)) {27737 if (field_name.eqlSlice("len", ip)) {
27702 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));27738 const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod));
27703 return anonDeclRef(sema, int_val.toIntern());27739 return uavRef(sema, int_val.toIntern());
27704 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27740 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27705 const ptr_info = object_ty.ptrInfo(mod);27741 const ptr_info = object_ty.ptrInfo(mod);
27706 const new_ptr_ty = try pt.ptrTypeSema(.{27742 const new_ptr_ty = try pt.ptrTypeSema(.{
...@@ -27839,7 +27875,7 @@ fn fieldPtr(...@@ -27839,7 +27875,7 @@ fn fieldPtr(
27839 child_type27875 child_type
27840 else27876 else
27841 try pt.singleErrorSetType(field_name);27877 try pt.singleErrorSetType(field_name);
27842 return anonDeclRef(sema, try pt.intern(.{ .err = .{27878 return uavRef(sema, try pt.intern(.{ .err = .{
27843 .ty = error_set_type.toIntern(),27879 .ty = error_set_type.toIntern(),
27844 .name = field_name,27880 .name = field_name,
27845 } }));27881 } }));
...@@ -27853,7 +27889,7 @@ fn fieldPtr(...@@ -27853,7 +27889,7 @@ fn fieldPtr(
27853 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {27889 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
27854 const field_index_u32: u32 = @intCast(field_index);27890 const field_index_u32: u32 = @intCast(field_index);
27855 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);27891 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
27856 return anonDeclRef(sema, idx_val.toIntern());27892 return uavRef(sema, idx_val.toIntern());
27857 }27893 }
27858 }27894 }
27859 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);27895 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
...@@ -27867,7 +27903,7 @@ fn fieldPtr(...@@ -27867,7 +27903,7 @@ fn fieldPtr(
27867 };27903 };
27868 const field_index_u32: u32 = @intCast(field_index);27904 const field_index_u32: u32 = @intCast(field_index);
27869 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);27905 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
27870 return anonDeclRef(sema, idx_val.toIntern());27906 return uavRef(sema, idx_val.toIntern());
27871 },27907 },
27872 .Struct, .Opaque => {27908 .Struct, .Opaque => {
27873 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27909 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
...@@ -27923,18 +27959,18 @@ fn fieldCallBind(...@@ -27923,18 +27959,18 @@ fn fieldCallBind(
27923 // in `fieldVal`. This function takes a pointer and returns a pointer.27959 // in `fieldVal`. This function takes a pointer and returns a pointer.
2792427960
27925 const pt = sema.pt;27961 const pt = sema.pt;
27926 const mod = pt.zcu;27962 const zcu = pt.zcu;
27927 const ip = &mod.intern_pool;27963 const ip = &zcu.intern_pool;
27928 const raw_ptr_src = src; // TODO better source location27964 const raw_ptr_src = src; // TODO better source location
27929 const raw_ptr_ty = sema.typeOf(raw_ptr);27965 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))27966 const inner_ty = if (raw_ptr_ty.zigTypeTag(zcu) == .Pointer and (raw_ptr_ty.ptrSize(zcu) == .One or raw_ptr_ty.ptrSize(zcu) == .C))
27931 raw_ptr_ty.childType(mod)27967 raw_ptr_ty.childType(zcu)
27932 else27968 else
27933 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});27969 return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)});
2793427970
27935 // Optionally dereference a second pointer to get the concrete type.27971 // 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;27972 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;27973 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;27974 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
27939 const object_ptr = if (is_double_ptr)27975 const object_ptr = if (is_double_ptr)
27940 try sema.analyzeLoad(block, src, raw_ptr, src)27976 try sema.analyzeLoad(block, src, raw_ptr, src)
...@@ -27942,36 +27978,36 @@ fn fieldCallBind(...@@ -27942,36 +27978,36 @@ fn fieldCallBind(
27942 raw_ptr;27978 raw_ptr;
2794327979
27944 find_field: {27980 find_field: {
27945 switch (concrete_ty.zigTypeTag(mod)) {27981 switch (concrete_ty.zigTypeTag(zcu)) {
27946 .Struct => {27982 .Struct => {
27947 try concrete_ty.resolveFields(pt);27983 try concrete_ty.resolveFields(pt);
27948 if (mod.typeToStruct(concrete_ty)) |struct_type| {27984 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
27949 const field_index = struct_type.nameIndex(ip, field_name) orelse27985 const field_index = struct_type.nameIndex(ip, field_name) orelse
27950 break :find_field;27986 break :find_field;
27951 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);27987 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2795227988
27953 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);27989 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
27954 } else if (concrete_ty.isTuple(mod)) {27990 } else if (concrete_ty.isTuple(zcu)) {
27955 if (field_name.eqlSlice("len", ip)) {27991 if (field_name.eqlSlice("len", ip)) {
27956 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) };27992 return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(zcu)) };
27957 }27993 }
27958 if (field_name.toUnsigned(ip)) |field_index| {27994 if (field_name.toUnsigned(ip)) |field_index| {
27959 if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field;27995 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);27996 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, zcu), field_index, object_ptr);
27961 }27997 }
27962 } else {27998 } else {
27963 const max = concrete_ty.structFieldCount(mod);27999 const max = concrete_ty.structFieldCount(zcu);
27964 for (0..max) |i_usize| {28000 for (0..max) |i_usize| {
27965 const i: u32 = @intCast(i_usize);28001 const i: u32 = @intCast(i_usize);
27966 if (field_name == concrete_ty.structFieldName(i, mod).unwrap().?) {28002 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);28003 return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, zcu), i, object_ptr);
27968 }28004 }
27969 }28005 }
27970 }28006 }
27971 },28007 },
27972 .Union => {28008 .Union => {
27973 try concrete_ty.resolveFields(pt);28009 try concrete_ty.resolveFields(pt);
27974 const union_obj = mod.typeToUnion(concrete_ty).?;28010 const union_obj = zcu.typeToUnion(concrete_ty).?;
27975 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;28011 _ = 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);28012 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) };28013 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };
...@@ -27985,23 +28021,23 @@ fn fieldCallBind(...@@ -27985,23 +28021,23 @@ fn fieldCallBind(
27985 }28021 }
2798628022
27987 // If we get here, we need to look for a decl in the struct type instead.28023 // If we get here, we need to look for a decl in the struct type instead.
27988 const found_decl = found_decl: {28024 const found_nav = found_nav: {
27989 const namespace = concrete_ty.getNamespace(mod) orelse28025 const namespace = concrete_ty.getNamespace(zcu) orelse
27990 break :found_decl null;28026 break :found_nav null;
27991 const decl_idx = (try sema.namespaceLookup(block, src, namespace, field_name)) orelse28027 const nav_index = try sema.namespaceLookup(block, src, namespace, field_name) orelse
27992 break :found_decl null;28028 break :found_nav null;
2799328029
27994 const decl_val = try sema.analyzeDeclVal(block, src, decl_idx);28030 const decl_val = try sema.analyzeNavVal(block, src, nav_index);
27995 const decl_type = sema.typeOf(decl_val);28031 const decl_type = sema.typeOf(decl_val);
27996 if (mod.typeToFunc(decl_type)) |func_type| f: {28032 if (zcu.typeToFunc(decl_type)) |func_type| f: {
27997 if (func_type.param_types.len == 0) break :f;28033 if (func_type.param_types.len == 0) break :f;
2799828034
27999 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);28035 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);
28000 if (first_param_type.isGenericPoison() or28036 if (first_param_type.isGenericPoison() or
28001 (first_param_type.zigTypeTag(mod) == .Pointer and28037 (first_param_type.zigTypeTag(zcu) == .Pointer and
28002 (first_param_type.ptrSize(mod) == .One or28038 (first_param_type.ptrSize(zcu) == .One or
28003 first_param_type.ptrSize(mod) == .C) and28039 first_param_type.ptrSize(zcu) == .C) and
28004 first_param_type.childType(mod).eql(concrete_ty, mod)))28040 first_param_type.childType(zcu).eql(concrete_ty, zcu)))
28005 {28041 {
28006 // Note that if the param type is generic poison, we know that it must28042 // 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 we28043 // specifically be `anytype` since it's the first parameter, meaning we
...@@ -28012,31 +28048,31 @@ fn fieldCallBind(...@@ -28012,31 +28048,31 @@ fn fieldCallBind(
28012 .func_inst = decl_val,28048 .func_inst = decl_val,
28013 .arg0_inst = object_ptr,28049 .arg0_inst = object_ptr,
28014 } };28050 } };
28015 } else if (first_param_type.eql(concrete_ty, mod)) {28051 } else if (first_param_type.eql(concrete_ty, zcu)) {
28016 const deref = try sema.analyzeLoad(block, src, object_ptr, src);28052 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
28017 return .{ .method = .{28053 return .{ .method = .{
28018 .func_inst = decl_val,28054 .func_inst = decl_val,
28019 .arg0_inst = deref,28055 .arg0_inst = deref,
28020 } };28056 } };
28021 } else if (first_param_type.zigTypeTag(mod) == .Optional) {28057 } else if (first_param_type.zigTypeTag(zcu) == .Optional) {
28022 const child = first_param_type.optionalChild(mod);28058 const child = first_param_type.optionalChild(zcu);
28023 if (child.eql(concrete_ty, mod)) {28059 if (child.eql(concrete_ty, zcu)) {
28024 const deref = try sema.analyzeLoad(block, src, object_ptr, src);28060 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
28025 return .{ .method = .{28061 return .{ .method = .{
28026 .func_inst = decl_val,28062 .func_inst = decl_val,
28027 .arg0_inst = deref,28063 .arg0_inst = deref,
28028 } };28064 } };
28029 } else if (child.zigTypeTag(mod) == .Pointer and28065 } else if (child.zigTypeTag(zcu) == .Pointer and
28030 child.ptrSize(mod) == .One and28066 child.ptrSize(zcu) == .One and
28031 child.childType(mod).eql(concrete_ty, mod))28067 child.childType(zcu).eql(concrete_ty, zcu))
28032 {28068 {
28033 return .{ .method = .{28069 return .{ .method = .{
28034 .func_inst = decl_val,28070 .func_inst = decl_val,
28035 .arg0_inst = object_ptr,28071 .arg0_inst = object_ptr,
28036 } };28072 } };
28037 }28073 }
28038 } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and28074 } else if (first_param_type.zigTypeTag(zcu) == .ErrorUnion and
28039 first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod))28075 first_param_type.errorUnionPayload(zcu).eql(concrete_ty, zcu))
28040 {28076 {
28041 const deref = try sema.analyzeLoad(block, src, object_ptr, src);28077 const deref = try sema.analyzeLoad(block, src, object_ptr, src);
28042 return .{ .method = .{28078 return .{ .method = .{
...@@ -28045,7 +28081,7 @@ fn fieldCallBind(...@@ -28045,7 +28081,7 @@ fn fieldCallBind(
28045 } };28081 } };
28046 }28082 }
28047 }28083 }
28048 break :found_decl decl_idx;28084 break :found_nav nav_index;
28049 };28085 };
2805028086
28051 const msg = msg: {28087 const msg = msg: {
...@@ -28055,14 +28091,15 @@ fn fieldCallBind(...@@ -28055,14 +28091,15 @@ fn fieldCallBind(
28055 });28091 });
28056 errdefer msg.destroy(sema.gpa);28092 errdefer msg.destroy(sema.gpa);
28057 try sema.addDeclaredHereNote(msg, concrete_ty);28093 try sema.addDeclaredHereNote(msg, concrete_ty);
28058 if (found_decl) |decl_idx| {28094 if (found_nav) |nav_index| {
28059 const decl = mod.declPtr(decl_idx);28095 try sema.errNote(
28060 try sema.errNote(.{28096 zcu.navSrcLoc(nav_index),
28061 .base_node_inst = decl.zir_decl_index.unwrap().?,28097 msg,
28062 .offset = LazySrcLoc.Offset.nodeOffset(0),28098 "'{}' is not a member function",
28063 }, msg, "'{}' is not a member function", .{field_name.fmt(ip)});28099 .{field_name.fmt(ip)},
28100 );
28064 }28101 }
28065 if (concrete_ty.zigTypeTag(mod) == .ErrorUnion) {28102 if (concrete_ty.zigTypeTag(zcu) == .ErrorUnion) {
28066 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});28103 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
28067 }28104 }
28068 if (is_double_ptr) {28105 if (is_double_ptr) {
...@@ -28119,27 +28156,22 @@ fn namespaceLookup(...@@ -28119,27 +28156,22 @@ fn namespaceLookup(
28119 src: LazySrcLoc,28156 src: LazySrcLoc,
28120 opt_namespace: InternPool.OptionalNamespaceIndex,28157 opt_namespace: InternPool.OptionalNamespaceIndex,
28121 decl_name: InternPool.NullTerminatedString,28158 decl_name: InternPool.NullTerminatedString,
28122) CompileError!?InternPool.DeclIndex {28159) CompileError!?InternPool.Nav.Index {
28123 const pt = sema.pt;28160 const pt = sema.pt;
28124 const mod = pt.zcu;28161 const zcu = pt.zcu;
28125 const gpa = sema.gpa;28162 const gpa = sema.gpa;
28126 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| {28163 if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |lookup| {
28127 const decl = mod.declPtr(decl_index);28164 if (!lookup.accessible) {
28128 if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {28165 return sema.failWithOwnedErrorMsg(block, msg: {
28129 const msg = msg: {
28130 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{28166 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
28131 decl_name.fmt(&mod.intern_pool),28167 decl_name.fmt(&zcu.intern_pool),
28132 });28168 });
28133 errdefer msg.destroy(gpa);28169 errdefer msg.destroy(gpa);
28134 try sema.errNote(.{28170 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;28171 break :msg msg;
28139 };28172 });
28140 return sema.failWithOwnedErrorMsg(block, msg);
28141 }28173 }
28142 return decl_index;28174 return lookup.nav;
28143 }28175 }
28144 return null;28176 return null;
28145}28177}
...@@ -28151,8 +28183,8 @@ fn namespaceLookupRef(...@@ -28151,8 +28183,8 @@ fn namespaceLookupRef(
28151 opt_namespace: InternPool.OptionalNamespaceIndex,28183 opt_namespace: InternPool.OptionalNamespaceIndex,
28152 decl_name: InternPool.NullTerminatedString,28184 decl_name: InternPool.NullTerminatedString,
28153) CompileError!?Air.Inst.Ref {28185) CompileError!?Air.Inst.Ref {
28154 const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null;28186 const nav = try sema.namespaceLookup(block, src, opt_namespace, decl_name) orelse return null;
28155 return try sema.analyzeDeclRef(src, decl);28187 return try sema.analyzeNavRef(src, nav);
28156}28188}
2815728189
28158fn namespaceLookupVal(28190fn namespaceLookupVal(
...@@ -28162,8 +28194,8 @@ fn namespaceLookupVal(...@@ -28162,8 +28194,8 @@ fn namespaceLookupVal(
28162 opt_namespace: InternPool.OptionalNamespaceIndex,28194 opt_namespace: InternPool.OptionalNamespaceIndex,
28163 decl_name: InternPool.NullTerminatedString,28195 decl_name: InternPool.NullTerminatedString,
28164) CompileError!?Air.Inst.Ref {28196) CompileError!?Air.Inst.Ref {
28165 const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null;28197 const nav = try sema.namespaceLookup(block, src, opt_namespace, decl_name) orelse return null;
28166 return try sema.analyzeDeclVal(block, src, decl);28198 return try sema.analyzeNavVal(block, src, nav);
28167}28199}
2816828200
28169fn structFieldPtr(28201fn structFieldPtr(
...@@ -29200,9 +29232,9 @@ const CoerceOpts = struct {...@@ -29200,9 +29232,9 @@ const CoerceOpts = struct {
2920029232
29201 fn get(info: @This(), sema: *Sema) !?LazySrcLoc {29233 fn get(info: @This(), sema: *Sema) !?LazySrcLoc {
29202 if (info.func_inst == .none) return null;29234 if (info.func_inst == .none) return null;
29203 const fn_decl = try sema.funcDeclSrc(info.func_inst) orelse return null;29235 const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null;
29204 return .{29236 return .{
29205 .base_node_inst = fn_decl.zir_decl_index.unwrap().?,29237 .base_node_inst = func_inst,
29206 .offset = .{ .fn_proto_param_type = .{29238 .offset = .{ .fn_proto_param_type = .{
29207 .fn_proto_node_offset = 0,29239 .fn_proto_node_offset = 0,
29208 .param_index = info.param_i,29240 .param_index = info.param_i,
...@@ -29303,8 +29335,12 @@ fn coerceExtra(...@@ -29303,8 +29335,12 @@ fn coerceExtra(
29303 // Function body to function pointer.29335 // Function body to function pointer.
29304 if (inst_ty.zigTypeTag(zcu) == .Fn) {29336 if (inst_ty.zigTypeTag(zcu) == .Fn) {
29305 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);29337 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
29306 const fn_decl = fn_val.pointerDecl(zcu).?;29338 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
29307 const inst_as_ptr = try sema.analyzeDeclRef(inst_src, fn_decl);29339 .func => |f| f.owner_nav,
29340 .@"extern" => |e| e.owner_nav,
29341 else => unreachable,
29342 };
29343 const inst_as_ptr = try sema.analyzeNavRef(inst_src, fn_nav);
29308 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);29344 return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
29309 }29345 }
2931029346
...@@ -29846,7 +29882,7 @@ fn coerceExtra(...@@ -29846,7 +29882,7 @@ fn coerceExtra(
29846 errdefer msg.destroy(sema.gpa);29882 errdefer msg.destroy(sema.gpa);
2984729883
29848 const ret_ty_src: LazySrcLoc = .{29884 const ret_ty_src: LazySrcLoc = .{
29849 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,29885 .base_node_inst = sema.getOwnerFuncDeclInst(),
29850 .offset = .{ .node_offset_fn_type_ret_ty = 0 },29886 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
29851 };29887 };
29852 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});29888 try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
...@@ -29879,10 +29915,10 @@ fn coerceExtra(...@@ -29879,10 +29915,10 @@ fn coerceExtra(
2987929915
29880 // Add notes about function return type29916 // Add notes about function return type
29881 if (opts.is_ret and29917 if (opts.is_ret and
29882 zcu.test_functions.get(zcu.funcOwnerDeclIndex(sema.func_index)) == null)29918 !zcu.test_functions.contains(zcu.funcInfo(sema.owner.unwrap().func).owner_nav))
29883 {29919 {
29884 const ret_ty_src: LazySrcLoc = .{29920 const ret_ty_src: LazySrcLoc = .{
29885 .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,29921 .base_node_inst = sema.getOwnerFuncDeclInst(),
29886 .offset = .{ .node_offset_fn_type_ret_ty = 0 },29922 .offset = .{ .node_offset_fn_type_ret_ty = 0 },
29887 };29923 };
29888 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {29924 if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
...@@ -30885,9 +30921,9 @@ fn coerceVarArgParam(...@@ -30885,9 +30921,9 @@ fn coerceVarArgParam(
30885 if (block.is_typeof) return inst;30921 if (block.is_typeof) return inst;
3088630922
30887 const pt = sema.pt;30923 const pt = sema.pt;
30888 const mod = pt.zcu;30924 const zcu = pt.zcu;
30889 const uncasted_ty = sema.typeOf(inst);30925 const uncasted_ty = sema.typeOf(inst);
30890 const coerced = switch (uncasted_ty.zigTypeTag(mod)) {30926 const coerced = switch (uncasted_ty.zigTypeTag(zcu)) {
30891 // TODO consider casting to c_int/f64 if they fit30927 // TODO consider casting to c_int/f64 if they fit
30892 .ComptimeInt, .ComptimeFloat => return sema.fail(30928 .ComptimeInt, .ComptimeFloat => return sema.fail(
30893 block,30929 block,
...@@ -30897,12 +30933,12 @@ fn coerceVarArgParam(...@@ -30897,12 +30933,12 @@ fn coerceVarArgParam(
30897 ),30933 ),
30898 .Fn => fn_ptr: {30934 .Fn => fn_ptr: {
30899 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);30935 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
30900 const fn_decl = fn_val.pointerDecl(mod).?;30936 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
30901 break :fn_ptr try sema.analyzeDeclRef(inst_src, fn_decl);30937 break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav);
30902 },30938 },
30903 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),30939 .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}),
30904 .Float => float: {30940 .Float => float: {
30905 const target = mod.getTarget();30941 const target = zcu.getTarget();
30906 const double_bits = target.c_type_bit_size(.double);30942 const double_bits = target.c_type_bit_size(.double);
30907 const inst_bits = uncasted_ty.floatBits(target);30943 const inst_bits = uncasted_ty.floatBits(target);
30908 if (inst_bits >= double_bits) break :float inst;30944 if (inst_bits >= double_bits) break :float inst;
...@@ -30912,10 +30948,10 @@ fn coerceVarArgParam(...@@ -30912,10 +30948,10 @@ fn coerceVarArgParam(
30912 else => unreachable,30948 else => unreachable,
30913 }30949 }
30914 },30950 },
30915 else => if (uncasted_ty.isAbiInt(mod)) int: {30951 else => if (uncasted_ty.isAbiInt(zcu)) int: {
30916 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;30952 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
30917 const target = mod.getTarget();30953 const target = zcu.getTarget();
30918 const uncasted_info = uncasted_ty.intInfo(mod);30954 const uncasted_info = uncasted_ty.intInfo(zcu);
30919 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {30955 if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) {
30920 .signed => .int,30956 .signed => .int,
30921 .unsigned => .uint,30957 .unsigned => .uint,
...@@ -32117,23 +32153,14 @@ fn coerceTupleToTuple(...@@ -32117,23 +32153,14 @@ fn coerceTupleToTuple(
32117 } })));32153 } })));
32118}32154}
3211932155
32120fn analyzeDeclVal(32156fn analyzeNavVal(
32121 sema: *Sema,32157 sema: *Sema,
32122 block: *Block,32158 block: *Block,
32123 src: LazySrcLoc,32159 src: LazySrcLoc,
32124 decl_index: InternPool.DeclIndex,32160 nav_index: InternPool.Nav.Index,
32125) CompileError!Air.Inst.Ref {32161) CompileError!Air.Inst.Ref {
32126 if (sema.decl_val_table.get(decl_index)) |result| {32162 const ref = try sema.analyzeNavRefInner(src, nav_index, false);
32127 return result;32163 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}32164}
3213832165
32139fn addReferenceEntry(32166fn addReferenceEntry(
...@@ -32148,44 +32175,37 @@ fn addReferenceEntry(...@@ -32148,44 +32175,37 @@ fn addReferenceEntry(
32148 // TODO: we need to figure out how to model inline calls here.32175 // 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!32176 // 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?32177 // Would representing inline calls in the reference table cause excessive memory usage?
32151 try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src);32178 try zcu.addUnitReference(sema.owner, referenced_unit, src);
32152}32179}
3215332180
32154pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void {32181pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!void {
32155 const pt = sema.pt;32182 const pt = sema.pt;
32156 const mod = pt.zcu;32183 const zcu = pt.zcu;
32157 const ip = &mod.intern_pool;32184 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 }
3216632185
32167 pt.ensureDeclAnalyzed(decl_index) catch |err| {32186 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}
3217632187
32177fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void {32188 const cau_index = nav.analysis_owner.unwrap() orelse {
32178 const pt = sema.pt;32189 assert(nav.status == .resolved);
32179 const mod = pt.zcu;32190 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 };32191 };
32192
32193 // Note that even if `nav.status == .resolved`, we must still trigger `ensureCauAnalyzed`
32194 // to make sure the value is up-to-date on incremental updates.
32195
32196 assert(ip.getCau(cau_index).owner.unwrap().nav == nav_index);
32197
32198 const anal_unit = AnalUnit.wrap(.{ .cau = cau_index });
32199 try sema.addReferenceEntry(src, anal_unit);
32200
32201 if (zcu.analysis_in_progress.contains(anal_unit)) {
32202 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{
32203 .base_node_inst = ip.getCau(cau_index).zir_index,
32204 .offset = LazySrcLoc.Offset.nodeOffset(0),
32205 }, "dependency loop detected", .{}));
32206 }
32207
32208 return pt.ensureCauAnalyzed(cau_index);
32189}32209}
3219032210
32191fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {32211fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
...@@ -32200,55 +32220,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {...@@ -32200,55 +32220,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
32200 } }));32220 } }));
32201}32221}
3220232222
32203fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref {32223fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref {
32204 return sema.analyzeDeclRefInner(src, decl_index, true);32224 return sema.analyzeNavRefInner(src, nav_index, true);
32205}32225}
3220632226
32207/// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but32227/// 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 a32228/// 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` wraps32229/// 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.32230/// this function with `analyze_fn_body` set to true.
32211fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref {32231fn analyzeNavRefInner(sema: *Sema, src: LazySrcLoc, orig_nav_index: InternPool.Nav.Index, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
32212 const pt = sema.pt;32232 const pt = sema.pt;
32213 const mod = pt.zcu;32233 const zcu = pt.zcu;
32214 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index }));32234 const ip = &zcu.intern_pool;
32215 try sema.ensureDeclAnalyzed(decl_index);
3221632235
32217 const decl_val = try mod.declPtr(decl_index).valueOrFail();32236 // 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())) {32237 try sema.declareDependency(.{ .nav_val = orig_nav_index });
32219 .variable => |variable| variable.decl,32238 try sema.ensureNavResolved(src, orig_nav_index);
32220 .extern_func => |extern_func| extern_func.decl,32239
32221 .func => |func| func.owner_decl,32240 const nav_val = zcu.navValue(orig_nav_index);
32222 else => decl_index,32241 const nav_index, const is_const = switch (ip.indexToKey(nav_val.toIntern())) {
32223 });32242 .variable => |v| .{ v.owner_nav, false },
32224 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type32243 .func => |f| .{ f.owner_nav, true },
32225 try sema.declareDependency(.{ .decl_val = decl_index });32244 .@"extern" => |e| .{ e.owner_nav, e.is_const },
32245 else => .{ orig_nav_index, true },
32246 };
32247 const nav_info = ip.getNav(nav_index).status.resolved;
32226 const ptr_ty = try pt.ptrTypeSema(.{32248 const ptr_ty = try pt.ptrTypeSema(.{
32227 .child = decl_val.typeOf(mod).toIntern(),32249 .child = nav_val.typeOf(zcu).toIntern(),
32228 .flags = .{32250 .flags = .{
32229 .alignment = owner_decl.alignment,32251 .alignment = nav_info.alignment,
32230 .is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true,32252 .is_const = is_const,
32231 .address_space = owner_decl.@"addrspace",32253 .address_space = nav_info.@"addrspace",
32232 },32254 },
32233 });32255 });
32234 if (analyze_fn_body) {32256 if (analyze_fn_body) {
32235 try sema.maybeQueueFuncBodyAnalysis(src, decl_index);32257 try sema.maybeQueueFuncBodyAnalysis(src, nav_index);
32236 }32258 }
32237 return Air.internedToRef((try pt.intern(.{ .ptr = .{32259 return Air.internedToRef((try pt.intern(.{ .ptr = .{
32238 .ty = ptr_ty.toIntern(),32260 .ty = ptr_ty.toIntern(),
32239 .base_addr = .{ .decl = decl_index },32261 .base_addr = .{ .nav = nav_index },
32240 .byte_offset = 0,32262 .byte_offset = 0,
32241 } })));32263 } })));
32242}32264}
3224332265
32244fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void {32266fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void {
32245 const mod = sema.pt.zcu;32267 const zcu = sema.pt.zcu;
32246 const decl = mod.declPtr(decl_index);32268 const ip = &zcu.intern_pool;
32247 const decl_val = try decl.valueOrFail();32269 const nav_val = zcu.navValue(nav_index);
32248 if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return;32270 if (!ip.isFuncBody(nav_val.toIntern())) return;
32249 if (!try sema.fnHasRuntimeBits(decl_val.typeOf(mod))) return;32271 if (!try sema.fnHasRuntimeBits(nav_val.typeOf(zcu))) return;
32250 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = decl_val.toIntern() }));32272 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() }));
32251 try mod.ensureFuncBodyAnalysisQueued(decl_val.toIntern());32273 try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
32252}32274}
3225332275
32254fn analyzeRef(32276fn analyzeRef(
...@@ -32263,9 +32285,9 @@ fn analyzeRef(...@@ -32263,9 +32285,9 @@ fn analyzeRef(
3226332285
32264 if (try sema.resolveValue(operand)) |val| {32286 if (try sema.resolveValue(operand)) |val| {
32265 switch (mod.intern_pool.indexToKey(val.toIntern())) {32287 switch (mod.intern_pool.indexToKey(val.toIntern())) {
32266 .extern_func => |extern_func| return sema.analyzeDeclRef(src, extern_func.decl),32288 .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav),
32267 .func => |func| return sema.analyzeDeclRef(src, func.owner_decl),32289 .func => |f| return sema.analyzeNavRef(src, f.owner_nav),
32268 else => return anonDeclRef(sema, val.toIntern()),32290 else => return uavRef(sema, val.toIntern()),
32269 }32291 }
32270 }32292 }
3227132293
...@@ -35198,7 +35220,7 @@ pub fn resolveStructAlignment(...@@ -35198,7 +35220,7 @@ pub fn resolveStructAlignment(
35198 const ip = &mod.intern_pool;35220 const ip = &mod.intern_pool;
35199 const target = mod.getTarget();35221 const target = mod.getTarget();
3520035222
35201 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);35223 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3520235224
35203 assert(struct_type.layout != .@"packed");35225 assert(struct_type.layout != .@"packed");
35204 assert(struct_type.flagsUnordered(ip).alignment == .none);35226 assert(struct_type.flagsUnordered(ip).alignment == .none);
...@@ -35242,7 +35264,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35242,7 +35264,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
35242 const ip = &zcu.intern_pool;35264 const ip = &zcu.intern_pool;
35243 const struct_type = zcu.typeToStruct(ty) orelse return;35265 const struct_type = zcu.typeToStruct(ty) orelse return;
3524435266
35245 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);35267 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3524635268
35247 if (struct_type.haveLayout(ip))35269 if (struct_type.haveLayout(ip))
35248 return;35270 return;
...@@ -35384,8 +35406,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp...@@ -35384,8 +35406,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35384 const gpa = zcu.gpa;35406 const gpa = zcu.gpa;
35385 const ip = &zcu.intern_pool;35407 const ip = &zcu.intern_pool;
3538635408
35387 const decl_index = struct_type.decl.unwrap().?;35409 const cau_index = struct_type.cau.unwrap().?;
35388 const decl = zcu.declPtr(decl_index);
3538935410
35390 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;35411 const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir;
3539135412
...@@ -35400,13 +35421,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp...@@ -35400,13 +35421,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35400 .gpa = gpa,35421 .gpa = gpa,
35401 .arena = analysis_arena.allocator(),35422 .arena = analysis_arena.allocator(),
35402 .code = zir,35423 .code = zir,
35403 .owner_decl = decl,35424 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
35404 .owner_decl_index = decl_index,
35405 .func_index = .none,35425 .func_index = .none,
35406 .func_is_naked = false,35426 .func_is_naked = false,
35407 .fn_ret_ty = Type.void,35427 .fn_ret_ty = Type.void,
35408 .fn_ret_ty_ies = null,35428 .fn_ret_ty_ies = null,
35409 .owner_func_index = .none,
35410 .comptime_err_ret_trace = &comptime_err_ret_trace,35429 .comptime_err_ret_trace = &comptime_err_ret_trace,
35411 };35430 };
35412 defer sema.deinit();35431 defer sema.deinit();
...@@ -35414,12 +35433,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp...@@ -35414,12 +35433,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp
35414 var block: Block = .{35433 var block: Block = .{
35415 .parent = null,35434 .parent = null,
35416 .sema = &sema,35435 .sema = &sema,
35417 .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,35436 .namespace = ip.getCau(cau_index).namespace,
35418 .instructions = .{},35437 .instructions = .{},
35419 .inlining = null,35438 .inlining = null,
35420 .is_comptime = true,35439 .is_comptime = true,
35421 .src_base_inst = struct_type.zir_index.unwrap().?,35440 .src_base_inst = struct_type.zir_index.unwrap().?,
35422 .type_name_ctx = decl.name,35441 .type_name_ctx = struct_type.name,
35423 };35442 };
35424 defer assert(block.instructions.items.len == 0);35443 defer assert(block.instructions.items.len == 0);
3542535444
...@@ -35544,7 +35563,7 @@ pub fn resolveUnionAlignment(...@@ -35544,7 +35563,7 @@ pub fn resolveUnionAlignment(
35544 const ip = &zcu.intern_pool;35563 const ip = &zcu.intern_pool;
35545 const target = zcu.getTarget();35564 const target = zcu.getTarget();
3554635565
35547 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35566 assert(sema.owner.unwrap().cau == union_type.cau);
3554835567
35549 assert(!union_type.haveLayout(ip));35568 assert(!union_type.haveLayout(ip));
3555035569
...@@ -35584,7 +35603,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {...@@ -35584,7 +35603,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35584 // Load again, since the tag type might have changed due to resolution.35603 // Load again, since the tag type might have changed due to resolution.
35585 const union_type = ip.loadUnionType(ty.ip_index);35604 const union_type = ip.loadUnionType(ty.ip_index);
3558635605
35587 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35606 assert(sema.owner.unwrap().cau == union_type.cau);
3558835607
35589 const old_flags = union_type.flagsUnordered(ip);35608 const old_flags = union_type.flagsUnordered(ip);
35590 switch (old_flags.status) {35609 switch (old_flags.status) {
...@@ -35697,7 +35716,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35697,7 +35716,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
35697 const ip = &mod.intern_pool;35716 const ip = &mod.intern_pool;
35698 const struct_type = mod.typeToStruct(ty).?;35717 const struct_type = mod.typeToStruct(ty).?;
3569935718
35700 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);35719 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3570135720
35702 if (struct_type.setFullyResolved(ip)) return;35721 if (struct_type.setFullyResolved(ip)) return;
35703 errdefer struct_type.clearFullyResolved(ip);35722 errdefer struct_type.clearFullyResolved(ip);
...@@ -35720,7 +35739,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {...@@ -35720,7 +35739,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35720 const ip = &mod.intern_pool;35739 const ip = &mod.intern_pool;
35721 const union_obj = mod.typeToUnion(ty).?;35740 const union_obj = mod.typeToUnion(ty).?;
3572235741
35723 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);35742 assert(sema.owner.unwrap().cau == union_obj.cau);
3572435743
35725 switch (union_obj.flagsUnordered(ip).status) {35744 switch (union_obj.flagsUnordered(ip).status) {
35726 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},35745 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
...@@ -35754,21 +35773,8 @@ pub fn resolveTypeFieldsStruct(...@@ -35754,21 +35773,8 @@ pub fn resolveTypeFieldsStruct(
35754 const pt = sema.pt;35773 const pt = sema.pt;
35755 const zcu = pt.zcu;35774 const zcu = pt.zcu;
35756 const ip = &zcu.intern_pool;35775 const ip = &zcu.intern_pool;
35757 // If there is no owner decl it means the struct has no fields.
35758 const owner_decl = struct_type.decl.unwrap() orelse return;
3575935776
35760 assert(sema.ownerUnit().unwrap().decl == owner_decl);35777 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 }
3577235778
35773 if (struct_type.haveFieldTypes(ip)) return;35779 if (struct_type.haveFieldTypes(ip)) return;
3577435780
...@@ -35783,13 +35789,7 @@ pub fn resolveTypeFieldsStruct(...@@ -35783,13 +35789,7 @@ pub fn resolveTypeFieldsStruct(
35783 defer struct_type.clearFieldTypesWip(ip);35789 defer struct_type.clearFieldTypesWip(ip);
3578435790
35785 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {35791 semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) {
35786 error.AnalysisFail => {35792 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,35793 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35794 };35794 };
35795}35795}
...@@ -35799,9 +35799,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35799,9 +35799,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35799 const zcu = pt.zcu;35799 const zcu = pt.zcu;
35800 const ip = &zcu.intern_pool;35800 const ip = &zcu.intern_pool;
35801 const struct_type = zcu.typeToStruct(ty) orelse return;35801 const struct_type = zcu.typeToStruct(ty) orelse return;
35802 const owner_decl = struct_type.decl.unwrap() orelse return;
3580335802
35804 assert(sema.ownerUnit().unwrap().decl == owner_decl);35803 assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?);
3580535804
35806 // Inits can start as resolved35805 // Inits can start as resolved
35807 if (struct_type.haveFieldInits(ip)) return;35806 if (struct_type.haveFieldInits(ip)) return;
...@@ -35819,13 +35818,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {...@@ -35819,13 +35818,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35819 defer struct_type.clearInitsWip(ip);35818 defer struct_type.clearInitsWip(ip);
3582035819
35821 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {35820 semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) {
35822 error.AnalysisFail => {35821 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,35822 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35830 };35823 };
35831 struct_type.setHaveFieldInits(ip);35824 struct_type.setHaveFieldInits(ip);
...@@ -35835,20 +35828,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35835,20 +35828,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35835 const pt = sema.pt;35828 const pt = sema.pt;
35836 const zcu = pt.zcu;35829 const zcu = pt.zcu;
35837 const ip = &zcu.intern_pool;35830 const ip = &zcu.intern_pool;
35838 const owner_decl = zcu.declPtr(union_type.decl);
3583935831
35840 assert(sema.ownerUnit().unwrap().decl == union_type.decl);35832 assert(sema.owner.unwrap().cau == union_type.cau);
3584135833
35842 switch (owner_decl.analysis) {
35843 .file_failure,
35844 .dependency_failure,
35845 .sema_failure,
35846 => {
35847 sema.owner_decl.analysis = .dependency_failure;
35848 return error.AnalysisFail;
35849 },
35850 else => {},
35851 }
35852 switch (union_type.flagsUnordered(ip).status) {35834 switch (union_type.flagsUnordered(ip).status) {
35853 .none => {},35835 .none => {},
35854 .field_types_wip => {35836 .field_types_wip => {
...@@ -35869,14 +35851,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35869,14 +35851,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3586935851
35870 union_type.setStatus(ip, .field_types_wip);35852 union_type.setStatus(ip, .field_types_wip);
35871 errdefer union_type.setStatus(ip, .none);35853 errdefer union_type.setStatus(ip, .none);
35872 semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) {35854 semaUnionFields(pt, sema.arena, ty.toIntern(), union_type) catch |err| switch (err) {
35873 error.AnalysisFail => {35855 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,35856 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35881 };35857 };
35882 union_type.setStatus(ip, .have_field_types);35858 union_type.setStatus(ip, .have_field_types);
...@@ -35891,28 +35867,28 @@ fn resolveInferredErrorSet(...@@ -35891,28 +35867,28 @@ fn resolveInferredErrorSet(
35891 ies_index: InternPool.Index,35867 ies_index: InternPool.Index,
35892) CompileError!InternPool.Index {35868) CompileError!InternPool.Index {
35893 const pt = sema.pt;35869 const pt = sema.pt;
35894 const mod = pt.zcu;35870 const zcu = pt.zcu;
35895 const ip = &mod.intern_pool;35871 const ip = &zcu.intern_pool;
35896 const func_index = ip.iesFuncIndex(ies_index);35872 const func_index = ip.iesFuncIndex(ies_index);
35897 const func = mod.funcInfo(func_index);35873 const func = zcu.funcInfo(func_index);
3589835874
35899 try sema.declareDependency(.{ .func_ies = func_index });35875 try sema.declareDependency(.{ .interned = func_index }); // resolved IES
3590035876
35901 // TODO: during an incremental update this might not be `.none`, but the35877 // TODO: during an incremental update this might not be `.none`, but the
35902 // function might be out-of-date!35878 // function might be out-of-date!
35903 const resolved_ty = func.resolvedErrorSetUnordered(ip);35879 const resolved_ty = func.resolvedErrorSetUnordered(ip);
35904 if (resolved_ty != .none) return resolved_ty;35880 if (resolved_ty != .none) return resolved_ty;
3590535881
35906 if (func.analysisUnordered(ip).state == .in_progress)35882 if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .func = func_index }))) {
35907 return sema.fail(block, src, "unable to resolve inferred error set", .{});35883 return sema.fail(block, src, "unable to resolve inferred error set", .{});
35884 }
3590835885
35909 // In order to ensure that all dependencies are properly added to the set,35886 // 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 error35887 // we need to ensure the function body is analyzed of the inferred error
35911 // set. However, in the case of comptime/inline function calls with35888 // set. However, in the case of comptime/inline function calls with
35912 // inferred error sets, each call gets an adhoc InferredErrorSet object, which35889 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
35913 // has no corresponding function body.35890 // has no corresponding function body.
35914 const ies_func_owner_decl = mod.declPtr(func.owner_decl);35891 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,35892 // 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,35893 // 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.35894 // so here we can simply skip this case.
...@@ -35920,22 +35896,17 @@ fn resolveInferredErrorSet(...@@ -35920,22 +35896,17 @@ fn resolveInferredErrorSet(
35920 assert(ies_func_info.cc == .Inline);35896 assert(ies_func_info.cc == .Inline);
35921 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {35897 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {
35922 if (ies_func_info.is_generic) {35898 if (ies_func_info.is_generic) {
35923 const msg = msg: {35899 return sema.failWithOwnedErrorMsg(block, msg: {
35924 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});35900 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});
35925 errdefer msg.destroy(sema.gpa);35901 errdefer msg.destroy(sema.gpa);
3592635902 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;35903 break :msg msg;
35932 };35904 });
35933 return sema.failWithOwnedErrorMsg(block, msg);
35934 }35905 }
35935 // In this case we are dealing with the actual InferredErrorSet object that35906 // 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.35907 // corresponds to the function, not one created to track an inline/comptime call.
35937 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));35908 try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index }));
35938 try sema.ensureFuncBodyAnalyzed(func_index);35909 try pt.ensureFuncBodyAnalyzed(func_index);
35939 }35910 }
3594035911
35941 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`35912 // This will now have been resolved by the logic at the end of `Module.analyzeFnBody`
...@@ -36092,9 +36063,8 @@ fn semaStructFields(...@@ -36092,9 +36063,8 @@ fn semaStructFields(
36092 const zcu = pt.zcu;36063 const zcu = pt.zcu;
36093 const gpa = zcu.gpa;36064 const gpa = zcu.gpa;
36094 const ip = &zcu.intern_pool;36065 const ip = &zcu.intern_pool;
36095 const decl_index = struct_type.decl.unwrap() orelse return;36066 const cau_index = struct_type.cau.unwrap().?;
36096 const decl = zcu.declPtr(decl_index);36067 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;36068 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36099 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);36069 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
3610036070
...@@ -36119,13 +36089,11 @@ fn semaStructFields(...@@ -36119,13 +36089,11 @@ fn semaStructFields(
36119 .gpa = gpa,36089 .gpa = gpa,
36120 .arena = arena,36090 .arena = arena,
36121 .code = zir,36091 .code = zir,
36122 .owner_decl = decl,36092 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
36123 .owner_decl_index = decl_index,
36124 .func_index = .none,36093 .func_index = .none,
36125 .func_is_naked = false,36094 .func_is_naked = false,
36126 .fn_ret_ty = Type.void,36095 .fn_ret_ty = Type.void,
36127 .fn_ret_ty_ies = null,36096 .fn_ret_ty_ies = null,
36128 .owner_func_index = .none,
36129 .comptime_err_ret_trace = &comptime_err_ret_trace,36097 .comptime_err_ret_trace = &comptime_err_ret_trace,
36130 };36098 };
36131 defer sema.deinit();36099 defer sema.deinit();
...@@ -36138,7 +36106,7 @@ fn semaStructFields(...@@ -36138,7 +36106,7 @@ fn semaStructFields(
36138 .inlining = null,36106 .inlining = null,
36139 .is_comptime = true,36107 .is_comptime = true,
36140 .src_base_inst = struct_type.zir_index.unwrap().?,36108 .src_base_inst = struct_type.zir_index.unwrap().?,
36141 .type_name_ctx = decl.name,36109 .type_name_ctx = struct_type.name,
36142 };36110 };
36143 defer assert(block_scope.instructions.items.len == 0);36111 defer assert(block_scope.instructions.items.len == 0);
3614436112
...@@ -36318,9 +36286,8 @@ fn semaStructFieldInits(...@@ -36318,9 +36286,8 @@ fn semaStructFieldInits(
3631836286
36319 assert(!struct_type.haveFieldInits(ip));36287 assert(!struct_type.haveFieldInits(ip));
3632036288
36321 const decl_index = struct_type.decl.unwrap() orelse return;36289 const cau_index = struct_type.cau.unwrap().?;
36322 const decl = zcu.declPtr(decl_index);36290 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;36291 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir;
36325 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);36292 const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
36326 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);36293 const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
...@@ -36333,13 +36300,11 @@ fn semaStructFieldInits(...@@ -36333,13 +36300,11 @@ fn semaStructFieldInits(
36333 .gpa = gpa,36300 .gpa = gpa,
36334 .arena = arena,36301 .arena = arena,
36335 .code = zir,36302 .code = zir,
36336 .owner_decl = decl,36303 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
36337 .owner_decl_index = decl_index,
36338 .func_index = .none,36304 .func_index = .none,
36339 .func_is_naked = false,36305 .func_is_naked = false,
36340 .fn_ret_ty = Type.void,36306 .fn_ret_ty = Type.void,
36341 .fn_ret_ty_ies = null,36307 .fn_ret_ty_ies = null,
36342 .owner_func_index = .none,
36343 .comptime_err_ret_trace = &comptime_err_ret_trace,36308 .comptime_err_ret_trace = &comptime_err_ret_trace,
36344 };36309 };
36345 defer sema.deinit();36310 defer sema.deinit();
...@@ -36352,7 +36317,7 @@ fn semaStructFieldInits(...@@ -36352,7 +36317,7 @@ fn semaStructFieldInits(
36352 .inlining = null,36317 .inlining = null,
36353 .is_comptime = true,36318 .is_comptime = true,
36354 .src_base_inst = struct_type.zir_index.unwrap().?,36319 .src_base_inst = struct_type.zir_index.unwrap().?,
36355 .type_name_ctx = decl.name,36320 .type_name_ctx = struct_type.name,
36356 };36321 };
36357 defer assert(block_scope.instructions.items.len == 0);36322 defer assert(block_scope.instructions.items.len == 0);
3635836323
...@@ -36449,14 +36414,14 @@ fn semaStructFieldInits(...@@ -36449,14 +36414,14 @@ fn semaStructFieldInits(
36449 try sema.flushExports();36414 try sema.flushExports();
36450}36415}
3645136416
36452fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void {36417fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_ty: InternPool.Index, union_type: InternPool.LoadedUnionType) CompileError!void {
36453 const tracy = trace(@src());36418 const tracy = trace(@src());
36454 defer tracy.end();36419 defer tracy.end();
3645536420
36456 const zcu = pt.zcu;36421 const zcu = pt.zcu;
36457 const gpa = zcu.gpa;36422 const gpa = zcu.gpa;
36458 const ip = &zcu.intern_pool;36423 const ip = &zcu.intern_pool;
36459 const decl_index = union_type.decl;36424 const cau_index = union_type.cau;
36460 const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir;36425 const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir;
36461 const zir_index = union_type.zir_index.resolve(ip);36426 const zir_index = union_type.zir_index.resolve(ip);
36462 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;36427 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
...@@ -36501,8 +36466,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36501,8 +36466,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36501 const body = zir.bodySlice(extra_index, body_len);36466 const body = zir.bodySlice(extra_index, body_len);
36502 extra_index += body.len;36467 extra_index += body.len;
3650336468
36504 const decl = zcu.declPtr(decl_index);
36505
36506 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);36469 var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
36507 defer comptime_err_ret_trace.deinit();36470 defer comptime_err_ret_trace.deinit();
3650836471
...@@ -36511,13 +36474,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36511,13 +36474,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36511 .gpa = gpa,36474 .gpa = gpa,
36512 .arena = arena,36475 .arena = arena,
36513 .code = zir,36476 .code = zir,
36514 .owner_decl = decl,36477 .owner = AnalUnit.wrap(.{ .cau = cau_index }),
36515 .owner_decl_index = decl_index,
36516 .func_index = .none,36478 .func_index = .none,
36517 .func_is_naked = false,36479 .func_is_naked = false,
36518 .fn_ret_ty = Type.void,36480 .fn_ret_ty = Type.void,
36519 .fn_ret_ty_ies = null,36481 .fn_ret_ty_ies = null,
36520 .owner_func_index = .none,
36521 .comptime_err_ret_trace = &comptime_err_ret_trace,36482 .comptime_err_ret_trace = &comptime_err_ret_trace,
36522 };36483 };
36523 defer sema.deinit();36484 defer sema.deinit();
...@@ -36530,7 +36491,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36530,7 +36491,7 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36530 .inlining = null,36491 .inlining = null,
36531 .is_comptime = true,36492 .is_comptime = true,
36532 .src_base_inst = union_type.zir_index,36493 .src_base_inst = union_type.zir_index,
36533 .type_name_ctx = decl.name,36494 .type_name_ctx = union_type.name,
36534 };36495 };
36535 defer assert(block_scope.instructions.items.len == 0);36496 defer assert(block_scope.instructions.items.len == 0);
3653636497
...@@ -36817,10 +36778,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L...@@ -36817,10 +36778,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L
36817 return sema.failWithOwnedErrorMsg(&block_scope, msg);36778 return sema.failWithOwnedErrorMsg(&block_scope, msg);
36818 }36779 }
36819 } else if (enum_field_vals.count() > 0) {36780 } else if (enum_field_vals.count() > 0) {
36820 const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl));36781 const enum_ty = try sema.generateUnionTagTypeNumbered(enum_field_names, enum_field_vals.keys(), union_ty, union_type.name);
36821 union_type.setTagType(ip, enum_ty);36782 union_type.setTagType(ip, enum_ty);
36822 } else {36783 } else {
36823 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl));36784 const enum_ty = try sema.generateUnionTagTypeSimple(enum_field_names, union_ty, union_type.name);
36824 union_type.setTagType(ip, enum_ty);36785 union_type.setTagType(ip, enum_ty);
36825 }36786 }
3682636787
...@@ -36836,39 +36797,27 @@ fn semaUnionFieldVal(sema: *Sema, block: *Block, src: LazySrcLoc, int_tag_ty: Ty...@@ -36836,39 +36797,27 @@ fn semaUnionFieldVal(sema: *Sema, block: *Block, src: LazySrcLoc, int_tag_ty: Ty
3683636797
36837fn generateUnionTagTypeNumbered(36798fn generateUnionTagTypeNumbered(
36838 sema: *Sema,36799 sema: *Sema,
36839 block: *Block,
36840 enum_field_names: []const InternPool.NullTerminatedString,36800 enum_field_names: []const InternPool.NullTerminatedString,
36841 enum_field_vals: []const InternPool.Index,36801 enum_field_vals: []const InternPool.Index,
36842 union_owner_decl: *Module.Decl,36802 union_type: InternPool.Index,
36803 union_name: InternPool.NullTerminatedString,
36843) !InternPool.Index {36804) !InternPool.Index {
36844 const pt = sema.pt;36805 const pt = sema.pt;
36845 const mod = pt.zcu;36806 const mod = pt.zcu;
36846 const gpa = sema.gpa;36807 const gpa = sema.gpa;
36847 const ip = &mod.intern_pool;36808 const ip = &mod.intern_pool;
3684836809
36849 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36850 errdefer pt.destroyDecl(new_decl_index);
36851 const name = try ip.getOrPutStringFmt(36810 const name = try ip.getOrPutStringFmt(
36852 gpa,36811 gpa,
36853 pt.tid,36812 pt.tid,
36854 "@typeInfo({}).Union.tag_type.?",36813 "@typeInfo({}).Union.tag_type.?",
36855 .{union_owner_decl.fqn.fmt(ip)},36814 .{union_name.fmt(ip)},
36856 .no_embedded_nulls,36815 .no_embedded_nulls,
36857 );36816 );
36858 try pt.initNewAnonDecl(
36859 new_decl_index,
36860 Value.@"unreachable",
36861 name,
36862 name.toOptional(),
36863 );
36864 errdefer pt.abortAnonDecl(new_decl_index);
36865
36866 const new_decl = mod.declPtr(new_decl_index);
36867 new_decl.owns_tv = true;
3686836817
36869 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{36818 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36870 .decl = new_decl_index,36819 .name = name,
36871 .owner_union_ty = union_owner_decl.val.toIntern(),36820 .owner_union_ty = union_type,
36872 .tag_ty = if (enum_field_vals.len == 0)36821 .tag_ty = if (enum_field_vals.len == 0)
36873 (try pt.intType(.unsigned, 0)).toIntern()36822 (try pt.intType(.unsigned, 0)).toIntern()
36874 else36823 else
...@@ -36878,46 +36827,31 @@ fn generateUnionTagTypeNumbered(...@@ -36878,46 +36827,31 @@ fn generateUnionTagTypeNumbered(
36878 .tag_mode = .explicit,36827 .tag_mode = .explicit,
36879 });36828 });
3688036829
36881 new_decl.val = Value.fromInterned(enum_ty);
36882
36883 try pt.finalizeAnonDecl(new_decl_index);
36884 return enum_ty;36830 return enum_ty;
36885}36831}
3688636832
36887fn generateUnionTagTypeSimple(36833fn generateUnionTagTypeSimple(
36888 sema: *Sema,36834 sema: *Sema,
36889 block: *Block,
36890 enum_field_names: []const InternPool.NullTerminatedString,36835 enum_field_names: []const InternPool.NullTerminatedString,
36891 union_owner_decl: *Module.Decl,36836 union_type: InternPool.Index,
36837 union_name: InternPool.NullTerminatedString,
36892) !InternPool.Index {36838) !InternPool.Index {
36893 const pt = sema.pt;36839 const pt = sema.pt;
36894 const mod = pt.zcu;36840 const mod = pt.zcu;
36895 const ip = &mod.intern_pool;36841 const ip = &mod.intern_pool;
36896 const gpa = sema.gpa;36842 const gpa = sema.gpa;
3689736843
36898 const new_decl_index = new_decl_index: {36844 const name = try ip.getOrPutStringFmt(
36899 const new_decl_index = try pt.allocateNewDecl(block.namespace);36845 gpa,
36900 errdefer pt.destroyDecl(new_decl_index);36846 pt.tid,
36901 const name = try ip.getOrPutStringFmt(36847 "@typeInfo({}).Union.tag_type.?",
36902 gpa,36848 .{union_name.fmt(ip)},
36903 pt.tid,36849 .no_embedded_nulls,
36904 "@typeInfo({}).Union.tag_type.?",36850 );
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);
3691736851
36918 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{36852 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36919 .decl = new_decl_index,36853 .name = name,
36920 .owner_union_ty = union_owner_decl.val.toIntern(),36854 .owner_union_ty = union_type,
36921 .tag_ty = if (enum_field_names.len == 0)36855 .tag_ty = if (enum_field_names.len == 0)
36922 (try pt.intType(.unsigned, 0)).toIntern()36856 (try pt.intType(.unsigned, 0)).toIntern()
36923 else36857 else
...@@ -36927,11 +36861,6 @@ fn generateUnionTagTypeSimple(...@@ -36927,11 +36861,6 @@ fn generateUnionTagTypeSimple(
36927 .tag_mode = .auto,36861 .tag_mode = .auto,
36928 });36862 });
3692936863
36930 const new_decl = mod.declPtr(new_decl_index);
36931 new_decl.owns_tv = true;
36932 new_decl.val = Value.fromInterned(enum_ty);
36933
36934 try pt.finalizeAnonDecl(new_decl_index);
36935 return enum_ty;36864 return enum_ty;
36936}36865}
3693736866
...@@ -37057,9 +36986,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37057,9 +36986,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37057 // values, not types36986 // values, not types
37058 .undef,36987 .undef,
37059 .simple_value,36988 .simple_value,
37060 .ptr_decl,36989 .ptr_nav,
37061 .ptr_anon_decl,36990 .ptr_uav,
37062 .ptr_anon_decl_aligned,36991 .ptr_uav_aligned,
37063 .ptr_comptime_alloc,36992 .ptr_comptime_alloc,
37064 .ptr_comptime_field,36993 .ptr_comptime_field,
37065 .ptr_int,36994 .ptr_int,
...@@ -37096,7 +37025,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37096,7 +37025,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37096 .float_c_longdouble_f128,37025 .float_c_longdouble_f128,
37097 .float_comptime_float,37026 .float_comptime_float,
37098 .variable,37027 .variable,
37099 .extern_func,37028 .@"extern",
37100 .func_decl,37029 .func_decl,
37101 .func_instance,37030 .func_instance,
37102 .func_coerced,37031 .func_coerced,
...@@ -37965,7 +37894,7 @@ fn intFitsInType(...@@ -37965,7 +37894,7 @@ fn intFitsInType(
37965 .zero_usize, .zero_u8 => return true,37894 .zero_usize, .zero_u8 => return true,
37966 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {37895 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
37967 .undef => return true,37896 .undef => return true,
37968 .variable, .extern_func, .func, .ptr => {37897 .variable, .@"extern", .func, .ptr => {
37969 const target = mod.getTarget();37898 const target = mod.getTarget();
37970 const ptr_bits = target.ptrBitWidth();37899 const ptr_bits = target.ptrBitWidth();
37971 return switch (info.signedness) {37900 return switch (info.signedness) {
...@@ -38240,24 +38169,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {...@@ -38240,24 +38169,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 would38169 // 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 resolve38170 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
38242 // the loop.38171 // the loop.
38243 if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) {38172 switch (sema.owner.unwrap()) {
38244 return;38173 .cau => |cau| switch (dependee) {
38174 .nav_val => |nav| if (zcu.intern_pool.getNav(nav).analysis_owner == cau.toOptional()) {
38175 return;
38176 },
38177 else => {},
38178 },
38179 .func => {},
38245 }38180 }
3824638181
38247 const depender = AnalUnit.wrap(38182 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}38183}
3825538184
38256fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {38185fn isComptimeMutablePtr(sema: *Sema, val: Value) bool {
38257 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {38186 return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) {
38258 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),38187 .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)),
38259 .ptr => |ptr| switch (ptr.base_addr) {38188 .ptr => |ptr| switch (ptr.base_addr) {
38260 .anon_decl, .decl, .int => false,38189 .uav, .nav, .int => false,
38261 .comptime_field => true,38190 .comptime_field => true,
38262 .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const,38191 .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const,
38263 .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)),38192 .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)),
...@@ -38388,19 +38317,17 @@ pub fn flushExports(sema: *Sema) !void {...@@ -38388,19 +38317,17 @@ pub fn flushExports(sema: *Sema) !void {
38388 const zcu = sema.pt.zcu;38317 const zcu = sema.pt.zcu;
38389 const gpa = zcu.gpa;38318 const gpa = zcu.gpa;
3839038319
38391 const unit = sema.ownerUnit();
38392
38393 // There may be existing exports. For instance, a struct may export38320 // There may be existing exports. For instance, a struct may export
38394 // things during both field type resolution and field default resolution.38321 // things during both field type resolution and field default resolution.
38395 //38322 //
38396 // So, pick up and delete any existing exports. This strategy performs38323 // So, pick up and delete any existing exports. This strategy performs
38397 // redundant work, but that's okay, because this case is exceedingly rare.38324 // redundant work, but that's okay, because this case is exceedingly rare.
38398 if (zcu.single_exports.get(unit)) |export_idx| {38325 if (zcu.single_exports.get(sema.owner)) |export_idx| {
38399 try sema.exports.append(gpa, zcu.all_exports.items[export_idx]);38326 try sema.exports.append(gpa, zcu.all_exports.items[export_idx]);
38400 } else if (zcu.multi_exports.get(unit)) |info| {38327 } else if (zcu.multi_exports.get(sema.owner)) |info| {
38401 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);38328 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
38402 }38329 }
38403 zcu.deleteUnitExports(unit);38330 zcu.deleteUnitExports(sema.owner);
3840438331
38405 // `sema.exports` is completed; store the data into the `Zcu`.38332 // `sema.exports` is completed; store the data into the `Zcu`.
38406 if (sema.exports.items.len == 1) {38333 if (sema.exports.items.len == 1) {
...@@ -38410,24 +38337,55 @@ pub fn flushExports(sema: *Sema) !void {...@@ -38410,24 +38337,55 @@ pub fn flushExports(sema: *Sema) !void {
38410 break :idx zcu.all_exports.items.len - 1;38337 break :idx zcu.all_exports.items.len - 1;
38411 };38338 };
38412 zcu.all_exports.items[export_idx] = sema.exports.items[0];38339 zcu.all_exports.items[export_idx] = sema.exports.items[0];
38413 zcu.single_exports.putAssumeCapacityNoClobber(unit, @intCast(export_idx));38340 zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, @intCast(export_idx));
38414 } else {38341 } else {
38415 try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);38342 try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);
38416 const exports_base = zcu.all_exports.items.len;38343 const exports_base = zcu.all_exports.items.len;
38417 try zcu.all_exports.appendSlice(gpa, sema.exports.items);38344 try zcu.all_exports.appendSlice(gpa, sema.exports.items);
38418 zcu.multi_exports.putAssumeCapacityNoClobber(unit, .{38345 zcu.multi_exports.putAssumeCapacityNoClobber(sema.owner, .{
38419 .index = @intCast(exports_base),38346 .index = @intCast(exports_base),
38420 .len = @intCast(sema.exports.items.len),38347 .len = @intCast(sema.exports.items.len),
38421 });38348 });
38422 }38349 }
38423}38350}
3842438351
38425pub fn ownerUnit(sema: Sema) AnalUnit {38352/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38426 if (sema.owner_func_index != .none) {38353/// the corresponding `Nav`.
38427 return AnalUnit.wrap(.{ .func = sema.owner_func_index });38354fn getOwnerCauNav(sema: *Sema) InternPool.Nav.Index {
38428 } else {38355 const cau = sema.owner.unwrap().cau;
38429 return AnalUnit.wrap(.{ .decl = sema.owner_decl_index });38356 return sema.pt.zcu.intern_pool.getCau(cau).owner.unwrap().nav;
38430 }38357}
38358
38359/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38360/// the declaration name from its corresponding `Nav`.
38361fn getOwnerCauNavName(sema: *Sema) InternPool.NullTerminatedString {
38362 const nav = sema.getOwnerCauNav();
38363 return sema.pt.zcu.intern_pool.getNav(nav).name;
38364}
38365
38366/// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches
38367/// the `TrackedInst` corresponding to this `declaration` instruction.
38368fn getOwnerCauDeclInst(sema: *Sema) InternPool.TrackedInst.Index {
38369 const ip = &sema.pt.zcu.intern_pool;
38370 const cau = ip.getCau(sema.owner.unwrap().cau);
38371 assert(cau.owner.unwrap() == .nav);
38372 return cau.zir_index;
38373}
38374
38375/// Given that this `Sema` is owned by a runtime function, fetches the
38376/// `TrackedInst` corresponding to its `declaration` instruction.
38377fn getOwnerFuncDeclInst(sema: *Sema) InternPool.TrackedInst.Index {
38378 const zcu = sema.pt.zcu;
38379 const ip = &zcu.intern_pool;
38380 const func = sema.owner.unwrap().func;
38381 const func_info = zcu.funcInfo(func);
38382 const cau = if (func_info.generic_owner == .none) cau: {
38383 break :cau ip.getNav(func_info.owner_nav).analysis_owner.unwrap().?;
38384 } else cau: {
38385 const generic_owner = zcu.funcInfo(func_info.generic_owner);
38386 break :cau ip.getNav(generic_owner.owner_nav).analysis_owner.unwrap().?;
38387 };
38388 return ip.getCau(cau).zir_index;
38431}38389}
3843238390
38433pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;38391pub 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+110-64
...@@ -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,
...@@ -3007,6 +3003,26 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {...@@ -3007,6 +3003,26 @@ pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {
3007 };3003 };
3008}3004}
30093005
3006// TODO: new dwarf structure will also need the enclosing code block for types created in imperative scopes
3007pub fn getParentNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex {
3008 const ip = &zcu.intern_pool;
3009 const cau = switch (ip.indexToKey(ty.toIntern())) {
3010 .struct_type => ip.loadStructType(ty.toIntern()).cau,
3011 .union_type => ip.loadUnionType(ty.toIntern()).cau.toOptional(),
3012 .enum_type => |e| switch (e) {
3013 .declared, .reified => ip.loadEnumType(ty.toIntern()).cau,
3014 .generated_tag => |gt| ip.loadUnionType(gt.union_type).cau.toOptional(),
3015 .empty_struct => unreachable,
3016 },
3017 // TODO: this doesn't handle opaque types with empty namespaces
3018 .opaque_type => return ip.namespacePtr(ip.loadOpaqueType(ty.toIntern()).namespace.unwrap().?).parent,
3019 else => return null,
3020 };
3021 return ip.namespacePtr(ip.getCau(cau.unwrap() orelse return .none).namespace)
3022 // TODO: I thought the cau contained the parent namespace based on "analyzed within" but alas
3023 .parent;
3024}
3025
3010// Works for vectors and vectors of integers.3026// Works for vectors and vectors of integers.
3011pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {3027pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
3012 const mod = pt.zcu;3028 const mod = pt.zcu;
...@@ -3321,21 +3337,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {...@@ -3321,21 +3337,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 {
3321 }3337 }
3322}3338}
33233339
3324pub fn getOwnerDecl(ty: Type, mod: *Module) InternPool.DeclIndex {
3325 return ty.getOwnerDeclOrNull(mod) orelse unreachable;
3326}
3327
3328pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?InternPool.DeclIndex {
3329 const ip = &mod.intern_pool;
3330 return switch (ip.indexToKey(ty.toIntern())) {
3331 .struct_type => ip.loadStructType(ty.toIntern()).decl.unwrap(),
3332 .union_type => ip.loadUnionType(ty.toIntern()).decl,
3333 .opaque_type => ip.loadOpaqueType(ty.toIntern()).decl,
3334 .enum_type => ip.loadEnumType(ty.toIntern()).decl,
3335 else => null,
3336 };
3337}
3338
3339pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {3340pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {
3340 const ip = &zcu.intern_pool;3341 const ip = &zcu.intern_pool;
3341 return .{3342 return .{
...@@ -3366,7 +3367,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {...@@ -3366,7 +3367,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool {
3366 .struct_type => {3367 .struct_type => {
3367 const struct_type = ip.loadStructType(ty.toIntern());3368 const struct_type = ip.loadStructType(ty.toIntern());
3368 if (struct_type.layout == .@"packed") return false;3369 if (struct_type.layout == .@"packed") return false;
3369 if (struct_type.decl == .none) return false;3370 if (struct_type.cau == .none) return false;
3370 return struct_type.flagsUnordered(ip).is_tuple;3371 return struct_type.flagsUnordered(ip).is_tuple;
3371 },3372 },
3372 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,3373 .anon_struct_type => |anon_struct| anon_struct.names.len == 0,
...@@ -3388,7 +3389,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {...@@ -3388,7 +3389,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool {
3388 .struct_type => {3389 .struct_type => {
3389 const struct_type = ip.loadStructType(ty.toIntern());3390 const struct_type = ip.loadStructType(ty.toIntern());
3390 if (struct_type.layout == .@"packed") return false;3391 if (struct_type.layout == .@"packed") return false;
3391 if (struct_type.decl == .none) return false;3392 if (struct_type.cau == .none) return false;
3392 return struct_type.flagsUnordered(ip).is_tuple;3393 return struct_type.flagsUnordered(ip).is_tuple;
3393 },3394 },
3394 .anon_struct_type => true,3395 .anon_struct_type => true,
...@@ -3444,6 +3445,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {...@@ -3444,6 +3445,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3444 };3445 };
3445}3446}
34463447
3448pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3449 const ip = &zcu.intern_pool;
3450 return switch (ip.indexToKey(ty.toIntern())) {
3451 .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(),
3452 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3453 .enum_type => |e| switch (e) {
3454 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3455 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3456 .empty_struct => unreachable,
3457 },
3458 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
3459 else => null,
3460 };
3461}
3462
3447pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {3463pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3448 const ip = &zcu.intern_pool;3464 const ip = &zcu.intern_pool;
3449 const tracked = switch (ip.indexToKey(ty.toIntern())) {3465 const tracked = switch (ip.indexToKey(ty.toIntern())) {
...@@ -3471,7 +3487,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {...@@ -3471,7 +3487,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3471 };3487 };
3472}3488}
34733489
3474/// Given a namespace type, returns its list of caotured values.3490/// Given a namespace type, returns its list of captured values.
3475pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {3491pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
3476 const ip = &zcu.intern_pool;3492 const ip = &zcu.intern_pool;
3477 return switch (ip.indexToKey(ty.toIntern())) {3493 return switch (ip.indexToKey(ty.toIntern())) {
...@@ -3773,7 +3789,11 @@ fn resolveStructInner(...@@ -3773,7 +3789,11 @@ fn resolveStructInner(
3773 const gpa = zcu.gpa;3789 const gpa = zcu.gpa;
37743790
3775 const struct_obj = zcu.typeToStruct(ty).?;3791 const struct_obj = zcu.typeToStruct(ty).?;
3776 const owner_decl_index = struct_obj.decl.unwrap() orelse return;3792 const owner = InternPool.AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap() orelse return });
3793
3794 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3795 return error.AnalysisFail;
3796 }
37773797
3778 var analysis_arena = std.heap.ArenaAllocator.init(gpa);3798 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3779 defer analysis_arena.deinit();3799 defer analysis_arena.deinit();
...@@ -3786,24 +3806,30 @@ fn resolveStructInner(...@@ -3786,24 +3806,30 @@ fn resolveStructInner(
3786 .gpa = gpa,3806 .gpa = gpa,
3787 .arena = analysis_arena.allocator(),3807 .arena = analysis_arena.allocator(),
3788 .code = undefined, // This ZIR will not be used.3808 .code = undefined, // This ZIR will not be used.
3789 .owner_decl = zcu.declPtr(owner_decl_index),3809 .owner = owner,
3790 .owner_decl_index = owner_decl_index,
3791 .func_index = .none,3810 .func_index = .none,
3792 .func_is_naked = false,3811 .func_is_naked = false,
3793 .fn_ret_ty = Type.void,3812 .fn_ret_ty = Type.void,
3794 .fn_ret_ty_ies = null,3813 .fn_ret_ty_ies = null,
3795 .owner_func_index = .none,
3796 .comptime_err_ret_trace = &comptime_err_ret_trace,3814 .comptime_err_ret_trace = &comptime_err_ret_trace,
3797 };3815 };
3798 defer sema.deinit();3816 defer sema.deinit();
37993817
3800 switch (resolution) {3818 (switch (resolution) {
3801 .fields => return sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),3819 .fields => sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),
3802 .inits => return sema.resolveStructFieldInits(ty),3820 .inits => sema.resolveStructFieldInits(ty),
3803 .alignment => return sema.resolveStructAlignment(ty.toIntern(), struct_obj),3821 .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3804 .layout => return sema.resolveStructLayout(ty),3822 .layout => sema.resolveStructLayout(ty),
3805 .full => return sema.resolveStructFully(ty),3823 .full => sema.resolveStructFully(ty),
3806 }3824 }) catch |err| switch (err) {
3825 error.AnalysisFail => {
3826 if (!zcu.failed_analysis.contains(owner)) {
3827 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3828 }
3829 return error.AnalysisFail;
3830 },
3831 error.OutOfMemory => |e| return e,
3832 };
3807}3833}
38083834
3809/// `ty` must be a union.3835/// `ty` must be a union.
...@@ -3816,7 +3842,11 @@ fn resolveUnionInner(...@@ -3816,7 +3842,11 @@ fn resolveUnionInner(
3816 const gpa = zcu.gpa;3842 const gpa = zcu.gpa;
38173843
3818 const union_obj = zcu.typeToUnion(ty).?;3844 const union_obj = zcu.typeToUnion(ty).?;
3819 const owner_decl_index = union_obj.decl;3845 const owner = InternPool.AnalUnit.wrap(.{ .cau = union_obj.cau });
3846
3847 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3848 return error.AnalysisFail;
3849 }
38203850
3821 var analysis_arena = std.heap.ArenaAllocator.init(gpa);3851 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3822 defer analysis_arena.deinit();3852 defer analysis_arena.deinit();
...@@ -3829,23 +3859,29 @@ fn resolveUnionInner(...@@ -3829,23 +3859,29 @@ fn resolveUnionInner(
3829 .gpa = gpa,3859 .gpa = gpa,
3830 .arena = analysis_arena.allocator(),3860 .arena = analysis_arena.allocator(),
3831 .code = undefined, // This ZIR will not be used.3861 .code = undefined, // This ZIR will not be used.
3832 .owner_decl = zcu.declPtr(owner_decl_index),3862 .owner = owner,
3833 .owner_decl_index = owner_decl_index,
3834 .func_index = .none,3863 .func_index = .none,
3835 .func_is_naked = false,3864 .func_is_naked = false,
3836 .fn_ret_ty = Type.void,3865 .fn_ret_ty = Type.void,
3837 .fn_ret_ty_ies = null,3866 .fn_ret_ty_ies = null,
3838 .owner_func_index = .none,
3839 .comptime_err_ret_trace = &comptime_err_ret_trace,3867 .comptime_err_ret_trace = &comptime_err_ret_trace,
3840 };3868 };
3841 defer sema.deinit();3869 defer sema.deinit();
38423870
3843 switch (resolution) {3871 (switch (resolution) {
3844 .fields => return sema.resolveTypeFieldsUnion(ty, union_obj),3872 .fields => sema.resolveTypeFieldsUnion(ty, union_obj),
3845 .alignment => return sema.resolveUnionAlignment(ty, union_obj),3873 .alignment => sema.resolveUnionAlignment(ty, union_obj),
3846 .layout => return sema.resolveUnionLayout(ty),3874 .layout => sema.resolveUnionLayout(ty),
3847 .full => return sema.resolveUnionFully(ty),3875 .full => sema.resolveUnionFully(ty),
3848 }3876 }) catch |err| switch (err) {
3877 error.AnalysisFail => {
3878 if (!zcu.failed_analysis.contains(owner)) {
3879 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3880 }
3881 return error.AnalysisFail;
3882 },
3883 error.OutOfMemory => |e| return e,
3884 };
3849}3885}
38503886
3851/// Fully resolves a simple type. This is usually a nop, but for builtin types with3887/// Fully resolves a simple type. This is usually a nop, but for builtin types with
...@@ -3945,6 +3981,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {...@@ -3945,6 +3981,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {
3945 });3981 });
3946}3982}
39473983
3984pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
3985 return switch (ip.indexToKey(ty.toIntern())) {
3986 .struct_type => ip.loadStructType(ty.toIntern()).name,
3987 .union_type => ip.loadUnionType(ty.toIntern()).name,
3988 .enum_type => ip.loadEnumType(ty.toIntern()).name,
3989 .opaque_type => ip.loadOpaqueType(ty.toIntern()).name,
3990 else => unreachable,
3991 };
3992}
3993
3948pub const @"u1": Type = .{ .ip_index = .u1_type };3994pub const @"u1": Type = .{ .ip_index = .u1_type };
3949pub const @"u8": Type = .{ .ip_index = .u8_type };3995pub const @"u8": Type = .{ .ip_index = .u8_type };
3950pub const @"u16": Type = .{ .ip_index = .u16_type };3996pub 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+835-843
...@@ -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;
...@@ -912,34 +898,37 @@ fn getFileRootStruct(...@@ -912,34 +898,37 @@ fn getFileRootStruct(
912 };898 };
913 errdefer wip_ty.cancel(ip, pt.tid);899 errdefer wip_ty.cancel(ip, pt.tid);
914900
901 wip_ty.setName(ip, try file.internFullyQualifiedName(pt));
902 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;
903 const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, namespace_index, wip_ty.index);
904
915 if (zcu.comp.incremental) {905 if (zcu.comp.incremental) {
916 try ip.addDependency(906 try ip.addDependency(
917 gpa,907 gpa,
918 InternPool.AnalUnit.wrap(.{ .decl = decl_index }),908 InternPool.AnalUnit.wrap(.{ .cau = new_cau_index }),
919 .{ .src_hash = tracked_inst },909 .{ .src_hash = tracked_inst },
920 );910 );
921 }911 }
922912
923 const decl = zcu.declPtr(decl_index);913 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 });914 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
931 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());915 zcu.setFileRootType(file_index, wip_ty.index);
916 return wip_ty.finish(ip, new_cau_index.toOptional(), namespace_index.toOptional());
932}917}
933918
934/// Re-analyze the root Decl of a file on an incremental update.919/// Re-analyze the root type of a file on an incremental update.
935/// If `type_outdated`, the struct type itself is considered outdated and is920/// If `type_outdated`, the struct type itself is considered outdated and is
936/// reconstructed at a new InternPool index. Otherwise, the namespace is just921/// reconstructed at a new InternPool index. Otherwise, the namespace is just
937/// re-analyzed. Returns whether the decl's tyval was invalidated.922/// re-analyzed. Returns whether the decl's tyval was invalidated.
923/// 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 {924fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool {
939 const zcu = pt.zcu;925 const zcu = pt.zcu;
940 const ip = &zcu.intern_pool;926 const ip = &zcu.intern_pool;
941 const file = zcu.fileByIndex(file_index);927 const file = zcu.fileByIndex(file_index);
942 const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?);928 const file_root_type = zcu.fileRootType(file_index);
929 const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu).unwrap().?;
930
931 assert(file_root_type != .none);
943932
944 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{933 log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{
945 file.mod.fully_qualified_name,934 file.mod.fully_qualified_name,
...@@ -948,33 +937,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:...@@ -948,33 +937,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
948 });937 });
949938
950 if (file.status != .success_zir) {939 if (file.status != .success_zir) {
951 if (decl.analysis == .file_failure) {940 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 }941 }
965942
966 assert(decl.has_tv);
967 assert(decl.owns_tv);
968
969 if (type_outdated) {943 if (type_outdated) {
970 // Invalidate the existing type, reusing the decl and namespace.944 // Invalidate the existing type, reusing its namespace.
971 const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?;945 const file_root_type_cau = ip.loadStructType(file_root_type).cau.unwrap().?;
972 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{946 ip.removeDependenciesForDepender(
973 .decl = file_root_decl,947 zcu.gpa,
974 }));948 InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }),
975 ip.remove(pt.tid, decl.val.toIntern());949 );
976 decl.val = undefined;950 ip.remove(pt.tid, file_root_type);
977 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);951 _ = try pt.createFileRootStruct(file_index, namespace_index);
978 return true;952 return true;
979 }953 }
980954
...@@ -994,7 +968,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:...@@ -994,7 +968,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
994 const decls = file.zir.bodySlice(extra_index, decls_len);968 const decls = file.zir.bodySlice(extra_index, decls_len);
995969
996 if (!type_outdated) {970 if (!type_outdated) {
997 try pt.scanNamespace(decl.src_namespace, decls, decl);971 try pt.scanNamespace(namespace_index, decls);
998 }972 }
999973
1000 return false;974 return false;
...@@ -1009,43 +983,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -1009,43 +983,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1009 const zcu = pt.zcu;983 const zcu = pt.zcu;
1010 const gpa = zcu.gpa;984 const gpa = zcu.gpa;
1011 const file = zcu.fileByIndex(file_index);985 const file = zcu.fileByIndex(file_index);
1012 assert(zcu.fileRootDecl(file_index) == .none);986 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;
1041987
1042 if (file.status != .success_zir) {988 if (file.status != .success_zir) {
1043 new_decl.analysis = .file_failure;989 return error.AnalysisFail;
1044 return;
1045 }990 }
1046 assert(file.zir_loaded);991 assert(file.zir_loaded);
1047992
1048 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);993 const new_namespace_index = try pt.createNamespace(.{
994 .parent = .none,
995 .owner_type = undefined, // set in `createFileRootStruct`
996 .file_scope = file_index,
997 });
998 const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index);
1049 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);999 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
10501000
1051 switch (zcu.comp.cache_use) {1001 switch (zcu.comp.cache_use) {
...@@ -1067,98 +1017,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -1067,98 +1017,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10671017
1068 whole.cache_manifest_mutex.lock();1018 whole.cache_manifest_mutex.lock();
1069 defer whole.cache_manifest_mutex.unlock();1019 defer whole.cache_manifest_mutex.unlock();
1070 try man.addFilePostContents(resolved_path, source.bytes, source.stat);1020 man.addFilePostContents(resolved_path, source.bytes, source.stat) catch |err| switch (err) {
1021 error.OutOfMemory => |e| return e,
1022 else => {
1023 try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)});
1024 return error.AnalysisFail;
1025 },
1026 };
1071 },1027 },
1072 .incremental => {},1028 .incremental => {},
1073 }1029 }
1074}1030}
10751031
1076fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {1032const SemaCauResult = packed struct {
1077 const tracy = trace(@src());1033 /// Whether the value of a `decl_val` of the corresponding Nav changed.
1078 defer tracy.end();1034 invalidate_decl_val: bool,
1035 /// Whether the type of a `decl_ref` of the corresponding Nav changed.
1036 invalidate_decl_ref: bool,
1037};
10791038
1039/// Performs semantic analysis on the given `Cau`, storing results to its owner `Nav` if needed.
1040/// If analysis fails, returns `error.AnalysisFail`, storing an error in `zcu.failed_analysis` unless
1041/// the error is transitive.
1042/// On success, returns information about whether the `Nav` value changed.
1043fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult {
1080 const zcu = pt.zcu;1044 const zcu = pt.zcu;
1081 const decl = zcu.declPtr(decl_index);1045 const gpa = zcu.gpa;
1082 const ip = &zcu.intern_pool;1046 const ip = &zcu.intern_pool;
10831047
1084 if (decl.getFileScope(zcu).status != .success_zir) {1048 const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index });
1085 return error.AnalysisFail;
1086 }
10871049
1088 assert(!zcu.declIsRoot(decl_index));1050 const cau = ip.getCau(cau_index);
1051 const inst_info = cau.zir_index.resolveFull(ip);
1052 const file = zcu.fileByIndex(inst_info.file);
1053 const zir = file.zir;
10891054
1090 if (decl.zir_decl_index == .none and decl.owns_tv) {1055 if (file.status != .success_zir) {
1091 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).1056 return error.AnalysisFail;
1092 return pt.semaAnonOwnerDecl(decl_index);
1093 }1057 }
10941058
1095 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});1059 // We are about to re-analyze this `Cau`; drop its depenndencies.
1096 log.debug("decl name '{}'", .{decl.fqn.fmt(ip)});1060 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
1097 defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)});
10981061
1099 const old_has_tv = decl.has_tv;1062 const builtin_type_target_index: InternPool.Index = switch (cau.owner.unwrap()) {
1100 // The following values are ignored if `!old_has_tv`1063 .none => ip_index: {
1101 const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined;1064 // `comptime` decl -- we will re-analyze its body.
1102 const old_val = decl.val;1065 // This declaration has no value so is definitely not a std.builtin type.
1103 const old_align = decl.alignment;1066 break :ip_index .none;
1104 const old_linksection = decl.@"linksection";1067 },
1105 const old_addrspace = decl.@"addrspace";1068 .type => |ty| {
1106 const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func|1069 // This is an incremental update, and this type is being re-analyzed because it is outdated.
1107 prev_func.analysisUnordered(ip).state == .inline_only1070 // The type must be recreated at a new `InternPool.Index`.
1108 else1071 // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed.
1109 false;1072 ip.remove(pt.tid, ty);
11101073 return .{
1111 const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip);1074 .invalidate_decl_val = true,
1075 .invalidate_decl_ref = true,
1076 };
1077 },
1078 .nav => |nav| ip_index: {
1079 // Other decl -- we will re-analyze its value.
1080 // This might be a type in `builtin.zig` -- check.
1081 if (file.mod != zcu.std_mod) break :ip_index .none;
1082 // We're in the std module.
1083 const nav_name = ip.getNav(nav).name;
1084 const std_file_imported = try pt.importPkg(zcu.std_mod);
1085 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
1086 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).?.unwrap().?);
1087 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
1088 const builtin_nav = ip.getNav(std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse break :ip_index .none);
1089 const builtin_namespace = switch (builtin_nav.status) {
1090 .unresolved => break :ip_index .none,
1091 .resolved => |r| Type.fromInterned(r.val).getNamespace(zcu).?.unwrap().?,
1092 };
1093 if (cau.namespace != builtin_namespace) break :ip_index .none;
1094 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
1095 for ([_][]const u8{
1096 "AtomicOrder",
1097 "AtomicRmwOp",
1098 "CallingConvention",
1099 "AddressSpace",
1100 "FloatMode",
1101 "ReduceOp",
1102 "CallModifier",
1103 "PrefetchOptions",
1104 "ExportOptions",
1105 "ExternOptions",
1106 "Type",
1107 }, [_]InternPool.Index{
1108 .atomic_order_type,
1109 .atomic_rmw_op_type,
1110 .calling_convention_type,
1111 .address_space_type,
1112 .float_mode_type,
1113 .reduce_op_type,
1114 .call_modifier_type,
1115 .prefetch_options_type,
1116 .export_options_type,
1117 .extern_options_type,
1118 .type_info_type,
1119 }) |type_name, type_ip| {
1120 if (nav_name.eqlSlice(type_name, ip)) break :ip_index type_ip;
1121 }
1122 break :ip_index .none;
1123 },
1124 };
11121125
1113 const gpa = zcu.gpa;1126 const is_usingnamespace = switch (cau.owner.unwrap()) {
1114 const zir = decl.getFileScope(zcu).zir;1127 .nav => |nav| ip.getNav(nav).is_usingnamespace,
11151128 .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 };1129 };
11581130
1159 zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));1131 log.debug("semaCau '{d}'", .{@intFromEnum(cau_index)});
11601132
1161 decl.analysis = .in_progress;1133 try zcu.analysis_in_progress.put(gpa, anal_unit, {});
1134 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
11621135
1163 var analysis_arena = std.heap.ArenaAllocator.init(gpa);1136 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
1164 defer analysis_arena.deinit();1137 defer analysis_arena.deinit();
...@@ -1171,224 +1144,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1171,224 +1144,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1171 .gpa = gpa,1144 .gpa = gpa,
1172 .arena = analysis_arena.allocator(),1145 .arena = analysis_arena.allocator(),
1173 .code = zir,1146 .code = zir,
1174 .owner_decl = decl,1147 .owner = anal_unit,
1175 .owner_decl_index = decl_index,
1176 .func_index = .none,1148 .func_index = .none,
1177 .func_is_naked = false,1149 .func_is_naked = false,
1178 .fn_ret_ty = Type.void,1150 .fn_ret_ty = Type.void,
1179 .fn_ret_ty_ies = null,1151 .fn_ret_ty_ies = null,
1180 .owner_func_index = .none,
1181 .comptime_err_ret_trace = &comptime_err_ret_trace,1152 .comptime_err_ret_trace = &comptime_err_ret_trace,
1182 .builtin_type_target_index = builtin_type_target_index,1153 .builtin_type_target_index = builtin_type_target_index,
1183 };1154 };
1184 defer sema.deinit();1155 defer sema.deinit();
11851156
1186 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.1157 // 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, .{1158 try sema.declareDependency(.{ .src_hash = cau.zir_index });
1188 .file = decl.getFileScopeIndex(zcu),
1189 .inst = decl_inst,
1190 }) });
11911159
1192 var block_scope: Sema.Block = .{1160 var block: Sema.Block = .{
1193 .parent = null,1161 .parent = null,
1194 .sema = &sema,1162 .sema = &sema,
1195 .namespace = decl.src_namespace,1163 .namespace = cau.namespace,
1196 .instructions = .{},1164 .instructions = .{},
1197 .inlining = null,1165 .inlining = null,
1198 .is_comptime = true,1166 .is_comptime = true,
1199 .src_base_inst = decl.zir_decl_index.unwrap().?,1167 .src_base_inst = cau.zir_index,
1200 .type_name_ctx = decl.name,1168 .type_name_ctx = switch (cau.owner.unwrap()) {
1169 .nav => |nav| ip.getNav(nav).fqn,
1170 .type => |ty| Type.fromInterned(ty).containerTypeName(ip),
1171 .none => try ip.getOrPutStringFmt(gpa, pt.tid, "{}.comptime", .{
1172 Type.fromInterned(zcu.namespacePtr(cau.namespace).owner_type).containerTypeName(ip).fmt(ip),
1173 }, .no_embedded_nulls),
1174 },
1175 };
1176 defer block.instructions.deinit(gpa);
1177
1178 const zir_decl: Zir.Inst.Declaration, const decl_bodies: Zir.Inst.Declaration.Bodies = decl: {
1179 const decl, const extra_end = zir.getDeclaration(inst_info.inst);
1180 break :decl .{ decl, decl.getBodies(extra_end, zir) };
1181 };
1182
1183 // We have to fetch this state before resolving the body because of the `nav_already_populated`
1184 // case below. We might change the language in future so that align/linksection/etc for functions
1185 // work in a way more in line with other declarations, in which case that logic will go away.
1186 const old_nav_info = switch (cau.owner.unwrap()) {
1187 .none, .type => undefined, // we'll never use `old_nav_info`
1188 .nav => |nav| ip.getNav(nav),
1201 };1189 };
1202 defer block_scope.instructions.deinit(gpa);
12031190
1204 const decl_bodies = decl.zirBodies(zcu);1191 const result_ref = try sema.resolveInlineBody(&block, decl_bodies.value_body, inst_info.inst);
12051192
1206 const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);1193 const nav_index = switch (cau.owner.unwrap()) {
1207 // We'll do some other bits with the Sema. Clear the type target index just1194 .none => {
1208 // in case they analyze any type.1195 // This is a `comptime` decl, so we are done -- the side effects are all we care about.
1196 // Just make sure to `flushExports`.
1197 try sema.flushExports();
1198 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1199 return .{
1200 .invalidate_decl_val = false,
1201 .invalidate_decl_ref = false,
1202 };
1203 },
1204 .nav => |nav| nav, // We will resolve this `Nav` below.
1205 .type => unreachable, // Handled at top of function.
1206 };
1207
1208 // We'll do more work with the Sema. Clear the target type index just in case we analyze any type.
1209 sema.builtin_type_target_index = .none;1209 sema.builtin_type_target_index = .none;
1210 const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 });1210
1211 const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 });1211 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 });1212 const section_src = block.src(.{ .node_offset_var_decl_section = 0 });
1213 const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 });1213 const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 });
1214 const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 });1214 const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
1215 const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);1215 const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
1216
1217 const decl_val = try sema.resolveFinalDeclValue(&block, init_src, result_ref);
1216 const decl_ty = decl_val.typeOf(zcu);1218 const decl_ty = decl_val.typeOf(zcu);
12171219
1218 // Note this resolves the type of the Decl, not the value; if this Decl1220 switch (decl_val.toIntern()) {
1219 // is a struct, for example, this resolves `type` (which needs no resolution),1221 .generic_poison => unreachable, // assertion failure
1220 // not the struct itself.1222 .unreachable_value => unreachable, // assertion failure
1223 else => {},
1224 }
1225
1226 // This resolves the type of the resolved value, not that value itself. If `decl_val` is a struct type,
1227 // this resolves the type `type` (which needs no resolution), not the struct itself.
1221 try decl_ty.resolveLayout(pt);1228 try decl_ty.resolveLayout(pt);
12221229
1223 if (decl.kind == .@"usingnamespace") {1230 // 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)) {1231 if (is_usingnamespace) {
1225 return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});1232 if (decl_ty.toIntern() != .type_type) {
1233 return sema.fail(&block, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)});
1226 }1234 }
1227 const ty = decl_val.toType();1235 if (decl_val.toType().getNamespace(zcu) == null) {
1228 if (ty.getNamespace(zcu) == null) {1236 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 }1237 }
12311238 ip.resolveNavValue(nav_index, .{
1232 decl.val = ty.toValue();1239 .val = decl_val.toIntern(),
1233 decl.alignment = .none;1240 .alignment = .none,
1234 decl.@"linksection" = .none;1241 .@"linksection" = .none,
1235 decl.has_tv = true;1242 .@"addrspace" = .generic,
1236 decl.owns_tv = false;1243 });
1237 decl.analysis = .complete;1244 // TODO: usingnamespace cannot participate in incremental compilation
12381245 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1239 // TODO: usingnamespace cannot currently participate in incremental compilation
1240 return .{1246 return .{
1241 .invalidate_decl_val = true,1247 .invalidate_decl_val = true,
1242 .invalidate_decl_ref = true,1248 .invalidate_decl_ref = true,
1243 };1249 };
1244 }1250 }
12451251
1246 var queue_linker_work = true;1252 const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) {
1247 var is_func = false;1253 .func => |f| .{ f.owner_nav == nav_index, false },
1248 var is_inline = false;1254 .variable => |v| .{ false, v.owner_nav == nav_index },
1249 switch (decl_val.toIntern()) {1255 .@"extern" => .{ false, false },
1250 .generic_poison => unreachable,1256 else => .{ false, true },
1251 .unreachable_value => unreachable,1257 };
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 }
12741258
1275 decl.val = decl_val;1259 if (nav_already_populated) {
1276 // Function linksection, align, and addrspace were already set by Sema1260 // This is a function declaration.
1277 if (!is_func) {1261 // Logic in `Sema.funcCommon` has already populated the `Nav` for us.
1278 decl.alignment = blk: {1262 assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern());
1279 const align_body = decl_bodies.align_body orelse break :blk .none;1263 } else {
1280 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);1264 // Keep in sync with logic in `Sema.zirVarExtended`.
1281 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);1265 const alignment: InternPool.Alignment = a: {
1266 const align_body = decl_bodies.align_body orelse break :a .none;
1267 const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst);
1268 break :a try sema.analyzeAsAlign(&block, align_src, align_ref);
1282 };1269 };
1283 decl.@"linksection" = blk: {1270
1284 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;1271 const @"linksection": InternPool.OptionalNullTerminatedString = ls: {
1285 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);1272 const linksection_body = decl_bodies.linksection_body orelse break :ls .none;
1286 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{1273 const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst);
1274 const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{
1287 .needed_comptime_reason = "linksection must be comptime-known",1275 .needed_comptime_reason = "linksection must be comptime-known",
1288 });1276 });
1289 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {1277 if (std.mem.indexOfScalar(u8, bytes, 0) != null) {
1290 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});1278 return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{});
1291 } else if (bytes.len == 0) {1279 } else if (bytes.len == 0) {
1292 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});1280 return sema.fail(&block, section_src, "linksection cannot be empty", .{});
1293 }1281 }
1294 break :blk try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);1282 break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls);
1295 };1283 };
1296 decl.@"addrspace" = blk: {1284
1285 const @"addrspace": std.builtin.AddressSpace = as: {
1297 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {1286 const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) {
1287 .func => .function,
1298 .variable => .variable,1288 .variable => .variable,
1299 .extern_func, .func => .function,1289 .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type)
1290 .function
1291 else
1292 .variable,
1300 else => .constant,1293 else => .constant,
1301 };1294 };
1302
1303 const target = zcu.getTarget();1295 const target = zcu.getTarget();
13041296 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),1297 .function => target_util.defaultAddressSpace(target, .function),
1307 .variable => target_util.defaultAddressSpace(target, .global_mutable),1298 .variable => target_util.defaultAddressSpace(target, .global_mutable),
1308 .constant => target_util.defaultAddressSpace(target, .global_constant),1299 .constant => target_util.defaultAddressSpace(target, .global_constant),
1309 else => unreachable,1300 else => unreachable,
1310 };1301 };
1311 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);1302 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);1303 break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx);
1313 };1304 };
1314 }
1315 decl.has_tv = true;
1316 decl.analysis = .complete;
1317
1318 const result: Zcu.SemaDeclResult = if (old_has_tv) .{
1319 .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or
1320 !decl.val.eql(old_val, decl_ty, zcu) or
1321 is_inline != old_is_inline,
1322 .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or
1323 decl.alignment != old_align or
1324 decl.@"linksection" != old_linksection or
1325 decl.@"addrspace" != old_addrspace or
1326 is_inline != old_is_inline,
1327 } else .{
1328 .invalidate_decl_val = true,
1329 .invalidate_decl_ref = true,
1330 };
1331
1332 const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty));
1333 if (has_runtime_bits) {
1334 // Needed for codegen_decl which will call updateDecl and then the
1335 // codegen backend wants full access to the Decl Type.
1336 try decl_ty.resolveFully(pt);
1337
1338 try zcu.comp.queueJob(.{ .codegen_decl = decl_index });
13391305
1340 if (result.invalidate_decl_ref and zcu.emit_h != null) {1306 ip.resolveNavValue(nav_index, .{
1341 try zcu.comp.queueJob(.{ .emit_h_decl = decl_index });1307 .val = decl_val.toIntern(),
1342 }1308 .alignment = alignment,
1309 .@"linksection" = @"linksection",
1310 .@"addrspace" = @"addrspace",
1311 });
1343 }1312 }
13441313
1345 if (decl.is_exported) {1314 // Mark the `Cau` as completed before evaluating the export!
1346 const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });1315 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1347 if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});1316
1348 // The scope needs to have the decl in it.1317 if (zir_decl.flags.is_export) {
1349 try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);1318 const export_src = block.src(.{ .token_offset = @intFromBool(zir_decl.flags.is_pub) });
1319 const name_slice = zir.nullTerminatedString(zir_decl.name.toString(zir).?);
1320 const name_ip = try ip.getOrPutString(gpa, pt.tid, name_slice, .no_embedded_nulls);
1321 try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_index);
1350 }1322 }
13511323
1352 try sema.flushExports();1324 try sema.flushExports();
13531325
1354 return result;1326 queue_codegen: {
1355}1327 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);
13601328
1361 assert(decl.has_tv);1329 // Needed for codegen_nav which will call updateDecl and then the
1362 assert(decl.owns_tv);1330 // codegen backend wants full access to the Decl Type.
1331 // We also need this for the `isFnOrHasRuntimeBits` check below.
1332 // TODO: we could make the language more lenient by deferring this work
1333 // to the `codegen_nav` job.
1334 try decl_ty.resolveFully(pt);
13631335
1364 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});1336 if (!decl_ty.isFnOrHasRuntimeBits(pt)) break :queue_codegen;
13651337
1366 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {1338 try zcu.comp.queueJob(.{ .codegen_nav = nav_index });
1367 .Fn => @panic("TODO: update fn instance"),
1368 .Type => {},
1369 else => unreachable,
1370 }1339 }
13711340
1372 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*1341 switch (old_nav_info.status) {
1373 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.1342 .unresolved => return .{
1374 //1343 .invalidate_decl_val = true,
1375 // However, as soon as we make that, the context that created us will require re-analysis anyway1344 .invalidate_decl_ref = true,
1376 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction1345 },
1377 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,1346 .resolved => |old| {
1378 // why should we bother implementing it here too when the Sema logic will be hit right after?1347 const new = ip.getNav(nav_index).status.resolved;
1379 //1348 return .{
1380 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely1349 .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 type1350 .invalidate_decl_ref = ip.typeOf(new.val) != ip.typeOf(old.val) or
1382 // with a new Decl.1351 new.alignment != old.alignment or
1383 //1352 new.@"linksection" != old.@"linksection" or
1384 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.1353 new.@"addrspace" != old.@"addrspace",
1385 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));1354 };
1386 zcu.intern_pool.remove(pt.tid, decl.val.toIntern());1355 },
1387 decl.analysis = .dependency_failure;1356 }
1388 return .{
1389 .invalidate_decl_val = true,
1390 .invalidate_decl_ref = true,
1391 };
1392}1357}
13931358
1394pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {1359pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
...@@ -1426,7 +1391,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {...@@ -1426,7 +1391,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1426 const file_index = try ip.createFile(gpa, pt.tid, .{1391 const file_index = try ip.createFile(gpa, pt.tid, .{
1427 .bin_digest = path_digest,1392 .bin_digest = path_digest,
1428 .file = builtin_file,1393 .file = builtin_file,
1429 .root_decl = .none,1394 .root_type = .none,
1430 });1395 });
1431 keep_resolved_path = true; // It's now owned by import_table.1396 keep_resolved_path = true; // It's now owned by import_table.
1432 gop.value_ptr.* = file_index;1397 gop.value_ptr.* = file_index;
...@@ -1453,7 +1418,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {...@@ -1453,7 +1418,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1453 const new_file_index = try ip.createFile(gpa, pt.tid, .{1418 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1454 .bin_digest = path_digest,1419 .bin_digest = path_digest,
1455 .file = new_file,1420 .file = new_file,
1456 .root_decl = .none,1421 .root_type = .none,
1457 });1422 });
1458 keep_resolved_path = true; // It's now owned by import_table.1423 keep_resolved_path = true; // It's now owned by import_table.
1459 gop.value_ptr.* = new_file_index;1424 gop.value_ptr.* = new_file_index;
...@@ -1563,7 +1528,7 @@ pub fn importFile(...@@ -1563,7 +1528,7 @@ pub fn importFile(
1563 const new_file_index = try ip.createFile(gpa, pt.tid, .{1528 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1564 .bin_digest = path_digest,1529 .bin_digest = path_digest,
1565 .file = new_file,1530 .file = new_file,
1566 .root_decl = .none,1531 .root_type = .none,
1567 });1532 });
1568 keep_resolved_path = true; // It's now owned by import_table.1533 keep_resolved_path = true; // It's now owned by import_table.
1569 gop.value_ptr.* = new_file_index;1534 gop.value_ptr.* = new_file_index;
...@@ -1726,7 +1691,7 @@ fn newEmbedFile(...@@ -1726,7 +1691,7 @@ fn newEmbedFile(
1726 })).toIntern();1691 })).toIntern();
1727 const ptr_val = try pt.intern(.{ .ptr = .{1692 const ptr_val = try pt.intern(.{ .ptr = .{
1728 .ty = ptr_ty,1693 .ty = ptr_ty,
1729 .base_addr = .{ .anon_decl = .{1694 .base_addr = .{ .uav = .{
1730 .val = array_val,1695 .val = array_val,
1731 .orig_ty = ptr_ty,1696 .orig_ty = ptr_ty,
1732 } },1697 } },
...@@ -1748,39 +1713,70 @@ pub fn scanNamespace(...@@ -1748,39 +1713,70 @@ pub fn scanNamespace(
1748 pt: Zcu.PerThread,1713 pt: Zcu.PerThread,
1749 namespace_index: Zcu.Namespace.Index,1714 namespace_index: Zcu.Namespace.Index,
1750 decls: []const Zir.Inst.Index,1715 decls: []const Zir.Inst.Index,
1751 parent_decl: *Zcu.Decl,
1752) Allocator.Error!void {1716) Allocator.Error!void {
1753 const tracy = trace(@src());1717 const tracy = trace(@src());
1754 defer tracy.end();1718 defer tracy.end();
17551719
1756 const zcu = pt.zcu;1720 const zcu = pt.zcu;
1721 const ip = &zcu.intern_pool;
1757 const gpa = zcu.gpa;1722 const gpa = zcu.gpa;
1758 const namespace = zcu.namespacePtr(namespace_index);1723 const namespace = zcu.namespacePtr(namespace_index);
17591724
1760 // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather1725 // 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`.1726 // than their name. We'll build an efficient mapping now, then discard the current `decls`.
1762 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index) = .{};1727 // We map to the `Cau`, since not every declaration has a `Nav`.
1728 var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index) = .{};
1763 defer existing_by_inst.deinit(gpa);1729 defer existing_by_inst.deinit(gpa);
17641730
1765 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count()));1731 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(
17661732 namespace.pub_decls.count() + namespace.priv_decls.count() +
1767 for (namespace.decls.keys()) |decl_index| {1733 namespace.pub_usingnamespace.items.len + namespace.priv_usingnamespace.items.len +
1768 const decl = zcu.declPtr(decl_index);1734 namespace.other_decls.items.len,
1769 existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index);1735 ));
1736
1737 for (namespace.pub_decls.keys()) |nav| {
1738 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1739 const zir_index = ip.getCau(cau_index).zir_index;
1740 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1741 }
1742 for (namespace.priv_decls.keys()) |nav| {
1743 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1744 const zir_index = ip.getCau(cau_index).zir_index;
1745 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1746 }
1747 for (namespace.pub_usingnamespace.items) |nav| {
1748 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1749 const zir_index = ip.getCau(cau_index).zir_index;
1750 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1751 }
1752 for (namespace.priv_usingnamespace.items) |nav| {
1753 const cau_index = ip.getNav(nav).analysis_owner.unwrap().?;
1754 const zir_index = ip.getCau(cau_index).zir_index;
1755 existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index);
1756 }
1757 for (namespace.other_decls.items) |cau_index| {
1758 const cau = ip.getCau(cau_index);
1759 existing_by_inst.putAssumeCapacityNoClobber(cau.zir_index, cau_index);
1760 // If this is a test, it'll be re-added to `test_functions` later on
1761 // if still alive. Remove it for now.
1762 switch (cau.owner.unwrap()) {
1763 .none, .type => {},
1764 .nav => |nav| _ = zcu.test_functions.swapRemove(nav),
1765 }
1770 }1766 }
17711767
1772 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};1768 var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
1773 defer seen_decls.deinit(gpa);1769 defer seen_decls.deinit(gpa);
17741770
1775 namespace.decls.clearRetainingCapacity();1771 namespace.pub_decls.clearRetainingCapacity();
1776 try namespace.decls.ensureTotalCapacity(gpa, decls.len);1772 namespace.priv_decls.clearRetainingCapacity();
17771773 namespace.pub_usingnamespace.clearRetainingCapacity();
1778 namespace.usingnamespace_set.clearRetainingCapacity();1774 namespace.priv_usingnamespace.clearRetainingCapacity();
1775 namespace.other_decls.clearRetainingCapacity();
17791776
1780 var scan_decl_iter: ScanDeclIter = .{1777 var scan_decl_iter: ScanDeclIter = .{
1781 .pt = pt,1778 .pt = pt,
1782 .namespace_index = namespace_index,1779 .namespace_index = namespace_index,
1783 .parent_decl = parent_decl,
1784 .seen_decls = &seen_decls,1780 .seen_decls = &seen_decls,
1785 .existing_by_inst = &existing_by_inst,1781 .existing_by_inst = &existing_by_inst,
1786 .pass = .named,1782 .pass = .named,
...@@ -1792,34 +1788,17 @@ pub fn scanNamespace(...@@ -1792,34 +1788,17 @@ pub fn scanNamespace(
1792 for (decls) |decl_inst| {1788 for (decls) |decl_inst| {
1793 try scan_decl_iter.scanDecl(decl_inst);1789 try scan_decl_iter.scanDecl(decl_inst);
1794 }1790 }
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}1791}
18111792
1812const ScanDeclIter = struct {1793const ScanDeclIter = struct {
1813 pt: Zcu.PerThread,1794 pt: Zcu.PerThread,
1814 namespace_index: Zcu.Namespace.Index,1795 namespace_index: Zcu.Namespace.Index,
1815 parent_decl: *Zcu.Decl,
1816 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),1796 seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
1817 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index),1797 existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index),
1818 /// Decl scanning is run in two passes, so that we can detect when a generated1798 /// 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.1799 /// name would clash with an explicit name and use a different one.
1820 pass: enum { named, unnamed },1800 pass: enum { named, unnamed },
1821 usingnamespace_index: usize = 0,1801 usingnamespace_index: usize = 0,
1822 comptime_index: usize = 0,
1823 unnamed_test_index: usize = 0,1802 unnamed_test_index: usize = 0,
18241803
1825 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {1804 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
...@@ -1843,37 +1822,35 @@ const ScanDeclIter = struct {...@@ -1843,37 +1822,35 @@ const ScanDeclIter = struct {
18431822
1844 const pt = iter.pt;1823 const pt = iter.pt;
1845 const zcu = pt.zcu;1824 const zcu = pt.zcu;
1825 const comp = zcu.comp;
1846 const namespace_index = iter.namespace_index;1826 const namespace_index = iter.namespace_index;
1847 const namespace = zcu.namespacePtr(namespace_index);1827 const namespace = zcu.namespacePtr(namespace_index);
1848 const gpa = zcu.gpa;1828 const gpa = zcu.gpa;
1849 const zir = namespace.fileScope(zcu).zir;1829 const file = namespace.fileScope(zcu);
1830 const zir = file.zir;
1850 const ip = &zcu.intern_pool;1831 const ip = &zcu.intern_pool;
18511832
1852 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;1833 const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration;
1853 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);1834 const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index);
1854 const declaration = extra.data;1835 const declaration = extra.data;
18551836
1856 // Every Decl needs a name.1837 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) {1838
1839 const maybe_name: InternPool.OptionalNullTerminatedString, const kind: Kind, const is_named_test: bool = switch (declaration.name) {
1858 .@"comptime" => info: {1840 .@"comptime" => info: {
1859 if (iter.pass != .unnamed) return;1841 if (iter.pass != .unnamed) return;
1860 const i = iter.comptime_index;
1861 iter.comptime_index += 1;
1862 break :info .{1842 break :info .{
1863 try iter.avoidNameConflict("comptime_{d}", .{i}),1843 .none,
1864 .@"comptime",1844 .@"comptime",
1865 false,1845 false,
1866 };1846 };
1867 },1847 },
1868 .@"usingnamespace" => info: {1848 .@"usingnamespace" => info: {
1869 // TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here.1849 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;1850 const i = iter.usingnamespace_index;
1874 iter.usingnamespace_index += 1;1851 iter.usingnamespace_index += 1;
1875 break :info .{1852 break :info .{
1876 try iter.avoidNameConflict("usingnamespace_{d}", .{i}),1853 (try iter.avoidNameConflict("usingnamespace_{d}", .{i})).toOptional(),
1877 .@"usingnamespace",1854 .@"usingnamespace",
1878 false,1855 false,
1879 };1856 };
...@@ -1883,7 +1860,7 @@ const ScanDeclIter = struct {...@@ -1883,7 +1860,7 @@ const ScanDeclIter = struct {
1883 const i = iter.unnamed_test_index;1860 const i = iter.unnamed_test_index;
1884 iter.unnamed_test_index += 1;1861 iter.unnamed_test_index += 1;
1885 break :info .{1862 break :info .{
1886 try iter.avoidNameConflict("test_{d}", .{i}),1863 (try iter.avoidNameConflict("test_{d}", .{i})).toOptional(),
1887 .@"test",1864 .@"test",
1888 false,1865 false,
1889 };1866 };
...@@ -1894,7 +1871,7 @@ const ScanDeclIter = struct {...@@ -1894,7 +1871,7 @@ const ScanDeclIter = struct {
1894 assert(declaration.flags.has_doc_comment);1871 assert(declaration.flags.has_doc_comment);
1895 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));1872 const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end]));
1896 break :info .{1873 break :info .{
1897 try iter.avoidNameConflict("decltest.{s}", .{name}),1874 (try iter.avoidNameConflict("decltest.{s}", .{name})).toOptional(),
1898 .@"test",1875 .@"test",
1899 true,1876 true,
1900 };1877 };
...@@ -1903,7 +1880,7 @@ const ScanDeclIter = struct {...@@ -1903,7 +1880,7 @@ const ScanDeclIter = struct {
1903 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.1880 // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary.
1904 if (iter.pass != .unnamed) return;1881 if (iter.pass != .unnamed) return;
1905 break :info .{1882 break :info .{
1906 try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}),1883 (try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)})).toOptional(),
1907 .@"test",1884 .@"test",
1908 true,1885 true,
1909 };1886 };
...@@ -1917,132 +1894,144 @@ const ScanDeclIter = struct {...@@ -1917,132 +1894,144 @@ const ScanDeclIter = struct {
1917 );1894 );
1918 try iter.seen_decls.putNoClobber(gpa, name, {});1895 try iter.seen_decls.putNoClobber(gpa, name, {});
1919 break :info .{1896 break :info .{
1920 name,1897 name.toOptional(),
1921 .named,1898 .named,
1922 false,1899 false,
1923 };1900 };
1924 },1901 },
1925 };1902 };
19261903
1927 switch (kind) {
1928 .@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1),
1929 .@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1),
1930 else => {},
1931 }
1932
1933 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
1934 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{1904 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
1935 .file = parent_file_scope_index,1905 .file = namespace.file_scope,
1936 .inst = decl_inst,1906 .inst = decl_inst,
1937 });1907 });
19381908
1939 // We create a Decl for it regardless of analysis status.1909 const existing_cau = iter.existing_by_inst.get(tracked_inst);
19401910
1941 const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: {1911 const cau, const want_analysis = switch (kind) {
1942 // We need only update this existing Decl.1912 .@"comptime" => cau: {
1943 const decl = zcu.declPtr(decl_index);1913 const cau = existing_cau orelse try ip.createComptimeCau(gpa, pt.tid, tracked_inst, namespace_index);
1944 const was_exported = decl.is_exported;1914
1945 assert(decl.kind == kind); // ZIR tracking should preserve this1915 // For a `comptime` declaration, whether to re-analyze is based solely on whether the
1946 decl.name = decl_name;1916 // `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);1917 const unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
1948 decl.is_pub = declaration.flags.is_pub;1918 if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| {
1949 decl.is_exported = declaration.flags.is_export;1919 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1950 break :decl_index .{ was_exported, decl_index };1920 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1951 } else decl_index: {1921 zcu.outdated.putAssumeCapacityNoClobber(unit, kv.value);
1952 // Create and set up a new Decl.1922 if (kv.value == 0) { // no PO deps
1953 const new_decl_index = try pt.allocateNewDecl(namespace_index);1923 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1954 const new_decl = zcu.declPtr(new_decl_index);1924 }
1955 new_decl.kind = kind;1925 } else if (!zcu.outdated.contains(unit)) {
1956 new_decl.name = decl_name;1926 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1957 new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);1927 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
1958 new_decl.is_pub = declaration.flags.is_pub;1928 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
1959 new_decl.is_exported = declaration.flags.is_export;1929 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
1960 new_decl.zir_decl_index = tracked_inst.toOptional();1930 }
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 });
19671931
1968 const comp = zcu.comp;1932 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 },1933 },
1977 .named => false,1934 else => cau: {
1978 .@"test" => a: {1935 const name = maybe_name.unwrap().?;
1979 if (!comp.config.is_test) break :a false;1936 const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name);
1980 if (decl_mod != zcu.main_mod) break :a false;1937 const cau, const nav = if (existing_cau) |cau_index| cau_nav: {
1981 if (is_named_test and comp.test_filters.len > 0) {1938 const nav_index = ip.getCau(cau_index).owner.unwrap().nav;
1982 const decl_fqn = decl.fqn.toSlice(ip);1939 const nav = ip.getNav(nav_index);
1983 for (comp.test_filters) |test_filter| {1940 assert(nav.name == name);
1984 if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break;1941 assert(nav.fqn == fqn);
1985 } else break :a false;1942 break :cau_nav .{ cau_index, nav_index };
1986 }1943 } 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 update1944 const want_analysis = switch (kind) {
1988 break :a true;1945 .@"comptime" => unreachable,
1946 .@"usingnamespace" => a: {
1947 if (declaration.flags.is_pub) {
1948 try namespace.pub_usingnamespace.append(gpa, nav);
1949 } else {
1950 try namespace.priv_usingnamespace.append(gpa, nav);
1951 }
1952 break :a true;
1953 },
1954 .@"test" => a: {
1955 try namespace.other_decls.append(gpa, cau);
1956 // TODO: incremental compilation!
1957 // * remove from `test_functions` if no longer matching filter
1958 // * add to `test_functions` if newly passing filter
1959 // This logic is unaware of incremental: we'll end up with duplicates.
1960 // Perhaps we should add all test indiscriminately and filter at the end of the update.
1961 if (!comp.config.is_test) break :a false;
1962 if (file.mod != zcu.main_mod) break :a false;
1963 if (is_named_test and comp.test_filters.len > 0) {
1964 const fqn_slice = fqn.toSlice(ip);
1965 for (comp.test_filters) |test_filter| {
1966 if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break;
1967 } else break :a false;
1968 }
1969 try zcu.test_functions.put(gpa, nav, {});
1970 break :a true;
1971 },
1972 .named => a: {
1973 if (declaration.flags.is_pub) {
1974 try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
1975 } else {
1976 try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
1977 }
1978 break :a false;
1979 },
1980 };
1981 break :cau .{ cau, want_analysis };
1989 },1982 },
1990 };1983 };
19911984
1992 if (want_analysis) {1985 if (want_analysis or declaration.flags.is_export) {
1993 // We will not queue analysis if the decl has been analyzed on a previous update and1986 log.debug(
1994 // `is_export` is unchanged. In this case, the incremental update mechanism will handle1987 "scanDecl queue analyze_cau file='{s}' cau_index={d}",
1995 // re-analysis for us if necessary.1988 .{ namespace.fileScope(zcu).sub_file_path, cau },
1996 if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) {1989 );
1997 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{1990 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 }1991 }
20031992
2004 if (decl.getOwnedFunction(zcu) != null) {1993 // 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 }1994 }
2012};1995};
20131996
2014/// Cancel the creation of an anon decl and delete any references to it.1997fn 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());1998 const tracy = trace(@src());
2030 defer tracy.end();1999 defer tracy.end();
20312000
2032 const mod = pt.zcu;2001 const zcu = pt.zcu;
2033 const gpa = mod.gpa;2002 const gpa = zcu.gpa;
2034 const ip = &mod.intern_pool;2003 const ip = &zcu.intern_pool;
2035 const func = mod.funcInfo(func_index);2004
2036 const decl_index = func.owner_decl;2005 const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index });
2037 const decl = mod.declPtr(decl_index);2006 const func = zcu.funcInfo(func_index);
2007 const inst_info = func.zir_body_inst.resolveFull(ip);
2008 const file = zcu.fileByIndex(inst_info.file);
2009 const zir = file.zir;
2010
2011 try zcu.analysis_in_progress.put(gpa, anal_unit, {});
2012 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
2013
2014 func.setAnalysisState(ip, .analyzed);
2015
2016 // This is the `Cau` corresponding to the `declaration` instruction which the function or its generic owner originates from.
2017 const decl_cau = ip.getCau(cau: {
2018 const orig_nav = if (func.generic_owner == .none)
2019 func.owner_nav
2020 else
2021 zcu.funcInfo(func.generic_owner).owner_nav;
2022
2023 break :cau ip.getNav(orig_nav).analysis_owner.unwrap().?;
2024 });
20382025
2039 log.debug("func name '{}'", .{decl.fqn.fmt(ip)});2026 const func_nav = ip.getNav(func.owner_nav);
2040 defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
20412027
2042 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);2028 const decl_prog_node = zcu.sema_prog_node.start(func_nav.fqn.toSlice(ip), 0);
2043 defer decl_prog_node.end();2029 defer decl_prog_node.end();
20442030
2045 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));2031 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
2032
2033 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
2034 defer analysis_arena.deinit();
20462035
2047 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);2036 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
2048 defer comptime_err_ret_trace.deinit();2037 defer comptime_err_ret_trace.deinit();
...@@ -2052,21 +2041,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2052,21 +2041,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2052 // the runtime-known parameters only, not to be confused with the2041 // the runtime-known parameters only, not to be confused with the
2053 // generic_owner function type, which potentially has more parameters,2042 // generic_owner function type, which potentially has more parameters,
2054 // including comptime parameters.2043 // including comptime parameters.
2055 const fn_ty = decl.typeOf(mod);2044 const fn_ty = Type.fromInterned(func.ty);
2056 const fn_ty_info = mod.typeToFunc(fn_ty).?;2045 const fn_ty_info = zcu.typeToFunc(fn_ty).?;
20572046
2058 var sema: Sema = .{2047 var sema: Sema = .{
2059 .pt = pt,2048 .pt = pt,
2060 .gpa = gpa,2049 .gpa = gpa,
2061 .arena = arena,2050 .arena = analysis_arena.allocator(),
2062 .code = decl.getFileScope(mod).zir,2051 .code = zir,
2063 .owner_decl = decl,2052 .owner = anal_unit,
2064 .owner_decl_index = decl_index,
2065 .func_index = func_index,2053 .func_index = func_index,
2066 .func_is_naked = fn_ty_info.cc == .Naked,2054 .func_is_naked = fn_ty_info.cc == .Naked,
2067 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),2055 .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type),
2068 .fn_ret_ty_ies = null,2056 .fn_ret_ty_ies = null,
2069 .owner_func_index = func_index,
2070 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),2057 .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota),
2071 .comptime_err_ret_trace = &comptime_err_ret_trace,2058 .comptime_err_ret_trace = &comptime_err_ret_trace,
2072 };2059 };
...@@ -2074,11 +2061,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2074,11 +2061,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
20742061
2075 // Every runtime function has a dependency on the source of the Decl it originates from.2062 // 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.2063 // It also depends on the value of its owner Decl.
2077 try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? });2064 try sema.declareDependency(.{ .src_hash = decl_cau.zir_index });
2078 try sema.declareDependency(.{ .decl_val = decl_index });2065 try sema.declareDependency(.{ .nav_val = func.owner_nav });
20792066
2080 if (func.analysisUnordered(ip).inferred_error_set) {2067 if (func.analysisUnordered(ip).inferred_error_set) {
2081 const ies = try arena.create(Sema.InferredErrorSet);2068 const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet);
2082 ies.* = .{ .func = func_index };2069 ies.* = .{ .func = func_index };
2083 sema.fn_ret_ty_ies = ies;2070 sema.fn_ret_ty_ies = ies;
2084 }2071 }
...@@ -2094,19 +2081,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2094,19 +2081,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2094 var inner_block: Sema.Block = .{2081 var inner_block: Sema.Block = .{
2095 .parent = null,2082 .parent = null,
2096 .sema = &sema,2083 .sema = &sema,
2097 .namespace = decl.src_namespace,2084 .namespace = decl_cau.namespace,
2098 .instructions = .{},2085 .instructions = .{},
2099 .inlining = null,2086 .inlining = null,
2100 .is_comptime = false,2087 .is_comptime = false,
2101 .src_base_inst = inst: {2088 .src_base_inst = decl_cau.zir_index,
2102 const owner_info = if (func.generic_owner == .none)2089 .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 };2090 };
2111 defer inner_block.instructions.deinit(gpa);2091 defer inner_block.instructions.deinit(gpa);
21122092
...@@ -2144,10 +2124,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2144,10 +2124,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2144 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);2124 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
2145 if (gop.found_existing) continue; // provided above by comptime arg2125 if (gop.found_existing) continue; // provided above by comptime arg
21462126
2147 const inst_info = sema.code.instructions.get(@intFromEnum(inst));2127 const param_inst_info = sema.code.instructions.get(@intFromEnum(inst));
2148 const param_name: Zir.NullTerminatedString = switch (inst_info.tag) {2128 const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) {
2149 .param_anytype => inst_info.data.str_tok.start,2129 .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,2130 .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name,
2151 else => unreachable,2131 else => unreachable,
2152 };2132 };
21532133
...@@ -2179,8 +2159,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2179,8 +2159,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2179 });2159 });
2180 }2160 }
21812161
2182 func.setAnalysisState(ip, .in_progress);
2183
2184 const last_arg_index = inner_block.instructions.items.len;2162 const last_arg_index = inner_block.instructions.items.len;
21852163
2186 // Save the error trace as our first action in the function.2164 // Save the error trace as our first action in the function.
...@@ -2190,9 +2168,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2190,9 +2168,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2190 inner_block.error_return_trace_index = error_return_trace_index;2168 inner_block.error_return_trace_index = error_return_trace_index;
21912169
2192 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {2170 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
2193 // TODO make these unreachable instead of @panic2171 error.GenericPoison => unreachable,
2194 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),2172 error.ComptimeReturn => unreachable,
2195 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
2196 else => |e| return e,2173 else => |e| return e,
2197 };2174 };
21982175
...@@ -2207,14 +2184,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2207,14 +2184,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
22072184
2208 // If we don't get an error return trace from a caller, create our own.2185 // 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 and2186 if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and
2210 mod.comp.config.any_error_tracing and2187 zcu.comp.config.any_error_tracing and
2211 !sema.fn_ret_ty.isError(mod))2188 !sema.fn_ret_ty.isError(zcu))
2212 {2189 {
2213 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {2190 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
2214 // TODO make these unreachable instead of @panic2191 error.GenericPoison => unreachable,
2215 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),2192 error.ComptimeReturn => unreachable,
2216 error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),2193 error.ComptimeBreak => unreachable,
2217 error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
2218 else => |e| return e,2194 else => |e| return e,
2219 };2195 };
2220 }2196 }
...@@ -2239,35 +2215,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -2239,35 +2215,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
2239 error.GenericPoison => unreachable,2215 error.GenericPoison => unreachable,
2240 error.ComptimeReturn => unreachable,2216 error.ComptimeReturn => unreachable,
2241 error.ComptimeBreak => unreachable,2217 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,2218 else => |e| return e,
2249 };2219 };
2250 assert(ies.resolved != .none);2220 assert(ies.resolved != .none);
2251 ip.funcSetIesResolved(func_index, ies.resolved);2221 ip.funcSetIesResolved(func_index, ies.resolved);
2252 }2222 }
22532223
2254 func.setAnalysisState(ip, .success);2224 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
22552225
2256 // Finally we must resolve the return type and parameter types so that backends2226 // Finally we must resolve the return type and parameter types so that backends
2257 // have full access to type information.2227 // have full access to type information.
2258 // Crucially, this happens *after* we set the function state to success above,2228 // 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 than2229 // so that dependencies on the function body will now be satisfied rather than
2260 // result in circular dependency errors.2230 // result in circular dependency errors.
2231 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
2232 // The codegen timing guarantees that the parameter types will be populated.
2261 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {2233 sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
2262 error.GenericPoison => unreachable,2234 error.GenericPoison => unreachable,
2263 error.ComptimeReturn => unreachable,2235 error.ComptimeReturn => unreachable,
2264 error.ComptimeBreak => unreachable,2236 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,2237 else => |e| return e,
2272 };2238 };
22732239
...@@ -2287,36 +2253,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index)...@@ -2287,36 +2253,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index)
2287 return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index);2253 return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index);
2288}2254}
22892255
2290pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.Decl.Index {
2291 const zcu = pt.zcu;
2292 const gpa = zcu.gpa;
2293 const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{
2294 .name = undefined,
2295 .fqn = undefined,
2296 .src_namespace = namespace,
2297 .has_tv = false,
2298 .owns_tv = false,
2299 .val = undefined,
2300 .alignment = undefined,
2301 .@"linksection" = .none,
2302 .@"addrspace" = .generic,
2303 .analysis = .unreferenced,
2304 .zir_decl_index = .none,
2305 .is_pub = false,
2306 .is_exported = false,
2307 .kind = .anon,
2308 });
2309
2310 if (zcu.emit_h) |zcu_emit_h| {
2311 if (@intFromEnum(decl_index) >= zcu_emit_h.allocated_emit_h.len) {
2312 try zcu_emit_h.allocated_emit_h.append(gpa, .{});
2313 assert(@intFromEnum(decl_index) == zcu_emit_h.allocated_emit_h.len);
2314 }
2315 }
2316
2317 return decl_index;
2318}
2319
2320pub fn getErrorValue(2256pub fn getErrorValue(
2321 pt: Zcu.PerThread,2257 pt: Zcu.PerThread,
2322 name: InternPool.NullTerminatedString,2258 name: InternPool.NullTerminatedString,
...@@ -2328,25 +2264,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err...@@ -2328,25 +2264,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));2264 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
2329}2265}
23302266
2331pub fn initNewAnonDecl(
2332 pt: Zcu.PerThread,
2333 new_decl_index: Zcu.Decl.Index,
2334 val: Value,
2335 name: InternPool.NullTerminatedString,
2336 fqn: InternPool.OptionalNullTerminatedString,
2337) Allocator.Error!void {
2338 const new_decl = pt.zcu.declPtr(new_decl_index);
2339
2340 new_decl.name = name;
2341 new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
2342 .internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
2343 new_decl.val = val;
2344 new_decl.alignment = .none;
2345 new_decl.@"linksection" = .none;
2346 new_decl.has_tv = true;
2347 new_decl.analysis = .complete;
2348}
2349
2350fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {2267fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
2351 switch (file.status) {2268 switch (file.status) {
2352 .success_zir, .retryable_failure => {},2269 .success_zir, .retryable_failure => {},
...@@ -2367,35 +2284,35 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -2367,35 +2284,35 @@ pub fn processExports(pt: Zcu.PerThread) !void {
2367 const zcu = pt.zcu;2284 const zcu = pt.zcu;
2368 const gpa = zcu.gpa;2285 const gpa = zcu.gpa;
23692286
2370 // First, construct a mapping of every exported value and Decl to the indices of all its different exports.2287 // 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)) = .{};2288 var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .{};
2372 var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};2289 var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{};
2373 defer {2290 defer {
2374 for (decl_exports.values()) |*exports| {2291 for (nav_exports.values()) |*exports| {
2375 exports.deinit(gpa);2292 exports.deinit(gpa);
2376 }2293 }
2377 decl_exports.deinit(gpa);2294 nav_exports.deinit(gpa);
2378 for (value_exports.values()) |*exports| {2295 for (uav_exports.values()) |*exports| {
2379 exports.deinit(gpa);2296 exports.deinit(gpa);
2380 }2297 }
2381 value_exports.deinit(gpa);2298 uav_exports.deinit(gpa);
2382 }2299 }
23832300
2384 // We note as a heuristic:2301 // We note as a heuristic:
2385 // * It is rare to export a value.2302 // * It is rare to export a value.
2386 // * It is rare for one Decl to be exported multiple times.2303 // * It is rare for one Nav to be exported multiple times.
2387 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.2304 // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization.
2388 try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());2305 try nav_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
23892306
2390 for (zcu.single_exports.values()) |export_idx| {2307 for (zcu.single_exports.values()) |export_idx| {
2391 const exp = zcu.all_exports.items[export_idx];2308 const exp = zcu.all_exports.items[export_idx];
2392 const value_ptr, const found_existing = switch (exp.exported) {2309 const value_ptr, const found_existing = switch (exp.exported) {
2393 .decl_index => |i| gop: {2310 .nav => |nav| gop: {
2394 const gop = try decl_exports.getOrPut(gpa, i);2311 const gop = try nav_exports.getOrPut(gpa, nav);
2395 break :gop .{ gop.value_ptr, gop.found_existing };2312 break :gop .{ gop.value_ptr, gop.found_existing };
2396 },2313 },
2397 .value => |i| gop: {2314 .uav => |uav| gop: {
2398 const gop = try value_exports.getOrPut(gpa, i);2315 const gop = try uav_exports.getOrPut(gpa, uav);
2399 break :gop .{ gop.value_ptr, gop.found_existing };2316 break :gop .{ gop.value_ptr, gop.found_existing };
2400 },2317 },
2401 };2318 };
...@@ -2406,12 +2323,12 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -2406,12 +2323,12 @@ pub fn processExports(pt: Zcu.PerThread) !void {
2406 for (zcu.multi_exports.values()) |info| {2323 for (zcu.multi_exports.values()) |info| {
2407 for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| {2324 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) {2325 const value_ptr, const found_existing = switch (exp.exported) {
2409 .decl_index => |i| gop: {2326 .nav => |nav| gop: {
2410 const gop = try decl_exports.getOrPut(gpa, i);2327 const gop = try nav_exports.getOrPut(gpa, nav);
2411 break :gop .{ gop.value_ptr, gop.found_existing };2328 break :gop .{ gop.value_ptr, gop.found_existing };
2412 },2329 },
2413 .value => |i| gop: {2330 .uav => |uav| gop: {
2414 const gop = try value_exports.getOrPut(gpa, i);2331 const gop = try uav_exports.getOrPut(gpa, uav);
2415 break :gop .{ gop.value_ptr, gop.found_existing };2332 break :gop .{ gop.value_ptr, gop.found_existing };
2416 },2333 },
2417 };2334 };
...@@ -2424,13 +2341,13 @@ pub fn processExports(pt: Zcu.PerThread) !void {...@@ -2424,13 +2341,13 @@ pub fn processExports(pt: Zcu.PerThread) !void {
2424 var symbol_exports: SymbolExports = .{};2341 var symbol_exports: SymbolExports = .{};
2425 defer symbol_exports.deinit(gpa);2342 defer symbol_exports.deinit(gpa);
24262343
2427 for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| {2344 for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| {
2428 const exported: Zcu.Exported = .{ .decl_index = exported_decl };2345 const exported: Zcu.Exported = .{ .nav = exported_nav };
2429 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);2346 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
2430 }2347 }
24312348
2432 for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| {2349 for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| {
2433 const exported: Zcu.Exported = .{ .value = exported_value };2350 const exported: Zcu.Exported = .{ .uav = exported_uav };
2434 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);2351 try pt.processExportsInner(&symbol_exports, exported, exports_list.items);
2435 }2352 }
2436}2353}
...@@ -2467,20 +2384,31 @@ fn processExportsInner(...@@ -2467,20 +2384,31 @@ fn processExportsInner(
2467 }2384 }
24682385
2469 switch (exported) {2386 switch (exported) {
2470 .decl_index => |idx| if (failed: {2387 .nav => |nav_index| if (failed: {
2471 const decl = zcu.declPtr(idx);2388 const nav = ip.getNav(nav_index);
2472 if (decl.analysis != .complete) break :failed true;2389 if (zcu.failed_codegen.contains(nav_index)) break :failed true;
2473 // Check if has owned function2390 if (nav.analysis_owner.unwrap()) |cau| {
2474 if (!decl.owns_tv) break :failed false;2391 const cau_unit = InternPool.AnalUnit.wrap(.{ .cau = cau });
2475 if (decl.typeOf(zcu).zigTypeTag(zcu) != .Fn) break :failed false;2392 if (zcu.failed_analysis.contains(cau_unit)) break :failed true;
2476 // Check if owned function failed2393 if (zcu.transitive_failed_analysis.contains(cau_unit)) break :failed true;
2477 break :failed zcu.funcInfo(decl.val.toIntern()).analysisUnordered(ip).state != .success;2394 }
2395 const val = switch (nav.status) {
2396 .unresolved => break :failed true,
2397 .resolved => |r| Value.fromInterned(r.val),
2398 };
2399 // If the value is a function, we also need to check if that function succeeded analysis.
2400 if (val.typeOf(zcu).zigTypeTag(zcu) == .Fn) {
2401 const func_unit = InternPool.AnalUnit.wrap(.{ .func = val.toIntern() });
2402 if (zcu.failed_analysis.contains(func_unit)) break :failed true;
2403 if (zcu.transitive_failed_analysis.contains(func_unit)) break :failed true;
2404 }
2405 break :failed false;
2478 }) {2406 }) {
2479 // This `Decl` is failed, so was never sent to codegen.2407 // 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`?2408 // TODO: we should probably tell the backend to delete any old exports of this `Decl`?
2481 return;2409 return;
2482 },2410 },
2483 .value => {},2411 .uav => {},
2484 }2412 }
24852413
2486 if (zcu.comp.bin_file) |lf| {2414 if (zcu.comp.bin_file) |lf| {
...@@ -2499,46 +2427,49 @@ pub fn populateTestFunctions(...@@ -2499,46 +2427,49 @@ pub fn populateTestFunctions(
2499 const ip = &zcu.intern_pool;2427 const ip = &zcu.intern_pool;
2500 const builtin_mod = zcu.root_mod.getBuiltinDependency();2428 const builtin_mod = zcu.root_mod.getBuiltinDependency();
2501 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;2429 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
2502 const root_decl_index = zcu.fileRootDecl(builtin_file_index);2430 pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) {
2503 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);2431 error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt
2504 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);2432 error.OutOfMemory => |e| return e,
2505 const test_functions_str = try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls);2433 };
2506 const decl_index = builtin_namespace.decls.getKeyAdapted(2434 const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index));
2507 test_functions_str,2435 const builtin_namespace = builtin_root_type.getNamespace(zcu).?.unwrap().?;
2508 Zcu.DeclAdapter{ .zcu = zcu },2436 const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted(
2437 try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls),
2438 Zcu.Namespace.NameAdapter{ .zcu = zcu },
2509 ).?;2439 ).?;
2510 {2440 {
2511 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`2441 // We have to call `ensureCauAnalyzed` here in case `builtin.test_functions`
2512 // was not referenced by start code.2442 // was not referenced by start code.
2513 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);2443 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
2514 defer {2444 defer {
2515 zcu.sema_prog_node.end();2445 zcu.sema_prog_node.end();
2516 zcu.sema_prog_node = std.Progress.Node.none;2446 zcu.sema_prog_node = std.Progress.Node.none;
2517 }2447 }
2518 try pt.ensureDeclAnalyzed(decl_index);2448 const cau_index = ip.getNav(nav_index).analysis_owner.unwrap().?;
2449 try pt.ensureCauAnalyzed(cau_index);
2519 }2450 }
25202451
2521 const decl = zcu.declPtr(decl_index);2452 const test_fns_val = zcu.navValue(nav_index);
2522 const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);2453 const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu);
25232454
2524 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: {2455 const array_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = array: {
2525 // Add zcu.test_functions to an array decl then make the test_functions2456 // Add zcu.test_functions to an array decl then make the test_functions
2526 // decl reference it as a slice.2457 // decl reference it as a slice.
2527 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());2458 const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count());
2528 defer gpa.free(test_fn_vals);2459 defer gpa.free(test_fn_vals);
25292460
2530 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {2461 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_nav_index| {
2531 const test_decl = zcu.declPtr(test_decl_index);2462 const test_nav = ip.getNav(test_nav_index);
2532 const test_decl_name = test_decl.fqn;2463 const test_nav_name = test_nav.fqn;
2533 const test_decl_name_len = test_decl_name.length(ip);2464 const test_nav_name_len = test_nav_name.length(ip);
2534 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {2465 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = n: {
2535 const test_name_ty = try pt.arrayType(.{2466 const test_name_ty = try pt.arrayType(.{
2536 .len = test_decl_name_len,2467 .len = test_nav_name_len,
2537 .child = .u8_type,2468 .child = .u8_type,
2538 });2469 });
2539 const test_name_val = try pt.intern(.{ .aggregate = .{2470 const test_name_val = try pt.intern(.{ .aggregate = .{
2540 .ty = test_name_ty.toIntern(),2471 .ty = test_name_ty.toIntern(),
2541 .storage = .{ .bytes = test_decl_name.toString() },2472 .storage = .{ .bytes = test_nav_name.toString() },
2542 } });2473 } });
2543 break :n .{2474 break :n .{
2544 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),2475 .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(),
...@@ -2552,23 +2483,18 @@ pub fn populateTestFunctions(...@@ -2552,23 +2483,18 @@ pub fn populateTestFunctions(
2552 .ty = .slice_const_u8_type,2483 .ty = .slice_const_u8_type,
2553 .ptr = try pt.intern(.{ .ptr = .{2484 .ptr = try pt.intern(.{ .ptr = .{
2554 .ty = .manyptr_const_u8_type,2485 .ty = .manyptr_const_u8_type,
2555 .base_addr = .{ .anon_decl = test_name_anon_decl },2486 .base_addr = .{ .uav = test_name_anon_decl },
2556 .byte_offset = 0,2487 .byte_offset = 0,
2557 } }),2488 } }),
2558 .len = try pt.intern(.{ .int = .{2489 .len = try pt.intern(.{ .int = .{
2559 .ty = .usize_type,2490 .ty = .usize_type,
2560 .storage = .{ .u64 = test_decl_name_len },2491 .storage = .{ .u64 = test_nav_name_len },
2561 } }),2492 } }),
2562 } }),2493 } }),
2563 // func2494 // func
2564 try pt.intern(.{ .ptr = .{2495 try pt.intern(.{ .ptr = .{
2565 .ty = try pt.intern(.{ .ptr_type = .{2496 .ty = (try pt.navPtrType(test_nav_index)).toIntern(),
2566 .child = test_decl.typeOf(zcu).toIntern(),2497 .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,2498 .byte_offset = 0,
2573 } }),2499 } }),
2574 };2500 };
...@@ -2601,22 +2527,16 @@ pub fn populateTestFunctions(...@@ -2601,22 +2527,16 @@ pub fn populateTestFunctions(
2601 .size = .Slice,2527 .size = .Slice,
2602 },2528 },
2603 });2529 });
2604 const new_val = decl.val;
2605 const new_init = try pt.intern(.{ .slice = .{2530 const new_init = try pt.intern(.{ .slice = .{
2606 .ty = new_ty.toIntern(),2531 .ty = new_ty.toIntern(),
2607 .ptr = try pt.intern(.{ .ptr = .{2532 .ptr = try pt.intern(.{ .ptr = .{
2608 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),2533 .ty = new_ty.slicePtrFieldType(zcu).toIntern(),
2609 .base_addr = .{ .anon_decl = array_anon_decl },2534 .base_addr = .{ .uav = array_anon_decl },
2610 .byte_offset = 0,2535 .byte_offset = 0,
2611 } }),2536 } }),
2612 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),2537 .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(),
2613 } });2538 } });
2614 ip.mutateVarInit(decl.val.toIntern(), new_init);2539 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 }2540 }
2621 {2541 {
2622 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);2542 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
...@@ -2625,40 +2545,45 @@ pub fn populateTestFunctions(...@@ -2625,40 +2545,45 @@ pub fn populateTestFunctions(
2625 zcu.codegen_prog_node = std.Progress.Node.none;2545 zcu.codegen_prog_node = std.Progress.Node.none;
2626 }2546 }
26272547
2628 try pt.linkerUpdateDecl(decl_index);2548 try pt.linkerUpdateNav(nav_index);
2629 }2549 }
2630}2550}
26312551
2632pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {2552pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
2633 const zcu = pt.zcu;2553 const zcu = pt.zcu;
2634 const comp = zcu.comp;2554 const comp = zcu.comp;
26352555
2636 const decl = zcu.declPtr(decl_index);2556 const nav = zcu.intern_pool.getNav(nav_index);
26372557 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();2558 defer codegen_prog_node.end();
26402559
2641 if (comp.bin_file) |lf| {2560 if (comp.bin_file) |lf| {
2642 lf.updateDecl(pt, decl_index) catch |err| switch (err) {2561 lf.updateNav(pt, nav_index) catch |err| switch (err) {
2643 error.OutOfMemory => return error.OutOfMemory,2562 error.OutOfMemory => return error.OutOfMemory,
2644 error.AnalysisFail => {2563 error.AnalysisFail => {
2645 decl.analysis = .codegen_failure;2564 assert(zcu.failed_codegen.contains(nav_index));
2646 },2565 },
2647 else => {2566 else => {
2648 const gpa = zcu.gpa;2567 const gpa = zcu.gpa;
2649 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);2568 try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1);
2650 zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create(2569 zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, try Zcu.ErrorMsg.create(
2651 gpa,2570 gpa,
2652 decl.navSrcLoc(zcu),2571 zcu.navSrcLoc(nav_index),
2653 "unable to codegen: {s}",2572 "unable to codegen: {s}",
2654 .{@errorName(err)},2573 .{@errorName(err)},
2655 ));2574 ));
2656 decl.analysis = .codegen_failure;2575 if (nav.analysis_owner.unwrap()) |cau| {
2657 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));2576 try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .cau = cau }));
2577 } else {
2578 // TODO: we don't have a way to indicate that this failure is retryable!
2579 // Since these are really rare, we could as a cop-out retry the whole build next update.
2580 // But perhaps we can do better...
2581 @panic("TODO: retryable failure codegenning non-declaration Nav");
2582 }
2658 },2583 },
2659 };2584 };
2660 } else if (zcu.llvm_object) |llvm_object| {2585 } else if (zcu.llvm_object) |llvm_object| {
2661 llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) {2586 llvm_object.updateNav(pt, nav_index) catch |err| switch (err) {
2662 error.OutOfMemory => return error.OutOfMemory,2587 error.OutOfMemory => return error.OutOfMemory,
2663 };2588 };
2664 }2589 }
...@@ -2750,9 +2675,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool...@@ -2750,9 +2675,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);2675 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
2751}2676}
27522677
2753/// Shortcut for calling `intern_pool.getCoerced`.2678/// Essentially a shortcut for calling `intern_pool.getCoerced`.
2679/// However, this function also allows coercing `extern`s. The `InternPool` function can't do
2680/// this because it requires potentially pushing to the job queue.
2754pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {2681pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {
2755 return Value.fromInterned(try pt.zcu.intern_pool.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));2682 const ip = &pt.zcu.intern_pool;
2683 switch (ip.indexToKey(val.toIntern())) {
2684 .@"extern" => |e| {
2685 const coerced = try pt.getExtern(.{
2686 .name = e.name,
2687 .ty = new_ty.toIntern(),
2688 .lib_name = e.lib_name,
2689 .is_const = e.is_const,
2690 .is_threadlocal = e.is_threadlocal,
2691 .is_weak_linkage = e.is_weak_linkage,
2692 .alignment = e.alignment,
2693 .@"addrspace" = e.@"addrspace",
2694 .zir_index = e.zir_index,
2695 .owner_nav = undefined, // ignored by `getExtern`.
2696 });
2697 return Value.fromInterned(coerced);
2698 },
2699 else => {},
2700 }
2701 return Value.fromInterned(try ip.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern()));
2756}2702}
27572703
2758pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {2704pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
...@@ -3237,24 +3183,29 @@ pub fn structPackedFieldBitOffset(...@@ -3237,24 +3183,29 @@ pub fn structPackedFieldBitOffset(
3237}3183}
32383184
3239pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {3185pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {
3240 const decl_index = try pt.getBuiltinDecl(name);3186 const zcu = pt.zcu;
3241 pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");3187 const ip = &zcu.intern_pool;
3242 return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern());3188 const nav = try pt.getBuiltinNav(name);
3189 pt.ensureCauAnalyzed(ip.getNav(nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3190 return Air.internedToRef(ip.getNav(nav).status.resolved.val);
3243}3191}
32443192
3245pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex {3193pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
3246 const zcu = pt.zcu;3194 const zcu = pt.zcu;
3247 const gpa = zcu.gpa;3195 const gpa = zcu.gpa;
3248 const ip = &zcu.intern_pool;3196 const ip = &zcu.intern_pool;
3249 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");3197 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().?;3198 const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index));
3251 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;3199 const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).?.unwrap().?);
3252 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);3200 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'");3201 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");3202 @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");3203 pt.ensureCauAnalyzed(ip.getNav(builtin_nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3204 const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.resolved.val);
3205 const builtin_namespace_index = (if (builtin_type.getNamespace(zcu)) |n| n.unwrap() else null) orelse @panic("std.builtin is corrupt");
3206 const builtin_namespace = zcu.namespacePtr(builtin_namespace_index);
3256 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);3207 const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3257 return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");3208 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3258}3209}
32593210
3260pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {3211pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {
...@@ -3264,6 +3215,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type...@@ -3264,6 +3215,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type
3264 return ty;3215 return ty;
3265}3216}
32663217
3218pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator.Error!Type {
3219 const zcu = pt.zcu;
3220 const ip = &zcu.intern_pool;
3221 const r = ip.getNav(nav_index).status.resolved;
3222 const ty = Value.fromInterned(r.val).typeOf(zcu);
3223 return pt.ptrType(.{
3224 .child = ty.toIntern(),
3225 .flags = .{
3226 .alignment = if (r.alignment == ty.abiAlignment(pt))
3227 .none
3228 else
3229 r.alignment,
3230 .address_space = r.@"addrspace",
3231 .is_const = switch (ip.indexToKey(r.val)) {
3232 .variable => false,
3233 .@"extern" => |e| e.is_const,
3234 else => true,
3235 },
3236 },
3237 });
3238}
3239
3240/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
3241/// If necessary, the new `Nav` is queued for codegen.
3242/// `key.owner_nav` is ignored and may be `undefined`.
3243pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!InternPool.Index {
3244 const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key);
3245 if (result.new_nav.unwrap()) |nav| {
3246 try pt.zcu.comp.queueJob(.{ .codegen_nav = nav });
3247 }
3248 return result.index;
3249}
3250
3251// TODO: this shouldn't need a `PerThread`! Fix the signature of `Type.abiAlignment`.
3252pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPool.Alignment {
3253 const zcu = pt.zcu;
3254 const r = zcu.intern_pool.getNav(nav_index).status.resolved;
3255 if (r.alignment != .none) return r.alignment;
3256 return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(pt);
3257}
3258
3267const Air = @import("../Air.zig");3259const Air = @import("../Air.zig");
3268const Allocator = std.mem.Allocator;3260const Allocator = std.mem.Allocator;
3269const assert = std.debug.assert;3261const 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+409-439
...@@ -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).unwrap().?);
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.namespacePtrUnwrap(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