| author | |
| committer | |
| log | 548a087fafeda5b07d2237d5137906b8d07da699 |
| tree | 69135f129b84ab5b65f443d0a52899b232696e2b |
| parent | 531cd177e89c1edfcd2e52f74f220eb186a25f78 |
| signature |
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 { |
| 354 | 354 | ||
| 355 | const Job = union(enum) { | 355 | const 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 the | 373 | /// 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 | }; |
| 420 | 417 | ||
| 421 | const CodegenJob = union(enum) { | 418 | const 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 | }; |
| 1447 | 1444 | ||
| 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 { |
| 2999 | 2989 | ||
| 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 | } |
| 3024 | 3014 | ||
| 3025 | //// TODO: compilation errors | 3015 | //// 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 | } |
| 3066 | 3056 | ||
| 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(); |
| 3070 | 3062 | ||
| ... | @@ -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 for | 3076 | // When a parse error is introduced, we keep all the semantic analysis for |
| 3085 | // the previous parse success, including compile errors, but we cannot | 3077 | // 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 | } | ||
| 3106 | 3091 | ||
| 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); |
| 3174 | 3161 | ||
| ... | @@ -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 | }; |
| 3226 | 3213 | ||
| 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; |
| 3230 | 3217 | ||
| 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 they | 3599 | // 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 { |
| 3704 | 3686 | ||
| 3705 | fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progress.Node) JobError!void { | 3687 | fn 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.?; |
| 3709 | 3691 | 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)) { |
| 3713 | 3695 | 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 by | 3738 | // Tests are always emitted in test binaries. The decl_refs are created by |
| 3816 | // Zcu.populateTestFunctions, but this will not queue body analysis, so do | 3739 | // 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(); |
| 3834 | 3757 | ||
| 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 { |
| 4054 | 3979 | ||
| 4055 | fn processOneCodegenJob(tid: usize, comp: *Compilation, codegen_job: CodegenJob) JobError!void { | 3980 | fn 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(); |
| 4060 | 3985 | ||
| 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(); |
| 4376 | 4301 | ||
| 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; |
| 4408 | 4333 | ||
| 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(); |
| 4412 | 4337 | ||
| ... | @@ -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. |
| 26 | src_hash_deps: std.AutoArrayHashMapUnmanaged(TrackedInst.Index, DepEntry.Index) = .{}, | 26 | src_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. |
| 29 | decl_val_deps: std.AutoArrayHashMapUnmanaged(DeclIndex, DepEntry.Index) = .{}, | 29 | nav_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) |
| 32 | func_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. | ||
| 34 | interned_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 | } |
| 211 | 213 | ||
| 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. |
| 216 | pub const AnalUnit = packed struct(u32) { | 218 | pub 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 | }; |
| 249 | 251 | ||
| 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. | ||
| 264 | pub 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. | ||
| 356 | pub 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 | |||
| 250 | pub const Dependee = union(enum) { | 517 | pub 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 { |
| 297 | pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyIterator { | 564 | pub 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, | ||
| 429 | 698 | ||
| 430 | decls: BucketListMutate, | ||
| 431 | namespaces: BucketListMutate, | 699 | namespaces: BucketListMutate, |
| 432 | } align(std.atomic.cache_line), | 700 | } align(std.atomic.cache_line), |
| 433 | 701 | ||
| ... | @@ -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, | ||
| 442 | 712 | ||
| 443 | decls: Decls, | ||
| 444 | namespaces: Namespaces, | 713 | namespaces: Namespaces, |
| 445 | 714 | ||
| 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 }); |
| 464 | 733 | 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 }); | ||
| 469 | 735 | ||
| 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 }); |
| 474 | 740 | ||
| 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 store | 1077 | /// 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 | } |
| 837 | 1101 | ||
| 838 | /// Rather than allocating Decl objects with an Allocator, we instead allocate | 1102 | 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 | } |
| 856 | 1110 | ||
| 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) { |
| 1038 | 1310 | ||
| 1039 | pub const ComptimeAllocIndex = enum(u32) { _ }; | 1311 | pub const ComptimeAllocIndex = enum(u32) { _ }; |
| 1040 | 1312 | ||
| 1041 | pub 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 | |||
| 1072 | pub 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 | |||
| 1086 | pub const NamespaceIndex = enum(u32) { | 1313 | pub const NamespaceIndex = enum(u32) { |
| 1087 | _, | 1314 | _, |
| 1088 | 1315 | ||
| ... | @@ -1153,7 +1380,8 @@ pub const FileIndex = enum(u32) { | ... | @@ -1153,7 +1380,8 @@ pub const FileIndex = enum(u32) { |
| 1153 | const File = struct { | 1380 | const 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 | }; |
| 1158 | 1386 | ||
| 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) |
| 1337 | pub const CaptureValue = packed struct(u32) { | 1565 | pub 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, |
| 1340 | 1568 | ||
| 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 | } |
| 1357 | 1585 | ||
| ... | @@ -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 | }; |
| 1366 | 1594 | ||
| 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 | }; |
| 1639 | 1867 | ||
| 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 | }; |
| 1650 | 1877 | ||
| 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 | }; |
| 1660 | 1900 | ||
| 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 find | 1931 | /// 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 ZIR | 1932 | /// 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 corresponding | 1933 | /// 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.?; |
| 1863 | 2102 | ||
| 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, |
| 1866 | 2105 | ||
| 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, |
| 1869 | 2108 | ||
| 1870 | /// Points to a single unnamed constant value. | 2109 | /// Points to a single unnamed constant value. |
| 1871 | anon_decl: AnonDecl, | 2110 | uav: Uav, |
| 1872 | 2111 | ||
| 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, |
| 1925 | 2164 | ||
| 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 anonymous | 2171 | /// Contains the canonical pointer type of the anonymous |
| 1937 | /// declaration. This may equal `ty` of the `Ptr` or it may be | 2172 | /// 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; |
| 1945 | 2180 | ||
| 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 and | 2184 | .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 | }, |
| 2050 | 2285 | ||
| 2051 | .variable => |variable| Hash.hash(seed, asBytes(&variable.decl)), | 2286 | .variable => |variable| Hash.hash(seed, asBytes(&variable.owner_nav)), |
| 2052 | 2287 | ||
| 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. |
| 2232 | 2467 | ||
| 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 | }, |
| 2252 | 2487 | ||
| 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 | } |
| 2256 | 2495 | ||
| ... | @@ -2331,11 +2570,19 @@ pub const Key = union(enum) { | ... | @@ -2331,11 +2570,19 @@ pub const Key = union(enum) { |
| 2331 | 2570 | ||
| 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; |
| 2345 | 2592 | ||
| 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 | } |
| 3750 | 4009 | ||
| 3751 | const LoadedEnumType = struct { | 4010 | const 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_union | 4094 | 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: PackedU64 | 4102 | 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_union | 4134 | 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: PackedU64 | 4142 | 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 { |
| 3896 | 4171 | ||
| 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`. |
| 3898 | pub const LoadedOpaqueType = struct { | 4173 | pub 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 | else | 4191 | 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) { |
| 4216 | 4492 | ||
| 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 pointer | 4959 | /// 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 is | 4962 | /// 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 other | 5085 | /// 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; |
| 4849 | 5125 | ||
| ... | @@ -4877,10 +5153,10 @@ pub const Tag = enum(u8) { | ... | @@ -4877,10 +5153,10 @@ pub const Tag = enum(u8) { |
| 4877 | 5153 | ||
| 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, |
| 4941 | 5217 | ||
| 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 | }; |
| 4950 | 5225 | ||
| 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 len | 5236 | /// 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 order | 5313 | /// 3. field type: Index for each field; declaration order |
| 5030 | /// 4. field align: Alignment for each field; declaration order | 5314 | /// 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 convenient | 5318 | /// This could be provided through the tag type, but it is more convenient |
| 5034 | /// to store it directly. This is also necessary for `dumpStatsFallible` to | 5319 | /// 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_layout | 5324 | /// 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_len | 5353 | /// 4. name: NullTerminatedString for each fields_len |
| 5069 | /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits | 5354 | /// 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 order | 5406 | /// field_index: RuntimeOrder // for each field in runtime order |
| 5121 | /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved | 5407 | /// 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, |
| 5190 | 5476 | ||
| 5191 | _: u13 = 0, | 5477 | _: u19 = 0, |
| 5192 | 5478 | ||
| 5193 | pub const State = enum(u8) { | 5479 | pub const State = enum(u2) { |
| 5194 | /// This function has not yet undergone analysis, because we have not | 5480 | /// 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 marked | 5486 | /// 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 | }; |
| 5216 | 5492 | ||
| ... | @@ -5477,13 +5753,13 @@ pub const Array = struct { | ... | @@ -5477,13 +5753,13 @@ pub const Array = struct { |
| 5477 | 5753 | ||
| 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 order | 5758 | /// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`) |
| 5483 | /// 4. tag value: Index for each fields_len; declaration order | 5759 | /// 4. field name: NullTerminatedString for each fields_len; declaration order |
| 5760 | /// 5. tag value: Index for each fields_len; declaration order | ||
| 5484 | pub const EnumExplicit = struct { | 5761 | pub 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 { |
| 5505 | 5781 | ||
| 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 order | 5786 | /// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`) |
| 5787 | /// 4. field name: NullTerminatedString for each fields_len; declaration order | ||
| 5511 | pub const EnumAuto = struct { | 5788 | pub 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 | }; |
| 5541 | 5817 | ||
| 5542 | pub const PtrDecl = struct { | 5818 | pub 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 | }; |
| 5559 | 5835 | ||
| 5560 | pub const PtrAnonDecl = struct { | 5836 | pub 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 | }; |
| 5577 | 5853 | ||
| 5578 | pub const PtrAnonDeclAligned = struct { | 5854 | pub 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, | ||
| 5808 | 6086 | ||
| 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, | ||
| 5822 | 6101 | ||
| 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 { |
| 5878 | 6156 | ||
| 5879 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { | 6157 | pub 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); |
| 5885 | 6163 | ||
| ... | @@ -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 | else | 6178 | 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 |
| 6905 | 7199 | ||
| 6906 | .enum_type => unreachable, // use getEnumType() instead | 7200 | .enum_type => unreachable, // use getEnumType() instead |
| 6907 | .func_type => unreachable, // use getFuncType() instead | 7201 | .func_type => unreachable, // use getFuncType() instead |
| 6908 | .extern_func => unreachable, // use getExternFunc() instead | 7202 | .@"extern" => unreachable, // use getExtern() instead |
| 6909 | .func => unreachable, // use getFuncInstance() or getFuncDecl() instead | 7203 | .func => unreachable, // use getFuncInstance() or getFuncDecl() instead |
| 6910 | 7204 | ||
| 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 | else | 7983 | else |
| ... | @@ -7693,18 +7988,44 @@ pub fn getUnionType( | ... | @@ -7693,18 +7988,44 @@ pub fn getUnionType( |
| 7693 | pub const WipNamespaceType = struct { | 7988 | pub 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 + // names | 8105 | ini.fields_len + // names |
| 7785 | ini.fields_len); // inits | 8106 | 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 | else | 8147 | 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 + namespace | 8167 | 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 | } |
| 8049 | 8374 | ||
| 8050 | pub 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. | ||
| 8377 | pub 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 | }; | ||
| 8059 | 8394 | ||
| 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); | ||
| 8064 | 8401 | ||
| 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 | } |
| 8075 | 8437 | ||
| 8076 | pub const GetFuncDeclKey = struct { | 8438 | pub 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( |
| 8105 | 8467 | ||
| 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 | } |
| 8141 | 8503 | ||
| 8142 | pub const GetFuncDeclIesKey = struct { | 8504 | pub 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( |
| 8209 | 8571 | ||
| 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( |
| 8401 | 8763 | ||
| 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 read | 8774 | // 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( |
| 8501 | 8863 | ||
| 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 read | 8874 | // 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); | ||
| 8638 | 8997 | ||
| 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 | } |
| 8652 | 9003 | ||
| 8653 | pub const EnumTypeInit = struct { | 9004 | pub 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, |
| 8680 | 9032 | ||
| 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: PackedU64 | 9144 | .reified => 2, // type_hash: PackedU64 |
| 8781 | } + | 9145 | } + |
| 8782 | // zig fmt: on | 9146 | // zig fmt: on |
| 9147 | 1 + // cau | ||
| 8783 | ini.fields_len); // field types | 9148 | ini.fields_len); // field types |
| 8784 | 9149 | ||
| 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: PackedU64 | 9203 | .reified => 2, // type_hash: PackedU64 |
| 8836 | } + | 9204 | } + |
| 8837 | // zig fmt: on | 9205 | // zig fmt: on |
| 9206 | 1 + // cau | ||
| 8838 | ini.fields_len + // field types | 9207 | ini.fields_len + // field types |
| 8839 | ini.fields_len * @intFromBool(ini.has_values)); // field values | 9208 | ini.fields_len * @intFromBool(ini.has_values)); // field values |
| 8840 | 9209 | ||
| 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 | } |
| 8888 | 9260 | ||
| 8889 | const GeneratedTagEnumTypeInit = struct { | 9261 | const 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 | else | 9433 | .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 | } |
| 9065 | 9440 | ||
| 9066 | pub fn getIfExists(ip: *const InternPool, key: Key) ?Index { | 9441 | pub 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( |
| 9436 | 9813 | ||
| 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, |
| 9446 | 9817 | ||
| 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; | ||
| 9872 | 10240 | ||
| 9873 | // TODO: map overhead size is not taken into account | 10241 | // 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; |
| 9875 | 10243 | ||
| 9876 | std.debug.print( | 10244 | std.debug.print( |
| 9877 | \\InternPool size: {d} bytes | 10245 | \\InternPool size: {d} bytes |
| 9878 | \\ {d} items: {d} bytes | 10246 | \\ {d} items: {d} bytes |
| 9879 | \\ {d} extra: {d} bytes | 10247 | \\ {d} extra: {d} bytes |
| 9880 | \\ {d} limbs: {d} bytes | 10248 | \\ {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 | }); |
| 9894 | 10259 | ||
| 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 | } |
| 10297 | 10662 | ||
| 10298 | pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl { | 10663 | pub 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 | |||
| 10669 | pub 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 | } |
| 10301 | 10674 | ||
| 10302 | pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl { | 10675 | pub 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 | } |
| 10308 | 10681 | ||
| 10309 | pub fn createDecl( | 10682 | /// Create a `Cau` associated with the type at the given `InternPool.Index`. |
| 10683 | pub 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 | } |
| 10344 | 10703 | ||
| 10345 | pub 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); | 10705 | pub 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 | } |
| 10352 | 10724 | ||
| 10353 | pub 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(); | 10727 | pub 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. | ||
| 10763 | pub 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. | ||
| 10807 | pub 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 | } |
| 10359 | 10841 | ||
| 10360 | pub fn createNamespace( | 10842 | pub 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 { |
| 10750 | 11232 | ||
| 10751 | .simple_type, .simple_value => unreachable, // handled via Index above | 11233 | .simple_type, .simple_value => unreachable, // handled via Index above |
| 10752 | 11234 | ||
| 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 | } |
| 10894 | 11376 | ||
| 10895 | pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex { | 11377 | pub 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 types | 11580 | // 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 | } |
| 11192 | 11674 | ||
| 11193 | pub 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 | |||
| 11205 | pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void { | 11675 | pub 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 | } |
| 11351 | 11821 | ||
| 11352 | pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex { | ||
| 11353 | return funcDeclInfo(ip, index).owner_decl; | ||
| 11354 | } | ||
| 11355 | |||
| 11356 | pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 { | 11822 | pub 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 | } |
| 11411 | 11877 | ||
| 11412 | /// Asserts the type is a struct. | ||
| 11413 | pub 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. |
| 11421 | pub fn addFieldName( | 11879 | pub 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 | } |
| 11438 | 11896 | ||
| 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. |
| 11441 | fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool { | 11899 | fn 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( |
| 11607 | pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt { | 12065 | pub 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 | |||
| 12069 | pub 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) = .{}, |
| 16 | air_extra: std.ArrayListUnmanaged(u32) = .{}, | 16 | air_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 17 | /// Maps ZIR to AIR. | 17 | /// Maps ZIR to AIR. |
| 18 | inst_map: InstMap = .{}, | 18 | inst_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. |
| 20 | owner_decl: *Decl, | 20 | /// This does not change throughout the entire lifetime of a `Sema`. For instance, |
| 21 | owner_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 function | 22 | /// even if an inline/comptime function call is being analyzed. |
| 23 | /// which contains the callsite. Corresponds to `owner_decl`. | 23 | owner: AnalUnit, |
| 24 | /// This could be `none`, a `func_decl`, or a `func_instance`. | ||
| 25 | owner_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 of | 25 | /// 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`. |
| 30 | func_index: InternPool.Index, | 28 | func_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 the | 46 | /// 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. |
| 50 | comptime_break_inst: Zir.Inst.Index = undefined, | 48 | comptime_break_inst: Zir.Inst.Index = undefined, |
| 51 | decl_val_table: std.AutoHashMapUnmanaged(InternPool.DeclIndex, Air.Inst.Ref) = .{}, | ||
| 52 | /// When doing a generic function instantiation, this array collects a value | 49 | /// 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 passed | 51 | /// 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. |
| 80 | unresolved_inferred_allocs: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{}, | 77 | unresolved_inferred_allocs: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, InferredAlloc) = .{}, |
| 81 | 78 | ||
| 82 | /// This is populated when `@setAlignStack` occurs so that if there is a duplicate | ||
| 83 | /// one encountered, the conflicting source location can be shown. | ||
| 84 | prev_stack_alignment_src: ?LazySrcLoc = null, | ||
| 85 | |||
| 86 | /// While analyzing a type which has a special InternPool index, this is set to the index at which | 79 | /// 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`. |
| 88 | builtin_type_target_index: InternPool.Index = .none, | 81 | builtin_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; |
| 177 | const Namespace = Module.Namespace; | 170 | const Namespace = Module.Namespace; |
| 178 | const CompileError = Module.CompileError; | 171 | const CompileError = Module.CompileError; |
| 179 | const SemaError = Module.SemaError; | 172 | const SemaError = Module.SemaError; |
| 180 | const Decl = Module.Decl; | ||
| 181 | const LazySrcLoc = Zcu.LazySrcLoc; | 173 | const LazySrcLoc = Zcu.LazySrcLoc; |
| 182 | const RangeSet = @import("RangeSet.zig"); | 174 | const RangeSet = @import("RangeSet.zig"); |
| 183 | const target_util = @import("target.zig"); | 175 | const 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 name | 387 | /// 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, |
| 399 | 391 | ||
| 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 |
| 2170 | fn resolveValueIntable(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value { | 2161 | fn 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; | ||
| 2507 | 2497 | ||
| 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 |
| 2531 | 2521 | ||
| 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 | } |
| 2536 | 2526 | ||
| 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 | } |
| 2546 | 2536 | ||
| 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 | } |
| 2559 | 2539 | ||
| ... | @@ -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); | ||
| 2666 | 2647 | ||
| 2667 | const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len); | 2648 | const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len); |
| 2668 | 2649 | ||
| ... | @@ -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) { |
| 2740 | fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool { | 2721 | fn 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; | ||
| 2743 | 2725 | ||
| 2744 | if (!zcu.comp.incremental) return false; | 2726 | if (!zcu.comp.incremental) return false; |
| 2745 | 2727 | ||
| 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) or | 2730 | .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 | } |
| 2758 | 2744 | ||
| ... | @@ -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); |
| 2833 | 2819 | ||
| 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 | } | ||
| 2851 | 2827 | ||
| 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); |
| 2859 | 2835 | ||
| 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 | } |
| 2864 | 2850 | ||
| 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 | } |
| 2870 | 2856 | ||
| 2871 | fn createAnonymousDeclTypeNamed( | 2857 | fn 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); | ||
| 2886 | 2870 | ||
| 2887 | switch (name_strategy) { | 2871 | switch (name_strategy) { |
| 2888 | .anon => {}, // handled after switch | 2872 | .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); |
| 2896 | 2877 | ||
| 2897 | var buf = std.ArrayList(u8).init(gpa); | 2878 | var buf: std.ArrayListUnmanaged(u8) = .{}; |
| 2898 | defer buf.deinit(); | 2879 | defer buf.deinit(gpa); |
| 2899 | 2880 | ||
| 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)}); |
| 2902 | 2883 | ||
| 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 | }; |
| 2932 | 2913 | ||
| 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 | } |
| 2957 | 2933 | ||
| 2958 | // anon strat handling. | 2934 | // anon strat handling |
| 2959 | 2935 | ||
| 2960 | // It would be neat to have "struct:line:column" but this name has | 2936 | // It would be neat to have "struct:line:column" but this name has |
| 2961 | // to survive incremental updates, where it may have been shifted down | 2937 | // to survive incremental updates, where it may have been shifted down |
| 2962 | // or up to a different line, but unchanged, and thus not unnecessarily | 2938 | // 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 be | 2940 | // 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. | ||
| 2966 | 2943 | ||
| 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 | } |
| 2973 | 2948 | ||
| 2974 | fn zirEnumDecl( | 2949 | fn zirEnumDecl( |
| ... | @@ -3068,60 +3043,53 @@ fn zirEnumDecl( | ... | @@ -3068,60 +3043,53 @@ fn zirEnumDecl( |
| 3068 | 3043 | ||
| 3069 | errdefer if (!done) wip_ty.cancel(ip, pt.tid); | 3044 | errdefer if (!done) wip_ty.cancel(ip, pt.tid); |
| 3070 | 3045 | ||
| 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 | } | ||
| 3089 | 3054 | ||
| 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); |
| 3097 | 3062 | ||
| 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 | } |
| 3101 | 3076 | ||
| 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; |
| 3106 | 3084 | ||
| 3107 | const int_tag_ty = ty: { | 3085 | const int_tag_ty = ty: { |
| 3108 | // We create a block for the field type instructions because they | 3086 | // 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. | ||
| 3112 | 3089 | ||
| 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; | ||
| 3125 | 3093 | ||
| 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); |
| 3141 | 3109 | ||
| ... | @@ -3253,7 +3221,6 @@ fn zirEnumDecl( | ... | @@ -3253,7 +3221,6 @@ fn zirEnumDecl( |
| 3253 | } | 3221 | } |
| 3254 | } | 3222 | } |
| 3255 | 3223 | ||
| 3256 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 3257 | return Air.internedToRef(wip_ty.index); | 3224 | return Air.internedToRef(wip_ty.index); |
| 3258 | } | 3225 | } |
| 3259 | 3226 | ||
| ... | @@ -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); |
| 3338 | 3305 | ||
| 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 | } | ||
| 3356 | 3313 | ||
| 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); |
| 3364 | 3321 | ||
| 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 | } |
| 3369 | 3336 | ||
| 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 | } |
| 3375 | 3342 | ||
| 3376 | fn zirOpaqueDecl( | 3343 | fn 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); |
| 3428 | 3393 | ||
| 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 | } | ||
| 3446 | 3401 | ||
| 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); |
| 3453 | 3408 | ||
| 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 | } |
| 3458 | 3413 | ||
| 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 | } |
| 3463 | 3416 | ||
| 3464 | fn zirErrorSetDecl( | 3417 | fn 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 | } |
| 4251 | 4204 | ||
| 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 | }; |
| 5521 | 5475 | ||
| 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 | } |
| 5526 | 5480 | ||
| ... | @@ -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().?); | ||
| 5539 | 5492 | ||
| 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); | ||
| 5566 | 5518 | ||
| 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 | } |
| 5753 | 5705 | ||
| 5754 | fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref { | 5706 | fn 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 | } |
| 5757 | 5709 | ||
| 5758 | fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { | 5710 | 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,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", .{}); |
| 5868 | 5820 | ||
| 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", .{}); |
| 6023 | 5975 | ||
| 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)}); |
| 6070 | 6022 | ||
| 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)}); |
| 6075 | 6027 | ||
| 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 | } |
| 6080 | 6034 | ||
| 6081 | fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6035 | fn 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(); |
| 6424 | 6378 | ||
| 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); |
| 6441 | 6396 | ||
| 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 | } |
| 6457 | 6415 | ||
| 6458 | fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 6416 | fn 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(); |
| 6461 | 6419 | ||
| 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 | } | ||
| 6479 | 6434 | ||
| 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 | } |
| 6487 | 6453 | ||
| 6488 | pub fn analyzeExport( | 6454 | pub 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; | ||
| 6498 | 6465 | ||
| 6499 | if (options.linkage == .internal) | 6466 | if (options.linkage == .internal) |
| 6500 | return; | 6467 | return; |
| 6501 | 6468 | ||
| 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); | ||
| 6506 | 6472 | ||
| 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); |
| 6511 | 6477 | ||
| ... | @@ -6513,59 +6479,50 @@ pub fn analyzeExport( | ... | @@ -6513,59 +6479,50 @@ pub fn analyzeExport( |
| 6513 | 6479 | ||
| 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 | } |
| 6519 | 6484 | ||
| 6520 | // TODO: some backends might support re-exporting extern decls | 6485 | // 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 | } |
| 6524 | 6489 | ||
| 6525 | try sema.maybeQueueFuncBodyAnalysis(src, exported_decl_index); | 6490 | try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index); |
| 6526 | 6491 | ||
| 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 | } |
| 6534 | 6499 | ||
| 6535 | fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6500 | fn 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 | } |
| 6547 | 6518 | ||
| 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; | ||
| 6567 | 6524 | ||
| 6568 | mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment); | 6525 | zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment); |
| 6569 | } | 6526 | } |
| 6570 | 6527 | ||
| 6571 | fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6528 | fn 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 function | 6537 | // 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 | } |
| 6583 | 6545 | ||
| 6584 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { | 6546 | fn 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 function | 6550 | 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 | } |
| 6591 | 6556 | ||
| 6592 | fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6557 | fn 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 | } |
| 6766 | 6731 | ||
| 6767 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6732 | fn 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 | } |
| 6781 | 6746 | ||
| 6782 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex { | 6747 | fn 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; | ||
| 6807 | 6779 | ||
| 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 | } | ||
| 6814 | 6784 | ||
| 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; | ||
| 6817 | 6786 | ||
| 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); |
| 6821 | 6791 | ||
| 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); |
| 6825 | 6795 | ||
| 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; |
| 6828 | 6798 | ||
| 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 different | 6802 | 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 | } |
| 6859 | 6824 | ||
| 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( |
| 6870 | 6842 | ||
| 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 | } |
| 6896 | 6869 | ||
| 6897 | return null; | 6870 | return null; |
| 6898 | } | 6871 | } |
| 6899 | 6872 | ||
| 6900 | fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { | 6873 | fn 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 | } |
| 6916 | 6890 | ||
| 6917 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { | 6891 | pub 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); |
| 7102 | 7076 | ||
| 7103 | if (sema.owner_func_index == .none or | 7077 | 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 trace | 7080 | // No errorable fn actually called; we have no error return trace |
| 7107 | input_is_error = false; | 7081 | input_is_error = false; |
| 7082 | }, | ||
| 7108 | } | 7083 | } |
| 7109 | 7084 | ||
| 7110 | if (block.ownerModule().error_tracing and | 7085 | 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 | } |
| 7201 | 7176 | ||
| 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); |
| 7217 | 7192 | ||
| 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); |
| 7555 | 7530 | ||
| 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 | } |
| 7686 | 7660 | ||
| ... | @@ -7712,7 +7686,12 @@ fn analyzeCall( | ... | @@ -7712,7 +7686,12 @@ fn analyzeCall( |
| 7712 | }; | 7686 | }; |
| 7713 | 7687 | ||
| 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); | ||
| 7716 | 7695 | ||
| 7717 | // We effectively want a child Sema here, but can't literally do that, because we need AIR | 7696 | // 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 in | 7697 | // 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 | }; |
| 7746 | 7726 | ||
| 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); |
| 7761 | 7741 | ||
| 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(); |
| 7810 | 7790 | ||
| 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( |
| 7957 | 7934 | ||
| 7958 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); | 7935 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); |
| 7959 | 7936 | ||
| 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 | } |
| 7963 | 7943 | ||
| 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( |
| 8018 | 7998 | ||
| 8019 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { | 7999 | fn 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` to | 8187 | // The actual monomorphization happens via adding `func_instance` to |
| 8208 | // `InternPool`. | 8188 | // `InternPool`. |
| 8209 | 8189 | ||
| 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)); |
| 8215 | 8195 | ||
| 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 the | 8213 | // 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 there | 8217 | // 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); |
| 8264 | 8242 | ||
| ... | @@ -8421,10 +8399,11 @@ fn instantiateGenericCall( | ... | @@ -8421,10 +8399,11 @@ fn instantiateGenericCall( |
| 8421 | 8399 | ||
| 8422 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); | 8400 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); |
| 8423 | 8401 | ||
| 8424 | if (sema.owner_func_index != .none and | 8402 | 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 | } |
| 8429 | 8408 | ||
| 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 }); |
| 9374 | 9354 | ||
| 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 defaults | 9390 | // 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; |
| 9420 | 9406 | ||
| ... | @@ -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 and | 9687 | 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 | } |
| 9771 | 9757 | ||
| 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; | ||
| 9780 | 9763 | ||
| 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(), |
| 9788 | 9771 | ||
| 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( |
| 9872 | 9871 | ||
| 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 | } |
| 13948 | 13954 | ||
| 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 | } |
| 13988 | 13995 | ||
| 13989 | fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13996 | fn 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 | } |
| 17164 | 17171 | ||
| 17165 | if (block.is_comptime) { | 17172 | try sema.requireRuntimeBlock(block, src, null); |
| 17166 | try sema.requireRuntimeBlock(block, src, null); | ||
| 17167 | } | ||
| 17168 | 17173 | ||
| 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 | } |
| 17655 | 17659 | ||
| 17656 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 17660 | fn 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); |
| 17661 | 17665 | ||
| 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 | }; |
| 17671 | 17675 | ||
| 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(); |
| 17770 | 17773 | ||
| 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); |
| 17778 | 17781 | ||
| 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(); | ||
| 17914 | 17916 | ||
| 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(); | ||
| 17924 | 17925 | ||
| 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(); | ||
| 18026 | 18026 | ||
| 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(); | ||
| 18054 | 18053 | ||
| 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 |
| 18074 | 18073 | ||
| 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 | }; |
| 18098 | 18095 | ||
| 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 | }; |
| 18141 | 18137 | ||
| 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 | }; |
| 18172 | 18167 | ||
| 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 | }; |
| 18201 | 18195 | ||
| 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 type | 18210 | // 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 | }; |
| 18228 | 18221 | ||
| 18229 | // Build our list of Error values | 18222 | // 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 | }; |
| 18334 | 18326 | ||
| 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); |
| 18352 | 18344 | ||
| 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 | }; |
| 18364 | 18355 | ||
| 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); |
| 18449 | 18440 | ||
| 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 | }; |
| 18461 | 18451 | ||
| 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 | }; |
| 18493 | 18482 | ||
| 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 | }; |
| 18505 | 18493 | ||
| 18506 | try ty.resolveLayout(pt); // Getting alignment requires type layout | 18494 | 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 | } }); |
| 18598 | 18586 | ||
| 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 | }; |
| 18610 | 18597 | ||
| 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 | }; |
| 18643 | 18629 | ||
| 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 | }; |
| 18655 | 18640 | ||
| 18656 | try ty.resolveLayout(pt); // Getting alignment requires type layout | 18641 | 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 | } }); |
| 18831 | 18816 | ||
| 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 | }; |
| 18843 | 18827 | ||
| 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 | }; |
| 18879 | 18862 | ||
| 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; |
| 18911 | 18895 | ||
| 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 | }; |
| 18923 | 18906 | ||
| 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(); |
| 18929 | 18912 | ||
| 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); |
| 18931 | 18914 | ||
| 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( |
| 18962 | fn typeInfoNamespaceDecls( | 18945 | fn 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; |
| 18973 | 18957 | ||
| 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); |
| 18976 | 18960 | ||
| 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; |
| 18979 | 18963 | ||
| 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 | }; |
| 19015 | 18994 | 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 | } |
| 19026 | 19015 | ||
| 19027 | fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19016 | fn 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 | } |
| 19908 | 19897 | ||
| 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; |
| 19911 | 19900 | ||
| 19912 | assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere | 19901 | 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 |
| 20232 | 20221 | ||
| 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 | } |
| 21057 | 21046 | ||
| 21058 | fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref { | 21047 | fn 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 | } |
| 21061 | 21050 | ||
| 21062 | fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 21051 | fn 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()); |
| 21165 | 21154 | ||
| 21166 | if (sema.owner_func_index != .none and | 21155 | switch (sema.owner.unwrap()) { |
| 21167 | ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and | 21156 | .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 | } |
| 21177 | 21166 | ||
| 21178 | fn zirFrame( | 21167 | fn 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; |
| 21374 | 21363 | ||
| 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) orelse | 21372 | .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 but | 21379 | // 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/15909 | 21381 | // 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 dupe | 21399 | // 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); |
| 21822 | 21810 | ||
| 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); | ||
| 21834 | 21818 | ||
| 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 | } |
| 22003 | 21987 | ||
| 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 | } |
| 22022 | 22008 | ||
| 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); | ||
| 22032 | 22018 | ||
| 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()); |
| 22035 | 22021 | ||
| 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 | } |
| 22078 | 22064 | ||
| 22079 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 22080 | return Air.internedToRef(wip_ty.index); | 22065 | return Air.internedToRef(wip_ty.index); |
| 22081 | } | 22066 | } |
| 22082 | 22067 | ||
| ... | @@ -22134,6 +22119,8 @@ fn reifyUnion( | ... | @@ -22134,6 +22119,8 @@ fn reifyUnion( |
| 22134 | } | 22119 | } |
| 22135 | } | 22120 | } |
| 22136 | 22121 | ||
| 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 later | 22145 | .field_types = &.{}, // set later |
| 22159 | .field_aligns = &.{}, // set later | 22146 | .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); |
| 22169 | 22156 | ||
| 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); | ||
| 22179 | 22165 | ||
| 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 | } |
| 22270 | 22256 | ||
| 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 error | 22260 | 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); |
| 22317 | 22303 | ||
| 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 | } |
| 22323 | 22310 | ||
| 22324 | fn reifyStruct( | 22311 | fn reifyStruct( |
| ... | @@ -22399,6 +22386,8 @@ fn reifyStruct( | ... | @@ -22399,6 +22386,8 @@ fn reifyStruct( |
| 22399 | } | 22386 | } |
| 22400 | } | 22387 | } |
| 22401 | 22388 | ||
| 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 | }; |
| 22428 | 22417 | ||
| 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); | ||
| 22438 | 22425 | ||
| 22439 | const struct_type = ip.loadStructType(wip_ty.index); | 22426 | const struct_type = ip.loadStructType(wip_ty.index); |
| 22440 | 22427 | ||
| ... | @@ -22582,10 +22569,11 @@ fn reifyStruct( | ... | @@ -22582,10 +22569,11 @@ fn reifyStruct( |
| 22582 | } | 22569 | } |
| 22583 | } | 22570 | } |
| 22584 | 22571 | ||
| 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 | } |
| 22590 | 22578 | ||
| 22591 | fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref { | 22579 | fn 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( |
| 26075 | 26064 | ||
| 26076 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); | 26065 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); |
| 26077 | 26066 | ||
| 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 | } |
| 26089 | 26124 | ||
| 26090 | fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 26125 | fn 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 | .C | 26294 | if (has_body) { |
| 26260 | else | 26295 | 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 | }; | ||
| 26262 | 26310 | ||
| 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( |
| 26600 | 26648 | ||
| 26601 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); | 26649 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); |
| 26602 | 26650 | ||
| 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); |
| 26607 | 26657 | ||
| 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 | else | 26670 | .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); | ||
| 26639 | 26677 | ||
| 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 | } |
| 27131 | 27169 | ||
| 27132 | fn prepareSimplePanic(sema: *Sema) !void { | 27170 | fn 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; |
| 27135 | 27173 | ||
| 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 actually | 27176 | 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-checked | 27203 | /// Backends depend on panic decls being available when lowering safety-checked |
| 27168 | /// instructions. This function ensures the panic function will be available to | 27204 | /// instructions. This function ensures the panic function will be available to |
| 27169 | /// be called during that time. | 27205 | /// be called during that time. |
| 27170 | fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex { | 27206 | fn 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; |
| 27175 | 27211 | ||
| 27176 | try sema.prepareSimplePanic(); | 27212 | try sema.prepareSimplePanic(block, src); |
| 27177 | 27213 | ||
| 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 | } |
| 27193 | 27229 | ||
| 27194 | fn addSafetyCheck( | 27230 | fn 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 | } |
| 27284 | 27320 | ||
| 27285 | try sema.prepareSimplePanic(); | 27321 | try sema.prepareSimplePanic(block, src); |
| 27286 | 27322 | ||
| 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); |
| 27290 | 27326 | ||
| 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 | } |
| 27456 | 27492 | ||
| 27457 | fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void { | 27493 | fn 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 | } |
| 27462 | 27498 | ||
| ... | @@ -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_type | 27875 | child_type |
| 27840 | else | 27876 | 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. |
| 27924 | 27960 | ||
| 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 location | 27964 | 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 | else | 27968 | 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)}); |
| 27934 | 27970 | ||
| 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; |
| 27943 | 27979 | ||
| 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) orelse | 27985 | 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]); |
| 27952 | 27988 | ||
| 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 | } |
| 27986 | 28022 | ||
| 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) orelse | 28025 | 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)) orelse | 28027 | const nav_index = try sema.namespaceLookup(block, src, namespace, field_name) orelse |
| 27992 | break :found_decl null; | 28028 | break :found_nav null; |
| 27993 | 28029 | ||
| 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; |
| 27998 | 28034 | ||
| 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() or | 28036 | if (first_param_type.isGenericPoison() or |
| 28001 | (first_param_type.zigTypeTag(mod) == .Pointer and | 28037 | (first_param_type.zigTypeTag(zcu) == .Pointer and |
| 28002 | (first_param_type.ptrSize(mod) == .One or | 28038 | (first_param_type.ptrSize(zcu) == .One or |
| 28003 | first_param_type.ptrSize(mod) == .C) and | 28039 | 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 must | 28042 | // 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 we | 28043 | // 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 and | 28065 | } else if (child.zigTypeTag(zcu) == .Pointer and |
| 28030 | child.ptrSize(mod) == .One and | 28066 | 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 and | 28074 | } 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 | }; |
| 28050 | 28086 | ||
| 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 | } |
| 28157 | 28189 | ||
| 28158 | fn namespaceLookupVal( | 28190 | fn 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 | } |
| 28168 | 28200 | ||
| 28169 | fn structFieldPtr( | 28201 | fn structFieldPtr( |
| ... | @@ -29200,9 +29232,9 @@ const CoerceOpts = struct { | ... | @@ -29200,9 +29232,9 @@ const CoerceOpts = struct { |
| 29200 | 29232 | ||
| 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 | } |
| 29310 | 29346 | ||
| ... | @@ -29846,7 +29882,7 @@ fn coerceExtra( | ... | @@ -29846,7 +29882,7 @@ fn coerceExtra( |
| 29846 | errdefer msg.destroy(sema.gpa); | 29882 | errdefer msg.destroy(sema.gpa); |
| 29847 | 29883 | ||
| 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( |
| 29879 | 29915 | ||
| 29880 | // Add notes about function return type | 29916 | // Add notes about function return type |
| 29881 | if (opts.is_ret and | 29917 | 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; |
| 30886 | 30922 | ||
| 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 fit | 30927 | // 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 | } |
| 32119 | 32155 | ||
| 32120 | fn analyzeDeclVal( | 32156 | fn 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 | } |
| 32138 | 32165 | ||
| 32139 | fn addReferenceEntry( | 32166 | fn 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 | } |
| 32153 | 32180 | ||
| 32154 | pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void { | 32181 | pub 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 | } | ||
| 32166 | 32185 | ||
| 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 | } | ||
| 32176 | 32187 | ||
| 32177 | fn 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 | } |
| 32190 | 32210 | ||
| 32191 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { | 32211 | fn 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 | } |
| 32202 | 32222 | ||
| 32203 | fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref { | 32223 | fn 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 | } |
| 32206 | 32226 | ||
| 32207 | /// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but | 32227 | /// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed, but |
| 32208 | /// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a | 32228 | /// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a |
| 32209 | /// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps | 32229 | /// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeNavRef` wraps |
| 32210 | /// this function with `analyze_fn_body` set to true. | 32230 | /// this function with `analyze_fn_body` set to true. |
| 32211 | fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex, analyze_fn_body: bool) CompileError!Air.Inst.Ref { | 32231 | fn 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); | ||
| 32216 | 32235 | ||
| 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 type | 32243 | .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 | } |
| 32243 | 32265 | ||
| 32244 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void { | 32266 | fn 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 | } |
| 32253 | 32275 | ||
| 32254 | fn analyzeRef( | 32276 | fn analyzeRef( |
| ... | @@ -32263,9 +32285,9 @@ fn analyzeRef( | ... | @@ -32263,9 +32285,9 @@ fn analyzeRef( |
| 32263 | 32285 | ||
| 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 | } |
| 32271 | 32293 | ||
| ... | @@ -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(); |
| 35200 | 35222 | ||
| 35201 | assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?); | 35223 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35202 | 35224 | ||
| 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; |
| 35244 | 35266 | ||
| 35245 | assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?); | 35267 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35246 | 35268 | ||
| 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; |
| 35386 | 35408 | ||
| 35387 | const decl_index = struct_type.decl.unwrap().?; | 35409 | const cau_index = struct_type.cau.unwrap().?; |
| 35388 | const decl = zcu.declPtr(decl_index); | ||
| 35389 | 35410 | ||
| 35390 | const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir; | 35411 | const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir; |
| 35391 | 35412 | ||
| ... | @@ -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); |
| 35425 | 35444 | ||
| ... | @@ -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(); |
| 35546 | 35565 | ||
| 35547 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35566 | assert(sema.owner.unwrap().cau == union_type.cau); |
| 35548 | 35567 | ||
| 35549 | assert(!union_type.haveLayout(ip)); | 35568 | assert(!union_type.haveLayout(ip)); |
| 35550 | 35569 | ||
| ... | @@ -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); |
| 35586 | 35605 | ||
| 35587 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35606 | assert(sema.owner.unwrap().cau == union_type.cau); |
| 35588 | 35607 | ||
| 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).?; |
| 35699 | 35718 | ||
| 35700 | assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?); | 35719 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35701 | 35720 | ||
| 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).?; |
| 35722 | 35741 | ||
| 35723 | assert(sema.ownerUnit().unwrap().decl == union_obj.decl); | 35742 | assert(sema.owner.unwrap().cau == union_obj.cau); |
| 35724 | 35743 | ||
| 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; | ||
| 35759 | 35776 | ||
| 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 | } | ||
| 35772 | 35778 | ||
| 35773 | if (struct_type.haveFieldTypes(ip)) return; | 35779 | if (struct_type.haveFieldTypes(ip)) return; |
| 35774 | 35780 | ||
| ... | @@ -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); |
| 35784 | 35790 | ||
| 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; | ||
| 35803 | 35802 | ||
| 35804 | assert(sema.ownerUnit().unwrap().decl == owner_decl); | 35803 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35805 | 35804 | ||
| 35806 | // Inits can start as resolved | 35805 | // 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); |
| 35820 | 35819 | ||
| 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); | ||
| 35839 | 35831 | ||
| 35840 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35832 | assert(sema.owner.unwrap().cau == union_type.cau); |
| 35841 | 35833 | ||
| 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 |
| 35869 | 35851 | ||
| 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); |
| 35898 | 35874 | ||
| 35899 | try sema.declareDependency(.{ .func_ies = func_index }); | 35875 | try sema.declareDependency(.{ .interned = func_index }); // resolved IES |
| 35900 | 35876 | ||
| 35901 | // TODO: during an incremental update this might not be `.none`, but the | 35877 | // 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; |
| 35905 | 35881 | ||
| 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 | } | ||
| 35908 | 35885 | ||
| 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 error | 35887 | // we need to ensure the function body is analyzed of the inferred error |
| 35911 | // set. However, in the case of comptime/inline function calls with | 35888 | // set. However, in the case of comptime/inline function calls with |
| 35912 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which | 35889 | // 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); |
| 35926 | 35902 | 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 that | 35906 | // 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 | } |
| 35940 | 35911 | ||
| 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); |
| 36100 | 36070 | ||
| ... | @@ -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); |
| 36144 | 36112 | ||
| ... | @@ -36318,9 +36286,8 @@ fn semaStructFieldInits( | ... | @@ -36318,9 +36286,8 @@ fn semaStructFieldInits( |
| 36318 | 36286 | ||
| 36319 | assert(!struct_type.haveFieldInits(ip)); | 36287 | assert(!struct_type.haveFieldInits(ip)); |
| 36320 | 36288 | ||
| 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); |
| 36358 | 36323 | ||
| ... | @@ -36449,14 +36414,14 @@ fn semaStructFieldInits( | ... | @@ -36449,14 +36414,14 @@ fn semaStructFieldInits( |
| 36449 | try sema.flushExports(); | 36414 | try sema.flushExports(); |
| 36450 | } | 36415 | } |
| 36451 | 36416 | ||
| 36452 | fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void { | 36417 | fn 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(); |
| 36455 | 36420 | ||
| 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; |
| 36503 | 36468 | ||
| 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(); |
| 36508 | 36471 | ||
| ... | @@ -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); |
| 36536 | 36497 | ||
| ... | @@ -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 | } |
| 36826 | 36787 | ||
| ... | @@ -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 |
| 36836 | 36797 | ||
| 36837 | fn generateUnionTagTypeNumbered( | 36798 | fn 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; |
| 36848 | 36809 | ||
| 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; | ||
| 36868 | 36817 | ||
| 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 | else | 36823 | else |
| ... | @@ -36878,46 +36827,31 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36878,46 +36827,31 @@ fn generateUnionTagTypeNumbered( |
| 36878 | .tag_mode = .explicit, | 36827 | .tag_mode = .explicit, |
| 36879 | }); | 36828 | }); |
| 36880 | 36829 | ||
| 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 | } |
| 36886 | 36832 | ||
| 36887 | fn generateUnionTagTypeSimple( | 36833 | fn 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; |
| 36897 | 36843 | ||
| 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); | ||
| 36917 | 36851 | ||
| 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 | else | 36857 | else |
| ... | @@ -36927,11 +36861,6 @@ fn generateUnionTagTypeSimple( | ... | @@ -36927,11 +36861,6 @@ fn generateUnionTagTypeSimple( |
| 36927 | .tag_mode = .auto, | 36861 | .tag_mode = .auto, |
| 36928 | }); | 36862 | }); |
| 36929 | 36863 | ||
| 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 | } |
| 36937 | 36866 | ||
| ... | @@ -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 types | 36986 | // 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 would | 38169 | // 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 resolve | 38170 | // 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 | } |
| 38246 | 38181 | ||
| 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 | } |
| 38255 | 38184 | ||
| 38256 | fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { | 38185 | fn 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; |
| 38390 | 38319 | ||
| 38391 | const unit = sema.ownerUnit(); | ||
| 38392 | |||
| 38393 | // There may be existing exports. For instance, a struct may export | 38320 | // 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 performs | 38323 | // 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); |
| 38404 | 38331 | ||
| 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 | } |
| 38424 | 38351 | ||
| 38425 | pub 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 }); | 38354 | fn 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`. | ||
| 38361 | fn 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. | ||
| 38368 | fn 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. | ||
| 38377 | fn 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 | } |
| 38432 | 38390 | ||
| 38433 | pub const bitCastVal = @import("Sema/bitcast.zig").bitCast; | 38391 | pub 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 | }; |
| 218 | 218 | ||
| 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( |
| 580 | 588 | ||
| 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 | }, |
| 367 | 363 | ||
| 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 | } |
| 3009 | 3005 | ||
| 3006 | // TODO: new dwarf structure will also need the enclosing code block for types created in imperative scopes | ||
| 3007 | pub 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. |
| 3011 | pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { | 3027 | pub 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 | } |
| 3323 | 3339 | ||
| 3324 | pub fn getOwnerDecl(ty: Type, mod: *Module) InternPool.DeclIndex { | ||
| 3325 | return ty.getOwnerDeclOrNull(mod) orelse unreachable; | ||
| 3326 | } | ||
| 3327 | |||
| 3328 | pub 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 | |||
| 3339 | pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc { | 3340 | pub 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 | } |
| 3446 | 3447 | ||
| 3448 | pub 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 | |||
| 3447 | pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 { | 3463 | pub 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 | } |
| 3473 | 3489 | ||
| 3474 | /// Given a namespace type, returns its list of caotured values. | 3490 | /// Given a namespace type, returns its list of captured values. |
| 3475 | pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice { | 3491 | pub 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; |
| 3774 | 3790 | ||
| 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 | } | ||
| 3777 | 3797 | ||
| 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(); |
| 3799 | 3817 | ||
| 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 | } |
| 3808 | 3834 | ||
| 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; |
| 3817 | 3843 | ||
| 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 | } | ||
| 3820 | 3850 | ||
| 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(); |
| 3842 | 3870 | ||
| 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 | } |
| 3850 | 3886 | ||
| 3851 | /// Fully resolves a simple type. This is usually a nop, but for builtin types with | 3887 | /// 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 | } |
| 3947 | 3983 | ||
| 3984 | pub 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 | |||
| 3948 | pub const @"u1": Type = .{ .ip_index = .u1_type }; | 3994 | pub const @"u1": Type = .{ .ip_index = .u1_type }; |
| 3949 | pub const @"u8": Type = .{ .ip_index = .u8_type }; | 3995 | pub const @"u8": Type = .{ .ip_index = .u8_type }; |
| 3950 | pub const @"u16": Type = .{ .ip_index = .u16_type }; | 3996 | pub 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 | } |
| 229 | 229 | ||
| 230 | pub 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 | |||
| 237 | pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable { | 230 | pub 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 | } |
| 321 | 314 | ||
| 322 | fn ptrHasIntAddr(val: Value, mod: *Module) bool { | 315 | fn 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 | } |
| 334 | 318 | ||
| 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 | } |
| 1275 | 1259 | ||
| 1276 | /// Gets the decl referenced by this pointer. If the pointer does not point | 1260 | /// 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. |
| 1279 | pub fn pointerDecl(val: Value, mod: *Module) ?InternPool.DeclIndex { | 1263 | pub 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 | } |
| 1343 | 1328 | ||
| 1344 | pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool { | 1329 | pub 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 | } |
| 1349 | 1338 | ||
| 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. |
| 119 | intern_pool: InternPool = .{}, | 119 | intern_pool: InternPool = .{}, |
| 120 | 120 | ||
| 121 | analysis_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. |
| 122 | failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .{}, | 123 | failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .{}, |
| 124 | /// This `AnalUnit` failed semantic analysis because it required analysis of another `AnalUnit` which itself failed. | ||
| 125 | transitive_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. | ||
| 129 | failed_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`. |
| 125 | compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { | 132 | compile_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. |
| 157 | outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{}, | 164 | outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .{}, |
| 158 | /// This contains a set of Decls which may not be in `outdated`, but are the | 165 | /// 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 preserved | 167 | /// 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`, the | 168 | /// 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. |
| 163 | outdated_file_root: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{}, | 170 | outdated_file_root: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{}, |
| 164 | /// This contains a list of AnalUnit whose analysis or codegen failed, but the | 171 | /// 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 may | 172 | /// 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 of | 173 | /// 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 { |
| 179 | 186 | ||
| 180 | compile_log_text: std.ArrayListUnmanaged(u8) = .{}, | 187 | compile_log_text: std.ArrayListUnmanaged(u8) = .{}, |
| 181 | 188 | ||
| 182 | emit_h: ?*GlobalEmitH, | 189 | test_functions: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .{}, |
| 183 | |||
| 184 | test_functions: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{}, | ||
| 185 | 190 | ||
| 186 | /// TODO: the key here will be a `Cau.Index`. | 191 | global_assembly: std.AutoArrayHashMapUnmanaged(InternPool.Cau.Index, []u8) = .{}, |
| 187 | global_assembly: std.AutoArrayHashMapUnmanaged(Decl.Index, []u8) = .{}, | ||
| 188 | 192 | ||
| 189 | /// Key is the `AnalUnit` *performing* the reference. This representation allows | 193 | /// 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`. |
| 197 | free_references: std.ArrayListUnmanaged(u32) = .{}, | 201 | free_references: std.ArrayListUnmanaged(u32) = .{}, |
| 198 | 202 | ||
| 199 | panic_messages: [PanicId.len]Decl.OptionalIndex = .{.none} ** PanicId.len, | 203 | panic_messages: [PanicId.len]InternPool.Nav.Index.Optional = .{.none} ** PanicId.len, |
| 200 | /// The panic function body. | 204 | /// The panic function body. |
| 201 | panic_func_index: InternPool.Index = .none, | 205 | panic_func_index: InternPool.Index = .none, |
| 202 | null_stack_trace: InternPool.Index = .none, | 206 | null_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 | }; |
| 252 | 256 | ||
| 253 | /// A `Module` has zero or one of these depending on whether `-femit-h` is enabled. | ||
| 254 | pub 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 | |||
| 273 | pub const ErrorInt = u32; | 257 | pub const ErrorInt = u32; |
| 274 | 258 | ||
| 275 | pub const Exported = union(enum) { | 259 | pub 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, |
| 280 | 264 | ||
| 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 | } |
| 287 | 271 | ||
| 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 | }; |
| 326 | 310 | ||
| 327 | pub 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. | ||
| 573 | pub const EmitH = struct { | ||
| 574 | fwd_decl: std.ArrayListUnmanaged(u8) = .{}, | ||
| 575 | }; | ||
| 576 | |||
| 577 | pub 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. |
| 592 | pub const Namespace = struct { | 312 | pub 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; anonymous | 319 | /// 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) = .{}, | ||
| 606 | 328 | ||
| 607 | pub const Index = InternPool.NamespaceIndex; | 329 | pub const Index = InternPool.NamespaceIndex; |
| 608 | pub const OptionalIndex = InternPool.OptionalNamespaceIndex; | 330 | pub const OptionalIndex = InternPool.OptionalNamespaceIndex; |
| 609 | 331 | ||
| 610 | const DeclContext = struct { | 332 | const NavNameContext = struct { |
| 611 | zcu: *Zcu, | 333 | zcu: *Zcu, |
| 612 | 334 | ||
| 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 | } |
| 617 | 339 | ||
| 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 | }; |
| 625 | 361 | ||
| ... | @@ -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 | } |
| 633 | 369 | ||
| 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 to | 399 | 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 | }; |
| 721 | 403 | ||
| ... | @@ -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| { |
| 2432 | 2114 | 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); | ||
| 2441 | 2120 | ||
| 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 | } |
| 2488 | 2167 | ||
| 2489 | pub fn declPtr(mod: *Zcu, index: Decl.Index) *Decl { | 2168 | pub fn namespacePtr(zcu: *Zcu, index: Namespace.Index) *Namespace { |
| 2490 | return mod.intern_pool.declPtr(index); | 2169 | return zcu.intern_pool.namespacePtr(index); |
| 2491 | } | ||
| 2492 | |||
| 2493 | pub fn namespacePtr(mod: *Zcu, index: Namespace.Index) *Namespace { | ||
| 2494 | return mod.intern_pool.namespacePtr(index); | ||
| 2495 | } | 2170 | } |
| 2496 | 2171 | ||
| 2497 | pub fn namespacePtrUnwrap(mod: *Zcu, index: Namespace.OptionalIndex) ?*Namespace { | 2172 | pub 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 | } |
| 2500 | 2175 | ||
| 2501 | /// Returns true if and only if the Decl is the top level struct associated with a File. | ||
| 2502 | pub 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/8643 | 2176 | // TODO https://github.com/ziglang/zig/issues/8643 |
| 2510 | pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8; | 2177 | pub const data_has_safety_tag = @sizeOf(Zir.Inst.Data) != 8; |
| 2511 | pub const HackDataLayout = extern struct { | 2178 | pub 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 tyval | 2309 | // 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 may | 2322 | /// 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. |
| 2653 | fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUnit) !void { | 2324 | fn 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 introduced | 2326 | 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 | }); |
| 2658 | 2333 | ||
| 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 |
| 2680 | pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit { | 2355 | pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit { |
| 2681 | if (!zcu.comp.incremental) return null; | 2356 | if (!zcu.comp.incremental) return null; |
| 2682 | 2357 | ||
| 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 | }); |
| 2744 | 2421 | ||
| 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; |
| 2747 | 2426 | ||
| ... | @@ -2939,65 +2618,20 @@ pub fn mapOldZirToNew( | ... | @@ -2939,65 +2618,20 @@ pub fn mapOldZirToNew( |
| 2939 | /// analyzed, and for ensuring it can exist at runtime (see | 2618 | /// analyzed, and for ensuring it can exist at runtime (see |
| 2940 | /// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body | 2619 | /// `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`. |
| 2942 | pub fn ensureFuncBodyAnalysisQueued(mod: *Zcu, func_index: InternPool.Index) !void { | 2621 | pub 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); | ||
| 2969 | 2624 | ||
| 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 | } |
| 2993 | 2634 | ||
| 2994 | pub 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 | |||
| 3001 | pub const ImportFileResult = struct { | 2635 | pub 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 | } |
| 3173 | 2807 | ||
| 3174 | pub fn addGlobalAssembly(mod: *Zcu, decl_index: Decl.Index, source: []const u8) !void { | 2808 | pub 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 | } |
| 3184 | 2819 | ||
| ... | @@ -3315,10 +2950,6 @@ pub fn atomicPtrAlignment( | ... | @@ -3315,10 +2950,6 @@ pub fn atomicPtrAlignment( |
| 3315 | return error.BadType; | 2950 | return error.BadType; |
| 3316 | } | 2951 | } |
| 3317 | 2952 | ||
| 3318 | pub 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 | } |
| 3354 | 2985 | ||
| 3355 | pub fn funcOwnerDeclPtr(mod: *Zcu, func_index: InternPool.Index) *Decl { | 2986 | pub 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 | |||
| 3359 | pub fn funcOwnerDeclIndex(mod: *Zcu, func_index: InternPool.Index) Decl.Index { | ||
| 3360 | return mod.funcInfo(func_index).owner_decl; | ||
| 3361 | } | ||
| 3362 | |||
| 3363 | pub fn iesFuncIndex(mod: *const Zcu, ies_index: InternPool.Index) InternPool.Index { | ||
| 3364 | return mod.intern_pool.iesFuncIndex(ies_index); | ||
| 3365 | } | 2988 | } |
| 3366 | 2989 | ||
| 3367 | pub fn funcInfo(mod: *Zcu, func_index: InternPool.Index) InternPool.Key.Func { | 2990 | pub 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 | } |
| 3374 | 2997 | ||
| 3375 | pub 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 | |||
| 3390 | pub 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 | |||
| 3413 | pub const UnionLayout = struct { | 2998 | pub 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 | } |
| 3470 | 3055 | ||
| 3471 | /// Returns the `Decl` of the struct that represents this `File`. | 3056 | /// Returns the struct that represents this `File`. |
| 3472 | pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex { | 3057 | /// If the struct has not been created, returns `.none`. |
| 3058 | pub 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 | } |
| 3478 | 3064 | ||
| 3479 | pub fn setFileRootDecl(zcu: *Zcu, file_index: File.Index, root_decl: Decl.OptionalIndex) void { | 3065 | pub 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 | } |
| 3485 | 3071 | ||
| 3486 | pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest { | 3072 | 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,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 | |||
| 3079 | pub 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 | |||
| 3087 | pub 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 | |||
| 3096 | pub 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 | |||
| 3100 | pub 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 | |||
| 3105 | pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File { | ||
| 3106 | return zcu.fileByIndex(zcu.navFileScopeIndex(nav)); | ||
| 3107 | } | ||
| 3108 | |||
| 3109 | pub 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, |
| 6 | pub const IdBacking = u7; | 6 | pub const IdBacking = u7; |
| 7 | pub const Id = if (InternPool.single_threaded) enum { main } else enum(IdBacking) { main, _ }; | 7 | pub const Id = if (InternPool.single_threaded) enum { main } else enum(IdBacking) { main, _ }; |
| 8 | 8 | ||
| 9 | pub 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 | |||
| 29 | fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | 9 | fn 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 | } |
| 325 | 302 | ||
| 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(); |
| 330 | 307 | ||
| 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 | } |
| 335 | 312 | ||
| ... | @@ -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 | } |
| 493 | 470 | ||
| 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. | ||
| 495 | pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | 473 | pub 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 | } |
| 502 | 482 | ||
| 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. | 486 | pub fn ensureCauAnalyzed(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) Zcu.SemaError!void { |
| 507 | pub 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(); |
| 512 | 489 | ||
| 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; |
| 516 | 493 | ||
| 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)); | ||
| 521 | 501 | ||
| 522 | // Determine whether or not this Decl is outdated, i.e. requires re-analysis | 502 | // 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 it | 503 | // even if `complete`. If a Cau is PO, we pessismistically assume that it |
| 524 | // *does* require re-analysis, to ensure that the Decl is definitely | 504 | // *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. |
| 526 | 506 | ||
| 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 file | 508 | // We do our best to avoid this by the other dependency logic in this file |
| 529 | // which tries to limit re-analysis to Decls whose previously listed | 509 | // which tries to limit re-analysis to Caus whose previously listed |
| 530 | // dependencies are all up-to-date. | 510 | // dependencies are all up-to-date. |
| 531 | 511 | ||
| 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) or | 513 | 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 | }; | ||
| 535 | 542 | ||
| 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 | } |
| 539 | 546 | ||
| 540 | const was_outdated = mod.outdated_file_root.swapRemove(decl_index) or decl_was_outdated; | 547 | if (!cau_outdated and !file_root_outdated) { |
| 541 | 548 | // 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; |
| 544 | 551 | } | |
| 545 | .file_failure => return error.AnalysisFail, | 552 | // If it wasn't failed and wasn't marked outdated, then either... |
| 546 | 553 | // * 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()) { |
| 551 | 558 | .type, .none => return, | |
| 552 | .complete => if (!was_outdated) return, | 559 | .nav => |nav| if (ip.getNav(nav).status == .resolved) return, |
| 553 | 560 | } | |
| 554 | .unreferenced => {}, | ||
| 555 | } | 561 | } |
| 556 | 562 | ||
| 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 here | 565 | 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 | } |
| 564 | 571 | ||
| 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 | } |
| 581 | 580 | ||
| 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(); |
| 584 | 587 | ||
| 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 would | 591 | // 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 this | 592 | // 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 | }; |
| 610 | 613 | ||
| 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 waiting | 623 | .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 | } |
| 627 | 638 | ||
| ... | @@ -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; |
| 637 | 648 | ||
| 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); |
| 641 | 651 | ||
| 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); | ||
| 645 | 653 | ||
| 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 | }); | ||
| 650 | 655 | ||
| 651 | // First, our owner decl must be up-to-date. This will always be the case | 656 | // Here's an interesting question: is this function actually valid? |
| 652 | // during the first update, but may not on successive updates if we happen | 657 | // 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. | ||
| 655 | 664 | ||
| 656 | // On an update, it's possible this function changed such that our owner | 665 | try pt.ensureCauAnalyzed(cau: { |
| 657 | // decl now refers to a different function, making this one orphaned. If | 666 | 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 | else | 685 | else |
| 671 | .none; | 686 | .none; |
| 672 | 687 | ||
| 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 | ||
| 678 | 691 | ||
| 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 | } |
| 697 | 698 | ||
| 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 this | 707 | .analyzed => return, // up-to-date |
| 708 | } | ||
| 707 | } | 709 | } |
| 708 | 710 | ||
| 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 | }); |
| 713 | 715 | ||
| 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 would | 719 | // 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 this | 720 | // 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); |
| 731 | 728 | ||
| 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 | } |
| 745 | 738 | ||
| 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 | } |
| 774 | 767 | ||
| 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); |
| 778 | 771 | ||
| 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); |
| 781 | 774 | ||
| 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 | } |
| 787 | 780 | ||
| 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 | } |
| 815 | 803 | ||
| 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(); |
| 818 | 806 | ||
| 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 function | 809 | // Correcting this failure will involve changing a type this function |
| 822 | // depends on, hence triggering re-analysis of this function, so this | 810 | // 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 |
| 851 | pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void { | 838 | pub 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 | } |
| 859 | 846 | ||
| 860 | fn getFileRootStruct( | 847 | fn 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); |
| 914 | 900 | ||
| 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 | } |
| 922 | 912 | ||
| 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 | } |
| 933 | 918 | ||
| 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 is | 920 | /// If `type_outdated`, the struct type itself is considered outdated and is |
| 936 | /// reconstructed at a new InternPool index. Otherwise, the namespace is just | 921 | /// 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. | ||
| 938 | fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool { | 924 | fn 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); | ||
| 943 | 932 | ||
| 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 | }); |
| 949 | 938 | ||
| 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 | } |
| 965 | 942 | ||
| 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 | } |
| 980 | 954 | ||
| ... | @@ -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); |
| 995 | 969 | ||
| 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 | } |
| 999 | 973 | ||
| 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; | ||
| 1041 | 987 | ||
| 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); |
| 1047 | 992 | ||
| 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); |
| 1050 | 1000 | ||
| 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 { |
| 1067 | 1017 | ||
| 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 | } |
| 1075 | 1031 | ||
| 1076 | fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { | 1032 | const 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 | }; | ||
| 1079 | 1038 | ||
| 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. | ||
| 1043 | fn 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; |
| 1083 | 1047 | ||
| 1084 | if (decl.getFileScope(zcu).status != .success_zir) { | 1048 | const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index }); |
| 1085 | return error.AnalysisFail; | ||
| 1086 | } | ||
| 1087 | 1049 | ||
| 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; | ||
| 1089 | 1054 | ||
| 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 | } |
| 1094 | 1058 | ||
| 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)}); | ||
| 1098 | 1061 | ||
| 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_only | 1070 | // The type must be recreated at a new `InternPool.Index`. |
| 1108 | else | 1071 | // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed. |
| 1109 | false; | 1072 | ip.remove(pt.tid, ty); |
| 1110 | 1073 | 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 | }; | ||
| 1112 | 1125 | ||
| 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, |
| 1115 | 1128 | .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 | }; |
| 1158 | 1130 | ||
| 1159 | zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | 1131 | log.debug("semaCau '{d}'", .{@intFromEnum(cau_index)}); |
| 1160 | 1132 | ||
| 1161 | decl.analysis = .in_progress; | 1133 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); |
| 1134 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); | ||
| 1162 | 1135 | ||
| 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(); |
| 1185 | 1156 | ||
| 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 | }) }); | ||
| 1191 | 1159 | ||
| 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); | ||
| 1203 | 1190 | ||
| 1204 | const decl_bodies = decl.zirBodies(zcu); | 1191 | const result_ref = try sema.resolveInlineBody(&block, decl_bodies.value_body, inst_info.inst); |
| 1205 | 1192 | ||
| 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 just | 1194 | .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); |
| 1217 | 1219 | ||
| 1218 | // Note this resolves the type of the Decl, not the value; if this Decl | 1220 | 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); |
| 1222 | 1229 | ||
| 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 | } |
| 1231 | 1238 | 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 |
| 1238 | 1245 | 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 | } |
| 1245 | 1251 | ||
| 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 | } | ||
| 1274 | 1258 | ||
| 1275 | decl.val = decl_val; | 1259 | if (nav_already_populated) { |
| 1276 | // Function linksection, align, and addrspace were already set by Sema | 1260 | // 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(); |
| 1304 | 1296 | 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 }); | ||
| 1339 | 1305 | ||
| 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 | } |
| 1344 | 1313 | ||
| 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 | } |
| 1351 | 1323 | ||
| 1352 | try sema.flushExports(); | 1324 | try sema.flushExports(); |
| 1353 | 1325 | ||
| 1354 | return result; | 1326 | queue_codegen: { |
| 1355 | } | 1327 | if (!queue_linker_work) break :queue_codegen; |
| 1356 | |||
| 1357 | pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { | ||
| 1358 | const zcu = pt.zcu; | ||
| 1359 | const decl = zcu.declPtr(decl_index); | ||
| 1360 | 1328 | ||
| 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); | ||
| 1363 | 1335 | ||
| 1364 | log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)}); | 1336 | if (!decl_ty.isFnOrHasRuntimeBits(pt)) break :queue_codegen; |
| 1365 | 1337 | ||
| 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 | } |
| 1371 | 1340 | ||
| 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 anyway | 1344 | .invalidate_decl_ref = true, |
| 1376 | // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction | 1345 | }, |
| 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 genuinely | 1349 | .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 type | 1350 | .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 | } |
| 1393 | 1358 | ||
| 1394 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | 1359 | 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,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(); |
| 1755 | 1719 | ||
| 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); |
| 1759 | 1724 | ||
| 1760 | // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather | 1725 | // 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); |
| 1764 | 1730 | ||
| 1765 | try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count())); | 1731 | try existing_by_inst.ensureTotalCapacity(gpa, @intCast( |
| 1766 | 1732 | 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 | } |
| 1771 | 1767 | ||
| 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); |
| 1774 | 1770 | ||
| 1775 | namespace.decls.clearRetainingCapacity(); | 1771 | namespace.pub_decls.clearRetainingCapacity(); |
| 1776 | try namespace.decls.ensureTotalCapacity(gpa, decls.len); | 1772 | namespace.priv_decls.clearRetainingCapacity(); |
| 1777 | 1773 | namespace.pub_usingnamespace.clearRetainingCapacity(); | |
| 1778 | namespace.usingnamespace_set.clearRetainingCapacity(); | 1774 | namespace.priv_usingnamespace.clearRetainingCapacity(); |
| 1775 | namespace.other_decls.clearRetainingCapacity(); | ||
| 1779 | 1776 | ||
| 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 | } |
| 1811 | 1792 | ||
| 1812 | const ScanDeclIter = struct { | 1793 | const 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 generated | 1798 | /// 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, |
| 1824 | 1803 | ||
| 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 { |
| 1843 | 1822 | ||
| 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; |
| 1851 | 1832 | ||
| 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; |
| 1855 | 1836 | ||
| 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 | }; |
| 1926 | 1903 | ||
| 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 | }); |
| 1938 | 1908 | ||
| 1939 | // We create a Decl for it regardless of analysis status. | 1909 | const existing_cau = iter.existing_by_inst.get(tracked_inst); |
| 1940 | 1910 | ||
| 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 this | 1915 | // 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 }); | ||
| 1967 | 1931 | ||
| 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 update | 1944 | 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 | }; |
| 1991 | 1984 | ||
| 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 and | 1986 | log.debug( |
| 1994 | // `is_export` is unchanged. In this case, the incremental update mechanism will handle | 1987 | "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 | } |
| 2003 | 1992 | ||
| 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 | }; |
| 2013 | 1996 | ||
| 2014 | /// Cancel the creation of an anon decl and delete any references to it. | 1997 | fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!Air { |
| 2015 | /// If other decls depend on this decl, they must be aborted first. | ||
| 2016 | pub 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. | ||
| 2022 | pub 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 | |||
| 2028 | pub 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(); |
| 2031 | 2000 | ||
| 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 | }); | ||
| 2038 | 2025 | ||
| 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)}); | ||
| 2041 | 2027 | ||
| 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(); |
| 2044 | 2030 | ||
| 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(); | ||
| 2046 | 2035 | ||
| 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 the | 2041 | // 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).?; |
| 2057 | 2046 | ||
| 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 |
| 2074 | 2061 | ||
| 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 }); |
| 2079 | 2066 | ||
| 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); |
| 2112 | 2092 | ||
| ... | @@ -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 arg | 2125 | if (gop.found_existing) continue; // provided above by comptime arg |
| 2146 | 2126 | ||
| 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 | }; |
| 2153 | 2133 | ||
| ... | @@ -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 | } |
| 2181 | 2161 | ||
| 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; |
| 2185 | 2163 | ||
| 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; |
| 2191 | 2169 | ||
| 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 @panic | 2171 | 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 | }; |
| 2198 | 2175 | ||
| ... | @@ -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 |
| 2207 | 2184 | ||
| 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 and | 2186 | if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and |
| 2210 | mod.comp.config.any_error_tracing and | 2187 | 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 @panic | 2191 | 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 | } |
| 2253 | 2223 | ||
| 2254 | func.setAnalysisState(ip, .success); | 2224 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); |
| 2255 | 2225 | ||
| 2256 | // Finally we must resolve the return type and parameter types so that backends | 2226 | // 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 than | 2229 | // 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 | }; |
| 2273 | 2239 | ||
| ... | @@ -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 | } |
| 2289 | 2255 | ||
| 2290 | pub 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 | |||
| 2320 | pub fn getErrorValue( | 2256 | pub 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 | } |
| 2330 | 2266 | ||
| 2331 | pub 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 | |||
| 2350 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | 2267 | fn 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; |
| 2369 | 2286 | ||
| 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 | } |
| 2383 | 2300 | ||
| 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()); |
| 2389 | 2306 | ||
| 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); |
| 2426 | 2343 | ||
| 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 | } |
| 2431 | 2348 | ||
| 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 | } |
| 2468 | 2385 | ||
| 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 function | 2390 | 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 failed | 2393 | 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 | } |
| 2485 | 2413 | ||
| 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 | } |
| 2520 | 2451 | ||
| 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); |
| 2523 | 2454 | ||
| 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_functions | 2456 | // 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); |
| 2529 | 2460 | ||
| 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 | // func | 2494 | // 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 | } |
| 2627 | 2547 | ||
| 2628 | try pt.linkerUpdateDecl(decl_index); | 2548 | try pt.linkerUpdateNav(nav_index); |
| 2629 | } | 2549 | } |
| 2630 | } | 2550 | } |
| 2631 | 2551 | ||
| 2632 | pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void { | 2552 | pub 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; |
| 2635 | 2555 | ||
| 2636 | const decl = zcu.declPtr(decl_index); | 2556 | const nav = zcu.intern_pool.getNav(nav_index); |
| 2637 | 2557 | 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(); |
| 2640 | 2559 | ||
| 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 | } |
| 2752 | 2677 | ||
| 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. | ||
| 2754 | pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value { | 2681 | pub 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 | } |
| 2757 | 2703 | ||
| 2758 | pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type { | 2704 | pub 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 | } |
| 3238 | 3184 | ||
| 3239 | pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref { | 3185 | pub 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 | } |
| 3244 | 3192 | ||
| 3245 | pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex { | 3193 | pub 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 | } |
| 3259 | 3210 | ||
| 3260 | pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type { | 3211 | 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,6 +3215,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type |
| 3264 | return ty; | 3215 | return ty; |
| 3265 | } | 3216 | } |
| 3266 | 3217 | ||
| 3218 | pub 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`. | ||
| 3243 | pub 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`. | ||
| 3252 | pub 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 | |||
| 3267 | const Air = @import("../Air.zig"); | 3259 | const Air = @import("../Air.zig"); |
| 3268 | const Allocator = std.mem.Allocator; | 3260 | const Allocator = std.mem.Allocator; |
| 3269 | const assert = std.debug.assert; | 3261 | const 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, |
| 52 | debug_output: DebugInfoOutput, | 52 | debug_output: DebugInfoOutput, |
| 53 | target: *const std.Target, | 53 | target: *const std.Target, |
| 54 | func_index: InternPool.Index, | 54 | func_index: InternPool.Index, |
| 55 | owner_decl: InternPool.DeclIndex, | 55 | owner_nav: InternPool.Nav.Index, |
| 56 | err_msg: ?*ErrorMsg, | 56 | err_msg: ?*ErrorMsg, |
| 57 | args: []MCValue, | 57 | args: []MCValue, |
| 58 | ret_mcv: MCValue, | 58 | ret_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 argument | 202 | else => unreachable, // not a possible argument |
| 203 | 203 | ||
| 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 { |
| 218 | 218 | ||
| 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; | ||
| 349 | 347 | ||
| 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 format | 4058 | 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; | ||
| 4292 | 4291 | ||
| 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 |
| 4351 | 4350 | ||
| 4352 | // Due to incremental compilation, how function calls are generated depends | 4351 | // 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 format | 5600 | 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 format | 5723 | 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 format | 5921 | 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; |
| 689 | 689 | ||
| 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 | } |
| 905 | 905 | ||
| 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 argument | 280 | else => unreachable, // not a possible argument |
| 281 | }; | 281 | }; |
| 282 | 282 | ||
| 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 { |
| 296 | 296 | ||
| 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; | ||
| 354 | 352 | ||
| 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); |
| 387 | 385 | ||
| 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; | ||
| 4267 | 4266 | ||
| 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 |
| 4333 | 4332 | ||
| 4334 | // Due to incremental compilation, how function calls are generated depends | 4333 | // 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 MachO | 4345 | 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 }; |
| 118 | pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; | 118 | pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; |
| 119 | 119 | ||
| 120 | const Owner = union(enum) { | 120 | const 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, |
| 123 | 123 | ||
| 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; | ||
| 776 | 764 | ||
| 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 | } |
| 820 | 808 | ||
| 821 | wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)}); | 809 | wip_mir_log.debug("{}:", .{fmtNav(func.owner_nav, ip)}); |
| 822 | 810 | ||
| 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 | } |
| 1076 | 1064 | ||
| 1077 | const FormatDeclData = struct { | 1065 | const FormatNavData = struct { |
| 1078 | zcu: *Zcu, | 1066 | ip: *const InternPool, |
| 1079 | decl_index: InternPool.DeclIndex, | 1067 | nav_index: InternPool.Nav.Index, |
| 1080 | }; | 1068 | }; |
| 1081 | fn formatDecl( | 1069 | fn 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 | } |
| 1089 | fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { | 1077 | fn 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 | } |
| 1095 | 1083 | ||
| ... | @@ -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)}); |
| 1400 | 1388 | ||
| 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); |
| 1410 | 1398 | ||
| 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)}); |
| 1418 | 1406 | ||
| ... | @@ -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 | } |
| 4683 | 4671 | ||
| 4684 | fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { | 4672 | fn 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)); |
| 4692 | 4677 | ||
| 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); |
| 4951 | 4936 | ||
| 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 format | 4950 | } 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); |
| 4972 | 4956 | ||
| 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( |
| 5223 | 5205 | ||
| 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 { |
| 7804 | 7786 | ||
| 7805 | fn airTagName(func: *Func, inst: Air.Inst.Index) !void { | 7787 | fn airTagName(func: *Func, inst: Air.Inst.Index) !void { |
| 7806 | const pt = func.pt; | 7788 | const pt = func.pt; |
| 7807 | const zcu = pt.zcu; | ||
| 7808 | 7789 | ||
| 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); |
| 7822 | 7803 | ||
| 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 { |
| 8033 | 8014 | ||
| 8034 | fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { | 8015 | fn 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; | ||
| 8038 | 8017 | ||
| 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; |
| 8042 | 8020 | ||
| 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 | }; |
| 51 | 51 | ||
| 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().?; |
| 54 | 54 | ||
| 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().?; |
| 86 | 86 | ||
| 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).?; |
| 113 | 113 |
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; | ||
| 281 | 279 | ||
| 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); |
| 314 | 312 | ||
| 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 |
| 1349 | 1348 | ||
| 1350 | // Due to incremental compilation, how function calls are generated depends | 1349 | // 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 | }); | ||
| 1377 | 1362 | ||
| 1378 | // TODO Find a way to fill this delay slot | 1363 | _ = 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)); |
| 3620 | 3615 | ||
| 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(); |
| 640 | 640 | ||
| 641 | /// Reference to the function declaration the code | 641 | /// Reference to the function declaration the code |
| 642 | /// section belongs to | 642 | /// section belongs to |
| 643 | decl: *Decl, | 643 | owner_nav: InternPool.Nav.Index, |
| 644 | decl_index: InternPool.DeclIndex, | 644 | src_loc: Zcu.LazySrcLoc, |
| 645 | /// Current block depth. Used to calculate the relative difference between a break | 645 | /// Current block depth. Used to calculate the relative difference between a break |
| 646 | /// and block | 646 | /// and block |
| 647 | block_depth: u32 = 0, | 647 | block_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. |
| 682 | simd_immediates: std.ArrayListUnmanaged([16]u8) = .{}, | 682 | simd_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) |
| 684 | target: std.Target, | 684 | target: *const std.Target, |
| 685 | /// Represents the wasm binary file that is being linked. | 685 | /// Represents the wasm binary file that is being linked. |
| 686 | bin_file: *link.File.Wasm, | 686 | bin_file: *link.File.Wasm, |
| 687 | pt: Zcu.PerThread, | 687 | pt: Zcu.PerThread, |
| ... | @@ -765,8 +765,7 @@ pub fn deinit(func: *CodeGen) void { | ... | @@ -765,8 +765,7 @@ pub fn deinit(func: *CodeGen) void { |
| 765 | 765 | ||
| 766 | /// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig | 766 | /// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig |
| 767 | fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError { | 767 | fn 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 | } |
| 772 | 771 | ||
| ... | @@ -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 fits | 803 | // 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 | else | 813 | else |
| 809 | try func.lowerConstant(val, ty); | 814 | try func.lowerConstant(val, ty); |
| 810 | 815 | ||
| ... | @@ -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 | } |
| 996 | 1001 | ||
| 997 | /// Using a given `Type`, returns the corresponding valtype for .auto callconv | 1002 | /// Using a given `Type`, returns the corresponding valtype for .auto callconv |
| 998 | fn typeToValtype(ty: Type, pt: Zcu.PerThread) wasm.Valtype { | 1003 | fn 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 | } |
| 1037 | 1041 | ||
| 1038 | /// Using a given `Type`, returns the byte representation of its wasm value type | 1042 | /// Using a given `Type`, returns the byte representation of its wasm value type |
| 1039 | fn genValtype(ty: Type, pt: Zcu.PerThread) u8 { | 1043 | fn 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 | } |
| 1042 | 1046 | ||
| 1043 | /// Using a given `Type`, returns the corresponding wasm value type | 1047 | /// Using a given `Type`, returns the corresponding wasm value type |
| 1044 | /// Differently from `genValtype` this also allows `void` to create a block | 1048 | /// Differently from `genValtype` this also allows `void` to create a block |
| 1045 | /// with no return type | 1049 | /// with no return type |
| 1046 | fn genBlockType(ty: Type, pt: Zcu.PerThread) u8 { | 1050 | fn 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 | } |
| 1052 | 1056 | ||
| ... | @@ -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 tag | 1112 | /// Returns a corresponding `Wvalue` with `local` as active tag |
| 1109 | fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue { | 1113 | fn 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. |
| 1129 | fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue { | 1133 | fn 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(); |
| 1151 | 1156 | ||
| 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 handle | 1158 | 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/f128 | 1188 | // 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 | } |
| 1191 | 1196 | ||
| ... | @@ -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); |
| 1248 | 1252 | ||
| 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); |
| 1251 | 1255 | ||
| 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 |
| 1367 | 1371 | ||
| 1368 | // Check if we store the result as a pointer to the stack rather than | 1372 | // Check if we store the result as a pointer to the stack rather than |
| 1369 | // by value | 1373 | // 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 we | 1375 | // 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 | } |
| 1403 | 1407 | ||
| 1404 | fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread) bool { | 1408 | fn 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 { |
| 1711 | 1715 | ||
| 1712 | /// For a given `Type`, will return true when the type will be passed | 1716 | /// For a given `Type`, will return true when the type will be passed |
| 1713 | /// by reference, rather than by value | 1717 | /// by reference, rather than by value |
| 1714 | fn isByRef(ty: Type, pt: Zcu.PerThread) bool { | 1718 | fn 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-simd | 1787 | /// 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 store | 1788 | /// 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. |
| 1787 | fn determineSimdStoreStrategy(ty: Type, pt: Zcu.PerThread) SimdStoreStrategy { | 1790 | fn 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); |
| 2096 | 2098 | ||
| 2097 | // result must be stored in the stack and we return a pointer | 2099 | // 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 void | 2142 | break :result try func.allocStack(Type.usize); // create pointer to void |
| 2141 | } | 2143 | } |
| 2142 | 2144 | ||
| 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 | } |
| 2147 | 2149 | ||
| ... | @@ -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); |
| 2160 | 2162 | ||
| 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 stack | 2169 | // 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.*); |
| 2194 | 2196 | ||
| 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; |
| 2197 | 2199 | ||
| 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 | } |
| 2243 | 2254 | ||
| 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 pointer | 2259 | // 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); |
| 2253 | 2264 | ||
| 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); |
| 2256 | 2267 | ||
| 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); |
| 2317 | 2328 | ||
| 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 | } |
| 2321 | 2332 | ||
| ... | @@ -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 instead | 2454 | // into lhs, so we calculate that and emit that instead |
| 2444 | try func.lowerToStack(rhs); | 2455 | try func.lowerToStack(rhs); |
| 2445 | 2456 | ||
| 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}); |
| 2473 | 2484 | ||
| 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 |
| 2522 | 2533 | ||
| 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 | } |
| 2633 | 2644 | ||
| 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! |
| 2644 | 2655 | ||
| 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 | } |
| 2898 | 2909 | ||
| 2899 | const float_bits = ty.floatBits(func.target); | 2910 | const float_bits = ty.floatBits(func.target.*); |
| 2900 | 2911 | ||
| 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 |
| 2955 | 2966 | ||
| 2956 | /// NOTE: The result value remains on top of the stack. | 2967 | /// NOTE: The result value remains on top of the stack. |
| 2957 | fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue { | 2968 | fn 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 | } |
| 3162 | 3173 | ||
| 3163 | fn lowerAnonDeclRef( | 3174 | fn 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)); | ||
| 3172 | 3182 | ||
| 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 | } |
| 3177 | 3187 | ||
| 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 | } |
| 3195 | 3203 | ||
| 3196 | fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue { | 3204 | fn 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; | ||
| 3199 | 3208 | ||
| 3200 | const decl = mod.declPtr(decl_index); | ||
| 3201 | // check if decl is an alias to a function, in which case we | 3209 | // 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 | } |
| 3216 | 3221 | ||
| 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); |
| 3219 | 3224 | ||
| 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 |
| 3229 | fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { | 3234 | fn 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); |
| 3235 | 3240 | ||
| ... | @@ -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 { |
| 3480 | 3481 | ||
| 3481 | fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void { | 3482 | fn 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.*); |
| 3484 | 3485 | ||
| 3485 | // if wasm_block_ty is non-empty, we create a register to store the temporary value | 3486 | // 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 overwritten | 3489 | 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; |
| 3490 | 3491 | ||
| ... | @@ -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 | } |
| 3614 | 3615 | ||
| ... | @@ -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); |
| 3627 | 3628 | ||
| 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. |
| 3647 | fn cmpFloat(func: *CodeGen, ty: Type, lhs: WValue, rhs: WValue, cmp_op: std.math.CompareOperator) InnerError!WValue { | 3648 | fn 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.*); |
| 3649 | 3650 | ||
| 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 | } |
| 3831 | 3832 | ||
| 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 |
| 3867 | 3868 | ||
| 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 | } |
| 4266 | 4267 | ||
| 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 | } |
| 4271 | 4272 | ||
| ... | @@ -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); |
| 4494 | 4495 | ||
| 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 | } |
| 4498 | 4499 | ||
| ... | @@ -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); |
| 4628 | 4629 | ||
| 4629 | const elem_result = if (isByRef(elem_ty, pt)) | 4630 | const elem_result = if (isByRef(elem_ty, pt, func.target.*)) |
| 4630 | .stack | 4631 | .stack |
| 4631 | else | 4632 | 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); |
| 4786 | 4787 | ||
| 4787 | const elem_result = if (isByRef(elem_ty, pt)) | 4788 | const elem_result = if (isByRef(elem_ty, pt, func.target.*)) |
| 4788 | .stack | 4789 | .stack |
| 4789 | else | 4790 | 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 | }; |
| 4837 | 4838 | ||
| 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 }); |
| 4841 | 4842 | ||
| ... | @@ -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); |
| 4984 | 4985 | ||
| 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 | } |
| 5027 | 5028 | ||
| 5028 | const elem_result = if (isByRef(elem_ty, pt)) | 5029 | const elem_result = if (isByRef(elem_ty, pt, func.target.*)) |
| 5029 | .stack | 5030 | .stack |
| 5030 | else | 5031 | 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 { |
| 5040 | 5041 | ||
| 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.*); |
| 5044 | 5045 | ||
| 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); |
| 5089 | 5090 | ||
| 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.*); |
| 5092 | 5093 | ||
| 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); |
| 5133 | 5134 | ||
| 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 directly | 5137 | // 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 load | 5138 | // 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); |
| 5216 | 5217 | ||
| 5217 | // TODO: One of them could be by ref; handle in loop | 5218 | // 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); |
| 5220 | 5221 | ||
| 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 entire | 5292 | // When the element type is by reference, we must copy the entire |
| 5292 | // value. It is therefore safer to move the offset pointer and store | 5293 | // 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 is | 5296 | // 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 | } |
| 5430 | 5431 | ||
| 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: |
| 5513 | 5514 | ||
| 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); |
| 5519 | 5520 | ||
| ... | @@ -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 stack | 5632 | /// NOTE: Leaves the result on the stack |
| 5632 | fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue { | 5633 | fn 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.*); |
| 5635 | 5636 | ||
| 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 stack | 5676 | /// NOTE: The result value remains on the stack |
| 5676 | fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue { | 5677 | fn 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.*); |
| 5679 | 5680 | ||
| 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; |
| 6252 | 6252 | ||
| 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 { |
| 6264 | 6264 | ||
| 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); |
| 6302 | 6302 | ||
| 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 { |
| 6457 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void { | 6457 | fn 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, &.{}); |
| 6459 | 6459 | ||
| 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}); |
| 6470 | 6468 | ||
| 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); |
| 6479 | 6477 | ||
| 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 | } |
| 6553 | 6551 | ||
| 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-ABI | 7124 | // 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); |
| 7133 | 7131 | ||
| 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 argument | 7134 | // 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); | ||
| 7185 | 7182 | ||
| 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(); |
| 7189 | 7186 | ||
| 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)}); | ||
| 7192 | 7188 | ||
| 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 | }; | ||
| 7240 | 7238 | ||
| 7241 | // block for this if case | 7239 | // 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)); |
| 7334 | 7332 | ||
| 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 | }; |
| 7479 | 7477 | ||
| 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 building | 7704 | // 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. |
| 23 | locals: []const u8, | 23 | locals: []const u8, |
| 24 | /// The declaration that code is being generated for. | 24 | /// The declaration that code is being generated for. |
| 25 | decl_index: InternPool.DeclIndex, | 25 | owner_nav: InternPool.Nav.Index, |
| 26 | 26 | ||
| 27 | // Debug information | 27 | // Debug information |
| 28 | /// Holds the debug information for this emission | 28 | /// 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 | } |
| 263 | 263 | ||
| ... | @@ -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); |
| 312 | 312 | ||
| 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); |
| 371 | 371 | ||
| 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); |
| 413 | 413 | ||
| 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 | } |
| 444 | 444 | ||
| 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 }; |
| 116 | const SymbolOffset = struct { sym: u32, off: i32 = 0 }; | 116 | const SymbolOffset = struct { sym: u32, off: i32 = 0 }; |
| 117 | 117 | ||
| 118 | const Owner = union(enum) { | 118 | const 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, |
| 121 | 121 | ||
| 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; | ||
| 814 | 800 | ||
| 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 | } |
| 849 | 835 | ||
| 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; | ||
| 853 | 837 | ||
| 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 | } |
| 1069 | 1053 | ||
| 1070 | const FormatDeclData = struct { | 1054 | const FormatNavData = struct { |
| 1071 | zcu: *Zcu, | 1055 | ip: *const InternPool, |
| 1072 | decl_index: InternPool.DeclIndex, | 1056 | nav_index: InternPool.Nav.Index, |
| 1073 | }; | 1057 | }; |
| 1074 | fn formatDecl( | 1058 | fn 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 | } |
| 1082 | fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { | 1066 | fn 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 | } |
| 1088 | 1072 | ||
| ... | @@ -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)}); |
| 2237 | 2221 | ||
| 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() }); |
| 2253 | 2237 | ||
| 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 | } |
| 11933 | 11917 | ||
| 11934 | fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { | 11918 | fn 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 may | 11938 | // 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( |
| 11979 | 11959 | ||
| 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 index | 11964 | // 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 may | 11988 | // 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; | ||
| 12094 | 12075 | ||
| 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.*); |
| 12112 | 12093 | ||
| 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); |
| 12231 | 12212 | ||
| ... | @@ -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 { |
| 12919 | 12899 | ||
| 12920 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | 12900 | fn 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; |
| 12924 | 12903 | ||
| 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); | ||
| 12929 | 12909 | ||
| 12930 | try self.spillEflagsIfOccupied(); | 12910 | try self.spillEflagsIfOccupied(); |
| 12931 | 12911 | ||
| ... | @@ -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 { |
| 16361 | 16341 | ||
| 16362 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | 16342 | fn 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, .{}); |
| 16395 | 16374 | ||
| 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 | ); | ||
| 16401 | 16377 | ||
| 16402 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); | 16378 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); |
| 16403 | } | 16379 | } |
| 16404 | 16380 | ||
| 16405 | fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | 16381 | fn 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; |
| 16409 | 16383 | ||
| 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); | ||
| 16420 | 16395 | ||
| 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 |
| 18808 | 18783 | ||
| 18809 | fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | 18784 | fn 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_direct | 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_direct |
| 228 | .target = symbol.sym_index, // we set sym_index to just be the atom index | 228 | .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); |
| 350 | 350 | ||
| 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); |
| 354 | 354 | ||
| ... | @@ -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]; |
| 430 | 430 |
src/codegen.zig+71-132| ... | @@ -17,7 +17,7 @@ const ErrorMsg = Zcu.ErrorMsg; | ... | @@ -17,7 +17,7 @@ const ErrorMsg = Zcu.ErrorMsg; |
| 17 | const InternPool = @import("InternPool.zig"); | 17 | const InternPool = @import("InternPool.zig"); |
| 18 | const Liveness = @import("Liveness.zig"); | 18 | const Liveness = @import("Liveness.zig"); |
| 19 | const Zcu = @import("Zcu.zig"); | 19 | const Zcu = @import("Zcu.zig"); |
| 20 | const Target = std.Target; | 20 | |
| 21 | const Type = @import("Type.zig"); | 21 | const Type = @import("Type.zig"); |
| 22 | const Value = @import("Value.zig"); | 22 | const Value = @import("Value.zig"); |
| 23 | const Zir = std.zig.Zir; | 23 | const Zir = std.zig.Zir; |
| ... | @@ -26,7 +26,7 @@ const dev = @import("dev.zig"); | ... | @@ -26,7 +26,7 @@ const dev = @import("dev.zig"); |
| 26 | 26 | ||
| 27 | pub const Result = union(enum) { | 27 | pub 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, |
| 30 | 30 | ||
| 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 | }; |
| 40 | 40 | ||
| 41 | pub const DebugInfoOutput = union(enum) { | 41 | pub 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 | } |
| 117 | 113 | ||
| 118 | fn writeFloat(comptime F: type, f: F, target: Target, endian: std.builtin.Endian, code: []u8) void { | 114 | fn 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( |
| 147 | 143 | ||
| 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 | }); |
| 152 | 148 | ||
| 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 | } |
| 157 | 153 | ||
| 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 | } |
| 191 | 188 | ||
| ... | @@ -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 | }; |
| 707 | 704 | ||
| 708 | fn lowerAnonDeclRef( | 705 | fn 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; |
| 721 | 718 | ||
| 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 | } |
| 731 | 728 | ||
| 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 | } |
| 738 | 735 | ||
| 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 | } |
| 754 | 751 | ||
| 755 | fn lowerDeclRef( | 752 | fn 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; | ||
| 771 | 767 | ||
| 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 | } |
| 778 | 775 | ||
| 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 | }; |
| 850 | 847 | ||
| 851 | fn genDeclRef( | 848 | fn 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); | ||
| 876 | 860 | ||
| 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 | } |
| 902 | 886 | ||
| 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 }, |
| 907 | 891 | 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 this | 898 | // 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 this | 923 | // 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 GOT | 925 | 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 | |||
| 959 | fn 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 | } |
| 995 | 939 | ||
| ... | @@ -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 | } |
| 1012 | 956 | ||
| 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 | } |
| 1123 | 1062 | ||
| 1124 | return genUnnamedConst(lf, pt, src_loc, val, owner_decl_index); | 1063 | return lf.lowerUav(pt, val.toIntern(), .none, src_loc); |
| 1125 | } | 1064 | } |
| 1126 | 1065 | ||
| 1127 | pub fn errUnionPayloadOffset(payload_ty: Type, pt: Zcu.PerThread) u64 { | 1066 | pub 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 fields | 38 | /// Index into a tuple's fields |
| 39 | field: usize, | 39 | field: usize, |
| 40 | /// By-value | 40 | /// 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 { |
| 58 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); | 58 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); |
| 59 | 59 | ||
| 60 | pub const LazyFnKey = union(enum) { | 60 | pub 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 | }; |
| 65 | pub const LazyFnValue = struct { | 65 | pub 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 | }; |
| 75 | pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue); | 68 | pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue); |
| 76 | 69 | ||
| ... | @@ -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 | } |
| 500 | 493 | ||
| 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; |
| 506 | 500 | ||
| 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 this | 613 | /// 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), |
| 623 | 617 | ||
| 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 | }; |
| 629 | 623 | ||
| ... | @@ -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 | } |
| 643 | 635 | ||
| 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); |
| 656 | 648 | ||
| 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 | } |
| 662 | 654 | ||
| 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), |
| 668 | 660 | else => {}, | |
| 669 | assert(decl_val.getVariable(zcu) == null); | 661 | } |
| 670 | 662 | ||
| 671 | // We shouldn't cast C function pointers as this is UB (when you call | 663 | // 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 function | 664 | // 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) and | 670 | 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(')'); |
| 688 | 680 | ||
| 689 | // Indicate that the anon decl should be rendered to the output so that | 681 | // 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.* = .{}; |
| 694 | 686 | ||
| 695 | // Only insert an alignment entry if the alignment is greater than ABI | 687 | // 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 | else | 696 | else |
| ... | @@ -707,47 +699,49 @@ pub const DeclGen = struct { | ... | @@ -707,47 +699,49 @@ pub const DeclGen = struct { |
| 707 | } | 699 | } |
| 708 | } | 700 | } |
| 709 | 701 | ||
| 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 | }; | ||
| 721 | 721 | ||
| 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 | } |
| 728 | 728 | ||
| 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 call | 729 | // 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 function | 730 | // them). The analysis until now should ensure that the C function |
| 737 | // pointers are compatible. If they are not, then there is a bug | 731 | // 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) and | 736 | 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 | } |
| 753 | 747 | ||
| ... | @@ -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 | }, |
| 771 | 765 | ||
| 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), |
| 774 | 768 | ||
| 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 { |
| 1805 | 1799 | ||
| 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 { |
| 2164 | 2158 | ||
| 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 | } |
| 2186 | 2186 | ||
| 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())) { |
| 2191 | 2191 | .@"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 | } |
| 2204 | 2205 | ||
| 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 | } |
| 2208 | 2209 | ||
| 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 | }, |
| 2341 | 2343 | ||
| 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( |
| 2370 | 2372 | ||
| 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 | }, |
| 2383 | 2385 | ||
| 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; |
| 2716 | 2718 | ||
| 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); |
| 2764 | 2766 | ||
| 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"); |
| 2771 | 2773 | ||
| 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 { |
| 2791 | 2793 | ||
| 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); | ||
| 2797 | 2801 | ||
| 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"); |
| 2811 | 2815 | ||
| 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(' '); |
| 2822 | 2826 | ||
| ... | @@ -2883,44 +2887,66 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -2883,44 +2887,66 @@ pub fn genDecl(o: *Object) !void { |
| 2883 | 2887 | ||
| 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 | }); | ||
| 2889 | 2903 | ||
| 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, |
| 2907 | 2921 | .is_const = false, | |
| 2908 | if (variable.is_extern) return; | 2922 | .is_threadlocal = variable.is_threadlocal, |
| 2909 | 2923 | .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 | } |
| 2926 | 2952 | ||
| ... | @@ -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'); |
| 2965 | 2991 | ||
| 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( |
| 4474 | 4503 | ||
| 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 { |
| 4554 | fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue { | 4578 | fn 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 | } |
| 4564 | 4589 | ||
| ... | @@ -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 | } |
| 6842 | 6867 | ||
| 6843 | fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { | 6868 | fn 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; |
| 6847 | 6870 | ||
| 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; | ||
| 7397 | 7419 | ||
| 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 { |
| 7941 | 7963 | ||
| 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 | }; |
| 840 | 840 | ||
| ... | @@ -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 and | 888 | .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 and | 891 | .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and |
| 892 | lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and | 892 | 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 and | 894 | .anon => |lhs_anon| rhs_info.aggregate.name == .anon and |
| 895 | lhs_anon.owner_decl == rhs_info.aggregate.name.anon.owner_decl and | 895 | lhs_anon.index == rhs_info.aggregate.name.anon.index and |
| 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 and | 897 | .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_decl | 1689 | 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_decl | 1828 | 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 | }; |
| 2427 | 2427 | ||
| 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 | }; |
| 2547 | 2547 | ||
| 2548 | pub const AlignAs = packed struct { | 2548 | pub const AlignAs = packed struct { |
| 2549 | @"align": Alignment, | 2549 | @"align": InternPool.Alignment, |
| 2550 | abi: Alignment, | 2550 | abi: InternPool.Alignment, |
| 2551 | 2551 | ||
| 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 | } |
| 2569 | 2569 | ||
| ... | @@ -2578,11 +2578,10 @@ pub const AlignAs = packed struct { | ... | @@ -2578,11 +2578,10 @@ pub const AlignAs = packed struct { |
| 2578 | } | 2578 | } |
| 2579 | }; | 2579 | }; |
| 2580 | 2580 | ||
| 2581 | const Alignment = @import("../../InternPool.zig").Alignment; | ||
| 2582 | const assert = std.debug.assert; | 2581 | const assert = std.debug.assert; |
| 2583 | const CType = @This(); | 2582 | const CType = @This(); |
| 2583 | const InternPool = @import("../../InternPool.zig"); | ||
| 2584 | const Module = @import("../../Package/Module.zig"); | 2584 | const Module = @import("../../Package/Module.zig"); |
| 2585 | const std = @import("std"); | 2585 | const std = @import("std"); |
| 2586 | const Type = @import("../../Type.zig"); | 2586 | const Type = @import("../../Type.zig"); |
| 2587 | const Zcu = @import("../../Zcu.zig"); | 2587 | const Zcu = @import("../../Zcu.zig"); |
| 2588 | const 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), |
| 778 | 778 | ||
| 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), |
| 781 | 781 | ||
| 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 of | 800 | /// 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 needs | 802 | /// 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]; |
| 1109 | 1113 | ||
| 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)); |
| 1112 | 1116 | ||
| 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; | ||
| 1340 | 1343 | ||
| 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 | }; |
| 1347 | 1349 | ||
| 1348 | const function_index = try o.resolveLlvmFunction(decl_index); | 1350 | const function_index = try o.resolveLlvmFunction(func.owner_nav); |
| 1349 | 1351 | ||
| 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 | } |
| 1411 | 1413 | ||
| 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); |
| 1414 | 1416 | ||
| 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 { |
| 1422 | 1424 | ||
| 1423 | var llvm_arg_i: u32 = 0; | 1425 | var llvm_arg_i: u32 = 0; |
| 1424 | 1426 | ||
| 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); |
| 1624 | 1626 | ||
| 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); |
| 1628 | 1630 | ||
| 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 { |
| 1675 | 1677 | ||
| 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 | } |
| 1688 | 1689 | ||
| 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; |
| 1725 | 1722 | ||
| 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 | } |
| 1870 | 1867 | ||
| 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 | } |
| 1941 | 1936 | ||
| 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); |
| 1946 | 1940 | ||
| ... | @@ -1963,9 +1957,11 @@ pub const Object = struct { | ... | @@ -1963,9 +1957,11 @@ pub const Object = struct { |
| 1963 | ); | 1957 | ); |
| 1964 | } | 1958 | } |
| 1965 | 1959 | ||
| 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; | ||
| 1969 | 1965 | ||
| 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, // Line | 1973 | 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 { |
| 2138 | 2134 | ||
| 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, // Line | 2148 | ty.typeDeclSrcLine(zcu).? + 1, // Line |
| 2149 | .none, // Underlying type | 2149 | .none, // Underlying type |
| 2150 | 0, // Size | 2150 | 0, // Size |
| 2151 | 0, // Align | 2151 | 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 the | 2461 | // 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 | } |
| 2471 | 2470 | ||
| 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); |
| 2543 | 2539 | ||
| ... | @@ -2546,7 +2542,7 @@ pub const Object = struct { | ... | @@ -2546,7 +2542,7 @@ pub const Object = struct { |
| 2546 | !ty.hasRuntimeBitsIgnoreComptime(pt) or | 2542 | !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); | ||
| 2767 | 2762 | ||
| 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); |
| 2769 | 2764 | ||
| ... | @@ -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 | } |
| 2774 | 2769 | ||
| 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 name | 2779 | 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; | ||
| 2794 | 2794 | ||
| 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; |
| 2797 | 2797 | ||
| 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 }).?; |
| 2802 | 2802 | ||
| 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); | ||
| 2809 | 2808 | ||
| 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 | } |
| 2814 | 2812 | ||
| 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; |
| 2839 | 2838 | ||
| 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); |
| 2844 | 2842 | ||
| 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; |
| 2852 | 2854 | ||
| ... | @@ -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 | } |
| 2903 | 2905 | ||
| 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); |
| 2906 | 2908 | ||
| 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 | } |
| 3008 | 3010 | ||
| 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_map | 3018 | // 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)); |
| 3027 | 3029 | ||
| 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); |
| 3030 | 3032 | ||
| 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; |
| 3037 | 3039 | ||
| 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 | } |
| 3045 | 3047 | ||
| 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)); |
| 3053 | 3055 | ||
| 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 | }; | ||
| 3059 | 3066 | ||
| 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; |
| 3066 | 3073 | ||
| ... | @@ -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 | } |
| 3288 | 3289 | ||
| 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 be | 3292 | // 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 | } |
| 3353 | 3352 | ||
| 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); |
| 3356 | 3355 | ||
| 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 | } |
| 3442 | 3441 | ||
| 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); |
| 3447 | 3444 | ||
| ... | @@ -3460,7 +3457,7 @@ pub const Object = struct { | ... | @@ -3460,7 +3457,7 @@ pub const Object = struct { |
| 3460 | }; | 3457 | }; |
| 3461 | 3458 | ||
| 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); |
| 3465 | 3462 | ||
| 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 | } |
| 3490 | 3487 | ||
| 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); |
| 3493 | 3490 | ||
| 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 { |
| 3632 | 3628 | ||
| 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 values | 3779 | => 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 | } |
| 4334 | 4326 | ||
| 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(); |
| 4347 | 4339 | ||
| 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 | } |
| 4355 | 4345 | ||
| 4356 | const ptr_ty = Type.fromInterned(anon_decl.orig_ty); | 4346 | const ptr_ty = Type.fromInterned(uav.orig_ty); |
| 4357 | 4347 | ||
| 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)) or | 4349 | 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); |
| 4361 | 4351 | ||
| 4362 | if (is_fn_body) | 4352 | if (is_fn_body) |
| 4363 | @panic("TODO"); | 4353 | @panic("TODO"); |
| 4364 | 4354 | ||
| 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; |
| 4368 | 4358 | ||
| 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 | } |
| 4376 | 4366 | ||
| 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; | ||
| 4380 | 4371 | ||
| 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 | } | ||
| 4396 | 4383 | ||
| 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); |
| 4399 | 4386 | ||
| 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)) or | 4388 | 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 | } |
| 4406 | 4393 | ||
| 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).global | 4395 | (try o.resolveLlvmFunction(owner_nav_index)).ptrConst(&o.builder).global |
| 4409 | else | 4396 | else |
| 4410 | (try o.resolveGlobalDecl(decl_index)).ptrConst(&o.builder).global; | 4397 | (try o.resolveGlobalNav(owner_nav_index)).ptrConst(&o.builder).global; |
| 4411 | 4398 | ||
| 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 | ); |
| 4416 | 4403 | ||
| 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()); |
| 4555 | 4542 | ||
| 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())); |
| 4560 | 4546 | ||
| 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 | ); |
| 4570 | 4555 | ||
| ... | @@ -4624,86 +4609,73 @@ pub const Object = struct { | ... | @@ -4624,86 +4609,73 @@ pub const Object = struct { |
| 4624 | } | 4609 | } |
| 4625 | }; | 4610 | }; |
| 4626 | 4611 | ||
| 4627 | pub const DeclGen = struct { | 4612 | pub 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, |
| 4632 | 4616 | ||
| 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 | } |
| 4640 | 4620 | ||
| 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 | } |
| 4650 | 4630 | ||
| 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)); | ||
| 4659 | 4646 | ||
| 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); |
| 4679 | 4659 | ||
| 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; | ||
| 4690 | 4664 | ||
| 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; | ||
| 4694 | 4666 | ||
| 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); |
| 4697 | 4669 | ||
| 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)), // Name | 4671 | try o.builder.metadataString(nav.name.toSlice(ip)), // Name |
| 4700 | try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name | 4672 | try o.builder.metadataStringFromStrtabString(variable_index.name(&o.builder)), // Linkage name |
| 4701 | debug_file, // File | 4673 | debug_file, // File |
| 4702 | debug_file, // Scope | 4674 | 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 | ); |
| 4708 | 4680 | ||
| 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 | } |
| 4720 | 4692 | ||
| 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).?; |
| 4723 | 4695 | ||
| 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 | }; |
| 4734 | 4706 | ||
| 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); |
| 4748 | 4720 | ||
| 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 | }; |
| 4755 | 4725 | ||
| 4756 | pub const FuncGen = struct { | 4726 | pub 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 { |
| 4815 | 4785 | ||
| 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 | } |
| 4820 | 4790 | ||
| 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.*; |
| 4825 | 4795 | ||
| 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 | } |
| 4830 | 4800 | ||
| 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 | } |
| 4856 | 4826 | ||
| 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 | } |
| 4868 | 4838 | ||
| 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; |
| 5133 | 5103 | ||
| 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; | ||
| 5138 | 5109 | ||
| 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; | ||
| 5145 | 5114 | ||
| 5146 | self.file = try o.getDebugFile(file_scope); | 5115 | self.file = try o.getDebugFile(file_scope); |
| 5147 | 5116 | ||
| 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; |
| 5150 | 5119 | ||
| 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 { |
| 5155 | 5124 | ||
| 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 | ); |
| 5173 | 5142 | ||
| 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 | } |
| 5185 | 5154 | ||
| 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 | } |
| 5516 | 5485 | ||
| 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 trace | 5501 | // 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 | } |
| 5554 | 5524 | ||
| 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); |
| 5561 | 5532 | ||
| ... | @@ -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 code | 5579 | // 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 | } |
| 5660 | 5631 | ||
| 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 code | 5643 | // 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 | } |
| 5690 | 5662 | ||
| 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 | } |
| 5700 | 5672 | ||
| 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 | } |
| 5726 | 5698 | ||
| 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 | } |
| 5768 | 5740 | ||
| 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 | } |
| 5949 | 5921 | ||
| 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 | } |
| 5989 | 5961 | ||
| 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 | } |
| 6004 | 5976 | ||
| 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 | } |
| 6089 | 6061 | ||
| 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 | } |
| 6153 | 6125 | ||
| 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 | } |
| 6177 | 6149 | ||
| 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 | } |
| 6196 | 6168 | ||
| 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; |
| 6282 | 6254 | ||
| 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 | } |
| 6343 | 6315 | ||
| 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 | } |
| 6349 | 6321 | ||
| 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 | } |
| 6379 | 6351 | ||
| 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 | } |
| 6390 | 6362 | ||
| 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 | } |
| 6414 | 6386 | ||
| 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 | } |
| 6428 | 6400 | ||
| 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 | } |
| 6461 | 6433 | ||
| 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 | } |
| 6487 | 6459 | ||
| 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 | } |
| 6530 | 6502 | ||
| 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 | } |
| 6636 | 6608 | ||
| 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 | } |
| 6698 | 6670 | ||
| 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 | } |
| 6730 | 6702 | ||
| 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 | ); |
| 6747 | 6719 | ||
| 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. |
| 6802 | 6774 | ||
| 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 | } |
| 7267 | 7239 | ||
| 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); |
| 7290 | 7262 | ||
| 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 | } |
| 7321 | 7293 | ||
| 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 | } |
| 7416 | 7388 | ||
| 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 | } |
| 7457 | 7429 | ||
| 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; |
| 7462 | 7434 | ||
| ... | @@ -7502,7 +7474,7 @@ pub const FuncGen = struct { | ... | @@ -7502,7 +7474,7 @@ pub const FuncGen = struct { |
| 7502 | } | 7474 | } |
| 7503 | 7475 | ||
| 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 | } |
| 7537 | 7509 | ||
| 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 | } |
| 7578 | 7550 | ||
| 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 | } |
| 7619 | 7591 | ||
| 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 | } |
| 7629 | 7601 | ||
| 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 | } |
| 7639 | 7611 | ||
| 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 | } |
| 7662 | 7634 | ||
| 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 | } |
| 7682 | 7654 | ||
| 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 | } |
| 7702 | 7674 | ||
| 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 | } |
| 7712 | 7684 | ||
| 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; |
| 7734 | 7706 | ||
| 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 | } |
| 7778 | 7750 | ||
| 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 | } |
| 7798 | 7770 | ||
| 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 | } |
| 7819 | 7791 | ||
| 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 | } |
| 7839 | 7811 | ||
| 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 | } |
| 7860 | 7832 | ||
| 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 | } |
| 7889 | 7861 | ||
| 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 | } |
| 7905 | 7877 | ||
| 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 | } |
| 7937 | 7909 | ||
| 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 | } |
| 7955 | 7927 | ||
| 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 | } |
| 7972 | 7944 | ||
| 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 | } |
| 8008 | 7980 | ||
| 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 | } |
| 8030 | 8002 | ||
| 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); |
| 8116 | 8088 | ||
| 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 | } |
| 8413 | 8385 | ||
| 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 | } |
| 8484 | 8456 | ||
| 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; |
| 8489 | 8461 | ||
| ... | @@ -8501,7 +8473,7 @@ pub const FuncGen = struct { | ... | @@ -8501,7 +8473,7 @@ pub const FuncGen = struct { |
| 8501 | } | 8473 | } |
| 8502 | 8474 | ||
| 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; |
| 8506 | 8478 | ||
| 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 | } |
| 8515 | 8487 | ||
| 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 | } |
| 8558 | 8530 | ||
| 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; |
| 8563 | 8535 | ||
| ... | @@ -8576,7 +8548,7 @@ pub const FuncGen = struct { | ... | @@ -8576,7 +8548,7 @@ pub const FuncGen = struct { |
| 8576 | } | 8548 | } |
| 8577 | 8549 | ||
| 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 | } |
| 8599 | 8571 | ||
| 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 | } |
| 8615 | 8587 | ||
| 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 | } |
| 8623 | 8595 | ||
| 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 | } |
| 8657 | 8629 | ||
| 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 | } |
| 8697 | 8669 | ||
| 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 | } |
| 8715 | 8687 | ||
| 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", .{}); |
| 8770 | 8742 | ||
| 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 | } |
| 8832 | 8804 | ||
| 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; |
| 8839 | 8811 | ||
| ... | @@ -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; |
| 8848 | 8820 | ||
| 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; |
| 8853 | 8824 | ||
| 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 | }; |
| 8872 | 8843 | ||
| 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 | } |
| 8921 | 8892 | ||
| 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 | } |
| 8935 | 8906 | ||
| 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 | } |
| 8960 | 8931 | ||
| ... | @@ -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 | } |
| 8970 | 8941 | ||
| 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 { |
| 8979 | 8950 | ||
| 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(); |
| 8983 | 8954 | ||
| 8984 | // Even if safety is disabled, we still emit a memset to undefined since it conveys | 8955 | // 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 difference | 8956 | // 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 | } |
| 9046 | 9017 | ||
| 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 { |
| 9077 | 9048 | ||
| 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/11946 | 9054 | // https://github.com/ziglang/zig/issues/11946 |
| ... | @@ -9089,7 +9060,7 @@ pub const FuncGen = struct { | ... | @@ -9089,7 +9060,7 @@ pub const FuncGen = struct { |
| 9089 | 9060 | ||
| 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 | } |
| 9158 | 9129 | ||
| 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 | } |
| 9222 | 9193 | ||
| 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 | } |
| 9295 | 9266 | ||
| 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 | } |
| 9449 | 9420 | ||
| 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 | } |
| 9503 | 9474 | ||
| 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 | } |
| 9525 | 9496 | ||
| 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 | } |
| 9564 | 9535 | ||
| 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 | } |
| 9582 | 9553 | ||
| 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 | } |
| 9600 | 9571 | ||
| 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 | } |
| 9634 | 9605 | ||
| 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 | } |
| 9666 | 9637 | ||
| 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 | } |
| 9684 | 9655 | ||
| 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()); |
| 9691 | 9662 | ||
| 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())); |
| 9696 | 9667 | ||
| 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 | ); |
| 9704 | 9674 | ||
| ... | @@ -9741,7 +9711,7 @@ pub const FuncGen = struct { | ... | @@ -9741,7 +9711,7 @@ pub const FuncGen = struct { |
| 9741 | } | 9711 | } |
| 9742 | 9712 | ||
| 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 | } |
| 9760 | 9730 | ||
| 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 | } |
| 9775 | 9745 | ||
| 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 | } |
| 9793 | 9763 | ||
| 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 | } |
| 9903 | 9873 | ||
| 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(); |
| 9908 | 9878 | ||
| ... | @@ -10012,7 +9982,7 @@ pub const FuncGen = struct { | ... | @@ -10012,7 +9982,7 @@ pub const FuncGen = struct { |
| 10012 | } | 9982 | } |
| 10013 | 9983 | ||
| 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 | } |
| 10134 | 10104 | ||
| 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 | } |
| 10257 | 10227 | ||
| 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; |
| 10261 | 10231 | ||
| 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 | } |
| 10307 | 10277 | ||
| 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 | } |
| 10330 | 10300 | ||
| 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 architectures | 10304 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures |
| 10335 | 10305 | ||
| ... | @@ -10339,7 +10309,7 @@ pub const FuncGen = struct { | ... | @@ -10339,7 +10309,7 @@ pub const FuncGen = struct { |
| 10339 | } | 10309 | } |
| 10340 | 10310 | ||
| 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 architectures | 10314 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures |
| 10345 | 10315 | ||
| ... | @@ -10362,7 +10332,7 @@ pub const FuncGen = struct { | ... | @@ -10362,7 +10332,7 @@ pub const FuncGen = struct { |
| 10362 | } | 10332 | } |
| 10363 | 10333 | ||
| 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 architectures | 10337 | assert(target.cpu.arch == .amdgcn); // TODO is to port this function to other GPU architectures |
| 10368 | 10338 | ||
| ... | @@ -10372,7 +10342,7 @@ pub const FuncGen = struct { | ... | @@ -10372,7 +10342,7 @@ pub const FuncGen = struct { |
| 10372 | } | 10342 | } |
| 10373 | 10343 | ||
| 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; |
| 10377 | 10347 | ||
| 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. |
| 10554 | 10524 | ||
| 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 { |
| 10784 | 10754 | ||
| 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 | } |
| 10870 | 10840 | ||
| 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 | } |
| 10876 | 10846 | ||
| 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); |
| 31 | 31 | ||
| 32 | pub const zig_call_abi_ver = 3; | 32 | pub const zig_call_abi_ver = 3; |
| 33 | 33 | ||
| 34 | const InternMap = std.AutoHashMapUnmanaged(struct { InternPool.Index, DeclGen.Repr }, IdResult); | 34 | const InternMap = std.AutoHashMapUnmanaged(struct { InternPool.Index, NavGen.Repr }, IdResult); |
| 35 | const PtrTypeMap = std.AutoHashMapUnmanaged( | 35 | const 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 | ); |
| 39 | 39 | ||
| ... | @@ -142,7 +142,7 @@ const ControlFlow = union(enum) { | ... | @@ -142,7 +142,7 @@ const ControlFlow = union(enum) { |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 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 a | 145 | /// in contrast to `NavGen`, which only holds relevant information about a |
| 146 | /// single decl. | 146 | /// single decl. |
| 147 | pub const Object = struct { | 147 | pub 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 { |
| 153 | 153 | ||
| 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) = .{}, |
| 157 | 157 | ||
| 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) = .{}, |
| 160 | 160 | ||
| 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 { |
| 178 | 178 | ||
| 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 | } |
| 186 | 186 | ||
| 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; | ||
| 199 | 197 | ||
| 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(); |
| 218 | 216 | ||
| 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_msg | 222 | // 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 | } |
| 229 | 227 | ||
| ... | @@ -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 | } |
| 246 | 244 | ||
| 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 | } |
| 254 | 252 | ||
| 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 | .func | 262 | .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 | }; |
| 277 | 274 | ||
| 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. |
| 279 | const DeclGen = struct { | 276 | const 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, |
| 282 | 279 | ||
| 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, |
| 292 | 289 | ||
| 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, |
| 295 | 292 | ||
| 296 | /// The intermediate code of the declaration we are currently generating. Note: If | 293 | /// 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 | }; |
| 401 | 398 | ||
| 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 | } |
| 409 | 406 | ||
| 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 | } |
| 414 | 411 | ||
| 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 | } |
| 423 | 420 | ||
| 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 | } |
| 427 | 424 | ||
| 428 | /// This imports the "default" extended instruction set for the target | 425 | /// 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 | } |
| 438 | 435 | ||
| 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 | } |
| 461 | 458 | ||
| 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. |
| 464 | 461 | ||
| 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); |
| 468 | 465 | ||
| 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); |
| 473 | 470 | ||
| ... | @@ -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 | } |
| 542 | 539 | ||
| 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 class | 543 | // 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 | } |
| 557 | 554 | ||
| 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(); |
| 560 | 557 | ||
| 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 to | 573 | /// 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(); |
| 595 | 592 | ||
| 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 there | 622 | /// 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 | 64 | 628 | 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 by | 633 | /// 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 | } |
| 642 | 639 | ||
| 643 | /// Checks whether the type can be directly translated to SPIR-V vectors | 640 | /// 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 | } |
| 669 | 666 | ||
| 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 | } |
| 716 | 713 | ||
| 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? |
| 720 | 717 | ||
| 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 bitcast | 740 | /// 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); |
| 814 | 811 | ||
| 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 { |
| 823 | 820 | ||
| 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); |
| 829 | 826 | ||
| ... | @@ -847,7 +844,7 @@ const DeclGen = struct { | ... | @@ -847,7 +844,7 @@ const DeclGen = struct { |
| 847 | 844 | ||
| 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); |
| 853 | 850 | ||
| ... | @@ -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. For | 880 | // 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 above | 919 | .undef => unreachable, // handled above |
| 923 | 920 | ||
| 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 | } |
| 1144 | 1141 | ||
| 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?? |
| 1147 | 1144 | ||
| 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 | } |
| 1162 | 1159 | ||
| 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 | } |
| 1229 | 1226 | ||
| 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. |
| 1236 | 1233 | ||
| ... | @@ -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)); | ||
| 1243 | 1239 | ||
| 1244 | if (Value.fromInterned(decl_val).getFunction(mod)) |func| { | 1240 | switch (ip.indexToKey(uav.val)) { |
| 1245 | _ = func; | 1241 | .func => unreachable, // TODO |
| 1246 | unreachable; // TODO | 1242 | .@"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 | } |
| 1251 | 1245 | ||
| 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 undefoined | 1248 | // Pointer to nothing - return undefined |
| 1255 | return self.spv.constUndef(ty_id); | 1249 | return self.spv.constUndef(ty_id); |
| 1256 | } | 1250 | } |
| 1257 | 1251 | ||
| 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); |
| 1266 | 1256 | ||
| 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 | } |
| 1280 | 1270 | ||
| 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); | ||
| 1286 | 1279 | ||
| 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 and | 1282 | // 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, // TODO | 1286 | .@"extern" => assert(!ip.isFunctionType(nav_ty.toIntern())), // TODO |
| 1294 | else => {}, | 1287 | else => {}, |
| 1295 | } | 1288 | } |
| 1296 | 1289 | ||
| 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 | } |
| 1301 | 1294 | ||
| 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); |
| 1304 | 1297 | ||
| 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 | }; |
| 1309 | 1302 | ||
| 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); |
| 1312 | 1305 | ||
| 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); |
| 1314 | 1307 | ||
| 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 | } |
| 1333 | 1326 | ||
| 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 perform | 1336 | /// 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 create | 1337 | /// 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 | } |
| 1360 | 1353 | ||
| 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 | } |
| 1373 | 1366 | ||
| 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 | } |
| 1377 | 1370 | ||
| 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 | } |
| 1409 | 1402 | ||
| 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?? |
| 1412 | 1405 | ||
| 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 | } |
| 1429 | 1422 | ||
| 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 | } |
| 1511 | 1504 | ||
| 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 this | 1508 | // 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 | } |
| 1527 | 1520 | ||
| 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 | } |
| 1538 | 1531 | ||
| 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 | } |
| 1841 | 1834 | ||
| 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 | }; |
| 1884 | 1877 | ||
| 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; |
| 1887 | 1880 | ||
| 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 | }; |
| 1915 | 1908 | ||
| 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 | } |
| 2006 | 1999 | ||
| 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 | } |
| 2023 | 2016 | ||
| 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 | } |
| 2027 | 2020 | ||
| 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 { |
| 2034 | 2027 | ||
| 2035 | /// 'Explode' a temporary into separate elements. This turns a vector | 2028 | /// '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; |
| 2039 | 2032 | ||
| 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 | } |
| 2047 | 2040 | ||
| 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); |
| 2051 | 2044 | ||
| 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 { |
| 2056 | 2049 | ||
| 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 | }; |
| 2070 | 2063 | ||
| 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 usually | 2086 | /// Derive a vectorization from a particular type. This usually |
| 2094 | /// only checks the size, but the source-of-truth is implemented | 2087 | /// 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 { |
| 2169 | 2162 | ||
| 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 { |
| 2183 | 2176 | ||
| 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 implements | 2191 | /// 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 access | 2192 | /// 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 | }); |
| 2222 | 2215 | ||
| 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` instance | 2317 | /// - 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 { |
| 2345 | 2338 | ||
| 2346 | /// This function builds an OpSConvert of OpUConvert depending on the | 2339 | /// 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; |
| 2350 | 2343 | ||
| 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 | } |
| 2386 | 2379 | ||
| 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(); |
| 2389 | 2382 | ||
| 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 | } |
| 2426 | 2419 | ||
| 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; |
| 2429 | 2422 | ||
| 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 | }; |
| 2477 | 2470 | ||
| 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 | }; |
| 2545 | 2538 | ||
| 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 | }; |
| 2675 | 2668 | ||
| 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(); |
| 2678 | 2671 | ||
| 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 | /// OpFunctionEnd | 2886 | /// OpFunctionEnd |
| 2894 | /// TODO is to also write out the error as a function call parameter, and to somehow fetch | 2887 | /// 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 | } |
| 2948 | 2941 | ||
| 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; |
| 2956 | 2948 | ||
| 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)); |
| 2962 | 2956 | ||
| 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); |
| 3014 | 3008 | ||
| 3015 | try self.spv.debugName(result_id, decl.fqn.toSlice(ip)); | 3009 | try self.spv.debugName(result_id, nav.fqn.toSlice(ip)); |
| 3016 | 3010 | ||
| 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); // TODO | 3023 | assert(maybe_init_val == null); // TODO |
| 3031 | 3024 | ||
| 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 globals | 3026 | assert(final_storage_class != .Generic); // These should be instance globals |
| 3034 | 3027 | ||
| 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); |
| 3036 | 3029 | ||
| 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 | }); |
| 3042 | 3035 | ||
| 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 | }; |
| 3054 | 3046 | ||
| 3055 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); | 3047 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); |
| 3056 | 3048 | ||
| 3057 | const ptr_ty_id = try self.ptrType(decl.typeOf(mod), .Function); | 3049 | const ptr_ty_id = try self.ptrType(ty, .Function); |
| 3058 | 3050 | ||
| 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; |
| 3076 | 3068 | ||
| 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); |
| 3086 | 3078 | ||
| 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)}); |
| 3088 | 3080 | ||
| 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 | } |
| 3108 | 3100 | ||
| 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 | } |
| 3112 | 3104 | ||
| 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); |
| 3116 | 3108 | ||
| ... | @@ -3123,7 +3115,7 @@ const DeclGen = struct { | ... | @@ -3123,7 +3115,7 @@ const DeclGen = struct { |
| 3123 | 3115 | ||
| 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 { |
| 3149 | 3141 | ||
| 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 | } |
| 3162 | 3154 | ||
| 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 | } |
| 3176 | 3168 | ||
| 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 | }; |
| 3195 | 3187 | ||
| 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 | } |
| 3210 | 3202 | ||
| 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 | } |
| 3222 | 3214 | ||
| 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 | } |
| 3228 | 3220 | ||
| 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 | } |
| 3399 | 3391 | ||
| 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 | } |
| 3408 | 3400 | ||
| 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; |
| 3412 | 3404 | ||
| ... | @@ -3441,7 +3433,7 @@ const DeclGen = struct { | ... | @@ -3441,7 +3433,7 @@ const DeclGen = struct { |
| 3441 | 3433 | ||
| 3442 | const MinMax = enum { min, max }; | 3434 | const MinMax = enum { min, max }; |
| 3443 | 3435 | ||
| 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; |
| 3446 | 3438 | ||
| 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 | } |
| 3453 | 3445 | ||
| 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); |
| 3456 | 3448 | ||
| 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 integer | 3477 | /// 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 | } |
| 3509 | 3501 | ||
| 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; |
| 3512 | 3504 | ||
| 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 | } |
| 3566 | 3558 | ||
| 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; |
| 3569 | 3561 | ||
| 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 | } |
| 3594 | 3586 | ||
| 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 | } |
| 3601 | 3593 | ||
| 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 | } |
| 3628 | 3620 | ||
| 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 | } |
| 3637 | 3629 | ||
| 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); |
| 3641 | 3633 | ||
| ... | @@ -3658,7 +3650,7 @@ const DeclGen = struct { | ... | @@ -3658,7 +3650,7 @@ const DeclGen = struct { |
| 3658 | } | 3650 | } |
| 3659 | 3651 | ||
| 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 | } |
| 3726 | 3718 | ||
| 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; |
| 3730 | 3722 | ||
| ... | @@ -3904,7 +3896,7 @@ const DeclGen = struct { | ... | @@ -3904,7 +3896,7 @@ const DeclGen = struct { |
| 3904 | ); | 3896 | ); |
| 3905 | } | 3897 | } |
| 3906 | 3898 | ||
| 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; |
| 3909 | 3901 | ||
| 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 | } |
| 3946 | 3938 | ||
| 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; |
| 3950 | 3942 | ||
| ... | @@ -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 | } |
| 3962 | 3954 | ||
| 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; |
| 3965 | 3957 | ||
| 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 | } |
| 3993 | 3985 | ||
| 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 | } |
| 4004 | 3996 | ||
| 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; |
| 4007 | 3999 | ||
| 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 | } |
| 4013 | 4005 | ||
| 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 | } |
| 4088 | 4080 | ||
| 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 | } |
| 4165 | 4157 | ||
| 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 | } |
| 4175 | 4167 | ||
| 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. AccessChain | 4186 | /// 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 | } |
| 4206 | 4198 | ||
| 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 | } |
| 4227 | 4219 | ||
| 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); |
| 4231 | 4223 | ||
| ... | @@ -4246,7 +4238,7 @@ const DeclGen = struct { | ... | @@ -4246,7 +4238,7 @@ const DeclGen = struct { |
| 4246 | } | 4238 | } |
| 4247 | } | 4239 | } |
| 4248 | 4240 | ||
| 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 | } |
| 4259 | 4251 | ||
| 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 | } |
| 4278 | 4270 | ||
| 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 | } |
| 4444 | 4436 | ||
| 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 | } |
| 4457 | 4449 | ||
| 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 { |
| 4468 | 4460 | ||
| 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 | } |
| 4538 | 4530 | ||
| 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 | } |
| 4546 | 4538 | ||
| 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 | } |
| 4572 | 4564 | ||
| 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 | } |
| 4583 | 4575 | ||
| 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 | } |
| 4589 | 4581 | ||
| 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 | } |
| 4597 | 4589 | ||
| 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 | } |
| 4616 | 4608 | ||
| 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 | } |
| 4623 | 4615 | ||
| 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 | } |
| 4642 | 4634 | ||
| 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 | } |
| 4649 | 4641 | ||
| 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 | } |
| 4664 | 4656 | ||
| 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 | } |
| 4683 | 4675 | ||
| 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 | } |
| 4711 | 4703 | ||
| 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 | } |
| 4728 | 4720 | ||
| 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 | } |
| 4818 | 4810 | ||
| 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 | } |
| 4834 | 4826 | ||
| 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 | } |
| 4843 | 4835 | ||
| 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 | } |
| 4859 | 4851 | ||
| 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 | } |
| 4866 | 4858 | ||
| 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 | } |
| 4883 | 4875 | ||
| 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 | } |
| 4900 | 4892 | ||
| 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 pointer | 4895 | // 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 | } |
| 4915 | 4907 | ||
| 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 | } |
| 4933 | 4925 | ||
| 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 | } |
| 4994 | 4986 | ||
| 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 | } |
| 5005 | 4997 | ||
| 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 | } |
| 5027 | 5019 | ||
| 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 | } |
| 5050 | 5042 | ||
| 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); |
| 5054 | 5046 | ||
| ... | @@ -5064,7 +5056,7 @@ const DeclGen = struct { | ... | @@ -5064,7 +5056,7 @@ const DeclGen = struct { |
| 5064 | } | 5056 | } |
| 5065 | 5057 | ||
| 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 | } |
| 5131 | 5123 | ||
| 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 | } |
| 5148 | 5140 | ||
| 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 | } |
| 5193 | 5185 | ||
| 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 | } |
| 5226 | 5218 | ||
| 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 | } |
| 5275 | 5267 | ||
| 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 actually | 5286 | // 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 | } |
| 5328 | 5320 | ||
| 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 | } |
| 5336 | 5328 | ||
| 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 emitted | 5335 | /// 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); |
| 5348 | 5340 | ||
| 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 when | 5354 | /// 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); |
| 5367 | 5359 | ||
| 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 with | 5391 | /// 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 | } |
| 5489 | 5481 | ||
| 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 | } |
| 5495 | 5487 | ||
| 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, but | 5489 | // 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 | } |
| 5635 | 5627 | ||
| 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 | } |
| 5672 | 5664 | ||
| 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 | } |
| 5732 | 5724 | ||
| 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 | } |
| 5779 | 5771 | ||
| 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 | } |
| 5790 | 5782 | ||
| 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 | } |
| 5801 | 5793 | ||
| 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 code | 5802 | // Functions with an empty error set are emitted with an error code |
| 5812 | // return type and return zero so they can be function pointers coerced | 5803 | // 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 | } |
| 5824 | 5815 | ||
| 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); |
| 5831 | 5822 | ||
| 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 code | 5826 | // Functions with an empty error set are emitted with an error code |
| 5837 | // return type and return zero so they can be function pointers coerced | 5827 | // 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 | } |
| 5852 | 5842 | ||
| 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 | } |
| 5922 | 5912 | ||
| 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 | } |
| 5945 | 5935 | ||
| 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 | } |
| 5958 | 5948 | ||
| 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 | } |
| 5983 | 5973 | ||
| 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 | } |
| 6005 | 5995 | ||
| 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 | } |
| 6082 | 6072 | ||
| 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 | } |
| 6115 | 6105 | ||
| 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 | } |
| 6132 | 6122 | ||
| 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 | } |
| 6157 | 6147 | ||
| 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 | } |
| 6180 | 6170 | ||
| 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 | } |
| 6349 | 6339 | ||
| 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 | } |
| 6353 | 6343 | ||
| 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 | } |
| 6366 | 6355 | ||
| 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 | } |
| 6377 | 6365 | ||
| 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 | } |
| 6384 | 6372 | ||
| 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); |
| 6471 | 6459 | ||
| ... | @@ -6511,7 +6499,7 @@ const DeclGen = struct { | ... | @@ -6511,7 +6499,7 @@ const DeclGen = struct { |
| 6511 | return null; | 6499 | return null; |
| 6512 | } | 6500 | } |
| 6513 | 6501 | ||
| 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; |
| 6516 | 6504 | ||
| 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 | } |
| 6568 | 6556 | ||
| 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 | } |
| 6584 | 6572 | ||
| 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 | } |
| 6595 | 6583 | ||
| 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 | } |
| 6606 | 6594 | ||
| 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 | } |
| 6617 | 6605 | ||
| 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 | } |
| 6622 | 6610 | ||
| 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 | } |
| 218 | 218 | ||
| 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 | } |
| 222 | 222 | ||
| 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 { |
| 317 | 317 | ||
| 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 | } |
| 331 | 331 | ||
| 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 | }; |
| 369 | 369 | ||
| 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 will | 371 | /// 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 it | 373 | /// 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 | } |
| 403 | 388 | ||
| 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 | } |
| 431 | 416 | ||
| 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 | }; |
| 677 | 664 | ||
| 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's | 666 | /// 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 the | 667 | /// 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 allocate | 669 | /// 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 | } |
| 695 | 682 | ||
| 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 | } |
| 715 | 700 | ||
| 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 }; |
| 965 | 950 | ||
| 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 | }; |
| 980 | 954 | ||
| 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"); |
| 19 | const Air = @import("../Air.zig"); | 19 | const Air = @import("../Air.zig"); |
| 20 | const Liveness = @import("../Liveness.zig"); | 20 | const Liveness = @import("../Liveness.zig"); |
| 21 | 21 | ||
| 22 | pub const base_tag: link.File.Tag = .c; | ||
| 23 | pub const zig_h = "#include \"zig.h\"\n"; | 22 | pub const zig_h = "#include \"zig.h\"\n"; |
| 24 | 23 | ||
| 25 | base: link.File, | 24 | base: 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 it | 26 | /// 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. |
| 29 | decl_table: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, DeclBlock) = .{}, | 28 | navs: 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, the | 30 | /// 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. |
| 33 | string_bytes: std.ArrayListUnmanaged(u8) = .{}, | 32 | string_bytes: std.ArrayListUnmanaged(u8) = .{}, |
| 34 | /// Tracks all the anonymous decls that are used by all the decls so they can | 33 | /// 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(). |
| 36 | anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, DeclBlock) = .{}, | 35 | uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, AvBlock) = .{}, |
| 37 | /// Sparse set of anon decls that are overaligned. Underaligned anon decls are | 36 | /// 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 of | 37 | /// 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`. |
| 40 | aligned_anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{}, | 39 | aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .{}, |
| 41 | 40 | ||
| 42 | exported_decls: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, ExportedBlock) = .{}, | 41 | exported_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, ExportedBlock) = .{}, |
| 43 | exported_values: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock) = .{}, | 42 | exported_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock) = .{}, |
| 44 | 43 | ||
| 45 | /// Optimization, `updateDecl` reuses this buffer rather than creating a new | 44 | /// 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 | }; |
| 68 | 67 | ||
| 69 | /// Per-declaration data. | 68 | /// Per-declaration data. |
| 70 | pub const DeclBlock = struct { | 69 | pub 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 iterate | 72 | /// 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_pool | 75 | /// May contain string references to ctype_pool |
| 77 | lazy_fns: codegen.LazyFnMap = .{}, | 76 | lazy_fns: codegen.LazyFnMap = .{}, |
| 78 | 77 | ||
| 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 | }; |
| 85 | 84 | ||
| ... | @@ -158,16 +157,16 @@ pub fn createEmpty( | ... | @@ -158,16 +157,16 @@ pub fn createEmpty( |
| 158 | pub fn deinit(self: *C) void { | 157 | pub fn deinit(self: *C) void { |
| 159 | const gpa = self.base.comp.gpa; | 158 | const gpa = self.base.comp.gpa; |
| 160 | 159 | ||
| 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); |
| 165 | 164 | ||
| 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); |
| 171 | 170 | ||
| 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(); |
| 210 | 207 | ||
| 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.code | 228 | .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 | } |
| 250 | 245 | ||
| 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 | } |
| 265 | 257 | ||
| 266 | fn updateAnonDecl(self: *C, pt: Zcu.PerThread, i: usize) !void { | 258 | fn 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]; |
| 269 | 261 | ||
| 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.code | 282 | .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); |
| 302 | 294 | ||
| 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 | }; |
| 313 | 305 | ||
| 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 | } |
| 321 | 313 | ||
| 322 | pub fn updateDecl(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 314 | pub 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(); |
| 325 | 317 | ||
| 326 | const gpa = self.base.comp.gpa; | 318 | const gpa = self.base.comp.gpa; |
| 327 | 319 | ||
| 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(); |
| 340 | 331 | ||
| 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.code | 347 | .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 | } |
| 370 | 359 | ||
| 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 | } |
| 385 | 371 | ||
| 386 | pub fn updateDeclLineNumber(self: *C, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 372 | pub 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-generating | 373 | // 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 | } |
| 393 | 379 | ||
| 394 | pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { | 380 | pub 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 }; |
| 426 | 413 | ||
| 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 | } |
| 433 | 420 | ||
| ... | @@ -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 | } |
| 486 | 473 | ||
| 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 | ); |
| 496 | 483 | ||
| 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 | } |
| 512 | 497 | ||
| 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); |
| 518 | 503 | ||
| 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 | } |
| 522 | 507 | ||
| 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 | } |
| 527 | 512 | ||
| ... | @@ -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; |
| 540 | 525 | ||
| 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 | .default | 531 | .@"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 | .default | 538 | .@"extern" => .zig_extern, |
| 557 | else if (zcu.declPtr(decl_index).isExtern(zcu)) | 539 | else => .static, |
| 558 | .zig_extern | 540 | }, |
| 559 | else | 541 | self.getString(av_block.code), |
| 560 | .static, | ||
| 561 | self.getString(decl_block.code), | ||
| 562 | ); | 542 | ); |
| 563 | 543 | ||
| 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.code | 676 | .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.code | 723 | .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 as | 727 | // 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 | } |
| 783 | 763 | ||
| 784 | fn flushDeclBlock( | 764 | fn 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 exported | 777 | // 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_decl | 780 | exported.fwd_decl |
| 801 | else | 781 | else |
| 802 | decl_block.fwd_decl)); | 782 | av_block.fwd_decl)); |
| 803 | } | 783 | } |
| 804 | 784 | ||
| 805 | pub fn flushEmitH(zcu: *Zcu) !void { | 785 | pub fn flushEmitH(zcu: *Zcu) !void { |
| 806 | const tracy = trace(@src()); | 786 | const tracy = trace(@src()); |
| 807 | defer tracy.end(); | 787 | defer tracy.end(); |
| 808 | 788 | ||
| 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; |
| 810 | 792 | ||
| 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. |
| 66 | lazy_syms: LazySymbolTable = .{}, | 66 | lazy_syms: LazySymbolTable = .{}, |
| 67 | 67 | ||
| 68 | /// Table of tracked Decls. | 68 | /// Table of tracked `Nav`s. |
| 69 | decls: DeclTable = .{}, | 69 | navs: NavTable = .{}, |
| 70 | 70 | ||
| 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. |
| 72 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 72 | atoms: 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. |
| 75 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{}, | 75 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{}, |
| 76 | 76 | ||
| 77 | /// Table of unnamed constants associated with a parent `Decl`. | 77 | uavs: 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`. | ||
| 96 | unnamed_const_atoms: UnnamedConstTable = .{}, | ||
| 97 | anon_decls: AnonDeclTable = .{}, | ||
| 98 | 78 | ||
| 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 | }; |
| 122 | 102 | ||
| 123 | const DeclTable = std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata); | 103 | const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata); |
| 124 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); | 104 | const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata); |
| 125 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); | 105 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 126 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); | 106 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 127 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Atom.Index)); | ||
| 128 | 107 | ||
| 129 | const default_file_alignment: u16 = 0x200; | 108 | const default_file_alignment: u16 = 0x200; |
| 130 | const default_size_of_stack_reserve: u32 = 0x1000000; | 109 | const 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 | }; |
| 157 | 136 | ||
| 158 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata); | 137 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata); |
| 159 | 138 | ||
| 160 | const LazySymbolMetadata = struct { | 139 | const 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 | }; |
| 167 | 146 | ||
| 168 | const DeclMetadata = struct { | 147 | const 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) = .{}, |
| 173 | 152 | ||
| 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 | } |
| 177 | 156 | ||
| 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 | } |
| 187 | 166 | ||
| 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 { |
| 486 | 465 | ||
| 487 | self.lazy_syms.deinit(gpa); | 466 | self.lazy_syms.deinit(gpa); |
| 488 | 467 | ||
| 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); |
| 493 | 472 | ||
| 494 | self.atom_by_index_table.deinit(gpa); | 473 | self.atom_by_index_table.deinit(gpa); |
| 495 | 474 | ||
| 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 | } |
| 508 | 482 | ||
| 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(); |
| 1134 | 1108 | ||
| 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); | ||
| 1139 | 1112 | ||
| 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); |
| 1143 | 1115 | ||
| 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(); |
| 1147 | 1118 | ||
| 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 | }; |
| 1166 | 1136 | ||
| 1167 | try self.updateDeclCode(pt, decl_index, code, .FUNCTION); | 1137 | try self.updateNavCode(pt, func.owner_nav, code, .FUNCTION); |
| 1168 | 1138 | ||
| 1169 | // Exports will be updated by `Zcu.processExports` after the update. | 1139 | // Exports will be updated by `Zcu.processExports` after the update. |
| 1170 | } | 1140 | } |
| 1171 | 1141 | ||
| 1172 | pub 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 | |||
| 1200 | const LowerConstResult = union(enum) { | 1142 | const 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 | } |
| 1248 | 1190 | ||
| 1249 | pub fn updateDecl( | 1191 | pub 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(); |
| 1261 | 1202 | ||
| 1262 | const decl = mod.declPtr(decl_index); | 1203 | const zcu = pt.zcu; |
| 1263 | 1204 | 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 | |
| 1267 | 1208 | 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 getGlobalSymbol | 1211 | 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 | }; | ||
| 1278 | 1221 | ||
| 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); |
| 1282 | 1225 | ||
| 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(); |
| 1285 | 1228 | ||
| 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 | }; |
| 1298 | 1245 | ||
| 1299 | try self.updateDeclCode(pt, decl_index, code, .NULL); | 1246 | try self.updateNavCode(pt, nav_index, code, .NULL); |
| 1300 | 1247 | ||
| 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( |
| 1317 | 1264 | ||
| 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); |
| 1323 | 1270 | ||
| 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().?; |
| 1326 | 1273 | ||
| 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 | } |
| 1364 | 1311 | ||
| 1365 | pub fn getOrCreateAtomForLazySymbol(self: *Coff, pt: Zcu.PerThread, sym: link.File.LazySymbol) !Atom.Index { | 1312 | pub 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 flushModule | 1331 | // 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 | } |
| 1389 | 1338 | ||
| 1390 | pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !Atom.Index { | 1339 | pub 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 | } |
| 1402 | 1351 | ||
| 1403 | fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 { | 1352 | fn 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 .bss | 1361 | // 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 | } |
| 1428 | 1378 | ||
| 1429 | fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void { | 1379 | fn 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); | ||
| 1432 | 1389 | ||
| 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); | ||
| 1435 | 1391 | ||
| 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)); |
| 1442 | 1402 | ||
| 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 }; |
| 1448 | 1408 | ||
| 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}); |
| 1455 | 1415 | ||
| 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 }; |
| 1472 | 1432 | ||
| 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; |
| 1478 | 1438 | ||
| ... | @@ -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 | } |
| 1484 | 1444 | ||
| 1485 | fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void { | 1445 | pub 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 | |||
| 1494 | pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void { | ||
| 1495 | if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index); | ||
| 1496 | 1447 | ||
| 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); | ||
| 1500 | 1450 | ||
| 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; |
| 1563 | 1511 | ||
| 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.processExportsInner | 1523 | // 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 | } |
| 1858 | 1806 | ||
| 1859 | pub fn getDeclVAddr(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { | 1807 | pub 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 | } |
| 1890 | 1836 | ||
| 1891 | pub fn lowerAnonDecl( | 1837 | pub 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 | } |
| 1910 | 1857 | ||
| 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 | } |
| 1939 | 1890 | ||
| 1940 | pub fn getAnonDeclVAddr(self: *Coff, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 1891 | pub 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); |
| 1942 | 1897 | ||
| 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; |
| 2760 | const codegen = @import("../codegen.zig"); | 2715 | const codegen = @import("../codegen.zig"); |
| 2761 | const link = @import("../link.zig"); | 2716 | const link = @import("../link.zig"); |
| 2762 | const lld = @import("Coff/lld.zig"); | 2717 | const lld = @import("Coff/lld.zig"); |
| 2718 | const target_util = @import("../target.zig"); | ||
| 2763 | const trace = @import("../tracy.zig").trace; | 2719 | const trace = @import("../tracy.zig").trace; |
| 2764 | 2720 | ||
| 2765 | const Air = @import("../Air.zig"); | 2721 | const Air = @import("../Air.zig"); |
| ... | @@ -2781,6 +2737,4 @@ const Value = @import("../Value.zig"); | ... | @@ -2781,6 +2737,4 @@ const Value = @import("../Value.zig"); |
| 2781 | const AnalUnit = InternPool.AnalUnit; | 2737 | const AnalUnit = InternPool.AnalUnit; |
| 2782 | const dev = @import("../dev.zig"); | 2738 | const dev = @import("../dev.zig"); |
| 2783 | 2739 | ||
| 2784 | pub const base_tag: link.File.Tag = .coff; | ||
| 2785 | |||
| 2786 | const msdos_stub = @embedFile("msdos-stub.bin"); | 2740 | const 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) = .{}, |
| 9 | src_fn_first_index: ?Atom.Index = null, | 9 | src_fn_first_index: ?Atom.Index = null, |
| 10 | src_fn_last_index: ?Atom.Index = null, | 10 | src_fn_last_index: ?Atom.Index = null, |
| 11 | src_fns: std.ArrayListUnmanaged(Atom) = .{}, | 11 | src_fns: std.ArrayListUnmanaged(Atom) = .{}, |
| 12 | src_fn_decls: AtomTable = .{}, | 12 | src_fn_navs: AtomTable = .{}, |
| 13 | 13 | ||
| 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) = .{}, |
| 17 | di_atom_first_index: ?Atom.Index = null, | 17 | di_atom_first_index: ?Atom.Index = null, |
| 18 | di_atom_last_index: ?Atom.Index = null, | 18 | di_atom_last_index: ?Atom.Index = null, |
| 19 | di_atoms: std.ArrayListUnmanaged(Atom) = .{}, | 19 | di_atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 20 | di_atom_decls: AtomTable = .{}, | 20 | di_atom_navs: AtomTable = .{}, |
| 21 | 21 | ||
| 22 | dbg_line_header: DbgLineHeader, | 22 | dbg_line_header: DbgLineHeader, |
| 23 | 23 | ||
| ... | @@ -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. |
| 28 | strtab: StringTable = .{}, | 28 | strtab: StringTable = .{}, |
| 29 | 29 | ||
| 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_directory | 32 | /// * []include_directory |
| 33 | /// * []file_names | 33 | /// * []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) = .{}, |
| 35 | 35 | ||
| 36 | global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, | 36 | global_abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{}, |
| 37 | 37 | ||
| 38 | const AtomTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, Atom.Index); | 38 | const AtomTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, Atom.Index); |
| 39 | 39 | ||
| 40 | const Atom = struct { | 40 | const Atom = struct { |
| 41 | /// Offset into .debug_info pointing to the tag for this Decl, or | 41 | /// Offset into .debug_info pointing to the tag for this Nav, or |
| 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, or | 44 | /// 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, not | 45 | /// 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 | }; |
| 63 | 63 | ||
| 64 | /// Represents state of the analysed Decl. | 64 | /// Represents state of the analysed Nav. |
| 65 | /// Includes Decl's abbrev table of type Types, matching arena | 65 | /// Includes Nav's abbrev table of type Types, matching arena |
| 66 | /// and a set of relocations that will be resolved once this | 66 | /// 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. |
| 68 | pub const DeclState = struct { | 68 | pub 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), |
| 80 | 80 | ||
| 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 | } |
| 91 | 91 | ||
| 92 | /// Adds local type relocation of the form: @offset => @this + addend | 92 | /// 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 + 0 | 104 | /// Adds global type relocation of the form: @offset => @symbol + 0 |
| 105 | /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section | 105 | /// @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 | } |
| 128 | 128 | ||
| 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 | }; |
| 551 | 551 | ||
| 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]; |
| 563 | 563 | ||
| 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 | } |
| 666 | 667 | ||
| 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 | } |
| 882 | 883 | ||
| 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 | } |
| 923 | 924 | ||
| 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 | } |
| 929 | 930 | ||
| 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 | } |
| 933 | 934 | ||
| 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 | } |
| 937 | 938 | ||
| 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; |
| 941 | 942 | ||
| ... | @@ -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); |
| 946 | 947 | ||
| 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 | } |
| 953 | 954 | ||
| 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 { |
| 1064 | 1065 | ||
| 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); |
| 1068 | 1069 | ||
| 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); |
| 1072 | 1073 | ||
| 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 | } |
| 1077 | 1078 | ||
| 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`. |
| 1080 | pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !DeclState { | 1081 | pub 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(); |
| 1083 | 1084 | ||
| 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)}); |
| 1086 | 1087 | ||
| 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; |
| 1104 | 1105 | ||
| 1105 | const di_atom_index = try self.getOrCreateAtomForDecl(.di_atom, decl_index); | 1106 | const di_atom_index = try self.getOrCreateAtomForNav(.di_atom, nav_index); |
| 1106 | 1107 | ||
| 1107 | assert(decl.has_tv); | 1108 | const nav_val = Value.fromInterned(nav.status.resolved.val); |
| 1108 | 1109 | ||
| 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); |
| 1112 | 1113 | ||
| 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); |
| 1116 | 1117 | ||
| 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); |
| 1125 | 1126 | ||
| 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 more | 1145 | // 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); |
| 1148 | 1149 | ||
| 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); |
| 1155 | 1156 | ||
| 1156 | // .debug_info subprogram | 1157 | // .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)); |
| 1161 | 1162 | ||
| 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.data4 | 1174 | 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.ref4 | 1177 | 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.string | 1181 | ); // 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.string | 1184 | ); // 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 | } |
| 1189 | 1190 | ||
| 1190 | return decl_state; | 1191 | return nav_state; |
| 1191 | } | 1192 | } |
| 1192 | 1193 | ||
| 1193 | pub fn commitDeclState( | 1194 | pub 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(); |
| 1203 | 1204 | ||
| 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(); |
| 1211 | 1211 | ||
| 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; |
| 1214 | 1214 | ||
| 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()); |
| 1219 | 1219 | ||
| 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( |
| 1254 | 1254 | ||
| 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. |
| 1256 | 1256 | ||
| 1257 | // This logic is nearly identical to the logic below in `updateDeclDebugInfo` for | 1257 | // This logic is nearly identical to the logic below in `updateNavDebugInfo` for |
| 1258 | // `TextBlock` and the .debug_info. If you are editing this logic, you | 1258 | // `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); |
| 1263 | 1263 | ||
| ... | @@ -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( |
| 1342 | 1335 | ||
| 1343 | // We only have support for one compilation unit so far, so the offsets are directly | 1336 | // 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 { |
| 1360 | 1364 | 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, |
| 1390 | 1394 | // 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 | } | ||
| 1415 | 1399 | ||
| 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; |
| 1424 | 1408 | ||
| 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 of | 1411 | // 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 actual | 1412 | // 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; |
| 1435 | 1419 | ||
| 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 | } |
| 1440 | 1424 | ||
| 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)); |
| 1442 | 1426 | ||
| 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 | } |
| 1481 | 1465 | ||
| 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 | // TODO | 1471 | // 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 | } |
| 1505 | 1486 | ||
| 1506 | try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items); | 1487 | try self.writeNavDebugInfo(di_atom_index, dbg_info_buffer.items); |
| 1507 | } | 1488 | } |
| 1508 | 1489 | ||
| 1509 | fn updateDeclDebugInfoAllocation(self: *Dwarf, atom_index: Atom.Index, len: u32) !void { | 1490 | fn 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(); |
| 1512 | 1493 | ||
| 1513 | // This logic is nearly identical to the logic above in `updateDecl` for | 1494 | // This logic is nearly identical to the logic above in `updateNav` for |
| 1514 | // `SrcFn` and the line number programs. If you are editing this logic, you | 1495 | // `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_info | 1555 | // 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; |
| 1584 | 1558 | ||
| ... | @@ -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 | } |
| 1588 | 1562 | ||
| 1589 | fn writeDeclDebugInfo(self: *Dwarf, atom_index: Atom.Index, dbg_info_buf: []const u8) !void { | 1563 | fn 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(); |
| 1592 | 1566 | ||
| 1593 | // This logic is nearly identical to the logic above in `updateDecl` for | 1567 | // This logic is nearly identical to the logic above in `updateNav` for |
| 1594 | // `SrcFn` and the line number programs. If you are editing this logic, you | 1568 | // `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. |
| 1596 | 1570 | ||
| 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; |
| 1610 | 1584 | ||
| 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; |
| 1613 | 1587 | ||
| 1614 | // We only have support for one compilation unit so far, so the offsets are directly | 1588 | // 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 { |
| 1632 | 1618 | 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( |
| 1664 | 1650 | // 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 | } |
| 1695 | 1660 | ||
| 1696 | pub fn updateDeclLineNumber(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void { | 1661 | pub 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(); |
| 1699 | 1664 | ||
| 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; |
| 1703 | 1668 | ||
| 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); |
| 1714 | 1680 | ||
| ... | @@ -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 | } |
| 1744 | 1710 | ||
| 1745 | pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void { | 1711 | pub fn freeNav(self: *Dwarf, nav_index: InternPool.Nav.Index) void { |
| 1746 | const gpa = self.allocator; | 1712 | const gpa = self.allocator; |
| 1747 | 1713 | ||
| 1748 | // Free SrcFn atom | 1714 | // 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 | } |
| 1774 | 1740 | ||
| 1775 | // Free DI atom | 1741 | // 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); |
| 1779 | 1745 | ||
| ... | @@ -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; |
| 1931 | 1897 | ||
| 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 | } |
| 1968 | 1927 | ||
| 1969 | fn dbgInfoHeaderBytes(self: *Dwarf) usize { | 1928 | fn 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); |
| 2028 | 1987 | ||
| 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 | } |
| 2062 | 2014 | ||
| 2063 | fn resolveCompilationDir(zcu: *Zcu, buffer: *[std.fs.max_path_bytes]u8) []const u8 { | 2015 | fn 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 | } |
| 2361 | 2313 | ||
| 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 | } |
| 2398 | 2343 | ||
| 2399 | pub fn writeDbgLineHeader(self: *Dwarf) !void { | 2344 | pub 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 { |
| 2502 | 2447 | ||
| 2503 | var src_fn_index = first_fn_index; | 2448 | var src_fn_index = first_fn_index; |
| 2504 | 2449 | ||
| 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); |
| 2507 | 2452 | ||
| 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; | ||
| 2515 | 2458 | ||
| 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; |
| 2518 | 2461 | ||
| 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; | ||
| 2528 | 2469 | ||
| 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; |
| 2531 | 2472 | ||
| 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; |
| 2539 | 2480 | ||
| 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; |
| 2542 | 2483 | ||
| 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 | } | ||
| 2559 | 2496 | ||
| 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 { |
| 2580 | 2517 | ||
| 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 | } |
| 2611 | 2541 | ||
| 2612 | fn getDebugInfoOff(self: Dwarf) ?u32 { | 2542 | fn 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 | ); |
| 2705 | 2635 | ||
| 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); |
| 2711 | 2641 | ||
| 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 first | 2655 | // 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; |
| 2733 | 2659 | ||
| 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()); |
| 2736 | 2662 | ||
| 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 | } |
| 2763 | 2682 | ||
| 2764 | fn addDIFile(self: *Dwarf, zcu: *Zcu, decl_index: InternPool.DeclIndex) !u28 { | 2683 | fn 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 | } |
| 2911 | 2822 | ||
| 2912 | fn getOrCreateAtomForDecl(self: *Dwarf, comptime kind: Kind, decl_index: InternPool.DeclIndex) !Atom.Index { | 2823 | fn 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 | } |
| 480 | 480 | ||
| 481 | pub fn getDeclVAddr(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { | 481 | pub 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 | } |
| 485 | 485 | ||
| 486 | pub fn lowerAnonDecl( | 486 | pub 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 | } |
| 495 | 495 | ||
| 496 | pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 496 | pub 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 | } |
| 500 | 500 | ||
| 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 | } |
| 2915 | 2915 | ||
| 2916 | pub fn freeDecl(self: *Elf, decl_index: InternPool.DeclIndex) void { | 2916 | pub 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 | } |
| 2920 | 2920 | ||
| 2921 | pub fn updateFunc(self: *Elf, pt: Zcu.PerThread, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { | 2921 | pub 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 | } |
| 2928 | 2928 | ||
| 2929 | pub fn updateDecl( | 2929 | pub 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 | |||
| 2941 | pub 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 | } |
| 2944 | 2940 | ||
| 2945 | pub fn updateExports( | 2941 | pub 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 | } |
| 2957 | 2953 | ||
| 2958 | pub fn updateDeclLineNumber(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 2954 | pub 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 | } |
| 2962 | 2958 | ||
| 2963 | pub fn deleteExport( | 2959 | pub 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. |
| 33 | lazy_syms: LazySymbolTable = .{}, | 33 | lazy_syms: LazySymbolTable = .{}, |
| 34 | 34 | ||
| 35 | /// Table of tracked Decls. | 35 | /// Table of tracked `Nav`s. |
| 36 | decls: DeclTable = .{}, | 36 | navs: NavTable = .{}, |
| 37 | 37 | ||
| 38 | /// TLS variables indexed by Atom.Index. | 38 | /// TLS variables indexed by Atom.Index. |
| 39 | tls_variables: TlsTable = .{}, | 39 | tls_variables: TlsTable = .{}, |
| 40 | 40 | ||
| 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` | 42 | uavs: 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`. | ||
| 60 | unnamed_consts: UnnamedConstTable = .{}, | ||
| 61 | |||
| 62 | /// Table of tracked AnonDecls. | ||
| 63 | anon_decls: AnonDeclTable = .{}, | ||
| 64 | 43 | ||
| 65 | debug_strtab_dirty: bool = false, | 44 | debug_strtab_dirty: bool = false, |
| 66 | debug_abbrev_section_dirty: bool = false, | 45 | debug_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); |
| 125 | 104 | ||
| 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 | } |
| 133 | 112 | ||
| 134 | self.lazy_syms.deinit(allocator); | 113 | self.lazy_syms.deinit(allocator); |
| 135 | 114 | ||
| 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 | } |
| 151 | 122 | ||
| 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 { |
| 161 | 132 | ||
| 162 | pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { | 133 | pub 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 }; |
| 166 | 137 | ||
| 167 | // Most lazy symbols can be updated on first use, but | 138 | // 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 | } |
| 663 | 634 | ||
| 664 | pub fn getDeclVAddr( | 635 | pub 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 | else | 650 | @"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 | } |
| 694 | 665 | ||
| 695 | pub fn getAnonDeclVAddr( | 666 | pub 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 | } |
| 713 | 684 | ||
| 714 | pub fn lowerAnonDecl( | 685 | pub 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 | } |
| 734 | 706 | ||
| 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 | } |
| 764 | 735 | ||
| 765 | pub fn getOrCreateMetadataForLazySymbol( | 736 | pub 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 flushModule | 762 | // 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 | } |
| 805 | 766 | ||
| 806 | fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void { | 767 | fn 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 | |||
| 815 | fn 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 here | 772 | // TODO free GOT entry here |
| 821 | } | 773 | } |
| 822 | 774 | ||
| 823 | pub fn freeDecl(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void { | 775 | pub 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; |
| 825 | 777 | ||
| 826 | log.debug("freeDecl ({d})", .{decl_index}); | 778 | log.debug("freeNav ({d})", .{nav_index}); |
| 827 | 779 | ||
| 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 | } |
| 835 | 786 | ||
| 836 | if (self.dwarf) |*dw| { | 787 | if (self.dwarf) |*dw| { |
| 837 | dw.freeDecl(decl_index); | 788 | dw.freeNav(nav_index); |
| 838 | } | 789 | } |
| 839 | } | 790 | } |
| 840 | 791 | ||
| 841 | pub fn getOrCreateMetadataForDecl( | 792 | pub 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 | } |
| 866 | 817 | ||
| 867 | fn getDeclShdrIndex( | 818 | fn 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 | } |
| 920 | 862 | ||
| 921 | fn updateDeclCode( | 863 | fn 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); |
| 935 | 877 | ||
| 936 | log.debug("updateDeclCode {}({d})", .{ decl.fqn.fmt(ip), decl_index }); | 878 | log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 937 | 879 | ||
| 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 | ); |
| 941 | 883 | ||
| 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)); |
| 946 | 888 | ||
| 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); |
| 983 | 926 | ||
| 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); |
| 1035 | 978 | ||
| 1036 | log.debug("updateTlv {}({d})", .{ decl.fqn.fmt(ip), decl_index }); | 979 | log.debug("updateTlv {}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1037 | 980 | ||
| 1038 | const required_alignment = decl.getAlignment(pt); | 981 | const required_alignment = pt.navAlignment(nav_index); |
| 1039 | 982 | ||
| 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)); |
| 1044 | 987 | ||
| 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; |
| 1051 | 994 | ||
| 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(); |
| 1088 | 1032 | ||
| 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); | ||
| 1095 | 1037 | ||
| 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 }); |
| 1097 | 1039 | ||
| 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); |
| 1101 | 1042 | ||
| 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(); |
| 1104 | 1045 | ||
| 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(); |
| 1107 | 1048 | ||
| 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 | ); |
| 1118 | 1059 | ||
| 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 | }; |
| 1127 | 1067 | ||
| 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); |
| 1130 | 1070 | ||
| 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 | } |
| 1144 | 1084 | ||
| 1145 | pub fn updateDecl( | 1085 | pub 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(); |
| 1153 | 1093 | ||
| 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); |
| 1157 | 1097 | ||
| 1158 | log.debug("updateDecl {}({d})", .{ decl.fqn.fmt(ip), decl_index }); | 1098 | log.debug("updateNav {}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1159 | 1099 | ||
| 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 | }; | ||
| 1170 | 1116 | ||
| 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); |
| 1173 | 1119 | ||
| 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(); |
| 1177 | 1122 | ||
| 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(); |
| 1180 | 1125 | ||
| 1181 | // TODO implement .debug_info for global variables | 1126 | // 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 | else | 1134 | .{ .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 | }); | ||
| 1193 | 1136 | ||
| 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 | }; |
| 1202 | 1144 | ||
| 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 | else | 1148 | 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); |
| 1208 | 1150 | ||
| 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 | } |
| 1219 | 1161 | ||
| ... | @@ -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 | }; |
| 1245 | 1187 | ||
| 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; |
| 1281 | 1223 | ||
| 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); |
| 1284 | 1226 | ||
| 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 | } |
| 1298 | 1240 | ||
| 1299 | pub 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 | |||
| 1339 | const LowerConstResult = union(enum) { | 1241 | const LowerConstResult = union(enum) { |
| 1340 | ok: Symbol.Index, | 1242 | ok: Symbol.Index, |
| 1341 | fail: *Module.ErrorMsg, | 1243 | fail: *Zcu.ErrorMsg, |
| 1342 | }; | 1244 | }; |
| 1343 | 1245 | ||
| 1344 | fn lowerConst( | 1246 | fn 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; |
| 1355 | 1257 | ||
| ... | @@ -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; |
| 1385 | 1287 | ||
| 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); | ||
| 1388 | 1291 | ||
| 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.processExportsInner | 1322 | // 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 | } |
| 1489 | 1392 | ||
| 1490 | /// Must be called only after a successful call to `updateDecl`. | 1393 | /// Must be called only after a successful call to `updateNav`. |
| 1491 | pub fn updateDeclLineNumber( | 1394 | pub 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(); |
| 1498 | 1401 | ||
| 1499 | const decl = pt.zcu.declPtr(decl_index); | 1402 | const ip = &pt.zcu.intern_pool; |
| 1403 | const nav = ip.getNav(nav_index); | ||
| 1500 | 1404 | ||
| 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 }); |
| 1502 | 1406 | ||
| 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 | } |
| 1507 | 1411 | ||
| ... | @@ -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 | }; |
| 1756 | 1660 | ||
| 1757 | const DeclMetadata = struct { | 1661 | const 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) = .{}, |
| 1761 | 1665 | ||
| 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 | }; |
| 1779 | 1683 | ||
| 1780 | const AtomList = std.ArrayListUnmanaged(Atom.Index); | 1684 | const AtomList = std.ArrayListUnmanaged(Atom.Index); |
| 1781 | const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index)); | 1685 | const NavTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, AvMetadata); |
| 1782 | const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata); | 1686 | const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata); |
| 1783 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); | 1687 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata); |
| 1784 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata); | ||
| 1785 | const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); | 1688 | const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); |
| 1786 | 1689 | ||
| 1787 | const assert = std.debug.assert; | 1690 | const assert = std.debug.assert; |
| ... | @@ -1792,8 +1695,8 @@ const link = @import("../../link.zig"); | ... | @@ -1792,8 +1695,8 @@ const link = @import("../../link.zig"); |
| 1792 | const log = std.log.scoped(.link); | 1695 | const log = std.log.scoped(.link); |
| 1793 | const mem = std.mem; | 1696 | const mem = std.mem; |
| 1794 | const relocation = @import("relocation.zig"); | 1697 | const relocation = @import("relocation.zig"); |
| 1795 | const trace = @import("../../tracy.zig").trace; | ||
| 1796 | const target_util = @import("../../target.zig"); | 1698 | const target_util = @import("../../target.zig"); |
| 1699 | const trace = @import("../../tracy.zig").trace; | ||
| 1797 | const std = @import("std"); | 1700 | const std = @import("std"); |
| 1798 | 1701 | ||
| 1799 | const Air = @import("../../Air.zig"); | 1702 | const Air = @import("../../Air.zig"); |
| ... | @@ -1806,8 +1709,6 @@ const File = @import("file.zig").File; | ... | @@ -1806,8 +1709,6 @@ const File = @import("file.zig").File; |
| 1806 | const InternPool = @import("../../InternPool.zig"); | 1709 | const InternPool = @import("../../InternPool.zig"); |
| 1807 | const Liveness = @import("../../Liveness.zig"); | 1710 | const Liveness = @import("../../Liveness.zig"); |
| 1808 | const Zcu = @import("../../Zcu.zig"); | 1711 | const Zcu = @import("../../Zcu.zig"); |
| 1809 | /// Deprecated. | ||
| 1810 | const Module = Zcu; | ||
| 1811 | const Object = @import("Object.zig"); | 1712 | const Object = @import("Object.zig"); |
| 1812 | const Symbol = @import("Symbol.zig"); | 1713 | const Symbol = @import("Symbol.zig"); |
| 1813 | const StringTable = @import("../StringTable.zig"); | 1714 | const 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 | } |
| 3000 | 3000 | ||
| 3001 | pub fn lowerUnnamedConst(self: *MachO, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 3001 | pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void { |
| 3002 | return self.getZigObject().?.lowerUnnamedConst(self, pt, val, decl_index); | ||
| 3003 | } | ||
| 3004 | |||
| 3005 | pub 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 | } |
| 3012 | 3008 | ||
| 3013 | pub fn updateDeclLineNumber(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 3009 | pub 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 | } |
| 3017 | 3013 | ||
| 3018 | pub fn updateExports( | 3014 | pub 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 | } |
| 3039 | 3035 | ||
| 3040 | pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void { | 3036 | pub 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 | } |
| 3044 | 3040 | ||
| 3045 | pub fn getDeclVAddr(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { | 3041 | pub 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 | } |
| 3049 | 3045 | ||
| 3050 | pub fn lowerAnonDecl( | 3046 | pub 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 | } |
| 3059 | 3055 | ||
| 3060 | pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 3056 | pub 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 | } |
| 3064 | 3060 | ||
| 3065 | pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { | 3061 | pub 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) { |
| 4051 | 4047 | ||
| 4052 | const default_entry_symbol_name = "_main"; | 4048 | const default_entry_symbol_name = "_main"; |
| 4053 | 4049 | ||
| 4054 | pub const base_tag: link.File.Tag = link.File.Tag.macho; | ||
| 4055 | |||
| 4056 | const Section = struct { | 4050 | const 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(); |
| 994 | 994 | ||
| 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); |
| 997 | 999 | ||
| ... | @@ -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 | } |
| 1017 | 1019 | ||
| 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. |
| 20 | lazy_syms: LazySymbolTable = .{}, | 20 | lazy_syms: LazySymbolTable = .{}, |
| 21 | 21 | ||
| 22 | /// Table of tracked Decls. | 22 | /// Table of tracked Navs. |
| 23 | decls: DeclTable = .{}, | 23 | navs: NavTable = .{}, |
| 24 | 24 | ||
| 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` | 26 | uavs: 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`. | ||
| 44 | unnamed_consts: UnnamedConstTable = .{}, | ||
| 45 | |||
| 46 | /// Table of tracked AnonDecls. | ||
| 47 | anon_decls: AnonDeclTable = .{}, | ||
| 48 | 27 | ||
| 49 | /// TLV initializers indexed by Atom.Index. | 28 | /// TLV initializers indexed by Atom.Index. |
| 50 | tlv_initializers: TlvInitializerTable = .{}, | 29 | tlv_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); |
| 102 | 81 | ||
| 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); | ||
| 110 | 86 | ||
| 111 | self.lazy_syms.deinit(allocator); | 87 | self.lazy_syms.deinit(allocator); |
| 112 | 88 | ||
| 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); | ||
| 128 | 93 | ||
| 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 |
| 601 | 566 | ||
| 602 | pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) !void { | 567 | pub 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 }; |
| 606 | 571 | ||
| 607 | // Most lazy symbols can be updated on first use, but | 572 | // 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 | } |
| 693 | 658 | ||
| 694 | pub fn getDeclVAddr( | 659 | pub 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 | else | 674 | @"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 | } |
| 731 | 696 | ||
| 732 | pub fn getAnonDeclVAddr( | 697 | pub 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 | } |
| 757 | 722 | ||
| 758 | pub fn lowerAnonDecl( | 723 | pub 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 | } |
| 778 | 744 | ||
| 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, |
| 807 | 773 | } }; | |
| 808 | fn 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 | } |
| 816 | 775 | ||
| 817 | fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { | 776 | fn 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 here | 781 | // TODO free GOT entry here |
| 823 | } | 782 | } |
| 824 | 783 | ||
| 825 | pub fn freeDecl(self: *ZigObject, macho_file: *MachO, decl_index: InternPool.DeclIndex) void { | 784 | pub 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); | ||
| 829 | 787 | ||
| 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 | } |
| 839 | 794 | ||
| ... | @@ -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(); |
| 853 | 808 | ||
| 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); | ||
| 859 | 812 | ||
| 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); |
| 863 | 815 | ||
| 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(); |
| 866 | 818 | ||
| 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(); |
| 869 | 821 | ||
| 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 | ); |
| 881 | 832 | ||
| 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 | }; |
| 890 | 840 | ||
| 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); |
| 893 | 843 | ||
| 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 | } |
| 907 | 857 | ||
| 908 | pub fn updateDecl( | 858 | pub 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(); |
| 916 | 866 | ||
| 917 | const mod = pt.zcu; | 867 | const zcu = pt.zcu; |
| 918 | const decl = mod.declPtr(decl_index); | 868 | const ip = &zcu.intern_pool; |
| 919 | 869 | 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"| { |
| 923 | 873 | 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 only | 875 | 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 | }; |
| 934 | 884 | ||
| 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); |
| 937 | 887 | ||
| 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(); |
| 941 | 890 | ||
| 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(); |
| 944 | 893 | ||
| 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 | ); | ||
| 950 | 903 | ||
| 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 | } | ||
| 966 | 916 | ||
| 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 | } |
| 977 | 927 | ||
| 978 | // Exports will be updated by `Zcu.processExports` after the update. | 928 | // Exports will be updated by `Zcu.processExports` after the update. |
| 979 | } | 929 | } |
| 980 | 930 | ||
| 981 | fn updateDeclCode( | 931 | fn 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); |
| 994 | 944 | ||
| 995 | log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl }); | 945 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); |
| 996 | 946 | ||
| 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 | ); | ||
| 998 | 950 | ||
| 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; |
| 1006 | 958 | ||
| 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( |
| 1025 | 977 | ||
| 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); |
| 1049 | 1001 | ||
| 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); |
| 1080 | 1032 | ||
| 1081 | log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl }); | 1033 | log.debug("updateTlv {} (0x{x})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1082 | 1034 | ||
| 1083 | // 1. Lower TLV initializer | 1035 | // 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 | ); |
| 1091 | 1043 | ||
| 1092 | // 2. Create TLV descriptor | 1044 | // 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 | } |
| 1095 | 1047 | ||
| 1096 | fn createTlvInitializer( | 1048 | fn createTlvInitializer( |
| ... | @@ -1197,102 +1149,52 @@ fn createTlvDescriptor( | ... | @@ -1197,102 +1149,52 @@ fn createTlvDescriptor( |
| 1197 | }); | 1149 | }); |
| 1198 | } | 1150 | } |
| 1199 | 1151 | ||
| 1200 | fn getDeclOutputSection( | 1152 | fn 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| { |
| 1252 | 1171 | if (byte != 0) break; | |
| 1253 | pub 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 | } |
| 1292 | 1194 | ||
| 1293 | const LowerConstResult = union(enum) { | 1195 | const LowerConstResult = union(enum) { |
| 1294 | ok: Symbol.Index, | 1196 | ok: Symbol.Index, |
| 1295 | fail: *Module.ErrorMsg, | 1197 | fail: *Zcu.ErrorMsg, |
| 1296 | }; | 1198 | }; |
| 1297 | 1199 | ||
| 1298 | fn lowerConst( | 1200 | fn 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; |
| 1309 | 1211 | ||
| ... | @@ -1338,7 +1240,7 @@ fn lowerConst( | ... | @@ -1338,7 +1240,7 @@ fn lowerConst( |
| 1338 | 1240 | ||
| 1339 | try atom.allocate(macho_file); | 1241 | try atom.allocate(macho_file); |
| 1340 | // TODO rename and re-audit this method | 1242 | // TODO rename and re-audit this method |
| 1341 | errdefer self.freeDeclMetadata(macho_file, sym_index); | 1243 | errdefer self.freeNavMetadata(macho_file, sym_index); |
| 1342 | 1244 | ||
| 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.processExportsInner | 1275 | // 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; |
| 1459 | 1361 | ||
| 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 | }; |
| 1472 | 1374 | ||
| 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; |
| 1512 | 1414 | ||
| 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); |
| 1515 | 1417 | ||
| 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 | } |
| 1529 | 1431 | ||
| 1530 | /// Must be called only after a successful call to `updateDecl`. | 1432 | /// Must be called only after a successful call to `updateNav`. |
| 1531 | pub fn updateDeclLineNumber(self: *ZigObject, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 1433 | pub 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 | } |
| 1536 | 1442 | ||
| ... | @@ -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.?; |
| 1544 | 1450 | ||
| 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; |
| 1550 | 1456 | ||
| 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 | } |
| 1579 | 1485 | ||
| 1580 | pub fn getOrCreateMetadataForDecl( | 1486 | pub 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 flushModule | 1531 | // 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 | } |
| 1640 | 1535 | ||
| 1641 | fn isThreadlocal(macho_file: *MachO, decl_index: InternPool.DeclIndex) bool { | 1536 | fn 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 | } |
| 1648 | 1546 | ||
| 1649 | fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { | 1547 | fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { |
| ... | @@ -1848,12 +1746,12 @@ fn formatAtoms( | ... | @@ -1848,12 +1746,12 @@ fn formatAtoms( |
| 1848 | } | 1746 | } |
| 1849 | } | 1747 | } |
| 1850 | 1748 | ||
| 1851 | const DeclMetadata = struct { | 1749 | const 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) = .{}, |
| 1855 | 1753 | ||
| 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 | }; |
| 1882 | 1780 | ||
| 1883 | const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata); | 1781 | const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata); |
| 1884 | const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Symbol.Index)); | 1782 | const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata); |
| 1885 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); | 1783 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata); |
| 1886 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata); | ||
| 1887 | const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation)); | 1784 | const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation)); |
| 1888 | const TlvInitializerTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlvInitializer); | 1785 | const TlvInitializerTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlvInitializer); |
| 1889 | 1786 | ||
| ... | @@ -1894,6 +1791,7 @@ const link = @import("../../link.zig"); | ... | @@ -1894,6 +1791,7 @@ const link = @import("../../link.zig"); |
| 1894 | const log = std.log.scoped(.link); | 1791 | const log = std.log.scoped(.link); |
| 1895 | const macho = std.macho; | 1792 | const macho = std.macho; |
| 1896 | const mem = std.mem; | 1793 | const mem = std.mem; |
| 1794 | const target_util = @import("../../target.zig"); | ||
| 1897 | const trace = @import("../../tracy.zig").trace; | 1795 | const trace = @import("../../tracy.zig").trace; |
| 1898 | const std = @import("std"); | 1796 | const std = @import("std"); |
| 1899 | 1797 | ||
| ... | @@ -1908,8 +1806,6 @@ const Liveness = @import("../../Liveness.zig"); | ... | @@ -1908,8 +1806,6 @@ const Liveness = @import("../../Liveness.zig"); |
| 1908 | const MachO = @import("../MachO.zig"); | 1806 | const MachO = @import("../MachO.zig"); |
| 1909 | const Nlist = Object.Nlist; | 1807 | const Nlist = Object.Nlist; |
| 1910 | const Zcu = @import("../../Zcu.zig"); | 1808 | const Zcu = @import("../../Zcu.zig"); |
| 1911 | /// Deprecated. | ||
| 1912 | const Module = Zcu; | ||
| 1913 | const Object = @import("Object.zig"); | 1809 | const Object = @import("Object.zig"); |
| 1914 | const Relocation = @import("Relocation.zig"); | 1810 | const Relocation = @import("Relocation.zig"); |
| 1915 | const Symbol = @import("Symbol.zig"); | 1811 | const 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 | } |
| 88 | 88 | ||
| 89 | pub fn updateDecl(self: *NvPtx, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 89 | pub 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 | } |
| 92 | 92 | ||
| 93 | pub fn updateExports( | 93 | pub 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; |
| 24 | const log = std.log.scoped(.link); | 24 | const log = std.log.scoped(.link); |
| 25 | const assert = std.debug.assert; | 25 | const assert = std.debug.assert; |
| 26 | 26 | ||
| 27 | pub const base_tag = .plan9; | ||
| 28 | |||
| 29 | base: link.File, | 27 | base: link.File, |
| 30 | sixtyfour_bit: bool, | 28 | sixtyfour_bit: bool, |
| 31 | bases: Bases, | 29 | bases: 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 symbol | 51 | /// 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) |
| 56 | fn_decl_table: std.AutoArrayHashMapUnmanaged( | 54 | fn_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 mutable | 58 | /// the code is modified when relocated, so that is why it is mutable |
| 61 | data_decl_table: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, []u8) = .{}, | 59 | data_nav_table: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u8) = .{}, |
| 62 | /// When `updateExports` is called, we store the export indices here, to be used | 60 | /// When `updateExports` is called, we store the export indices here, to be used |
| 63 | /// during flush. | 61 | /// during flush. |
| 64 | decl_exports: std.AutoArrayHashMapUnmanaged(InternPool.DeclIndex, []u32) = .{}, | 62 | nav_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`. | ||
| 85 | unnamed_const_atoms: UnnamedConstTable = .{}, | ||
| 86 | 63 | ||
| 87 | lazy_syms: LazySymbolTable = .{}, | 64 | lazy_syms: LazySymbolTable = .{}, |
| 88 | 65 | ||
| 89 | anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, | 66 | uavs: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, |
| 90 | 67 | ||
| 91 | relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{}, | 68 | relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{}, |
| 92 | hdr: aout.ExecHdr = undefined, | 69 | hdr: 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) = .{}, |
| 104 | syms_index_free_list: std.ArrayListUnmanaged(usize) = .{}, | 81 | syms_index_free_list: std.ArrayListUnmanaged(usize) = .{}, |
| 105 | 82 | ||
| 106 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 83 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 107 | decls: std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata) = .{}, | 84 | navs: std.AutoHashMapUnmanaged(InternPool.Nav.Index, NavMetadata) = .{}, |
| 108 | 85 | ||
| 109 | /// Indices of the three "special" symbols into atoms | 86 | /// Indices of the three "special" symbols into atoms |
| 110 | etext_edata_end_atom_indices: [3]?Atom.Index = .{ null, null, null }, | 87 | etext_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 | }; |
| 133 | 110 | ||
| 134 | const UnnamedConstTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, std.ArrayListUnmanaged(Atom.Index)); | 111 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata); |
| 135 | |||
| 136 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.OptionalDeclIndex, LazySymbolMetadata); | ||
| 137 | 112 | ||
| 138 | const LazySymbolMetadata = struct { | 113 | const 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 got | 136 | /// offset into got |
| 162 | got_index: ?usize, | 137 | got_index: ?usize, |
| 163 | /// We include the code here to be use in relocs | 138 | /// 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 field | 140 | /// 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 | }; |
| 243 | 219 | ||
| 244 | const DeclMetadata = struct { | 220 | const NavMetadata = struct { |
| 245 | index: Atom.Index, | 221 | index: Atom.Index, |
| 246 | exports: std.ArrayListUnmanaged(usize) = .{}, | 222 | exports: std.ArrayListUnmanaged(usize) = .{}, |
| 247 | 223 | ||
| 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 | }; |
| 256 | 232 | ||
| 257 | const FnDeclOutput = struct { | 233 | const FnNavOutput = struct { |
| 258 | /// this code is modified when relocated so it is mutable | 234 | /// 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 mutable | 236 | /// 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 | } |
| 340 | 316 | ||
| 341 | fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !void { | 317 | fn 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 symbol | 330 | // 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); |
| 363 | 339 | ||
| 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); | ||
| 424 | 397 | ||
| 425 | const atom_idx = try self.seeDecl(decl_index); | 398 | const atom_idx = try self.seeNav(pt, func.owner_nav); |
| 426 | 399 | ||
| 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 | } |
| 470 | 442 | ||
| 471 | pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index: InternPool.DeclIndex) !u32 { | 443 | pub 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); |
| 477 | 449 | const nav_init = switch (ip.indexToKey(nav_val.toIntern())) { | |
| 478 | const decl = mod.declPtr(decl_index); | 450 | .variable => |variable| Value.fromInterned(variable.init), |
| 479 | 451 | .@"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 freed | 457 | 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 | |||
| 531 | pub 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); | ||
| 541 | 458 | ||
| 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 atom | 461 | // 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} |
| 566 | fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void { | 482 | fn 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; |
| 572 | 489 | ||
| 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 metadata | 491 | // write the internal linker metadata |
| 575 | atom.type = sym_t; | 492 | atom.type = sym_t; |
| 576 | // write the symbol | 493 | // 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 flushModule | 496 | .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 | }; |
| 583 | 500 | ||
| 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 syms | 563 | // counts decls, and lazy syms |
| 647 | fn atomCount(self: *Plan9) usize { | 564 | fn 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 submap | 568 | // 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 | } |
| 670 | 582 | ||
| 671 | pub fn flushModule(self: *Plan9, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | 583 | pub 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 |
| 734 | 646 | ||
| 735 | var hdr_buf: [40]u8 = undefined; | 647 | var hdr_buf: [40]u8 = undefined; |
| 736 | // account for the fat header | 648 | // 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 | // text | 658 | // 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 next | 670 | // 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 | // data | 738 | // 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.*; |
| 834 | 746 | ||
| 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 | } |
| 1014 | fn addDeclExports( | 904 | fn 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); |
| 1023 | 913 | ||
| 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 | } |
| 1101 | fn 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 | |||
| 1113 | fn createAtom(self: *Plan9) !Atom.Index { | 990 | fn 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 | } |
| 1126 | 1003 | ||
| 1127 | pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index { | 1004 | pub 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 them | 1018 | // 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 externs | 1021 | // 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 | } |
| 1159 | 1037 | ||
| ... | @@ -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 flush | 1057 | // all proper work is done in flush |
| 1180 | _ = pt; | ||
| 1181 | } | 1058 | } |
| 1182 | 1059 | ||
| 1183 | pub fn getOrCreateAtomForLazySymbol(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol) !Atom.Index { | 1060 | pub 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(); |
| 1187 | 1063 | ||
| 1188 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 1064 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 1189 | 1065 | ||
| 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 flushModule | 1079 | // 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 | } |
| 1209 | 1083 | ||
| ... | @@ -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 name | 1091 | // 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 | }); |
| 1222 | 1096 | ||
| 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; |
| 1229 | 1103 | ||
| 1230 | // generate the code | 1104 | // 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 submap | 1151 | // 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); |
| 1318 | 1186 | ||
| 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 | } |
| 1327 | 1195 | ||
| ... | @@ -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 { |
| 1402 | 1270 | ||
| 1403 | // write the data symbols | 1271 | // 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 it | 1301 | // the file of a text symbol is the .z symbol before it |
| 1445 | // so we have to write everything in the right order | 1302 | // 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 symbols | 1307 | // 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 symbol | 1311 | // 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 | } |
| 1502 | 1359 | ||
| 1503 | pub fn getDeclVAddr( | 1360 | pub 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 relocation | 1395 | // 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 parent | 1397 | // 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 | } |
| 1548 | 1405 | ||
| 1549 | pub fn lowerAnonDecl( | 1406 | pub 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)}); |
| 1571 | 1427 | ||
| 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 latex | 1431 | // 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 | } |
| 1599 | 1454 | ||
| 1600 | pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 1455 | pub 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; |
| 36 | const build_options = @import("build_options"); | 36 | const build_options = @import("build_options"); |
| 37 | const Air = @import("../Air.zig"); | 37 | const Air = @import("../Air.zig"); |
| 38 | const Liveness = @import("../Liveness.zig"); | 38 | const Liveness = @import("../Liveness.zig"); |
| 39 | const Type = @import("../Type.zig"); | ||
| 39 | const Value = @import("../Value.zig"); | 40 | const Value = @import("../Value.zig"); |
| 40 | 41 | ||
| 41 | const SpvModule = @import("../codegen/spirv/Module.zig"); | 42 | const SpvModule = @import("../codegen/spirv/Module.zig"); |
| ... | @@ -50,8 +51,6 @@ base: link.File, | ... | @@ -50,8 +51,6 @@ base: link.File, |
| 50 | 51 | ||
| 51 | object: codegen.Object, | 52 | object: codegen.Object, |
| 52 | 53 | ||
| 53 | pub const base_tag: link.File.Tag = .spirv; | ||
| 54 | |||
| 55 | pub fn createEmpty( | 54 | pub 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 | } |
| 130 | 129 | ||
| 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)}); | ||
| 134 | 133 | ||
| 135 | try self.object.updateFunc(pt, func_index, air, liveness); | 134 | try self.object.updateFunc(pt, func_index, air, liveness); |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | pub fn updateDecl(self: *SpirV, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 137 | pub 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 | } |
| 142 | 141 | ||
| 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)}); |
| 145 | 144 | ||
| 146 | try self.object.updateDecl(pt, decl_index); | 145 | try self.object.updateNav(pt, nav); |
| 147 | } | 146 | } |
| 148 | 147 | ||
| 149 | pub fn updateExports( | 148 | pub 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"); |
| 39 | pub const Atom = @import("Wasm/Atom.zig"); | 39 | pub const Atom = @import("Wasm/Atom.zig"); |
| 40 | pub const Relocation = types.Relocation; | 40 | pub const Relocation = types.Relocation; |
| 41 | 41 | ||
| 42 | pub const base_tag: link.File.Tag = .wasm; | ||
| 43 | |||
| 44 | base: link.File, | 42 | base: link.File, |
| 45 | /// Symbol name of the entry function to export | 43 | /// Symbol name of the entry function to export |
| 46 | entry_name: ?[]const u8, | 44 | entry_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 | } |
| 1453 | 1451 | ||
| 1454 | // Generate code for the Decl, storing it in memory to be later written to | 1452 | // Generate code for the "Nav", storing it in memory to be later written to |
| 1455 | // the file on flush(). | 1453 | // the file on flush(). |
| 1456 | pub fn updateDecl(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 1454 | pub 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 | } |
| 1463 | 1461 | ||
| 1464 | pub fn updateDeclLineNumber(wasm: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void { | 1462 | pub 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 | } |
| 1468 | 1466 | ||
| 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 | } |
| 1507 | 1505 | ||
| 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. | ||
| 1511 | pub 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 instead | 1508 | /// 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 | } |
| 1523 | 1514 | ||
| 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 address | 1516 | /// Returns the given pointer address |
| 1526 | pub fn getDeclVAddr( | 1517 | pub 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 | } |
| 1534 | 1525 | ||
| 1535 | pub fn lowerAnonDecl( | 1526 | pub 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 | } |
| 1544 | 1535 | ||
| 1545 | pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 1536 | pub 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 | } |
| 1548 | 1539 | ||
| 1549 | pub fn deleteExport( | 1540 | pub 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 | } |
| 4020 | 4011 | ||
| 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. |
| 4024 | pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 { | 4015 | pub 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 | } |
| 4027 | 4018 | ||
| 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`. |
| 4039 | pub fn getOrCreateAtomForDecl(wasm_file: *Wasm, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !Atom.Index { | 4030 | pub 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 | } |
| 4042 | 4033 | ||
| 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 @@ |
| 6 | path: []const u8, | 6 | path: []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. |
| 8 | index: File.Index, | 8 | index: 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`. |
| 11 | decls_map: std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclInfo) = .{}, | 11 | navs: 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. |
| 13 | func_types: std.ArrayListUnmanaged(std.wasm.Type) = .{}, | 13 | func_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. |
| 37 | string_table: StringTable = .{}, | 37 | string_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. |
| 39 | anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, | 39 | uavs: 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. |
| 41 | synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{}, | 41 | synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 42 | /// Represents the symbol index of the error name table | 42 | /// 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. |
| 87 | debug_abbrev_index: ?u32 = null, | 87 | debug_abbrev_index: ?u32 = null, |
| 88 | 88 | ||
| 89 | const DeclInfo = struct { | 89 | const NavInfo = struct { |
| 90 | atom: Atom.Index = .null, | 90 | atom: Atom.Index = .null, |
| 91 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, | 91 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 92 | 92 | ||
| 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 | } |
| 103 | 103 | ||
| 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 | } |
| 107 | 107 | ||
| 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 | } |
| 156 | 156 | ||
| 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 | } |
| 238 | 238 | ||
| 239 | // Generate code for the Decl, storing it in memory to be later written to | 239 | // Generate code for the `Nav`, storing it in memory to be later written to |
| 240 | // the file on flush(). | 240 | // the file on flush(). |
| 241 | pub fn updateDecl( | 241 | pub 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 | }; | ||
| 254 | 260 | ||
| 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(); |
| 259 | 265 | ||
| 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; | ||
| 267 | 268 | ||
| 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 | }; |
| 289 | 289 | ||
| 290 | return zig_object.finishUpdateDecl(wasm_file, pt, decl_index, code); | 290 | return zig_object.finishUpdateNav(wasm_file, pt, nav_index, code); |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | pub fn updateFunc( | 293 | pub 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(); |
| 308 | 307 | ||
| ... | @@ -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 | }; |
| 330 | 328 | ||
| 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 | } |
| 333 | 331 | ||
| 334 | fn finishUpdateDecl( | 332 | fn 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); |
| 352 | 351 | ||
| 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 | } |
| 399 | 394 | ||
| 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 | } |
| 422 | 417 | ||
| 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`. |
| 426 | pub fn getOrCreateAtomForDecl( | 421 | pub 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 | } |
| 443 | 439 | ||
| 444 | pub fn lowerAnonDecl( | 440 | pub 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; |
| 459 | 455 | ||
| 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 | } |
| 465 | 461 | ||
| 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. | ||
| 480 | pub 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 | } |
| 522 | 472 | ||
| 523 | const LowerConstResult = union(enum) { | 473 | const 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 |
| 782 | 732 | ||
| 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 address | 734 | /// Returns the given pointer address |
| 785 | pub fn getDeclVAddr( | 735 | pub 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; | ||
| 797 | 747 | ||
| 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 | else | 755 | 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 | } |
| 809 | 761 | ||
| 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 relocations | 767 | 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 | } |
| 836 | 788 | ||
| 837 | pub fn getAnonDeclVAddr( | 789 | pub 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); |
| 847 | 799 | ||
| 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 relocations | 806 | 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)}); |
| 920 | 873 | ||
| 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 | } |
| 932 | 885 | ||
| 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 | }; |
| 939 | 892 | ||
| ... | @@ -954,9 +907,9 @@ pub fn updateExports( | ... | @@ -954,9 +907,9 @@ pub fn updateExports( |
| 954 | }, | 907 | }, |
| 955 | .strong => {}, // symbols are strong by default | 908 | .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 | } |
| 974 | 927 | ||
| 975 | pub fn freeDecl(zig_object: *ZigObject, wasm_file: *Wasm, decl_index: InternPool.DeclIndex) void { | 928 | pub 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 free | 953 | segment.name = &.{}; // Ensure no accidental double free |
| 1001 | } | 954 | } |
| 1002 | 955 | ||
| 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 | } |
| 1030 | 981 | ||
| ... | @@ -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. |
| 1185 | pub fn storeDeclType(zig_object: *ZigObject, gpa: std.mem.Allocator, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 { | 1136 | pub 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 | } |
| 1191 | 1142 |
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 | } |
| 680 | 680 | ||
| 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's | 141 | // 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's | 160 | // 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 | }; |
| 296 | 292 | ||
| 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 | } |
| 612 | 612 | ||
| 613 | test "@typeInfo decls ignore dependency loops" { | 613 | test "@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 | } |
| 92 | 92 | ||
| 93 | comptime { | ||
| 94 | _ = @import("usingnamespace/file_1.zig"); | ||
| 95 | } | ||
| 96 | |||
| 97 | const Bar = struct { | 93 | const Bar = struct { |
| 98 | usingnamespace Mixin; | 94 | usingnamespace Mixin; |
| 99 | }; | 95 | }; |
test/behavior/usingnamespace/file_0.zig deleted-1| ... | @@ -1 +0,0 @@ | ||
| 1 | pub const A = 123; | ||
test/behavior/usingnamespace/file_1.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | const imports = @import("imports.zig"); | ||
| 4 | const builtin = @import("builtin"); | ||
| 5 | |||
| 6 | const A = 456; | ||
| 7 | |||
| 8 | test { | ||
| 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 @@ | ||
| 1 | const file_0 = @import("file_0.zig"); | ||
| 2 | const file_1 = @import("file_1.zig"); | ||
| 3 | |||
| 4 | pub usingnamespace file_0; | ||
| 5 | pub usingnamespace file_1; | ||
test/cases/compile_errors/setAlignStack_in_inline_function.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | export fn entry() void { | ||
| 2 | foo(); | ||
| 3 | } | ||
| 4 | inline fn foo() void { | ||
| 5 | @setAlignStack(16); | ||
| 6 | } | ||
| 7 | |||
| 8 | export fn entry1() void { | ||
| 9 | comptime bar(); | ||
| 10 | } | ||
| 11 | fn 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 @@ | ||
| 1 | export 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=native | 8 | // target=native |
| 9 | // is_test=true | 9 | // 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 here | 12 | // :2:15: note: declared here |