| author | |
| committer | |
| log | fc2924080694d68945308d394751a2ec4841b3c0 |
| tree | c4b372662b0253de33483225d17a8a79c735ada5 |
| parent | 531cd177e89c1edfcd2e52f74f220eb186a25f78 |
| parent | 153e7d6235a7d74d0c02d51f84edc5c06ab7469d |
| signature |
compiler: split `Decl` into `Nav` and `Cau`49 files changed, 6455 insertions(+), 7288 deletions(-)
src/Compilation.zig+76-151| ... | @@ -354,28 +354,25 @@ pub const RcIncludes = enum { | ... | @@ -354,28 +354,25 @@ pub const RcIncludes = enum { |
| 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+964-523| ... | @@ -24,12 +24,14 @@ tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th | ... | @@ -24,12 +24,14 @@ tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th |
| 24 | /// These are also invalidated if tracking fails for this instruction. | 24 | /// These are also invalidated if tracking fails for this instruction. |
| 25 | /// Value is index into `dep_entries` of the first dependency on this hash. | 25 | /// Value is index into `dep_entries` of the first dependency on this hash. |
| 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: | 1103 | return .{ |
| 840 | /// * Stable memory so that one thread can access a Decl object while another | 1104 | .gpa = gpa, |
| 841 | /// thread allocates additional Decl objects from this list. | 1105 | .arena = &local.mutate.arena, |
| 842 | /// * It allows us to use u32 indexes to reference Decl objects rather than | 1106 | .mutate = &local.mutate.caus, |
| 843 | /// pointers, saving memory in Type, Value, and dependency sets. | 1107 | .list = &local.shared.caus, |
| 844 | /// * Using integers to reference Decl objects rather than pointers makes | 1108 | }; |
| 845 | /// serialization trivial. | 1109 | } |
| 846 | /// * It provides a unique integer to be used for anonymous symbol names, avoiding | 1110 | |
| 847 | /// multi-threaded contention on an atomic counter. | 1111 | pub fn getMutableNavs(local: *Local, gpa: Allocator) Navs.Mutable { |
| 848 | pub fn getMutableDecls(local: *Local, gpa: Allocator) Decls.Mutable { | ||
| 849 | return .{ | 1112 | return .{ |
| 850 | .gpa = gpa, | 1113 | .gpa = gpa, |
| 851 | .arena = &local.mutate.arena, | 1114 | .arena = &local.mutate.arena, |
| 852 | .mutate = &local.mutate.decls.buckets_list, | 1115 | .mutate = &local.mutate.navs, |
| 853 | .list = &local.shared.decls, | 1116 | .list = &local.shared.navs, |
| 854 | }; | 1117 | }; |
| 855 | } | 1118 | } |
| 856 | 1119 | ||
| 857 | /// Same pattern as with `getMutableDecls`. | 1120 | /// Rather than allocating Namespace objects with an Allocator, we instead allocate |
| 1121 | /// them with this BucketList. This provides four advantages: | ||
| 1122 | /// * Stable memory so that one thread can access a Namespace object while another | ||
| 1123 | /// thread allocates additional Namespace objects from this list. | ||
| 1124 | /// * It allows us to use u32 indexes to reference Namespace objects rather than | ||
| 1125 | /// pointers, saving memory in types. | ||
| 1126 | /// * Using integers to reference Namespace objects rather than pointers makes | ||
| 1127 | /// serialization trivial. | ||
| 1128 | /// * It provides a unique integer to be used for anonymous symbol names, avoiding | ||
| 1129 | /// multi-threaded contention on an atomic counter. | ||
| 858 | pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable { | 1130 | pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable { |
| 859 | return .{ | 1131 | return .{ |
| 860 | .gpa = gpa, | 1132 | .gpa = gpa, |
| ... | @@ -1038,51 +1310,6 @@ pub const RuntimeIndex = enum(u32) { | ... | @@ -1038,51 +1310,6 @@ pub const RuntimeIndex = enum(u32) { |
| 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,10 +2879,13 @@ pub const LoadedUnionType = struct { | ... | @@ -2632,10 +2879,13 @@ pub const LoadedUnionType = struct { |
| 2632 | tid: Zcu.PerThread.Id, | 2879 | tid: Zcu.PerThread.Id, |
| 2633 | /// The index of the `Tag.TypeUnion` payload. | 2880 | /// The index of the `Tag.TypeUnion` payload. |
| 2634 | extra_index: u32, | 2881 | extra_index: u32, |
| 2635 | /// The Decl that corresponds to the union itself. | 2882 | // TODO: the non-fqn will be needed by the new dwarf structure |
| 2636 | decl: DeclIndex, | 2883 | /// The name of this union type. |
| 2884 | name: NullTerminatedString, | ||
| 2885 | /// The `Cau` within which type resolution occurs. | ||
| 2886 | cau: Cau.Index, | ||
| 2637 | /// Represents the declarations inside this union. | 2887 | /// Represents the declarations inside this union. |
| 2638 | namespace: OptionalNamespaceIndex, | 2888 | namespace: NamespaceIndex, |
| 2639 | /// The enum tag type. | 2889 | /// The enum tag type. |
| 2640 | enum_tag_ty: Index, | 2890 | enum_tag_ty: Index, |
| 2641 | /// List of field types in declaration order. | 2891 | /// List of field types in declaration order. |
| ... | @@ -2949,7 +3199,8 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType { | ... | @@ -2949,7 +3199,8 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType { |
| 2949 | return .{ | 3199 | return .{ |
| 2950 | .tid = unwrapped_index.tid, | 3200 | .tid = unwrapped_index.tid, |
| 2951 | .extra_index = data, | 3201 | .extra_index = data, |
| 2952 | .decl = type_union.data.decl, | 3202 | .name = type_union.data.name, |
| 3203 | .cau = type_union.data.cau, | ||
| 2953 | .namespace = type_union.data.namespace, | 3204 | .namespace = type_union.data.namespace, |
| 2954 | .enum_tag_ty = type_union.data.tag_ty, | 3205 | .enum_tag_ty = type_union.data.tag_ty, |
| 2955 | .field_types = field_types, | 3206 | .field_types = field_types, |
| ... | @@ -2963,9 +3214,12 @@ pub const LoadedStructType = struct { | ... | @@ -2963,9 +3214,12 @@ pub const LoadedStructType = struct { |
| 2963 | tid: Zcu.PerThread.Id, | 3214 | tid: Zcu.PerThread.Id, |
| 2964 | /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload. | 3215 | /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload. |
| 2965 | extra_index: u32, | 3216 | extra_index: u32, |
| 2966 | /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`. | 3217 | // TODO: the non-fqn will be needed by the new dwarf structure |
| 2967 | decl: OptionalDeclIndex, | 3218 | /// The name of this struct type. |
| 2968 | /// `none` when the struct has no declarations. | 3219 | name: NullTerminatedString, |
| 3220 | /// The `Cau` within which type resolution occurs. `none` when the struct is `@TypeOf(.{})`. | ||
| 3221 | cau: Cau.Index.Optional, | ||
| 3222 | /// `none` when the struct is `@TypeOf(.{})`. | ||
| 2969 | namespace: OptionalNamespaceIndex, | 3223 | namespace: OptionalNamespaceIndex, |
| 2970 | /// Index of the `struct_decl` or `reify` ZIR instruction. | 3224 | /// Index of the `struct_decl` or `reify` ZIR instruction. |
| 2971 | /// Only `none` when the struct is `@TypeOf(.{})`. | 3225 | /// Only `none` when the struct is `@TypeOf(.{})`. |
| ... | @@ -3563,7 +3817,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3563,7 +3817,8 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3563 | if (item.data == 0) return .{ | 3817 | if (item.data == 0) return .{ |
| 3564 | .tid = .main, | 3818 | .tid = .main, |
| 3565 | .extra_index = 0, | 3819 | .extra_index = 0, |
| 3566 | .decl = .none, | 3820 | .name = .empty, |
| 3821 | .cau = .none, | ||
| 3567 | .namespace = .none, | 3822 | .namespace = .none, |
| 3568 | .zir_index = .none, | 3823 | .zir_index = .none, |
| 3569 | .layout = .auto, | 3824 | .layout = .auto, |
| ... | @@ -3577,7 +3832,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3577,7 +3832,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3577 | .names_map = .none, | 3832 | .names_map = .none, |
| 3578 | .captures = CaptureValue.Slice.empty, | 3833 | .captures = CaptureValue.Slice.empty, |
| 3579 | }; | 3834 | }; |
| 3580 | const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]); | 3835 | const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]); |
| 3836 | const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "cau").?]); | ||
| 3837 | const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]); | ||
| 3581 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]); | 3838 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]); |
| 3582 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?]; | 3839 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?]; |
| 3583 | const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered)); | 3840 | const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered)); |
| ... | @@ -3622,11 +3879,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3622,11 +3879,6 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3622 | extra_index += fields_len; | 3879 | extra_index += fields_len; |
| 3623 | break :i inits; | 3880 | break :i inits; |
| 3624 | } else Index.Slice.empty; | 3881 | } else Index.Slice.empty; |
| 3625 | const namespace: OptionalNamespaceIndex = if (flags.has_namespace) n: { | ||
| 3626 | const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); | ||
| 3627 | extra_index += 1; | ||
| 3628 | break :n n.toOptional(); | ||
| 3629 | } else .none; | ||
| 3630 | const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: { | 3882 | const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: { |
| 3631 | const a: Alignment.Slice = .{ | 3883 | const a: Alignment.Slice = .{ |
| 3632 | .tid = unwrapped_index.tid, | 3884 | .tid = unwrapped_index.tid, |
| ... | @@ -3667,8 +3919,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3667,8 +3919,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3667 | return .{ | 3919 | return .{ |
| 3668 | .tid = unwrapped_index.tid, | 3920 | .tid = unwrapped_index.tid, |
| 3669 | .extra_index = item.data, | 3921 | .extra_index = item.data, |
| 3670 | .decl = decl.toOptional(), | 3922 | .name = name, |
| 3671 | .namespace = namespace, | 3923 | .cau = cau.toOptional(), |
| 3924 | .namespace = namespace.toOptional(), | ||
| 3672 | .zir_index = zir_index.toOptional(), | 3925 | .zir_index = zir_index.toOptional(), |
| 3673 | .layout = if (flags.is_extern) .@"extern" else .auto, | 3926 | .layout = if (flags.is_extern) .@"extern" else .auto, |
| 3674 | .field_names = names, | 3927 | .field_names = names, |
| ... | @@ -3683,10 +3936,11 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3683,10 +3936,11 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3683 | }; | 3936 | }; |
| 3684 | }, | 3937 | }, |
| 3685 | .type_struct_packed, .type_struct_packed_inits => { | 3938 | .type_struct_packed, .type_struct_packed_inits => { |
| 3686 | const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]); | 3939 | const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]); |
| 3940 | const cau: Cau.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?]); | ||
| 3687 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]); | 3941 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]); |
| 3688 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?]; | 3942 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?]; |
| 3689 | const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]); | 3943 | const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]); |
| 3690 | const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]); | 3944 | const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]); |
| 3691 | const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered)); | 3945 | const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered)); |
| 3692 | var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len); | 3946 | var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len); |
| ... | @@ -3729,8 +3983,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3729,8 +3983,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3729 | return .{ | 3983 | return .{ |
| 3730 | .tid = unwrapped_index.tid, | 3984 | .tid = unwrapped_index.tid, |
| 3731 | .extra_index = item.data, | 3985 | .extra_index = item.data, |
| 3732 | .decl = decl.toOptional(), | 3986 | .name = name, |
| 3733 | .namespace = namespace, | 3987 | .cau = cau.toOptional(), |
| 3988 | .namespace = namespace.toOptional(), | ||
| 3734 | .zir_index = zir_index.toOptional(), | 3989 | .zir_index = zir_index.toOptional(), |
| 3735 | .layout = .@"packed", | 3990 | .layout = .@"packed", |
| 3736 | .field_names = field_names, | 3991 | .field_names = field_names, |
| ... | @@ -3749,10 +4004,14 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { | ... | @@ -3749,10 +4004,14 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3749 | } | 4004 | } |
| 3750 | 4005 | ||
| 3751 | const LoadedEnumType = struct { | 4006 | const LoadedEnumType = struct { |
| 3752 | /// The Decl that corresponds to the enum itself. | 4007 | // TODO: the non-fqn will be needed by the new dwarf structure |
| 3753 | decl: DeclIndex, | 4008 | /// The name of this enum type. |
| 4009 | name: NullTerminatedString, | ||
| 4010 | /// The `Cau` within which type resolution occurs. | ||
| 4011 | /// `null` if this is a generated tag type. | ||
| 4012 | cau: Cau.Index.Optional, | ||
| 3754 | /// Represents the declarations inside this enum. | 4013 | /// Represents the declarations inside this enum. |
| 3755 | namespace: OptionalNamespaceIndex, | 4014 | namespace: NamespaceIndex, |
| 3756 | /// An integer type which is used for the numerical value of the enum. | 4015 | /// An integer type which is used for the numerical value of the enum. |
| 3757 | /// This field is present regardless of whether the enum has an | 4016 | /// This field is present regardless of whether the enum has an |
| 3758 | /// explicitly provided tag type or auto-numbered. | 4017 | /// explicitly provided tag type or auto-numbered. |
| ... | @@ -3827,15 +4086,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { | ... | @@ -3827,15 +4086,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { |
| 3827 | .type_enum_auto => { | 4086 | .type_enum_auto => { |
| 3828 | const extra = extraDataTrail(extra_list, EnumAuto, item.data); | 4087 | const extra = extraDataTrail(extra_list, EnumAuto, item.data); |
| 3829 | var extra_index: u32 = @intCast(extra.end); | 4088 | var extra_index: u32 = @intCast(extra.end); |
| 3830 | if (extra.data.zir_index == .none) { | 4089 | const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: { |
| 3831 | extra_index += 1; // owner_union | 4090 | extra_index += 1; // owner_union |
| 3832 | } | 4091 | break :cau .none; |
| 4092 | } else cau: { | ||
| 4093 | const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); | ||
| 4094 | extra_index += 1; // cau | ||
| 4095 | break :cau cau.toOptional(); | ||
| 4096 | }; | ||
| 3833 | const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: { | 4097 | const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: { |
| 3834 | extra_index += 2; // type_hash: PackedU64 | 4098 | extra_index += 2; // type_hash: PackedU64 |
| 3835 | break :c 0; | 4099 | break :c 0; |
| 3836 | } else extra.data.captures_len; | 4100 | } else extra.data.captures_len; |
| 3837 | return .{ | 4101 | return .{ |
| 3838 | .decl = extra.data.decl, | 4102 | .name = extra.data.name, |
| 4103 | .cau = cau, | ||
| 3839 | .namespace = extra.data.namespace, | 4104 | .namespace = extra.data.namespace, |
| 3840 | .tag_ty = extra.data.int_tag_type, | 4105 | .tag_ty = extra.data.int_tag_type, |
| 3841 | .names = .{ | 4106 | .names = .{ |
| ... | @@ -3861,15 +4126,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { | ... | @@ -3861,15 +4126,21 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { |
| 3861 | }; | 4126 | }; |
| 3862 | const extra = extraDataTrail(extra_list, EnumExplicit, item.data); | 4127 | const extra = extraDataTrail(extra_list, EnumExplicit, item.data); |
| 3863 | var extra_index: u32 = @intCast(extra.end); | 4128 | var extra_index: u32 = @intCast(extra.end); |
| 3864 | if (extra.data.zir_index == .none) { | 4129 | const cau: Cau.Index.Optional = if (extra.data.zir_index == .none) cau: { |
| 3865 | extra_index += 1; // owner_union | 4130 | extra_index += 1; // owner_union |
| 3866 | } | 4131 | break :cau .none; |
| 4132 | } else cau: { | ||
| 4133 | const cau: Cau.Index = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); | ||
| 4134 | extra_index += 1; // cau | ||
| 4135 | break :cau cau.toOptional(); | ||
| 4136 | }; | ||
| 3867 | const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: { | 4137 | const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: { |
| 3868 | extra_index += 2; // type_hash: PackedU64 | 4138 | extra_index += 2; // type_hash: PackedU64 |
| 3869 | break :c 0; | 4139 | break :c 0; |
| 3870 | } else extra.data.captures_len; | 4140 | } else extra.data.captures_len; |
| 3871 | return .{ | 4141 | return .{ |
| 3872 | .decl = extra.data.decl, | 4142 | .name = extra.data.name, |
| 4143 | .cau = cau, | ||
| 3873 | .namespace = extra.data.namespace, | 4144 | .namespace = extra.data.namespace, |
| 3874 | .tag_ty = extra.data.int_tag_type, | 4145 | .tag_ty = extra.data.int_tag_type, |
| 3875 | .names = .{ | 4146 | .names = .{ |
| ... | @@ -3896,10 +4167,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { | ... | @@ -3896,10 +4167,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType { |
| 3896 | 4167 | ||
| 3897 | /// Note that this type doubles as the payload for `Tag.type_opaque`. | 4168 | /// Note that this type doubles as the payload for `Tag.type_opaque`. |
| 3898 | pub const LoadedOpaqueType = struct { | 4169 | pub const LoadedOpaqueType = struct { |
| 3899 | /// The opaque's owner Decl. | ||
| 3900 | decl: DeclIndex, | ||
| 3901 | /// Contains the declarations inside this opaque. | 4170 | /// Contains the declarations inside this opaque. |
| 3902 | namespace: OptionalNamespaceIndex, | 4171 | namespace: NamespaceIndex, |
| 4172 | // TODO: the non-fqn will be needed by the new dwarf structure | ||
| 4173 | /// The name of this opaque type. | ||
| 4174 | name: NullTerminatedString, | ||
| 3903 | /// Index of the `opaque_decl` or `reify` instruction. | 4175 | /// Index of the `opaque_decl` or `reify` instruction. |
| 3904 | zir_index: TrackedInst.Index, | 4176 | zir_index: TrackedInst.Index, |
| 3905 | captures: CaptureValue.Slice, | 4177 | captures: CaptureValue.Slice, |
| ... | @@ -3915,7 +4187,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType { | ... | @@ -3915,7 +4187,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType { |
| 3915 | else | 4187 | else |
| 3916 | extra.data.captures_len; | 4188 | extra.data.captures_len; |
| 3917 | return .{ | 4189 | return .{ |
| 3918 | .decl = extra.data.decl, | 4190 | .name = extra.data.name, |
| 3919 | .namespace = extra.data.namespace, | 4191 | .namespace = extra.data.namespace, |
| 3920 | .zir_index = extra.data.zir_index, | 4192 | .zir_index = extra.data.zir_index, |
| 3921 | .captures = .{ | 4193 | .captures = .{ |
| ... | @@ -4216,10 +4488,10 @@ pub const Index = enum(u32) { | ... | @@ -4216,10 +4488,10 @@ pub const Index = enum(u32) { |
| 4216 | 4488 | ||
| 4217 | undef: DataIsIndex, | 4489 | undef: DataIsIndex, |
| 4218 | simple_value: void, | 4490 | simple_value: void, |
| 4219 | ptr_decl: struct { data: *PtrDecl }, | 4491 | ptr_nav: struct { data: *PtrNav }, |
| 4220 | ptr_comptime_alloc: struct { data: *PtrComptimeAlloc }, | 4492 | ptr_comptime_alloc: struct { data: *PtrComptimeAlloc }, |
| 4221 | ptr_anon_decl: struct { data: *PtrAnonDecl }, | 4493 | ptr_uav: struct { data: *PtrUav }, |
| 4222 | ptr_anon_decl_aligned: struct { data: *PtrAnonDeclAligned }, | 4494 | ptr_uav_aligned: struct { data: *PtrUavAligned }, |
| 4223 | ptr_comptime_field: struct { data: *PtrComptimeField }, | 4495 | ptr_comptime_field: struct { data: *PtrComptimeField }, |
| 4224 | ptr_int: struct { data: *PtrInt }, | 4496 | ptr_int: struct { data: *PtrInt }, |
| 4225 | ptr_eu_payload: struct { data: *PtrBase }, | 4497 | ptr_eu_payload: struct { data: *PtrBase }, |
| ... | @@ -4255,7 +4527,7 @@ pub const Index = enum(u32) { | ... | @@ -4255,7 +4527,7 @@ pub const Index = enum(u32) { |
| 4255 | float_c_longdouble_f128: struct { data: *Float128 }, | 4527 | float_c_longdouble_f128: struct { data: *Float128 }, |
| 4256 | float_comptime_float: struct { data: *Float128 }, | 4528 | float_comptime_float: struct { data: *Float128 }, |
| 4257 | variable: struct { data: *Tag.Variable }, | 4529 | variable: struct { data: *Tag.Variable }, |
| 4258 | extern_func: struct { data: *Key.ExternFunc }, | 4530 | @"extern": struct { data: *Tag.Extern }, |
| 4259 | func_decl: struct { | 4531 | func_decl: struct { |
| 4260 | const @"data.analysis.inferred_error_set" = opaque {}; | 4532 | const @"data.analysis.inferred_error_set" = opaque {}; |
| 4261 | data: *Tag.FuncDecl, | 4533 | data: *Tag.FuncDecl, |
| ... | @@ -4669,23 +4941,23 @@ pub const Tag = enum(u8) { | ... | @@ -4669,23 +4941,23 @@ pub const Tag = enum(u8) { |
| 4669 | /// A value that can be represented with only an enum tag. | 4941 | /// A value that can be represented with only an enum tag. |
| 4670 | /// data is SimpleValue enum value. | 4942 | /// data is SimpleValue enum value. |
| 4671 | simple_value, | 4943 | simple_value, |
| 4672 | /// A pointer to a decl. | 4944 | /// A pointer to a `Nav`. |
| 4673 | /// data is extra index of `PtrDecl`, which contains the type and address. | 4945 | /// data is extra index of `PtrNav`, which contains the type and address. |
| 4674 | ptr_decl, | 4946 | ptr_nav, |
| 4675 | /// A pointer to a decl that can be mutated at comptime. | 4947 | /// A pointer to a decl that can be mutated at comptime. |
| 4676 | /// data is extra index of `PtrComptimeAlloc`, which contains the type and address. | 4948 | /// data is extra index of `PtrComptimeAlloc`, which contains the type and address. |
| 4677 | ptr_comptime_alloc, | 4949 | ptr_comptime_alloc, |
| 4678 | /// A pointer to an anonymous decl. | 4950 | /// A pointer to an anonymous addressable value. |
| 4679 | /// data is extra index of `PtrAnonDecl`, which contains the pointer type and decl value. | 4951 | /// data is extra index of `PtrUav`, which contains the pointer type and decl value. |
| 4680 | /// The alignment of the anonymous decl is communicated via the pointer type. | 4952 | /// The alignment of the uav is communicated via the pointer type. |
| 4681 | ptr_anon_decl, | 4953 | ptr_uav, |
| 4682 | /// A pointer to an anonymous decl. | 4954 | /// A pointer to an unnamed addressable value. |
| 4683 | /// data is extra index of `PtrAnonDeclAligned`, which contains the pointer | 4955 | /// data is extra index of `PtrUavAligned`, which contains the pointer |
| 4684 | /// type and decl value. | 4956 | /// type and decl value. |
| 4685 | /// The original pointer type is also provided, which will be different than `ty`. | 4957 | /// The original pointer type is also provided, which will be different than `ty`. |
| 4686 | /// This encoding is only used when a pointer to an anonymous decl is | 4958 | /// This encoding is only used when a pointer to a Uav is |
| 4687 | /// coerced to a different pointer type with a different alignment. | 4959 | /// coerced to a different pointer type with a different alignment. |
| 4688 | ptr_anon_decl_aligned, | 4960 | ptr_uav_aligned, |
| 4689 | /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value. | 4961 | /// data is extra index of `PtrComptimeField`, which contains the pointer type and field value. |
| 4690 | ptr_comptime_field, | 4962 | ptr_comptime_field, |
| 4691 | /// A pointer with an integer value. | 4963 | /// A pointer with an integer value. |
| ... | @@ -4800,9 +5072,10 @@ pub const Tag = enum(u8) { | ... | @@ -4800,9 +5072,10 @@ pub const Tag = enum(u8) { |
| 4800 | /// A global variable. | 5072 | /// A global variable. |
| 4801 | /// data is extra index to Variable. | 5073 | /// data is extra index to Variable. |
| 4802 | variable, | 5074 | variable, |
| 4803 | /// An extern function. | 5075 | /// An extern function or variable. |
| 4804 | /// data is extra index to ExternFunc. | 5076 | /// data is extra index to Extern. |
| 4805 | extern_func, | 5077 | /// Some parts of the key are stored in `owner_nav`. |
| 5078 | @"extern", | ||
| 4806 | /// A non-extern function corresponding directly to the AST node from whence it originated. | 5079 | /// A non-extern function corresponding directly to the AST node from whence it originated. |
| 4807 | /// data is extra index to `FuncDecl`. | 5080 | /// data is extra index to `FuncDecl`. |
| 4808 | /// Only the owner Decl is used for hashing and equality because the other | 5081 | /// Only the owner Decl is used for hashing and equality because the other |
| ... | @@ -4843,7 +5116,6 @@ pub const Tag = enum(u8) { | ... | @@ -4843,7 +5116,6 @@ pub const Tag = enum(u8) { |
| 4843 | const TypeValue = Key.TypeValue; | 5116 | const TypeValue = Key.TypeValue; |
| 4844 | const Error = Key.Error; | 5117 | const Error = Key.Error; |
| 4845 | const EnumTag = Key.EnumTag; | 5118 | const EnumTag = Key.EnumTag; |
| 4846 | const ExternFunc = Key.ExternFunc; | ||
| 4847 | const Union = Key.Union; | 5119 | const Union = Key.Union; |
| 4848 | const TypePointer = Key.PtrType; | 5120 | const TypePointer = Key.PtrType; |
| 4849 | 5121 | ||
| ... | @@ -4877,10 +5149,10 @@ pub const Tag = enum(u8) { | ... | @@ -4877,10 +5149,10 @@ pub const Tag = enum(u8) { |
| 4877 | 5149 | ||
| 4878 | .undef => unreachable, | 5150 | .undef => unreachable, |
| 4879 | .simple_value => unreachable, | 5151 | .simple_value => unreachable, |
| 4880 | .ptr_decl => PtrDecl, | 5152 | .ptr_nav => PtrNav, |
| 4881 | .ptr_comptime_alloc => PtrComptimeAlloc, | 5153 | .ptr_comptime_alloc => PtrComptimeAlloc, |
| 4882 | .ptr_anon_decl => PtrAnonDecl, | 5154 | .ptr_uav => PtrUav, |
| 4883 | .ptr_anon_decl_aligned => PtrAnonDeclAligned, | 5155 | .ptr_uav_aligned => PtrUavAligned, |
| 4884 | .ptr_comptime_field => PtrComptimeField, | 5156 | .ptr_comptime_field => PtrComptimeField, |
| 4885 | .ptr_int => PtrInt, | 5157 | .ptr_int => PtrInt, |
| 4886 | .ptr_eu_payload => PtrBase, | 5158 | .ptr_eu_payload => PtrBase, |
| ... | @@ -4916,7 +5188,7 @@ pub const Tag = enum(u8) { | ... | @@ -4916,7 +5188,7 @@ pub const Tag = enum(u8) { |
| 4916 | .float_c_longdouble_f128 => unreachable, | 5188 | .float_c_longdouble_f128 => unreachable, |
| 4917 | .float_comptime_float => unreachable, | 5189 | .float_comptime_float => unreachable, |
| 4918 | .variable => Variable, | 5190 | .variable => Variable, |
| 4919 | .extern_func => ExternFunc, | 5191 | .@"extern" => Extern, |
| 4920 | .func_decl => FuncDecl, | 5192 | .func_decl => FuncDecl, |
| 4921 | .func_instance => FuncInstance, | 5193 | .func_instance => FuncInstance, |
| 4922 | .func_coerced => FuncCoerced, | 5194 | .func_coerced => FuncCoerced, |
| ... | @@ -4933,21 +5205,29 @@ pub const Tag = enum(u8) { | ... | @@ -4933,21 +5205,29 @@ pub const Tag = enum(u8) { |
| 4933 | ty: Index, | 5205 | ty: Index, |
| 4934 | /// May be `none`. | 5206 | /// May be `none`. |
| 4935 | init: Index, | 5207 | init: Index, |
| 4936 | decl: DeclIndex, | 5208 | owner_nav: Nav.Index, |
| 4937 | /// Library name if specified. | 5209 | /// Library name if specified. |
| 4938 | /// For example `extern "c" var stderrp = ...` would have 'c' as library name. | 5210 | /// For example `extern "c" var stderrp = ...` would have 'c' as library name. |
| 4939 | lib_name: OptionalNullTerminatedString, | 5211 | lib_name: OptionalNullTerminatedString, |
| 4940 | flags: Flags, | 5212 | flags: Flags, |
| 4941 | 5213 | ||
| 4942 | pub const Flags = packed struct(u32) { | 5214 | pub const Flags = packed struct(u32) { |
| 4943 | is_extern: bool, | ||
| 4944 | is_const: bool, | 5215 | is_const: bool, |
| 4945 | is_threadlocal: bool, | 5216 | is_threadlocal: bool, |
| 4946 | is_weak_linkage: bool, | 5217 | is_weak_linkage: bool, |
| 4947 | _: u28 = 0, | 5218 | _: u29 = 0, |
| 4948 | }; | 5219 | }; |
| 4949 | }; | 5220 | }; |
| 4950 | 5221 | ||
| 5222 | pub const Extern = struct { | ||
| 5223 | // name, alignment, addrspace come from `owner_nav`. | ||
| 5224 | ty: Index, | ||
| 5225 | lib_name: OptionalNullTerminatedString, | ||
| 5226 | flags: Variable.Flags, | ||
| 5227 | owner_nav: Nav.Index, | ||
| 5228 | zir_index: TrackedInst.Index, | ||
| 5229 | }; | ||
| 5230 | |||
| 4951 | /// Trailing: | 5231 | /// Trailing: |
| 4952 | /// 0. element: Index for each len | 5232 | /// 0. element: Index for each len |
| 4953 | /// len is determined by the aggregate type. | 5233 | /// len is determined by the aggregate type. |
| ... | @@ -4962,7 +5242,7 @@ pub const Tag = enum(u8) { | ... | @@ -4962,7 +5242,7 @@ pub const Tag = enum(u8) { |
| 4962 | /// A `none` value marks that the inferred error set is not resolved yet. | 5242 | /// A `none` value marks that the inferred error set is not resolved yet. |
| 4963 | pub const FuncDecl = struct { | 5243 | pub const FuncDecl = struct { |
| 4964 | analysis: FuncAnalysis, | 5244 | analysis: FuncAnalysis, |
| 4965 | owner_decl: DeclIndex, | 5245 | owner_nav: Nav.Index, |
| 4966 | ty: Index, | 5246 | ty: Index, |
| 4967 | zir_body_inst: TrackedInst.Index, | 5247 | zir_body_inst: TrackedInst.Index, |
| 4968 | lbrace_line: u32, | 5248 | lbrace_line: u32, |
| ... | @@ -4979,7 +5259,7 @@ pub const Tag = enum(u8) { | ... | @@ -4979,7 +5259,7 @@ pub const Tag = enum(u8) { |
| 4979 | pub const FuncInstance = struct { | 5259 | pub const FuncInstance = struct { |
| 4980 | analysis: FuncAnalysis, | 5260 | analysis: FuncAnalysis, |
| 4981 | // Needed by the linker for codegen. Not part of hashing or equality. | 5261 | // Needed by the linker for codegen. Not part of hashing or equality. |
| 4982 | owner_decl: DeclIndex, | 5262 | owner_nav: Nav.Index, |
| 4983 | ty: Index, | 5263 | ty: Index, |
| 4984 | branch_quota: u32, | 5264 | branch_quota: u32, |
| 4985 | /// Points to a `FuncDecl`. | 5265 | /// Points to a `FuncDecl`. |
| ... | @@ -5029,6 +5309,7 @@ pub const Tag = enum(u8) { | ... | @@ -5029,6 +5309,7 @@ pub const Tag = enum(u8) { |
| 5029 | /// 3. field type: Index for each field; declaration order | 5309 | /// 3. field type: Index for each field; declaration order |
| 5030 | /// 4. field align: Alignment for each field; declaration order | 5310 | /// 4. field align: Alignment for each field; declaration order |
| 5031 | pub const TypeUnion = struct { | 5311 | pub const TypeUnion = struct { |
| 5312 | name: NullTerminatedString, | ||
| 5032 | flags: Flags, | 5313 | flags: Flags, |
| 5033 | /// This could be provided through the tag type, but it is more convenient | 5314 | /// 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 | 5315 | /// to store it directly. This is also necessary for `dumpStatsFallible` to |
| ... | @@ -5038,8 +5319,8 @@ pub const Tag = enum(u8) { | ... | @@ -5038,8 +5319,8 @@ pub const Tag = enum(u8) { |
| 5038 | size: u32, | 5319 | size: u32, |
| 5039 | /// Only valid after .have_layout | 5320 | /// Only valid after .have_layout |
| 5040 | padding: u32, | 5321 | padding: u32, |
| 5041 | decl: DeclIndex, | 5322 | cau: Cau.Index, |
| 5042 | namespace: OptionalNamespaceIndex, | 5323 | namespace: NamespaceIndex, |
| 5043 | /// The enum that provides the list of field names and values. | 5324 | /// The enum that provides the list of field names and values. |
| 5044 | tag_ty: Index, | 5325 | tag_ty: Index, |
| 5045 | zir_index: TrackedInst.Index, | 5326 | zir_index: TrackedInst.Index, |
| ... | @@ -5068,10 +5349,11 @@ pub const Tag = enum(u8) { | ... | @@ -5068,10 +5349,11 @@ pub const Tag = enum(u8) { |
| 5068 | /// 4. name: NullTerminatedString for each fields_len | 5349 | /// 4. name: NullTerminatedString for each fields_len |
| 5069 | /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits | 5350 | /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits |
| 5070 | pub const TypeStructPacked = struct { | 5351 | pub const TypeStructPacked = struct { |
| 5071 | decl: DeclIndex, | 5352 | name: NullTerminatedString, |
| 5353 | cau: Cau.Index, | ||
| 5072 | zir_index: TrackedInst.Index, | 5354 | zir_index: TrackedInst.Index, |
| 5073 | fields_len: u32, | 5355 | fields_len: u32, |
| 5074 | namespace: OptionalNamespaceIndex, | 5356 | namespace: NamespaceIndex, |
| 5075 | backing_int_ty: Index, | 5357 | backing_int_ty: Index, |
| 5076 | names_map: MapIndex, | 5358 | names_map: MapIndex, |
| 5077 | flags: Flags, | 5359 | flags: Flags, |
| ... | @@ -5110,18 +5392,18 @@ pub const Tag = enum(u8) { | ... | @@ -5110,18 +5392,18 @@ pub const Tag = enum(u8) { |
| 5110 | /// name: NullTerminatedString // for each field in declared order | 5392 | /// name: NullTerminatedString // for each field in declared order |
| 5111 | /// 5. if any_default_inits: | 5393 | /// 5. if any_default_inits: |
| 5112 | /// init: Index // for each field in declared order | 5394 | /// init: Index // for each field in declared order |
| 5113 | /// 6. if has_namespace: | 5395 | /// 6. if any_aligned_fields: |
| 5114 | /// namespace: NamespaceIndex | ||
| 5115 | /// 7. if any_aligned_fields: | ||
| 5116 | /// align: Alignment // for each field in declared order | 5396 | /// align: Alignment // for each field in declared order |
| 5117 | /// 8. if any_comptime_fields: | 5397 | /// 7. if any_comptime_fields: |
| 5118 | /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0 | 5398 | /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0 |
| 5119 | /// 9. if not is_extern: | 5399 | /// 8. if not is_extern: |
| 5120 | /// field_index: RuntimeOrder // for each field in runtime order | 5400 | /// field_index: RuntimeOrder // for each field in runtime order |
| 5121 | /// 10. field_offset: u32 // for each field in declared order, undef until layout_resolved | 5401 | /// 9. field_offset: u32 // for each field in declared order, undef until layout_resolved |
| 5122 | pub const TypeStruct = struct { | 5402 | pub const TypeStruct = struct { |
| 5123 | decl: DeclIndex, | 5403 | name: NullTerminatedString, |
| 5404 | cau: Cau.Index, | ||
| 5124 | zir_index: TrackedInst.Index, | 5405 | zir_index: TrackedInst.Index, |
| 5406 | namespace: NamespaceIndex, | ||
| 5125 | fields_len: u32, | 5407 | fields_len: u32, |
| 5126 | flags: Flags, | 5408 | flags: Flags, |
| 5127 | size: u32, | 5409 | size: u32, |
| ... | @@ -5134,7 +5416,6 @@ pub const Tag = enum(u8) { | ... | @@ -5134,7 +5416,6 @@ pub const Tag = enum(u8) { |
| 5134 | is_tuple: bool = false, | 5416 | is_tuple: bool = false, |
| 5135 | assumed_runtime_bits: bool = false, | 5417 | assumed_runtime_bits: bool = false, |
| 5136 | assumed_pointer_aligned: bool = false, | 5418 | assumed_pointer_aligned: bool = false, |
| 5137 | has_namespace: bool = false, | ||
| 5138 | any_comptime_fields: bool = false, | 5419 | any_comptime_fields: bool = false, |
| 5139 | any_default_inits: bool = false, | 5420 | any_default_inits: bool = false, |
| 5140 | any_aligned_fields: bool = false, | 5421 | any_aligned_fields: bool = false, |
| ... | @@ -5157,17 +5438,16 @@ pub const Tag = enum(u8) { | ... | @@ -5157,17 +5438,16 @@ pub const Tag = enum(u8) { |
| 5157 | // which `layout_resolved` does not ensure. | 5438 | // which `layout_resolved` does not ensure. |
| 5158 | fully_resolved: bool = false, | 5439 | fully_resolved: bool = false, |
| 5159 | is_reified: bool = false, | 5440 | is_reified: bool = false, |
| 5160 | _: u6 = 0, | 5441 | _: u7 = 0, |
| 5161 | }; | 5442 | }; |
| 5162 | }; | 5443 | }; |
| 5163 | 5444 | ||
| 5164 | /// Trailing: | 5445 | /// Trailing: |
| 5165 | /// 0. capture: CaptureValue // for each `captures_len` | 5446 | /// 0. capture: CaptureValue // for each `captures_len` |
| 5166 | pub const TypeOpaque = struct { | 5447 | pub const TypeOpaque = struct { |
| 5167 | /// The opaque's owner Decl. | 5448 | name: NullTerminatedString, |
| 5168 | decl: DeclIndex, | ||
| 5169 | /// Contains the declarations inside this opaque. | 5449 | /// Contains the declarations inside this opaque. |
| 5170 | namespace: OptionalNamespaceIndex, | 5450 | namespace: NamespaceIndex, |
| 5171 | /// The index of the `opaque_decl` instruction. | 5451 | /// The index of the `opaque_decl` instruction. |
| 5172 | zir_index: TrackedInst.Index, | 5452 | zir_index: TrackedInst.Index, |
| 5173 | /// `std.math.maxInt(u32)` indicates this type is reified. | 5453 | /// `std.math.maxInt(u32)` indicates this type is reified. |
| ... | @@ -5188,29 +5468,19 @@ pub const FuncAnalysis = packed struct(u32) { | ... | @@ -5188,29 +5468,19 @@ pub const FuncAnalysis = packed struct(u32) { |
| 5188 | inferred_error_set: bool, | 5468 | inferred_error_set: bool, |
| 5189 | disable_instrumentation: bool, | 5469 | disable_instrumentation: bool, |
| 5190 | 5470 | ||
| 5191 | _: u13 = 0, | 5471 | _: u19 = 0, |
| 5192 | 5472 | ||
| 5193 | pub const State = enum(u8) { | 5473 | pub const State = enum(u2) { |
| 5194 | /// This function has not yet undergone analysis, because we have not | 5474 | /// The runtime function has never been referenced. |
| 5195 | /// seen a potential runtime call. It may be analyzed in future. | 5475 | /// As such, it has never been analyzed, nor is it queued for analysis. |
| 5196 | none, | 5476 | unreferenced, |
| 5197 | /// Analysis for this function has been queued, but not yet completed. | 5477 | /// The runtime function has been referenced, but has not yet been analyzed. |
| 5478 | /// Its semantic analysis is queued. | ||
| 5198 | queued, | 5479 | queued, |
| 5199 | /// This function intentionally only has ZIR generated because it is marked | 5480 | /// The runtime function has been (or is currently being) semantically analyzed. |
| 5200 | /// inline, which means no runtime version of the function will be generated. | 5481 | /// To know if analysis succeeded, consult `zcu.[transitive_]failed_analysis`. |
| 5201 | inline_only, | 5482 | /// To know if analysis is up-to-date, consult `zcu.[potentially_]outdated`. |
| 5202 | in_progress, | 5483 | analyzed, |
| 5203 | /// There will be a corresponding ErrorMsg in Zcu.failed_decls | ||
| 5204 | sema_failure, | ||
| 5205 | /// This function might be OK but it depends on another Decl which did not | ||
| 5206 | /// successfully complete semantic analysis. | ||
| 5207 | dependency_failure, | ||
| 5208 | /// There will be a corresponding ErrorMsg in Zcu.failed_decls. | ||
| 5209 | /// Indicates that semantic analysis succeeded, but code generation for | ||
| 5210 | /// this function failed. | ||
| 5211 | codegen_failure, | ||
| 5212 | /// Semantic analysis and code generation of this function succeeded. | ||
| 5213 | success, | ||
| 5214 | }; | 5484 | }; |
| 5215 | }; | 5485 | }; |
| 5216 | 5486 | ||
| ... | @@ -5477,17 +5747,16 @@ pub const Array = struct { | ... | @@ -5477,17 +5747,16 @@ pub const Array = struct { |
| 5477 | 5747 | ||
| 5478 | /// Trailing: | 5748 | /// Trailing: |
| 5479 | /// 0. owner_union: Index // if `zir_index == .none` | 5749 | /// 0. owner_union: Index // if `zir_index == .none` |
| 5480 | /// 1. capture: CaptureValue // for each `captures_len` | 5750 | /// 1. cau: Cau.Index // if `zir_index != .none` |
| 5481 | /// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`) | 5751 | /// 2. capture: CaptureValue // for each `captures_len` |
| 5482 | /// 3. field name: NullTerminatedString for each fields_len; declaration order | 5752 | /// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`) |
| 5483 | /// 4. tag value: Index for each fields_len; declaration order | 5753 | /// 4. field name: NullTerminatedString for each fields_len; declaration order |
| 5754 | /// 5. tag value: Index for each fields_len; declaration order | ||
| 5484 | pub const EnumExplicit = struct { | 5755 | pub const EnumExplicit = struct { |
| 5485 | /// The Decl that corresponds to the enum itself. | 5756 | name: NullTerminatedString, |
| 5486 | decl: DeclIndex, | ||
| 5487 | /// `std.math.maxInt(u32)` indicates this type is reified. | 5757 | /// `std.math.maxInt(u32)` indicates this type is reified. |
| 5488 | captures_len: u32, | 5758 | captures_len: u32, |
| 5489 | /// This may be `none` if there are no declarations. | 5759 | namespace: NamespaceIndex, |
| 5490 | namespace: OptionalNamespaceIndex, | ||
| 5491 | /// An integer type which is used for the numerical value of the enum, which | 5760 | /// An integer type which is used for the numerical value of the enum, which |
| 5492 | /// has been explicitly provided by the enum declaration. | 5761 | /// has been explicitly provided by the enum declaration. |
| 5493 | int_tag_type: Index, | 5762 | int_tag_type: Index, |
| ... | @@ -5505,16 +5774,15 @@ pub const EnumExplicit = struct { | ... | @@ -5505,16 +5774,15 @@ pub const EnumExplicit = struct { |
| 5505 | 5774 | ||
| 5506 | /// Trailing: | 5775 | /// Trailing: |
| 5507 | /// 0. owner_union: Index // if `zir_index == .none` | 5776 | /// 0. owner_union: Index // if `zir_index == .none` |
| 5508 | /// 1. capture: CaptureValue // for each `captures_len` | 5777 | /// 1. cau: Cau.Index // if `zir_index != .none` |
| 5509 | /// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`) | 5778 | /// 2. capture: CaptureValue // for each `captures_len` |
| 5510 | /// 3. field name: NullTerminatedString for each fields_len; declaration order | 5779 | /// 3. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`) |
| 5780 | /// 4. field name: NullTerminatedString for each fields_len; declaration order | ||
| 5511 | pub const EnumAuto = struct { | 5781 | pub const EnumAuto = struct { |
| 5512 | /// The Decl that corresponds to the enum itself. | 5782 | name: NullTerminatedString, |
| 5513 | decl: DeclIndex, | ||
| 5514 | /// `std.math.maxInt(u32)` indicates this type is reified. | 5783 | /// `std.math.maxInt(u32)` indicates this type is reified. |
| 5515 | captures_len: u32, | 5784 | captures_len: u32, |
| 5516 | /// This may be `none` if there are no declarations. | 5785 | namespace: NamespaceIndex, |
| 5517 | namespace: OptionalNamespaceIndex, | ||
| 5518 | /// An integer type which is used for the numerical value of the enum, which | 5786 | /// An integer type which is used for the numerical value of the enum, which |
| 5519 | /// was inferred by Zig based on the number of tags. | 5787 | /// was inferred by Zig based on the number of tags. |
| 5520 | int_tag_type: Index, | 5788 | int_tag_type: Index, |
| ... | @@ -5539,15 +5807,15 @@ pub const PackedU64 = packed struct(u64) { | ... | @@ -5539,15 +5807,15 @@ pub const PackedU64 = packed struct(u64) { |
| 5539 | } | 5807 | } |
| 5540 | }; | 5808 | }; |
| 5541 | 5809 | ||
| 5542 | pub const PtrDecl = struct { | 5810 | pub const PtrNav = struct { |
| 5543 | ty: Index, | 5811 | ty: Index, |
| 5544 | decl: DeclIndex, | 5812 | nav: Nav.Index, |
| 5545 | byte_offset_a: u32, | 5813 | byte_offset_a: u32, |
| 5546 | byte_offset_b: u32, | 5814 | byte_offset_b: u32, |
| 5547 | fn init(ty: Index, decl: DeclIndex, byte_offset: u64) @This() { | 5815 | fn init(ty: Index, nav: Nav.Index, byte_offset: u64) @This() { |
| 5548 | return .{ | 5816 | return .{ |
| 5549 | .ty = ty, | 5817 | .ty = ty, |
| 5550 | .decl = decl, | 5818 | .nav = nav, |
| 5551 | .byte_offset_a = @intCast(byte_offset >> 32), | 5819 | .byte_offset_a = @intCast(byte_offset >> 32), |
| 5552 | .byte_offset_b = @truncate(byte_offset), | 5820 | .byte_offset_b = @truncate(byte_offset), |
| 5553 | }; | 5821 | }; |
| ... | @@ -5557,7 +5825,7 @@ pub const PtrDecl = struct { | ... | @@ -5557,7 +5825,7 @@ pub const PtrDecl = struct { |
| 5557 | } | 5825 | } |
| 5558 | }; | 5826 | }; |
| 5559 | 5827 | ||
| 5560 | pub const PtrAnonDecl = struct { | 5828 | pub const PtrUav = struct { |
| 5561 | ty: Index, | 5829 | ty: Index, |
| 5562 | val: Index, | 5830 | val: Index, |
| 5563 | byte_offset_a: u32, | 5831 | byte_offset_a: u32, |
| ... | @@ -5575,7 +5843,7 @@ pub const PtrAnonDecl = struct { | ... | @@ -5575,7 +5843,7 @@ pub const PtrAnonDecl = struct { |
| 5575 | } | 5843 | } |
| 5576 | }; | 5844 | }; |
| 5577 | 5845 | ||
| 5578 | pub const PtrAnonDeclAligned = struct { | 5846 | pub const PtrUavAligned = struct { |
| 5579 | ty: Index, | 5847 | ty: Index, |
| 5580 | val: Index, | 5848 | val: Index, |
| 5581 | /// Must be nonequal to `ty`. Only the alignment from this value is important. | 5849 | /// Must be nonequal to `ty`. Only the alignment from this value is important. |
| ... | @@ -5805,8 +6073,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5805,8 +6073,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5805 | .tracked_insts = Local.TrackedInsts.empty, | 6073 | .tracked_insts = Local.TrackedInsts.empty, |
| 5806 | .files = Local.List(File).empty, | 6074 | .files = Local.List(File).empty, |
| 5807 | .maps = Local.Maps.empty, | 6075 | .maps = Local.Maps.empty, |
| 6076 | .caus = Local.Caus.empty, | ||
| 6077 | .navs = Local.Navs.empty, | ||
| 5808 | 6078 | ||
| 5809 | .decls = Local.Decls.empty, | ||
| 5810 | .namespaces = Local.Namespaces.empty, | 6079 | .namespaces = Local.Namespaces.empty, |
| 5811 | }, | 6080 | }, |
| 5812 | .mutate = .{ | 6081 | .mutate = .{ |
| ... | @@ -5819,8 +6088,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5819,8 +6088,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5819 | .tracked_insts = Local.ListMutate.empty, | 6088 | .tracked_insts = Local.ListMutate.empty, |
| 5820 | .files = Local.ListMutate.empty, | 6089 | .files = Local.ListMutate.empty, |
| 5821 | .maps = Local.ListMutate.empty, | 6090 | .maps = Local.ListMutate.empty, |
| 6091 | .caus = Local.ListMutate.empty, | ||
| 6092 | .navs = Local.ListMutate.empty, | ||
| 5822 | 6093 | ||
| 5823 | .decls = Local.BucketListMutate.empty, | ||
| 5824 | .namespaces = Local.BucketListMutate.empty, | 6094 | .namespaces = Local.BucketListMutate.empty, |
| 5825 | }, | 6095 | }, |
| 5826 | }); | 6096 | }); |
| ... | @@ -5878,8 +6148,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5878,8 +6148,8 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5878 | 6148 | ||
| 5879 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { | 6149 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5880 | ip.src_hash_deps.deinit(gpa); | 6150 | ip.src_hash_deps.deinit(gpa); |
| 5881 | ip.decl_val_deps.deinit(gpa); | 6151 | ip.nav_val_deps.deinit(gpa); |
| 5882 | ip.func_ies_deps.deinit(gpa); | 6152 | ip.interned_deps.deinit(gpa); |
| 5883 | ip.namespace_deps.deinit(gpa); | 6153 | ip.namespace_deps.deinit(gpa); |
| 5884 | ip.namespace_name_deps.deinit(gpa); | 6154 | ip.namespace_name_deps.deinit(gpa); |
| 5885 | 6155 | ||
| ... | @@ -5900,8 +6170,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { | ... | @@ -5900,8 +6170,11 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5900 | else | 6170 | else |
| 5901 | local.mutate.namespaces.last_bucket_len]) |*namespace| | 6171 | local.mutate.namespaces.last_bucket_len]) |*namespace| |
| 5902 | { | 6172 | { |
| 5903 | namespace.decls.deinit(gpa); | 6173 | namespace.pub_decls.deinit(gpa); |
| 5904 | namespace.usingnamespace_set.deinit(gpa); | 6174 | namespace.priv_decls.deinit(gpa); |
| 6175 | namespace.pub_usingnamespace.deinit(gpa); | ||
| 6176 | namespace.priv_usingnamespace.deinit(gpa); | ||
| 6177 | namespace.other_decls.deinit(gpa); | ||
| 5905 | } | 6178 | } |
| 5906 | }; | 6179 | }; |
| 5907 | const maps = local.getMutableMaps(gpa); | 6180 | const maps = local.getMutableMaps(gpa); |
| ... | @@ -6082,14 +6355,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6082,14 +6355,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6082 | if (extra.data.captures_len == std.math.maxInt(u32)) { | 6355 | if (extra.data.captures_len == std.math.maxInt(u32)) { |
| 6083 | break :ns .{ .reified = .{ | 6356 | break :ns .{ .reified = .{ |
| 6084 | .zir_index = zir_index, | 6357 | .zir_index = zir_index, |
| 6085 | .type_hash = extraData(extra_list, PackedU64, extra.end).get(), | 6358 | .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(), |
| 6086 | } }; | 6359 | } }; |
| 6087 | } | 6360 | } |
| 6088 | break :ns .{ .declared = .{ | 6361 | break :ns .{ .declared = .{ |
| 6089 | .zir_index = zir_index, | 6362 | .zir_index = zir_index, |
| 6090 | .captures = .{ .owned = .{ | 6363 | .captures = .{ .owned = .{ |
| 6091 | .tid = unwrapped_index.tid, | 6364 | .tid = unwrapped_index.tid, |
| 6092 | .start = extra.end, | 6365 | .start = extra.end + 1, |
| 6093 | .len = extra.data.captures_len, | 6366 | .len = extra.data.captures_len, |
| 6094 | } }, | 6367 | } }, |
| 6095 | } }; | 6368 | } }; |
| ... | @@ -6106,14 +6379,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6106,14 +6379,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6106 | if (extra.data.captures_len == std.math.maxInt(u32)) { | 6379 | if (extra.data.captures_len == std.math.maxInt(u32)) { |
| 6107 | break :ns .{ .reified = .{ | 6380 | break :ns .{ .reified = .{ |
| 6108 | .zir_index = zir_index, | 6381 | .zir_index = zir_index, |
| 6109 | .type_hash = extraData(extra_list, PackedU64, extra.end).get(), | 6382 | .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(), |
| 6110 | } }; | 6383 | } }; |
| 6111 | } | 6384 | } |
| 6112 | break :ns .{ .declared = .{ | 6385 | break :ns .{ .declared = .{ |
| 6113 | .zir_index = zir_index, | 6386 | .zir_index = zir_index, |
| 6114 | .captures = .{ .owned = .{ | 6387 | .captures = .{ .owned = .{ |
| 6115 | .tid = unwrapped_index.tid, | 6388 | .tid = unwrapped_index.tid, |
| 6116 | .start = extra.end, | 6389 | .start = extra.end + 1, |
| 6117 | .len = extra.data.captures_len, | 6390 | .len = extra.data.captures_len, |
| 6118 | } }, | 6391 | } }, |
| 6119 | } }; | 6392 | } }; |
| ... | @@ -6132,24 +6405,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6132,24 +6405,24 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6132 | .val = extra.val, | 6405 | .val = extra.val, |
| 6133 | } }; | 6406 | } }; |
| 6134 | }, | 6407 | }, |
| 6135 | .ptr_decl => { | 6408 | .ptr_nav => { |
| 6136 | const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data); | 6409 | const info = extraData(unwrapped_index.getExtra(ip), PtrNav, data); |
| 6137 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } }; | 6410 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .nav = info.nav }, .byte_offset = info.byteOffset() } }; |
| 6138 | }, | 6411 | }, |
| 6139 | .ptr_comptime_alloc => { | 6412 | .ptr_comptime_alloc => { |
| 6140 | const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data); | 6413 | const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data); |
| 6141 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } }; | 6414 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } }; |
| 6142 | }, | 6415 | }, |
| 6143 | .ptr_anon_decl => { | 6416 | .ptr_uav => { |
| 6144 | const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data); | 6417 | const info = extraData(unwrapped_index.getExtra(ip), PtrUav, data); |
| 6145 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{ | 6418 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{ |
| 6146 | .val = info.val, | 6419 | .val = info.val, |
| 6147 | .orig_ty = info.ty, | 6420 | .orig_ty = info.ty, |
| 6148 | } }, .byte_offset = info.byteOffset() } }; | 6421 | } }, .byte_offset = info.byteOffset() } }; |
| 6149 | }, | 6422 | }, |
| 6150 | .ptr_anon_decl_aligned => { | 6423 | .ptr_uav_aligned => { |
| 6151 | const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data); | 6424 | const info = extraData(unwrapped_index.getExtra(ip), PtrUavAligned, data); |
| 6152 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{ | 6425 | return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .uav = .{ |
| 6153 | .val = info.val, | 6426 | .val = info.val, |
| 6154 | .orig_ty = info.orig_ty, | 6427 | .orig_ty = info.orig_ty, |
| 6155 | } }, .byte_offset = info.byteOffset() } }; | 6428 | } }, .byte_offset = info.byteOffset() } }; |
| ... | @@ -6293,15 +6566,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { | ... | @@ -6293,15 +6566,28 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 6293 | return .{ .variable = .{ | 6566 | return .{ .variable = .{ |
| 6294 | .ty = extra.ty, | 6567 | .ty = extra.ty, |
| 6295 | .init = extra.init, | 6568 | .init = extra.init, |
| 6296 | .decl = extra.decl, | 6569 | .owner_nav = extra.owner_nav, |
| 6570 | .lib_name = extra.lib_name, | ||
| 6571 | .is_threadlocal = extra.flags.is_threadlocal, | ||
| 6572 | .is_weak_linkage = extra.flags.is_weak_linkage, | ||
| 6573 | } }; | ||
| 6574 | }, | ||
| 6575 | .@"extern" => { | ||
| 6576 | const extra = extraData(unwrapped_index.getExtra(ip), Tag.Extern, data); | ||
| 6577 | const nav = ip.getNav(extra.owner_nav); | ||
| 6578 | return .{ .@"extern" = .{ | ||
| 6579 | .name = nav.name, | ||
| 6580 | .ty = extra.ty, | ||
| 6297 | .lib_name = extra.lib_name, | 6581 | .lib_name = extra.lib_name, |
| 6298 | .is_extern = extra.flags.is_extern, | ||
| 6299 | .is_const = extra.flags.is_const, | 6582 | .is_const = extra.flags.is_const, |
| 6300 | .is_threadlocal = extra.flags.is_threadlocal, | 6583 | .is_threadlocal = extra.flags.is_threadlocal, |
| 6301 | .is_weak_linkage = extra.flags.is_weak_linkage, | 6584 | .is_weak_linkage = extra.flags.is_weak_linkage, |
| 6585 | .alignment = nav.status.resolved.alignment, | ||
| 6586 | .@"addrspace" = nav.status.resolved.@"addrspace", | ||
| 6587 | .zir_index = extra.zir_index, | ||
| 6588 | .owner_nav = extra.owner_nav, | ||
| 6302 | } }; | 6589 | } }; |
| 6303 | }, | 6590 | }, |
| 6304 | .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) }, | ||
| 6305 | .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, | 6591 | .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, |
| 6306 | .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, | 6592 | .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) }, |
| 6307 | .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) }, | 6593 | .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) }, |
| ... | @@ -6513,7 +6799,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke | ... | @@ -6513,7 +6799,7 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke |
| 6513 | .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?, | 6799 | .zir_body_inst_extra_index = extra_index + std.meta.fieldIndex(P, "zir_body_inst").?, |
| 6514 | .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0, | 6800 | .resolved_error_set_extra_index = if (func_decl.data.analysis.inferred_error_set) func_decl.end else 0, |
| 6515 | .branch_quota_extra_index = 0, | 6801 | .branch_quota_extra_index = 0, |
| 6516 | .owner_decl = func_decl.data.owner_decl, | 6802 | .owner_nav = func_decl.data.owner_nav, |
| 6517 | .zir_body_inst = func_decl.data.zir_body_inst, | 6803 | .zir_body_inst = func_decl.data.zir_body_inst, |
| 6518 | .lbrace_line = func_decl.data.lbrace_line, | 6804 | .lbrace_line = func_decl.data.lbrace_line, |
| 6519 | .rbrace_line = func_decl.data.rbrace_line, | 6805 | .rbrace_line = func_decl.data.rbrace_line, |
| ... | @@ -6528,7 +6814,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local. | ... | @@ -6528,7 +6814,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local. |
| 6528 | const extra_items = extra.view().items(.@"0"); | 6814 | const extra_items = extra.view().items(.@"0"); |
| 6529 | const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?; | 6815 | const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?; |
| 6530 | const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .unordered)); | 6816 | const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .unordered)); |
| 6531 | const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]); | 6817 | const owner_nav: Nav.Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").?]); |
| 6532 | const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]); | 6818 | const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]); |
| 6533 | const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]); | 6819 | const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]); |
| 6534 | const func_decl = ip.funcDeclInfo(generic_owner); | 6820 | const func_decl = ip.funcDeclInfo(generic_owner); |
| ... | @@ -6541,7 +6827,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local. | ... | @@ -6541,7 +6827,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local. |
| 6541 | .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index, | 6827 | .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index, |
| 6542 | .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0, | 6828 | .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0, |
| 6543 | .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?, | 6829 | .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?, |
| 6544 | .owner_decl = owner_decl, | 6830 | .owner_nav = owner_nav, |
| 6545 | .zir_body_inst = func_decl.zir_body_inst, | 6831 | .zir_body_inst = func_decl.zir_body_inst, |
| 6546 | .lbrace_line = func_decl.lbrace_line, | 6832 | .lbrace_line = func_decl.lbrace_line, |
| 6547 | .rbrace_line = func_decl.rbrace_line, | 6833 | .rbrace_line = func_decl.rbrace_line, |
| ... | @@ -6905,7 +7191,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All | ... | @@ -6905,7 +7191,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6905 | 7191 | ||
| 6906 | .enum_type => unreachable, // use getEnumType() instead | 7192 | .enum_type => unreachable, // use getEnumType() instead |
| 6907 | .func_type => unreachable, // use getFuncType() instead | 7193 | .func_type => unreachable, // use getFuncType() instead |
| 6908 | .extern_func => unreachable, // use getExternFunc() instead | 7194 | .@"extern" => unreachable, // use getExtern() instead |
| 6909 | .func => unreachable, // use getFuncInstance() or getFuncDecl() instead | 7195 | .func => unreachable, // use getFuncInstance() or getFuncDecl() instead |
| 6910 | 7196 | ||
| 6911 | .variable => |variable| { | 7197 | .variable => |variable| { |
| ... | @@ -6916,11 +7202,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All | ... | @@ -6916,11 +7202,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6916 | .data = try addExtra(extra, Tag.Variable{ | 7202 | .data = try addExtra(extra, Tag.Variable{ |
| 6917 | .ty = variable.ty, | 7203 | .ty = variable.ty, |
| 6918 | .init = variable.init, | 7204 | .init = variable.init, |
| 6919 | .decl = variable.decl, | 7205 | .owner_nav = variable.owner_nav, |
| 6920 | .lib_name = variable.lib_name, | 7206 | .lib_name = variable.lib_name, |
| 6921 | .flags = .{ | 7207 | .flags = .{ |
| 6922 | .is_extern = variable.is_extern, | 7208 | .is_const = false, |
| 6923 | .is_const = variable.is_const, | ||
| 6924 | .is_threadlocal = variable.is_threadlocal, | 7209 | .is_threadlocal = variable.is_threadlocal, |
| 6925 | .is_weak_linkage = variable.is_weak_linkage, | 7210 | .is_weak_linkage = variable.is_weak_linkage, |
| 6926 | }, | 7211 | }, |
| ... | @@ -6945,29 +7230,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All | ... | @@ -6945,29 +7230,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6945 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; | 7230 | const ptr_type = ip.indexToKey(ptr.ty).ptr_type; |
| 6946 | assert(ptr_type.flags.size != .Slice); | 7231 | assert(ptr_type.flags.size != .Slice); |
| 6947 | items.appendAssumeCapacity(switch (ptr.base_addr) { | 7232 | items.appendAssumeCapacity(switch (ptr.base_addr) { |
| 6948 | .decl => |decl| .{ | 7233 | .nav => |nav| .{ |
| 6949 | .tag = .ptr_decl, | 7234 | .tag = .ptr_nav, |
| 6950 | .data = try addExtra(extra, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)), | 7235 | .data = try addExtra(extra, PtrNav.init(ptr.ty, nav, ptr.byte_offset)), |
| 6951 | }, | 7236 | }, |
| 6952 | .comptime_alloc => |alloc_index| .{ | 7237 | .comptime_alloc => |alloc_index| .{ |
| 6953 | .tag = .ptr_comptime_alloc, | 7238 | .tag = .ptr_comptime_alloc, |
| 6954 | .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)), | 7239 | .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)), |
| 6955 | }, | 7240 | }, |
| 6956 | .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: { | 7241 | .uav => |uav| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, uav.orig_ty)) item: { |
| 6957 | if (ptr.ty != anon_decl.orig_ty) { | 7242 | if (ptr.ty != uav.orig_ty) { |
| 6958 | gop.cancel(); | 7243 | gop.cancel(); |
| 6959 | var new_key = key; | 7244 | var new_key = key; |
| 6960 | new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty; | 7245 | new_key.ptr.base_addr.uav.orig_ty = ptr.ty; |
| 6961 | gop = try ip.getOrPutKey(gpa, tid, new_key); | 7246 | gop = try ip.getOrPutKey(gpa, tid, new_key); |
| 6962 | if (gop == .existing) return gop.existing; | 7247 | if (gop == .existing) return gop.existing; |
| 6963 | } | 7248 | } |
| 6964 | break :item .{ | 7249 | break :item .{ |
| 6965 | .tag = .ptr_anon_decl, | 7250 | .tag = .ptr_uav, |
| 6966 | .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)), | 7251 | .data = try addExtra(extra, PtrUav.init(ptr.ty, uav.val, ptr.byte_offset)), |
| 6967 | }; | 7252 | }; |
| 6968 | } else .{ | 7253 | } else .{ |
| 6969 | .tag = .ptr_anon_decl_aligned, | 7254 | .tag = .ptr_uav_aligned, |
| 6970 | .data = try addExtra(extra, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)), | 7255 | .data = try addExtra(extra, PtrUavAligned.init(ptr.ty, uav.val, uav.orig_ty, ptr.byte_offset)), |
| 6971 | }, | 7256 | }, |
| 6972 | .comptime_field => |field_val| item: { | 7257 | .comptime_field => |field_val| item: { |
| 6973 | assert(field_val != .none); | 7258 | assert(field_val != .none); |
| ... | @@ -7561,7 +7846,6 @@ pub const UnionTypeInit = struct { | ... | @@ -7561,7 +7846,6 @@ pub const UnionTypeInit = struct { |
| 7561 | assumed_pointer_aligned: bool, | 7846 | assumed_pointer_aligned: bool, |
| 7562 | alignment: Alignment, | 7847 | alignment: Alignment, |
| 7563 | }, | 7848 | }, |
| 7564 | has_namespace: bool, | ||
| 7565 | fields_len: u32, | 7849 | fields_len: u32, |
| 7566 | enum_tag_ty: Index, | 7850 | enum_tag_ty: Index, |
| 7567 | /// May have length 0 which leaves the values unset until later. | 7851 | /// May have length 0 which leaves the values unset until later. |
| ... | @@ -7635,8 +7919,9 @@ pub fn getUnionType( | ... | @@ -7635,8 +7919,9 @@ pub fn getUnionType( |
| 7635 | .fields_len = ini.fields_len, | 7919 | .fields_len = ini.fields_len, |
| 7636 | .size = std.math.maxInt(u32), | 7920 | .size = std.math.maxInt(u32), |
| 7637 | .padding = std.math.maxInt(u32), | 7921 | .padding = std.math.maxInt(u32), |
| 7638 | .decl = undefined, // set by `finish` | 7922 | .name = undefined, // set by `finish` |
| 7639 | .namespace = .none, // set by `finish` | 7923 | .cau = undefined, // set by `finish` |
| 7924 | .namespace = undefined, // set by `finish` | ||
| 7640 | .tag_ty = ini.enum_tag_ty, | 7925 | .tag_ty = ini.enum_tag_ty, |
| 7641 | .zir_index = switch (ini.key) { | 7926 | .zir_index = switch (ini.key) { |
| 7642 | inline else => |x| x.zir_index, | 7927 | inline else => |x| x.zir_index, |
| ... | @@ -7682,29 +7967,49 @@ pub fn getUnionType( | ... | @@ -7682,29 +7967,49 @@ pub fn getUnionType( |
| 7682 | return .{ .wip = .{ | 7967 | return .{ .wip = .{ |
| 7683 | .tid = tid, | 7968 | .tid = tid, |
| 7684 | .index = gop.put(), | 7969 | .index = gop.put(), |
| 7685 | .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?, | 7970 | .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?, |
| 7686 | .namespace_extra_index = if (ini.has_namespace) | 7971 | .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "cau").?, |
| 7687 | extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").? | 7972 | .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?, |
| 7688 | else | ||
| 7689 | null, | ||
| 7690 | } }; | 7973 | } }; |
| 7691 | } | 7974 | } |
| 7692 | 7975 | ||
| 7693 | pub const WipNamespaceType = struct { | 7976 | pub const WipNamespaceType = struct { |
| 7694 | tid: Zcu.PerThread.Id, | 7977 | tid: Zcu.PerThread.Id, |
| 7695 | index: Index, | 7978 | index: Index, |
| 7696 | decl_extra_index: u32, | 7979 | type_name_extra_index: u32, |
| 7697 | namespace_extra_index: ?u32, | 7980 | cau_extra_index: ?u32, |
| 7698 | pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index { | 7981 | namespace_extra_index: u32, |
| 7699 | const extra_items = ip.getLocalShared(wip.tid).extra.acquire().view().items(.@"0"); | 7982 | |
| 7700 | extra_items[wip.decl_extra_index] = @intFromEnum(decl); | 7983 | pub fn setName( |
| 7701 | if (wip.namespace_extra_index) |i| { | 7984 | wip: WipNamespaceType, |
| 7702 | extra_items[i] = @intFromEnum(namespace.unwrap().?); | 7985 | ip: *InternPool, |
| 7986 | type_name: NullTerminatedString, | ||
| 7987 | ) void { | ||
| 7988 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); | ||
| 7989 | const extra_items = extra.view().items(.@"0"); | ||
| 7990 | extra_items[wip.type_name_extra_index] = @intFromEnum(type_name); | ||
| 7991 | } | ||
| 7992 | |||
| 7993 | pub fn finish( | ||
| 7994 | wip: WipNamespaceType, | ||
| 7995 | ip: *InternPool, | ||
| 7996 | analysis_owner: Cau.Index.Optional, | ||
| 7997 | namespace: NamespaceIndex, | ||
| 7998 | ) Index { | ||
| 7999 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); | ||
| 8000 | const extra_items = extra.view().items(.@"0"); | ||
| 8001 | |||
| 8002 | if (wip.cau_extra_index) |i| { | ||
| 8003 | extra_items[i] = @intFromEnum(analysis_owner.unwrap().?); | ||
| 7703 | } else { | 8004 | } else { |
| 7704 | assert(namespace == .none); | 8005 | assert(analysis_owner == .none); |
| 7705 | } | 8006 | } |
| 8007 | |||
| 8008 | extra_items[wip.namespace_extra_index] = @intFromEnum(namespace); | ||
| 8009 | |||
| 7706 | return wip.index; | 8010 | return wip.index; |
| 7707 | } | 8011 | } |
| 8012 | |||
| 7708 | pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void { | 8013 | pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void { |
| 7709 | ip.remove(tid, wip.index); | 8014 | ip.remove(tid, wip.index); |
| 7710 | } | 8015 | } |
| ... | @@ -7725,7 +8030,6 @@ pub const StructTypeInit = struct { | ... | @@ -7725,7 +8030,6 @@ pub const StructTypeInit = struct { |
| 7725 | any_default_inits: bool, | 8030 | any_default_inits: bool, |
| 7726 | inits_resolved: bool, | 8031 | inits_resolved: bool, |
| 7727 | any_aligned_fields: bool, | 8032 | any_aligned_fields: bool, |
| 7728 | has_namespace: bool, | ||
| 7729 | key: union(enum) { | 8033 | key: union(enum) { |
| 7730 | declared: struct { | 8034 | declared: struct { |
| 7731 | zir_index: TrackedInst.Index, | 8035 | zir_index: TrackedInst.Index, |
| ... | @@ -7784,10 +8088,11 @@ pub fn getStructType( | ... | @@ -7784,10 +8088,11 @@ pub fn getStructType( |
| 7784 | ini.fields_len + // names | 8088 | ini.fields_len + // names |
| 7785 | ini.fields_len); // inits | 8089 | ini.fields_len); // inits |
| 7786 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{ | 8090 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{ |
| 7787 | .decl = undefined, // set by `finish` | 8091 | .name = undefined, // set by `finish` |
| 8092 | .cau = undefined, // set by `finish` | ||
| 7788 | .zir_index = zir_index, | 8093 | .zir_index = zir_index, |
| 7789 | .fields_len = ini.fields_len, | 8094 | .fields_len = ini.fields_len, |
| 7790 | .namespace = .none, | 8095 | .namespace = undefined, // set by `finish` |
| 7791 | .backing_int_ty = .none, | 8096 | .backing_int_ty = .none, |
| 7792 | .names_map = names_map, | 8097 | .names_map = names_map, |
| 7793 | .flags = .{ | 8098 | .flags = .{ |
| ... | @@ -7818,11 +8123,9 @@ pub fn getStructType( | ... | @@ -7818,11 +8123,9 @@ pub fn getStructType( |
| 7818 | return .{ .wip = .{ | 8123 | return .{ .wip = .{ |
| 7819 | .tid = tid, | 8124 | .tid = tid, |
| 7820 | .index = gop.put(), | 8125 | .index = gop.put(), |
| 7821 | .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?, | 8126 | .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?, |
| 7822 | .namespace_extra_index = if (ini.has_namespace) | 8127 | .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "cau").?, |
| 7823 | extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").? | 8128 | .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?, |
| 7824 | else | ||
| 7825 | null, | ||
| 7826 | } }; | 8129 | } }; |
| 7827 | }, | 8130 | }, |
| 7828 | }; | 8131 | }; |
| ... | @@ -7841,10 +8144,12 @@ pub fn getStructType( | ... | @@ -7841,10 +8144,12 @@ pub fn getStructType( |
| 7841 | // zig fmt: on | 8144 | // zig fmt: on |
| 7842 | (ini.fields_len * 5) + // types, names, inits, runtime order, offsets | 8145 | (ini.fields_len * 5) + // types, names, inits, runtime order, offsets |
| 7843 | align_elements_len + comptime_elements_len + | 8146 | align_elements_len + comptime_elements_len + |
| 7844 | 2); // names_map + namespace | 8147 | 1); // names_map |
| 7845 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{ | 8148 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{ |
| 7846 | .decl = undefined, // set by `finish` | 8149 | .name = undefined, // set by `finish` |
| 8150 | .cau = undefined, // set by `finish` | ||
| 7847 | .zir_index = zir_index, | 8151 | .zir_index = zir_index, |
| 8152 | .namespace = undefined, // set by `finish` | ||
| 7848 | .fields_len = ini.fields_len, | 8153 | .fields_len = ini.fields_len, |
| 7849 | .size = std.math.maxInt(u32), | 8154 | .size = std.math.maxInt(u32), |
| 7850 | .flags = .{ | 8155 | .flags = .{ |
| ... | @@ -7855,7 +8160,6 @@ pub fn getStructType( | ... | @@ -7855,7 +8160,6 @@ pub fn getStructType( |
| 7855 | .is_tuple = ini.is_tuple, | 8160 | .is_tuple = ini.is_tuple, |
| 7856 | .assumed_runtime_bits = false, | 8161 | .assumed_runtime_bits = false, |
| 7857 | .assumed_pointer_aligned = false, | 8162 | .assumed_pointer_aligned = false, |
| 7858 | .has_namespace = ini.has_namespace, | ||
| 7859 | .any_comptime_fields = ini.any_comptime_fields, | 8163 | .any_comptime_fields = ini.any_comptime_fields, |
| 7860 | .any_default_inits = ini.any_default_inits, | 8164 | .any_default_inits = ini.any_default_inits, |
| 7861 | .any_aligned_fields = ini.any_aligned_fields, | 8165 | .any_aligned_fields = ini.any_aligned_fields, |
| ... | @@ -7891,10 +8195,6 @@ pub fn getStructType( | ... | @@ -7891,10 +8195,6 @@ pub fn getStructType( |
| 7891 | if (ini.any_default_inits) { | 8195 | if (ini.any_default_inits) { |
| 7892 | extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); | 8196 | extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); |
| 7893 | } | 8197 | } |
| 7894 | const namespace_extra_index: ?u32 = if (ini.has_namespace) i: { | ||
| 7895 | extra.appendAssumeCapacity(undefined); // set by `finish` | ||
| 7896 | break :i @intCast(extra.mutate.len - 1); | ||
| 7897 | } else null; | ||
| 7898 | if (ini.any_aligned_fields) { | 8198 | if (ini.any_aligned_fields) { |
| 7899 | extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len); | 8199 | extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len); |
| 7900 | } | 8200 | } |
| ... | @@ -7908,8 +8208,9 @@ pub fn getStructType( | ... | @@ -7908,8 +8208,9 @@ pub fn getStructType( |
| 7908 | return .{ .wip = .{ | 8208 | return .{ .wip = .{ |
| 7909 | .tid = tid, | 8209 | .tid = tid, |
| 7910 | .index = gop.put(), | 8210 | .index = gop.put(), |
| 7911 | .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?, | 8211 | .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?, |
| 7912 | .namespace_extra_index = namespace_extra_index, | 8212 | .cau_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "cau").?, |
| 8213 | .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?, | ||
| 7913 | } }; | 8214 | } }; |
| 7914 | } | 8215 | } |
| 7915 | 8216 | ||
| ... | @@ -8047,34 +8348,71 @@ pub fn getFuncType( | ... | @@ -8047,34 +8348,71 @@ pub fn getFuncType( |
| 8047 | return gop.put(); | 8348 | return gop.put(); |
| 8048 | } | 8349 | } |
| 8049 | 8350 | ||
| 8050 | pub fn getExternFunc( | 8351 | /// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary. |
| 8352 | /// This will *not* queue the extern for codegen: see `Zcu.PerThread.getExtern` for a wrapper which does. | ||
| 8353 | pub fn getExtern( | ||
| 8051 | ip: *InternPool, | 8354 | ip: *InternPool, |
| 8052 | gpa: Allocator, | 8355 | gpa: Allocator, |
| 8053 | tid: Zcu.PerThread.Id, | 8356 | tid: Zcu.PerThread.Id, |
| 8054 | key: Key.ExternFunc, | 8357 | /// `key.owner_nav` is ignored. |
| 8055 | ) Allocator.Error!Index { | 8358 | key: Key.Extern, |
| 8056 | var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key }); | 8359 | ) Allocator.Error!struct { |
| 8360 | index: Index, | ||
| 8361 | /// Only set if the `Nav` was newly created. | ||
| 8362 | new_nav: Nav.Index.Optional, | ||
| 8363 | } { | ||
| 8364 | var gop = try ip.getOrPutKey(gpa, tid, .{ .@"extern" = key }); | ||
| 8057 | defer gop.deinit(); | 8365 | defer gop.deinit(); |
| 8058 | if (gop == .existing) return gop.existing; | 8366 | if (gop == .existing) return .{ |
| 8367 | .index = gop.existing, | ||
| 8368 | .new_nav = .none, | ||
| 8369 | }; | ||
| 8059 | 8370 | ||
| 8060 | const local = ip.getLocal(tid); | 8371 | const local = ip.getLocal(tid); |
| 8061 | const items = local.getMutableItems(gpa); | 8372 | const items = local.getMutableItems(gpa); |
| 8062 | try items.ensureUnusedCapacity(1); | ||
| 8063 | const extra = local.getMutableExtra(gpa); | 8373 | const extra = local.getMutableExtra(gpa); |
| 8374 | try items.ensureUnusedCapacity(1); | ||
| 8375 | try extra.ensureUnusedCapacity(@typeInfo(Tag.Extern).Struct.fields.len); | ||
| 8376 | try local.getMutableNavs(gpa).ensureUnusedCapacity(1); | ||
| 8064 | 8377 | ||
| 8065 | const prev_extra_len = extra.mutate.len; | 8378 | // Predict the index the `@"extern" will live at, so we can construct the owner `Nav` before releasing the shard's mutex. |
| 8066 | const extra_index = try addExtra(extra, @as(Tag.ExternFunc, key)); | 8379 | const extern_index = Index.Unwrapped.wrap(.{ |
| 8067 | errdefer extra.mutate.len = prev_extra_len; | 8380 | .tid = tid, |
| 8381 | .index = items.mutate.len, | ||
| 8382 | }, ip); | ||
| 8383 | const owner_nav = ip.createNav(gpa, tid, .{ | ||
| 8384 | .name = key.name, | ||
| 8385 | .fqn = key.name, | ||
| 8386 | .val = extern_index, | ||
| 8387 | .alignment = key.alignment, | ||
| 8388 | .@"linksection" = .none, | ||
| 8389 | .@"addrspace" = key.@"addrspace", | ||
| 8390 | }) catch unreachable; // capacity asserted above | ||
| 8391 | const extra_index = addExtraAssumeCapacity(extra, Tag.Extern{ | ||
| 8392 | .ty = key.ty, | ||
| 8393 | .lib_name = key.lib_name, | ||
| 8394 | .flags = .{ | ||
| 8395 | .is_const = key.is_const, | ||
| 8396 | .is_threadlocal = key.is_threadlocal, | ||
| 8397 | .is_weak_linkage = key.is_weak_linkage, | ||
| 8398 | }, | ||
| 8399 | .zir_index = key.zir_index, | ||
| 8400 | .owner_nav = owner_nav, | ||
| 8401 | }); | ||
| 8068 | items.appendAssumeCapacity(.{ | 8402 | items.appendAssumeCapacity(.{ |
| 8069 | .tag = .extern_func, | 8403 | .tag = .@"extern", |
| 8070 | .data = extra_index, | 8404 | .data = extra_index, |
| 8071 | }); | 8405 | }); |
| 8072 | errdefer items.mutate.len -= 1; | 8406 | assert(gop.put() == extern_index); |
| 8073 | return gop.put(); | 8407 | |
| 8408 | return .{ | ||
| 8409 | .index = extern_index, | ||
| 8410 | .new_nav = owner_nav.toOptional(), | ||
| 8411 | }; | ||
| 8074 | } | 8412 | } |
| 8075 | 8413 | ||
| 8076 | pub const GetFuncDeclKey = struct { | 8414 | pub const GetFuncDeclKey = struct { |
| 8077 | owner_decl: DeclIndex, | 8415 | owner_nav: Nav.Index, |
| 8078 | ty: Index, | 8416 | ty: Index, |
| 8079 | zir_body_inst: TrackedInst.Index, | 8417 | zir_body_inst: TrackedInst.Index, |
| 8080 | lbrace_line: u32, | 8418 | lbrace_line: u32, |
| ... | @@ -8105,7 +8443,7 @@ pub fn getFuncDecl( | ... | @@ -8105,7 +8443,7 @@ pub fn getFuncDecl( |
| 8105 | 8443 | ||
| 8106 | const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{ | 8444 | const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{ |
| 8107 | .analysis = .{ | 8445 | .analysis = .{ |
| 8108 | .state = if (key.cc == .Inline) .inline_only else .none, | 8446 | .state = .unreferenced, |
| 8109 | .is_cold = false, | 8447 | .is_cold = false, |
| 8110 | .is_noinline = key.is_noinline, | 8448 | .is_noinline = key.is_noinline, |
| 8111 | .calls_or_awaits_errorable_fn = false, | 8449 | .calls_or_awaits_errorable_fn = false, |
| ... | @@ -8113,7 +8451,7 @@ pub fn getFuncDecl( | ... | @@ -8113,7 +8451,7 @@ pub fn getFuncDecl( |
| 8113 | .inferred_error_set = false, | 8451 | .inferred_error_set = false, |
| 8114 | .disable_instrumentation = false, | 8452 | .disable_instrumentation = false, |
| 8115 | }, | 8453 | }, |
| 8116 | .owner_decl = key.owner_decl, | 8454 | .owner_nav = key.owner_nav, |
| 8117 | .ty = key.ty, | 8455 | .ty = key.ty, |
| 8118 | .zir_body_inst = key.zir_body_inst, | 8456 | .zir_body_inst = key.zir_body_inst, |
| 8119 | .lbrace_line = key.lbrace_line, | 8457 | .lbrace_line = key.lbrace_line, |
| ... | @@ -8140,7 +8478,7 @@ pub fn getFuncDecl( | ... | @@ -8140,7 +8478,7 @@ pub fn getFuncDecl( |
| 8140 | } | 8478 | } |
| 8141 | 8479 | ||
| 8142 | pub const GetFuncDeclIesKey = struct { | 8480 | pub const GetFuncDeclIesKey = struct { |
| 8143 | owner_decl: DeclIndex, | 8481 | owner_nav: Nav.Index, |
| 8144 | param_types: []Index, | 8482 | param_types: []Index, |
| 8145 | noalias_bits: u32, | 8483 | noalias_bits: u32, |
| 8146 | comptime_bits: u32, | 8484 | comptime_bits: u32, |
| ... | @@ -8209,7 +8547,7 @@ pub fn getFuncDeclIes( | ... | @@ -8209,7 +8547,7 @@ pub fn getFuncDeclIes( |
| 8209 | 8547 | ||
| 8210 | const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{ | 8548 | const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{ |
| 8211 | .analysis = .{ | 8549 | .analysis = .{ |
| 8212 | .state = if (key.cc == .Inline) .inline_only else .none, | 8550 | .state = .unreferenced, |
| 8213 | .is_cold = false, | 8551 | .is_cold = false, |
| 8214 | .is_noinline = key.is_noinline, | 8552 | .is_noinline = key.is_noinline, |
| 8215 | .calls_or_awaits_errorable_fn = false, | 8553 | .calls_or_awaits_errorable_fn = false, |
| ... | @@ -8217,7 +8555,7 @@ pub fn getFuncDeclIes( | ... | @@ -8217,7 +8555,7 @@ pub fn getFuncDeclIes( |
| 8217 | .inferred_error_set = true, | 8555 | .inferred_error_set = true, |
| 8218 | .disable_instrumentation = false, | 8556 | .disable_instrumentation = false, |
| 8219 | }, | 8557 | }, |
| 8220 | .owner_decl = key.owner_decl, | 8558 | .owner_nav = key.owner_nav, |
| 8221 | .ty = func_ty, | 8559 | .ty = func_ty, |
| 8222 | .zir_body_inst = key.zir_body_inst, | 8560 | .zir_body_inst = key.zir_body_inst, |
| 8223 | .lbrace_line = key.lbrace_line, | 8561 | .lbrace_line = key.lbrace_line, |
| ... | @@ -8401,7 +8739,7 @@ pub fn getFuncInstance( | ... | @@ -8401,7 +8739,7 @@ pub fn getFuncInstance( |
| 8401 | 8739 | ||
| 8402 | const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{ | 8740 | const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{ |
| 8403 | .analysis = .{ | 8741 | .analysis = .{ |
| 8404 | .state = if (arg.cc == .Inline) .inline_only else .none, | 8742 | .state = .unreferenced, |
| 8405 | .is_cold = false, | 8743 | .is_cold = false, |
| 8406 | .is_noinline = arg.is_noinline, | 8744 | .is_noinline = arg.is_noinline, |
| 8407 | .calls_or_awaits_errorable_fn = false, | 8745 | .calls_or_awaits_errorable_fn = false, |
| ... | @@ -8409,9 +8747,9 @@ pub fn getFuncInstance( | ... | @@ -8409,9 +8747,9 @@ pub fn getFuncInstance( |
| 8409 | .inferred_error_set = false, | 8747 | .inferred_error_set = false, |
| 8410 | .disable_instrumentation = false, | 8748 | .disable_instrumentation = false, |
| 8411 | }, | 8749 | }, |
| 8412 | // This is populated after we create the Decl below. It is not read | 8750 | // This is populated after we create the Nav below. It is not read |
| 8413 | // by equality or hashing functions. | 8751 | // by equality or hashing functions. |
| 8414 | .owner_decl = undefined, | 8752 | .owner_nav = undefined, |
| 8415 | .ty = func_ty, | 8753 | .ty = func_ty, |
| 8416 | .branch_quota = 0, | 8754 | .branch_quota = 0, |
| 8417 | .generic_owner = generic_owner, | 8755 | .generic_owner = generic_owner, |
| ... | @@ -8501,7 +8839,7 @@ pub fn getFuncInstanceIes( | ... | @@ -8501,7 +8839,7 @@ pub fn getFuncInstanceIes( |
| 8501 | 8839 | ||
| 8502 | const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{ | 8840 | const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{ |
| 8503 | .analysis = .{ | 8841 | .analysis = .{ |
| 8504 | .state = if (arg.cc == .Inline) .inline_only else .none, | 8842 | .state = .unreferenced, |
| 8505 | .is_cold = false, | 8843 | .is_cold = false, |
| 8506 | .is_noinline = arg.is_noinline, | 8844 | .is_noinline = arg.is_noinline, |
| 8507 | .calls_or_awaits_errorable_fn = false, | 8845 | .calls_or_awaits_errorable_fn = false, |
| ... | @@ -8509,9 +8847,9 @@ pub fn getFuncInstanceIes( | ... | @@ -8509,9 +8847,9 @@ pub fn getFuncInstanceIes( |
| 8509 | .inferred_error_set = true, | 8847 | .inferred_error_set = true, |
| 8510 | .disable_instrumentation = false, | 8848 | .disable_instrumentation = false, |
| 8511 | }, | 8849 | }, |
| 8512 | // This is populated after we create the Decl below. It is not read | 8850 | // This is populated after we create the Nav below. It is not read |
| 8513 | // by equality or hashing functions. | 8851 | // by equality or hashing functions. |
| 8514 | .owner_decl = undefined, | 8852 | .owner_nav = undefined, |
| 8515 | .ty = func_ty, | 8853 | .ty = func_ty, |
| 8516 | .branch_quota = 0, | 8854 | .branch_quota = 0, |
| 8517 | .generic_owner = generic_owner, | 8855 | .generic_owner = generic_owner, |
| ... | @@ -8617,41 +8955,29 @@ fn finishFuncInstance( | ... | @@ -8617,41 +8955,29 @@ fn finishFuncInstance( |
| 8617 | alignment: Alignment, | 8955 | alignment: Alignment, |
| 8618 | section: OptionalNullTerminatedString, | 8956 | section: OptionalNullTerminatedString, |
| 8619 | ) Allocator.Error!void { | 8957 | ) Allocator.Error!void { |
| 8620 | const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner)); | 8958 | const fn_owner_nav = ip.getNav(ip.funcDeclInfo(generic_owner).owner_nav); |
| 8621 | const decl_index = try ip.createDecl(gpa, tid, .{ | 8959 | const fn_namespace = ip.getCau(fn_owner_nav.analysis_owner.unwrap().?).namespace; |
| 8622 | .name = undefined, | 8960 | |
| 8623 | .fqn = undefined, | 8961 | // TODO: improve this name |
| 8624 | .src_namespace = fn_owner_decl.src_namespace, | 8962 | const nav_name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{ |
| 8625 | .has_tv = true, | 8963 | fn_owner_nav.name.fmt(ip), @intFromEnum(func_index), |
| 8626 | .owns_tv = true, | 8964 | }, .no_embedded_nulls); |
| 8627 | .val = @import("Value.zig").fromInterned(func_index), | 8965 | const nav_index = try ip.createNav(gpa, tid, .{ |
| 8966 | .name = nav_name, | ||
| 8967 | .fqn = try ip.namespacePtr(fn_namespace).internFullyQualifiedName(ip, gpa, tid, nav_name), | ||
| 8968 | .val = func_index, | ||
| 8628 | .alignment = alignment, | 8969 | .alignment = alignment, |
| 8629 | .@"linksection" = section, | 8970 | .@"linksection" = section, |
| 8630 | .@"addrspace" = fn_owner_decl.@"addrspace", | 8971 | .@"addrspace" = fn_owner_nav.status.resolved.@"addrspace", |
| 8631 | .analysis = .complete, | ||
| 8632 | .zir_decl_index = fn_owner_decl.zir_decl_index, | ||
| 8633 | .is_pub = fn_owner_decl.is_pub, | ||
| 8634 | .is_exported = fn_owner_decl.is_exported, | ||
| 8635 | .kind = .anon, | ||
| 8636 | }); | 8972 | }); |
| 8637 | errdefer ip.destroyDecl(tid, decl_index); | ||
| 8638 | 8973 | ||
| 8639 | // Populate the owner_decl field which was left undefined until now. | 8974 | // Populate the owner_nav field which was left undefined until now. |
| 8640 | extra.view().items(.@"0")[ | 8975 | extra.view().items(.@"0")[ |
| 8641 | func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").? | 8976 | func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_nav").? |
| 8642 | ] = @intFromEnum(decl_index); | 8977 | ] = @intFromEnum(nav_index); |
| 8643 | |||
| 8644 | // TODO: improve this name | ||
| 8645 | const decl = ip.declPtr(decl_index); | ||
| 8646 | decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{ | ||
| 8647 | fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index), | ||
| 8648 | }, .no_embedded_nulls); | ||
| 8649 | decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace) | ||
| 8650 | .internFullyQualifiedName(ip, gpa, tid, decl.name); | ||
| 8651 | } | 8978 | } |
| 8652 | 8979 | ||
| 8653 | pub const EnumTypeInit = struct { | 8980 | pub const EnumTypeInit = struct { |
| 8654 | has_namespace: bool, | ||
| 8655 | has_values: bool, | 8981 | has_values: bool, |
| 8656 | tag_mode: LoadedEnumType.TagMode, | 8982 | tag_mode: LoadedEnumType.TagMode, |
| 8657 | fields_len: u32, | 8983 | fields_len: u32, |
| ... | @@ -8671,27 +8997,35 @@ pub const WipEnumType = struct { | ... | @@ -8671,27 +8997,35 @@ pub const WipEnumType = struct { |
| 8671 | tid: Zcu.PerThread.Id, | 8997 | tid: Zcu.PerThread.Id, |
| 8672 | index: Index, | 8998 | index: Index, |
| 8673 | tag_ty_index: u32, | 8999 | tag_ty_index: u32, |
| 8674 | decl_index: u32, | 9000 | type_name_extra_index: u32, |
| 8675 | namespace_index: ?u32, | 9001 | cau_extra_index: u32, |
| 9002 | namespace_extra_index: u32, | ||
| 8676 | names_map: MapIndex, | 9003 | names_map: MapIndex, |
| 8677 | names_start: u32, | 9004 | names_start: u32, |
| 8678 | values_map: OptionalMapIndex, | 9005 | values_map: OptionalMapIndex, |
| 8679 | values_start: u32, | 9006 | values_start: u32, |
| 8680 | 9007 | ||
| 9008 | pub fn setName( | ||
| 9009 | wip: WipEnumType, | ||
| 9010 | ip: *InternPool, | ||
| 9011 | type_name: NullTerminatedString, | ||
| 9012 | ) void { | ||
| 9013 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); | ||
| 9014 | const extra_items = extra.view().items(.@"0"); | ||
| 9015 | extra_items[wip.type_name_extra_index] = @intFromEnum(type_name); | ||
| 9016 | } | ||
| 9017 | |||
| 8681 | pub fn prepare( | 9018 | pub fn prepare( |
| 8682 | wip: WipEnumType, | 9019 | wip: WipEnumType, |
| 8683 | ip: *InternPool, | 9020 | ip: *InternPool, |
| 8684 | decl: DeclIndex, | 9021 | analysis_owner: Cau.Index, |
| 8685 | namespace: OptionalNamespaceIndex, | 9022 | namespace: NamespaceIndex, |
| 8686 | ) void { | 9023 | ) void { |
| 8687 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); | 9024 | const extra = ip.getLocalShared(wip.tid).extra.acquire(); |
| 8688 | const extra_items = extra.view().items(.@"0"); | 9025 | const extra_items = extra.view().items(.@"0"); |
| 8689 | extra_items[wip.decl_index] = @intFromEnum(decl); | 9026 | |
| 8690 | if (wip.namespace_index) |i| { | 9027 | extra_items[wip.cau_extra_index] = @intFromEnum(analysis_owner); |
| 8691 | extra_items[i] = @intFromEnum(namespace.unwrap().?); | 9028 | extra_items[wip.namespace_extra_index] = @intFromEnum(namespace); |
| 8692 | } else { | ||
| 8693 | assert(namespace == .none); | ||
| 8694 | } | ||
| 8695 | } | 9029 | } |
| 8696 | 9030 | ||
| 8697 | pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void { | 9031 | pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void { |
| ... | @@ -8780,15 +9114,16 @@ pub fn getEnumType( | ... | @@ -8780,15 +9114,16 @@ pub fn getEnumType( |
| 8780 | .reified => 2, // type_hash: PackedU64 | 9114 | .reified => 2, // type_hash: PackedU64 |
| 8781 | } + | 9115 | } + |
| 8782 | // zig fmt: on | 9116 | // zig fmt: on |
| 9117 | 1 + // cau | ||
| 8783 | ini.fields_len); // field types | 9118 | ini.fields_len); // field types |
| 8784 | 9119 | ||
| 8785 | const extra_index = addExtraAssumeCapacity(extra, EnumAuto{ | 9120 | const extra_index = addExtraAssumeCapacity(extra, EnumAuto{ |
| 8786 | .decl = undefined, // set by `prepare` | 9121 | .name = undefined, // set by `prepare` |
| 8787 | .captures_len = switch (ini.key) { | 9122 | .captures_len = switch (ini.key) { |
| 8788 | .declared => |d| @intCast(d.captures.len), | 9123 | .declared => |d| @intCast(d.captures.len), |
| 8789 | .reified => std.math.maxInt(u32), | 9124 | .reified => std.math.maxInt(u32), |
| 8790 | }, | 9125 | }, |
| 8791 | .namespace = .none, | 9126 | .namespace = undefined, // set by `prepare` |
| 8792 | .int_tag_type = .none, // set by `prepare` | 9127 | .int_tag_type = .none, // set by `prepare` |
| 8793 | .fields_len = ini.fields_len, | 9128 | .fields_len = ini.fields_len, |
| 8794 | .names_map = names_map, | 9129 | .names_map = names_map, |
| ... | @@ -8800,6 +9135,8 @@ pub fn getEnumType( | ... | @@ -8800,6 +9135,8 @@ pub fn getEnumType( |
| 8800 | .tag = .type_enum_auto, | 9135 | .tag = .type_enum_auto, |
| 8801 | .data = extra_index, | 9136 | .data = extra_index, |
| 8802 | }); | 9137 | }); |
| 9138 | const cau_extra_index = extra.view().len; | ||
| 9139 | extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish` | ||
| 8803 | switch (ini.key) { | 9140 | switch (ini.key) { |
| 8804 | .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}), | 9141 | .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}), |
| 8805 | .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)), | 9142 | .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)), |
| ... | @@ -8810,8 +9147,9 @@ pub fn getEnumType( | ... | @@ -8810,8 +9147,9 @@ pub fn getEnumType( |
| 8810 | .tid = tid, | 9147 | .tid = tid, |
| 8811 | .index = gop.put(), | 9148 | .index = gop.put(), |
| 8812 | .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?, | 9149 | .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?, |
| 8813 | .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?, | 9150 | .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?, |
| 8814 | .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null, | 9151 | .cau_extra_index = @intCast(cau_extra_index), |
| 9152 | .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "namespace").?, | ||
| 8815 | .names_map = names_map, | 9153 | .names_map = names_map, |
| 8816 | .names_start = @intCast(names_start), | 9154 | .names_start = @intCast(names_start), |
| 8817 | .values_map = .none, | 9155 | .values_map = .none, |
| ... | @@ -8835,16 +9173,17 @@ pub fn getEnumType( | ... | @@ -8835,16 +9173,17 @@ pub fn getEnumType( |
| 8835 | .reified => 2, // type_hash: PackedU64 | 9173 | .reified => 2, // type_hash: PackedU64 |
| 8836 | } + | 9174 | } + |
| 8837 | // zig fmt: on | 9175 | // zig fmt: on |
| 9176 | 1 + // cau | ||
| 8838 | ini.fields_len + // field types | 9177 | ini.fields_len + // field types |
| 8839 | ini.fields_len * @intFromBool(ini.has_values)); // field values | 9178 | ini.fields_len * @intFromBool(ini.has_values)); // field values |
| 8840 | 9179 | ||
| 8841 | const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{ | 9180 | const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{ |
| 8842 | .decl = undefined, // set by `prepare` | 9181 | .name = undefined, // set by `prepare` |
| 8843 | .captures_len = switch (ini.key) { | 9182 | .captures_len = switch (ini.key) { |
| 8844 | .declared => |d| @intCast(d.captures.len), | 9183 | .declared => |d| @intCast(d.captures.len), |
| 8845 | .reified => std.math.maxInt(u32), | 9184 | .reified => std.math.maxInt(u32), |
| 8846 | }, | 9185 | }, |
| 8847 | .namespace = .none, | 9186 | .namespace = undefined, // set by `prepare` |
| 8848 | .int_tag_type = .none, // set by `prepare` | 9187 | .int_tag_type = .none, // set by `prepare` |
| 8849 | .fields_len = ini.fields_len, | 9188 | .fields_len = ini.fields_len, |
| 8850 | .names_map = names_map, | 9189 | .names_map = names_map, |
| ... | @@ -8861,6 +9200,8 @@ pub fn getEnumType( | ... | @@ -8861,6 +9200,8 @@ pub fn getEnumType( |
| 8861 | }, | 9200 | }, |
| 8862 | .data = extra_index, | 9201 | .data = extra_index, |
| 8863 | }); | 9202 | }); |
| 9203 | const cau_extra_index = extra.view().len; | ||
| 9204 | extra.appendAssumeCapacity(undefined); // `cau` will be set by `finish` | ||
| 8864 | switch (ini.key) { | 9205 | switch (ini.key) { |
| 8865 | .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}), | 9206 | .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}), |
| 8866 | .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)), | 9207 | .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)), |
| ... | @@ -8874,9 +9215,10 @@ pub fn getEnumType( | ... | @@ -8874,9 +9215,10 @@ pub fn getEnumType( |
| 8874 | return .{ .wip = .{ | 9215 | return .{ .wip = .{ |
| 8875 | .tid = tid, | 9216 | .tid = tid, |
| 8876 | .index = gop.put(), | 9217 | .index = gop.put(), |
| 8877 | .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?, | 9218 | .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?, |
| 8878 | .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?, | 9219 | .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?, |
| 8879 | .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null, | 9220 | .cau_extra_index = @intCast(cau_extra_index), |
| 9221 | .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").?, | ||
| 8880 | .names_map = names_map, | 9222 | .names_map = names_map, |
| 8881 | .names_start = @intCast(names_start), | 9223 | .names_start = @intCast(names_start), |
| 8882 | .values_map = values_map, | 9224 | .values_map = values_map, |
| ... | @@ -8887,12 +9229,13 @@ pub fn getEnumType( | ... | @@ -8887,12 +9229,13 @@ pub fn getEnumType( |
| 8887 | } | 9229 | } |
| 8888 | 9230 | ||
| 8889 | const GeneratedTagEnumTypeInit = struct { | 9231 | const GeneratedTagEnumTypeInit = struct { |
| 8890 | decl: DeclIndex, | 9232 | name: NullTerminatedString, |
| 8891 | owner_union_ty: Index, | 9233 | owner_union_ty: Index, |
| 8892 | tag_ty: Index, | 9234 | tag_ty: Index, |
| 8893 | names: []const NullTerminatedString, | 9235 | names: []const NullTerminatedString, |
| 8894 | values: []const Index, | 9236 | values: []const Index, |
| 8895 | tag_mode: LoadedEnumType.TagMode, | 9237 | tag_mode: LoadedEnumType.TagMode, |
| 9238 | parent_namespace: NamespaceIndex, | ||
| 8896 | }; | 9239 | }; |
| 8897 | 9240 | ||
| 8898 | /// Creates an enum type which was automatically-generated as the tag type of a | 9241 | /// Creates an enum type which was automatically-generated as the tag type of a |
| ... | @@ -8919,6 +9262,18 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8919,6 +9262,18 @@ pub fn getGeneratedTagEnumType( |
| 8919 | 9262 | ||
| 8920 | const fields_len: u32 = @intCast(ini.names.len); | 9263 | const fields_len: u32 = @intCast(ini.names.len); |
| 8921 | 9264 | ||
| 9265 | // Predict the index the enum will live at so we can construct the namespace before releasing the shard's mutex. | ||
| 9266 | const enum_index = Index.Unwrapped.wrap(.{ | ||
| 9267 | .tid = tid, | ||
| 9268 | .index = items.mutate.len, | ||
| 9269 | }, ip); | ||
| 9270 | const namespace = try ip.createNamespace(gpa, tid, .{ | ||
| 9271 | .parent = ini.parent_namespace.toOptional(), | ||
| 9272 | .owner_type = enum_index, | ||
| 9273 | .file_scope = ip.namespacePtr(ini.parent_namespace).file_scope, | ||
| 9274 | }); | ||
| 9275 | errdefer ip.destroyNamespace(tid, namespace); | ||
| 9276 | |||
| 8922 | const prev_extra_len = extra.mutate.len; | 9277 | const prev_extra_len = extra.mutate.len; |
| 8923 | switch (ini.tag_mode) { | 9278 | switch (ini.tag_mode) { |
| 8924 | .auto => { | 9279 | .auto => { |
| ... | @@ -8928,9 +9283,9 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8928,9 +9283,9 @@ pub fn getGeneratedTagEnumType( |
| 8928 | items.appendAssumeCapacity(.{ | 9283 | items.appendAssumeCapacity(.{ |
| 8929 | .tag = .type_enum_auto, | 9284 | .tag = .type_enum_auto, |
| 8930 | .data = addExtraAssumeCapacity(extra, EnumAuto{ | 9285 | .data = addExtraAssumeCapacity(extra, EnumAuto{ |
| 8931 | .decl = ini.decl, | 9286 | .name = ini.name, |
| 8932 | .captures_len = 0, | 9287 | .captures_len = 0, |
| 8933 | .namespace = .none, | 9288 | .namespace = namespace, |
| 8934 | .int_tag_type = ini.tag_ty, | 9289 | .int_tag_type = ini.tag_ty, |
| 8935 | .fields_len = fields_len, | 9290 | .fields_len = fields_len, |
| 8936 | .names_map = names_map, | 9291 | .names_map = names_map, |
| ... | @@ -8961,9 +9316,9 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8961,9 +9316,9 @@ pub fn getGeneratedTagEnumType( |
| 8961 | .auto => unreachable, | 9316 | .auto => unreachable, |
| 8962 | }, | 9317 | }, |
| 8963 | .data = addExtraAssumeCapacity(extra, EnumExplicit{ | 9318 | .data = addExtraAssumeCapacity(extra, EnumExplicit{ |
| 8964 | .decl = ini.decl, | 9319 | .name = ini.name, |
| 8965 | .captures_len = 0, | 9320 | .captures_len = 0, |
| 8966 | .namespace = .none, | 9321 | .namespace = namespace, |
| 8967 | .int_tag_type = ini.tag_ty, | 9322 | .int_tag_type = ini.tag_ty, |
| 8968 | .fields_len = fields_len, | 9323 | .fields_len = fields_len, |
| 8969 | .names_map = names_map, | 9324 | .names_map = names_map, |
| ... | @@ -8988,11 +9343,11 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8988,11 +9343,11 @@ pub fn getGeneratedTagEnumType( |
| 8988 | .generated_tag = .{ .union_type = ini.owner_union_ty }, | 9343 | .generated_tag = .{ .union_type = ini.owner_union_ty }, |
| 8989 | } }); | 9344 | } }); |
| 8990 | defer gop.deinit(); | 9345 | defer gop.deinit(); |
| 8991 | return gop.put(); | 9346 | assert(gop.put() == enum_index); |
| 9347 | return enum_index; | ||
| 8992 | } | 9348 | } |
| 8993 | 9349 | ||
| 8994 | pub const OpaqueTypeInit = struct { | 9350 | pub const OpaqueTypeInit = struct { |
| 8995 | has_namespace: bool, | ||
| 8996 | key: union(enum) { | 9351 | key: union(enum) { |
| 8997 | declared: struct { | 9352 | declared: struct { |
| 8998 | zir_index: TrackedInst.Index, | 9353 | zir_index: TrackedInst.Index, |
| ... | @@ -9034,8 +9389,8 @@ pub fn getOpaqueType( | ... | @@ -9034,8 +9389,8 @@ pub fn getOpaqueType( |
| 9034 | .reified => 0, | 9389 | .reified => 0, |
| 9035 | }); | 9390 | }); |
| 9036 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{ | 9391 | const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{ |
| 9037 | .decl = undefined, // set by `finish` | 9392 | .name = undefined, // set by `finish` |
| 9038 | .namespace = .none, | 9393 | .namespace = undefined, // set by `finish` |
| 9039 | .zir_index = switch (ini.key) { | 9394 | .zir_index = switch (ini.key) { |
| 9040 | inline else => |x| x.zir_index, | 9395 | inline else => |x| x.zir_index, |
| 9041 | }, | 9396 | }, |
| ... | @@ -9052,15 +9407,15 @@ pub fn getOpaqueType( | ... | @@ -9052,15 +9407,15 @@ pub fn getOpaqueType( |
| 9052 | .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}), | 9407 | .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}), |
| 9053 | .reified => {}, | 9408 | .reified => {}, |
| 9054 | } | 9409 | } |
| 9055 | return .{ .wip = .{ | 9410 | return .{ |
| 9056 | .tid = tid, | 9411 | .wip = .{ |
| 9057 | .index = gop.put(), | 9412 | .tid = tid, |
| 9058 | .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?, | 9413 | .index = gop.put(), |
| 9059 | .namespace_extra_index = if (ini.has_namespace) | 9414 | .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?, |
| 9060 | extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").? | 9415 | .cau_extra_index = null, // opaques do not undergo type resolution |
| 9061 | else | 9416 | .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?, |
| 9062 | null, | 9417 | }, |
| 9063 | } }; | 9418 | }; |
| 9064 | } | 9419 | } |
| 9065 | 9420 | ||
| 9066 | pub fn getIfExists(ip: *const InternPool, key: Key) ?Index { | 9421 | pub fn getIfExists(ip: *const InternPool, key: Key) ?Index { |
| ... | @@ -9181,7 +9536,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 { | ... | @@ -9181,7 +9536,8 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 { |
| 9181 | inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| { | 9536 | inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| { |
| 9182 | extra.appendAssumeCapacity(.{switch (field.type) { | 9537 | extra.appendAssumeCapacity(.{switch (field.type) { |
| 9183 | Index, | 9538 | Index, |
| 9184 | DeclIndex, | 9539 | Cau.Index, |
| 9540 | Nav.Index, | ||
| 9185 | NamespaceIndex, | 9541 | NamespaceIndex, |
| 9186 | OptionalNamespaceIndex, | 9542 | OptionalNamespaceIndex, |
| 9187 | MapIndex, | 9543 | MapIndex, |
| ... | @@ -9244,7 +9600,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat | ... | @@ -9244,7 +9600,8 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat |
| 9244 | const extra_item = extra_items[extra_index]; | 9600 | const extra_item = extra_items[extra_index]; |
| 9245 | @field(result, field.name) = switch (field.type) { | 9601 | @field(result, field.name) = switch (field.type) { |
| 9246 | Index, | 9602 | Index, |
| 9247 | DeclIndex, | 9603 | Cau.Index, |
| 9604 | Nav.Index, | ||
| 9248 | NamespaceIndex, | 9605 | NamespaceIndex, |
| 9249 | OptionalNamespaceIndex, | 9606 | OptionalNamespaceIndex, |
| 9250 | MapIndex, | 9607 | MapIndex, |
| ... | @@ -9436,12 +9793,6 @@ pub fn getCoerced( | ... | @@ -9436,12 +9793,6 @@ pub fn getCoerced( |
| 9436 | 9793 | ||
| 9437 | switch (ip.indexToKey(val)) { | 9794 | switch (ip.indexToKey(val)) { |
| 9438 | .undef => return ip.get(gpa, tid, .{ .undef = new_ty }), | 9795 | .undef => return ip.get(gpa, tid, .{ .undef = new_ty }), |
| 9439 | .extern_func => |extern_func| if (ip.isFunctionType(new_ty)) | ||
| 9440 | return ip.getExternFunc(gpa, tid, .{ | ||
| 9441 | .ty = new_ty, | ||
| 9442 | .decl = extern_func.decl, | ||
| 9443 | .lib_name = extern_func.lib_name, | ||
| 9444 | }), | ||
| 9445 | .func => unreachable, | 9796 | .func => unreachable, |
| 9446 | 9797 | ||
| 9447 | .int => |int| switch (ip.indexToKey(new_ty)) { | 9798 | .int => |int| switch (ip.indexToKey(new_ty)) { |
| ... | @@ -9858,27 +10209,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -9858,27 +10209,23 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 9858 | var items_len: usize = 0; | 10209 | var items_len: usize = 0; |
| 9859 | var extra_len: usize = 0; | 10210 | var extra_len: usize = 0; |
| 9860 | var limbs_len: usize = 0; | 10211 | var limbs_len: usize = 0; |
| 9861 | var decls_len: usize = 0; | ||
| 9862 | for (ip.locals) |*local| { | 10212 | for (ip.locals) |*local| { |
| 9863 | items_len += local.mutate.items.len; | 10213 | items_len += local.mutate.items.len; |
| 9864 | extra_len += local.mutate.extra.len; | 10214 | extra_len += local.mutate.extra.len; |
| 9865 | limbs_len += local.mutate.limbs.len; | 10215 | limbs_len += local.mutate.limbs.len; |
| 9866 | decls_len += local.mutate.decls.buckets_list.len; | ||
| 9867 | } | 10216 | } |
| 9868 | const items_size = (1 + 4) * items_len; | 10217 | const items_size = (1 + 4) * items_len; |
| 9869 | const extra_size = 4 * extra_len; | 10218 | const extra_size = 4 * extra_len; |
| 9870 | const limbs_size = 8 * limbs_len; | 10219 | const limbs_size = 8 * limbs_len; |
| 9871 | const decls_size = @sizeOf(Zcu.Decl) * decls_len; | ||
| 9872 | 10220 | ||
| 9873 | // TODO: map overhead size is not taken into account | 10221 | // TODO: map overhead size is not taken into account |
| 9874 | const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size; | 10222 | const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size; |
| 9875 | 10223 | ||
| 9876 | std.debug.print( | 10224 | std.debug.print( |
| 9877 | \\InternPool size: {d} bytes | 10225 | \\InternPool size: {d} bytes |
| 9878 | \\ {d} items: {d} bytes | 10226 | \\ {d} items: {d} bytes |
| 9879 | \\ {d} extra: {d} bytes | 10227 | \\ {d} extra: {d} bytes |
| 9880 | \\ {d} limbs: {d} bytes | 10228 | \\ {d} limbs: {d} bytes |
| 9881 | \\ {d} decls: {d} bytes | ||
| 9882 | \\ | 10229 | \\ |
| 9883 | , .{ | 10230 | , .{ |
| 9884 | total_size, | 10231 | total_size, |
| ... | @@ -9888,8 +10235,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -9888,8 +10235,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 9888 | extra_size, | 10235 | extra_size, |
| 9889 | limbs_len, | 10236 | limbs_len, |
| 9890 | limbs_size, | 10237 | limbs_size, |
| 9891 | decls_len, | ||
| 9892 | decls_size, | ||
| 9893 | }); | 10238 | }); |
| 9894 | 10239 | ||
| 9895 | const TagStats = struct { | 10240 | const TagStats = struct { |
| ... | @@ -9967,7 +10312,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -9967,7 +10312,6 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 9967 | } | 10312 | } |
| 9968 | if (info.flags.any_default_inits) | 10313 | if (info.flags.any_default_inits) |
| 9969 | ints += info.fields_len; // inits | 10314 | ints += info.fields_len; // inits |
| 9970 | ints += @intFromBool(info.flags.has_namespace); // namespace | ||
| 9971 | if (info.flags.any_aligned_fields) | 10315 | if (info.flags.any_aligned_fields) |
| 9972 | ints += (info.fields_len + 3) / 4; // aligns | 10316 | ints += (info.fields_len + 3) / 4; // aligns |
| 9973 | if (info.flags.any_comptime_fields) | 10317 | if (info.flags.any_comptime_fields) |
| ... | @@ -10034,10 +10378,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -10034,10 +10378,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 10034 | .undef => 0, | 10378 | .undef => 0, |
| 10035 | .simple_type => 0, | 10379 | .simple_type => 0, |
| 10036 | .simple_value => 0, | 10380 | .simple_value => 0, |
| 10037 | .ptr_decl => @sizeOf(PtrDecl), | 10381 | .ptr_nav => @sizeOf(PtrNav), |
| 10038 | .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc), | 10382 | .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc), |
| 10039 | .ptr_anon_decl => @sizeOf(PtrAnonDecl), | 10383 | .ptr_uav => @sizeOf(PtrUav), |
| 10040 | .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned), | 10384 | .ptr_uav_aligned => @sizeOf(PtrUavAligned), |
| 10041 | .ptr_comptime_field => @sizeOf(PtrComptimeField), | 10385 | .ptr_comptime_field => @sizeOf(PtrComptimeField), |
| 10042 | .ptr_int => @sizeOf(PtrInt), | 10386 | .ptr_int => @sizeOf(PtrInt), |
| 10043 | .ptr_eu_payload => @sizeOf(PtrBase), | 10387 | .ptr_eu_payload => @sizeOf(PtrBase), |
| ... | @@ -10092,7 +10436,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -10092,7 +10436,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 10092 | .float_c_longdouble_f128 => @sizeOf(Float128), | 10436 | .float_c_longdouble_f128 => @sizeOf(Float128), |
| 10093 | .float_comptime_float => @sizeOf(Float128), | 10437 | .float_comptime_float => @sizeOf(Float128), |
| 10094 | .variable => @sizeOf(Tag.Variable), | 10438 | .variable => @sizeOf(Tag.Variable), |
| 10095 | .extern_func => @sizeOf(Tag.ExternFunc), | 10439 | .@"extern" => @sizeOf(Tag.Extern), |
| 10096 | .func_decl => @sizeOf(Tag.FuncDecl), | 10440 | .func_decl => @sizeOf(Tag.FuncDecl), |
| 10097 | .func_instance => b: { | 10441 | .func_instance => b: { |
| 10098 | const info = extraData(extra_list, Tag.FuncInstance, data); | 10442 | const info = extraData(extra_list, Tag.FuncInstance, data); |
| ... | @@ -10171,10 +10515,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { | ... | @@ -10171,10 +10515,10 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { |
| 10171 | .type_union, | 10515 | .type_union, |
| 10172 | .type_function, | 10516 | .type_function, |
| 10173 | .undef, | 10517 | .undef, |
| 10174 | .ptr_decl, | 10518 | .ptr_nav, |
| 10175 | .ptr_comptime_alloc, | 10519 | .ptr_comptime_alloc, |
| 10176 | .ptr_anon_decl, | 10520 | .ptr_uav, |
| 10177 | .ptr_anon_decl_aligned, | 10521 | .ptr_uav_aligned, |
| 10178 | .ptr_comptime_field, | 10522 | .ptr_comptime_field, |
| 10179 | .ptr_int, | 10523 | .ptr_int, |
| 10180 | .ptr_eu_payload, | 10524 | .ptr_eu_payload, |
| ... | @@ -10212,7 +10556,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { | ... | @@ -10212,7 +10556,7 @@ fn dumpAllFallible(ip: *const InternPool) anyerror!void { |
| 10212 | .float_c_longdouble_f128, | 10556 | .float_c_longdouble_f128, |
| 10213 | .float_comptime_float, | 10557 | .float_comptime_float, |
| 10214 | .variable, | 10558 | .variable, |
| 10215 | .extern_func, | 10559 | .@"extern", |
| 10216 | .func_decl, | 10560 | .func_decl, |
| 10217 | .func_instance, | 10561 | .func_instance, |
| 10218 | .func_coerced, | 10562 | .func_coerced, |
| ... | @@ -10275,13 +10619,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) | ... | @@ -10275,13 +10619,13 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) |
| 10275 | instances.sort(SortContext{ .values = instances.values() }); | 10619 | instances.sort(SortContext{ .values = instances.values() }); |
| 10276 | var it = instances.iterator(); | 10620 | var it = instances.iterator(); |
| 10277 | while (it.next()) |entry| { | 10621 | while (it.next()) |entry| { |
| 10278 | const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*)); | 10622 | const generic_fn_owner_nav = ip.getNav(ip.funcDeclInfo(entry.key_ptr.*).owner_nav); |
| 10279 | try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len }); | 10623 | try w.print("{} ({}): \n", .{ generic_fn_owner_nav.name.fmt(ip), entry.value_ptr.items.len }); |
| 10280 | for (entry.value_ptr.items) |index| { | 10624 | for (entry.value_ptr.items) |index| { |
| 10281 | const unwrapped_index = index.unwrap(ip); | 10625 | const unwrapped_index = index.unwrap(ip); |
| 10282 | const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip)); | 10626 | const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip)); |
| 10283 | const owner_decl = ip.declPtrConst(func.owner_decl); | 10627 | const owner_nav = ip.getNav(func.owner_nav); |
| 10284 | try w.print(" {}: (", .{owner_decl.name.fmt(ip)}); | 10628 | try w.print(" {}: (", .{owner_nav.name.fmt(ip)}); |
| 10285 | for (func.comptime_args.get(ip)) |arg| { | 10629 | for (func.comptime_args.get(ip)) |arg| { |
| 10286 | if (arg != .none) { | 10630 | if (arg != .none) { |
| 10287 | const key = ip.indexToKey(arg); | 10631 | const key = ip.indexToKey(arg); |
| ... | @@ -10295,66 +10639,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) | ... | @@ -10295,66 +10639,183 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) |
| 10295 | try bw.flush(); | 10639 | try bw.flush(); |
| 10296 | } | 10640 | } |
| 10297 | 10641 | ||
| 10298 | pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl { | 10642 | pub fn getCau(ip: *const InternPool, index: Cau.Index) Cau { |
| 10299 | return @constCast(ip.declPtrConst(decl_index)); | 10643 | const unwrapped = index.unwrap(ip); |
| 10644 | const caus = ip.getLocalShared(unwrapped.tid).caus.acquire(); | ||
| 10645 | return caus.view().items(.@"0")[unwrapped.index]; | ||
| 10300 | } | 10646 | } |
| 10301 | 10647 | ||
| 10302 | pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl { | 10648 | pub fn getNav(ip: *const InternPool, index: Nav.Index) Nav { |
| 10303 | const unwrapped_decl_index = decl_index.unwrap(ip); | 10649 | const unwrapped = index.unwrap(ip); |
| 10304 | const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire(); | 10650 | const navs = ip.getLocalShared(unwrapped.tid).navs.acquire(); |
| 10305 | const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index]; | 10651 | return navs.view().get(unwrapped.index).unpack(); |
| 10306 | return &decls_bucket[unwrapped_decl_index.index]; | 10652 | } |
| 10653 | |||
| 10654 | pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace { | ||
| 10655 | const unwrapped_namespace_index = namespace_index.unwrap(ip); | ||
| 10656 | const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire(); | ||
| 10657 | const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index]; | ||
| 10658 | return &namespaces_bucket[unwrapped_namespace_index.index]; | ||
| 10307 | } | 10659 | } |
| 10308 | 10660 | ||
| 10309 | pub fn createDecl( | 10661 | /// Create a `Cau` associated with the type at the given `InternPool.Index`. |
| 10662 | pub fn createTypeCau( | ||
| 10310 | ip: *InternPool, | 10663 | ip: *InternPool, |
| 10311 | gpa: Allocator, | 10664 | gpa: Allocator, |
| 10312 | tid: Zcu.PerThread.Id, | 10665 | tid: Zcu.PerThread.Id, |
| 10313 | initialization: Zcu.Decl, | 10666 | zir_index: TrackedInst.Index, |
| 10314 | ) Allocator.Error!DeclIndex { | 10667 | namespace: NamespaceIndex, |
| 10315 | const local = ip.getLocal(tid); | 10668 | owner_type: InternPool.Index, |
| 10316 | const free_list_next = local.mutate.decls.free_list; | 10669 | ) Allocator.Error!Cau.Index { |
| 10317 | if (free_list_next != Local.BucketListMutate.free_list_sentinel) { | 10670 | const caus = ip.getLocal(tid).getMutableCaus(gpa); |
| 10318 | const reused_decl_index: DeclIndex = @enumFromInt(free_list_next); | 10671 | const index_unwrapped: Cau.Index.Unwrapped = .{ |
| 10319 | const reused_decl = ip.declPtr(reused_decl_index); | ||
| 10320 | local.mutate.decls.free_list = @intFromEnum(@field(reused_decl, Local.decl_next_free_field)); | ||
| 10321 | reused_decl.* = initialization; | ||
| 10322 | return reused_decl_index; | ||
| 10323 | } | ||
| 10324 | const decls = local.getMutableDecls(gpa); | ||
| 10325 | if (local.mutate.decls.last_bucket_len == 0) { | ||
| 10326 | try decls.ensureUnusedCapacity(1); | ||
| 10327 | var arena = decls.arena.promote(decls.gpa); | ||
| 10328 | defer decls.arena.* = arena.state; | ||
| 10329 | decls.appendAssumeCapacity(.{try arena.allocator().create( | ||
| 10330 | [1 << Local.decls_bucket_width]Zcu.Decl, | ||
| 10331 | )}); | ||
| 10332 | } | ||
| 10333 | const unwrapped_decl_index: DeclIndex.Unwrapped = .{ | ||
| 10334 | .tid = tid, | 10672 | .tid = tid, |
| 10335 | .bucket_index = decls.mutate.len - 1, | 10673 | .index = caus.mutate.len, |
| 10336 | .index = local.mutate.decls.last_bucket_len, | ||
| 10337 | }; | 10674 | }; |
| 10338 | local.mutate.decls.last_bucket_len = | 10675 | try caus.append(.{.{ |
| 10339 | (unwrapped_decl_index.index + 1) & Local.namespaces_bucket_mask; | 10676 | .zir_index = zir_index, |
| 10340 | const decl_index = unwrapped_decl_index.wrap(ip); | 10677 | .namespace = namespace, |
| 10341 | ip.declPtr(decl_index).* = initialization; | 10678 | .owner = Cau.Owner.wrap(.{ .type = owner_type }), |
| 10342 | return decl_index; | 10679 | }}); |
| 10680 | return index_unwrapped.wrap(ip); | ||
| 10343 | } | 10681 | } |
| 10344 | 10682 | ||
| 10345 | pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex) void { | 10683 | /// Create a `Cau` for a `comptime` declaration. |
| 10346 | const local = ip.getLocal(tid); | 10684 | pub fn createComptimeCau( |
| 10347 | const decl = ip.declPtr(decl_index); | 10685 | ip: *InternPool, |
| 10348 | decl.* = undefined; | 10686 | gpa: Allocator, |
| 10349 | @field(decl, Local.decl_next_free_field) = @enumFromInt(local.mutate.decls.free_list); | 10687 | tid: Zcu.PerThread.Id, |
| 10350 | local.mutate.decls.free_list = @intFromEnum(decl_index); | 10688 | zir_index: TrackedInst.Index, |
| 10689 | namespace: NamespaceIndex, | ||
| 10690 | ) Allocator.Error!Cau.Index { | ||
| 10691 | const caus = ip.getLocal(tid).getMutableCaus(gpa); | ||
| 10692 | const index_unwrapped: Cau.Index.Unwrapped = .{ | ||
| 10693 | .tid = tid, | ||
| 10694 | .index = caus.mutate.len, | ||
| 10695 | }; | ||
| 10696 | try caus.append(.{.{ | ||
| 10697 | .zir_index = zir_index, | ||
| 10698 | .namespace = namespace, | ||
| 10699 | .owner = Cau.Owner.wrap(.none), | ||
| 10700 | }}); | ||
| 10701 | return index_unwrapped.wrap(ip); | ||
| 10351 | } | 10702 | } |
| 10352 | 10703 | ||
| 10353 | pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace { | 10704 | /// Create a `Nav` not associated with any `Cau`. |
| 10354 | const unwrapped_namespace_index = namespace_index.unwrap(ip); | 10705 | /// Since there is no analysis owner, the `Nav`'s value must be known at creation time. |
| 10355 | const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire(); | 10706 | pub fn createNav( |
| 10356 | const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index]; | 10707 | ip: *InternPool, |
| 10357 | return &namespaces_bucket[unwrapped_namespace_index.index]; | 10708 | gpa: Allocator, |
| 10709 | tid: Zcu.PerThread.Id, | ||
| 10710 | opts: struct { | ||
| 10711 | name: NullTerminatedString, | ||
| 10712 | fqn: NullTerminatedString, | ||
| 10713 | val: InternPool.Index, | ||
| 10714 | alignment: Alignment, | ||
| 10715 | @"linksection": OptionalNullTerminatedString, | ||
| 10716 | @"addrspace": std.builtin.AddressSpace, | ||
| 10717 | }, | ||
| 10718 | ) Allocator.Error!Nav.Index { | ||
| 10719 | const navs = ip.getLocal(tid).getMutableNavs(gpa); | ||
| 10720 | const index_unwrapped: Nav.Index.Unwrapped = .{ | ||
| 10721 | .tid = tid, | ||
| 10722 | .index = navs.mutate.len, | ||
| 10723 | }; | ||
| 10724 | try navs.append(Nav.pack(.{ | ||
| 10725 | .name = opts.name, | ||
| 10726 | .fqn = opts.fqn, | ||
| 10727 | .analysis_owner = .none, | ||
| 10728 | .status = .{ .resolved = .{ | ||
| 10729 | .val = opts.val, | ||
| 10730 | .alignment = opts.alignment, | ||
| 10731 | .@"linksection" = opts.@"linksection", | ||
| 10732 | .@"addrspace" = opts.@"addrspace", | ||
| 10733 | } }, | ||
| 10734 | .is_usingnamespace = false, | ||
| 10735 | })); | ||
| 10736 | return index_unwrapped.wrap(ip); | ||
| 10737 | } | ||
| 10738 | |||
| 10739 | /// Create a `Cau` and `Nav` which are paired. The value of the `Nav` is | ||
| 10740 | /// determined by semantic analysis of the `Cau`. The value of the `Nav` | ||
| 10741 | /// is initially unresolved. | ||
| 10742 | pub fn createPairedCauNav( | ||
| 10743 | ip: *InternPool, | ||
| 10744 | gpa: Allocator, | ||
| 10745 | tid: Zcu.PerThread.Id, | ||
| 10746 | name: NullTerminatedString, | ||
| 10747 | fqn: NullTerminatedString, | ||
| 10748 | zir_index: TrackedInst.Index, | ||
| 10749 | namespace: NamespaceIndex, | ||
| 10750 | /// TODO: this is hacky! See `Nav.is_usingnamespace`. | ||
| 10751 | is_usingnamespace: bool, | ||
| 10752 | ) Allocator.Error!struct { Cau.Index, Nav.Index } { | ||
| 10753 | const caus = ip.getLocal(tid).getMutableCaus(gpa); | ||
| 10754 | const navs = ip.getLocal(tid).getMutableNavs(gpa); | ||
| 10755 | |||
| 10756 | try caus.ensureUnusedCapacity(1); | ||
| 10757 | try navs.ensureUnusedCapacity(1); | ||
| 10758 | |||
| 10759 | const cau = Cau.Index.Unwrapped.wrap(.{ | ||
| 10760 | .tid = tid, | ||
| 10761 | .index = caus.mutate.len, | ||
| 10762 | }, ip); | ||
| 10763 | const nav = Nav.Index.Unwrapped.wrap(.{ | ||
| 10764 | .tid = tid, | ||
| 10765 | .index = navs.mutate.len, | ||
| 10766 | }, ip); | ||
| 10767 | |||
| 10768 | caus.appendAssumeCapacity(.{.{ | ||
| 10769 | .zir_index = zir_index, | ||
| 10770 | .namespace = namespace, | ||
| 10771 | .owner = Cau.Owner.wrap(.{ .nav = nav }), | ||
| 10772 | }}); | ||
| 10773 | navs.appendAssumeCapacity(Nav.pack(.{ | ||
| 10774 | .name = name, | ||
| 10775 | .fqn = fqn, | ||
| 10776 | .analysis_owner = cau.toOptional(), | ||
| 10777 | .status = .unresolved, | ||
| 10778 | .is_usingnamespace = is_usingnamespace, | ||
| 10779 | })); | ||
| 10780 | |||
| 10781 | return .{ cau, nav }; | ||
| 10782 | } | ||
| 10783 | |||
| 10784 | /// Resolve the value of a `Nav` with an analysis owner. | ||
| 10785 | /// If its status is already `resolved`, the old value is discarded. | ||
| 10786 | pub fn resolveNavValue( | ||
| 10787 | ip: *InternPool, | ||
| 10788 | nav: Nav.Index, | ||
| 10789 | resolved: struct { | ||
| 10790 | val: InternPool.Index, | ||
| 10791 | alignment: Alignment, | ||
| 10792 | @"linksection": OptionalNullTerminatedString, | ||
| 10793 | @"addrspace": std.builtin.AddressSpace, | ||
| 10794 | }, | ||
| 10795 | ) void { | ||
| 10796 | const unwrapped = nav.unwrap(ip); | ||
| 10797 | |||
| 10798 | const local = ip.getLocal(unwrapped.tid); | ||
| 10799 | local.mutate.extra.mutex.lock(); | ||
| 10800 | defer local.mutate.extra.mutex.unlock(); | ||
| 10801 | |||
| 10802 | const navs = local.shared.navs.view(); | ||
| 10803 | |||
| 10804 | const nav_analysis_owners = navs.items(.analysis_owner); | ||
| 10805 | const nav_vals = navs.items(.val); | ||
| 10806 | const nav_linksections = navs.items(.@"linksection"); | ||
| 10807 | const nav_bits = navs.items(.bits); | ||
| 10808 | |||
| 10809 | assert(nav_analysis_owners[unwrapped.index] != .none); | ||
| 10810 | |||
| 10811 | @atomicStore(InternPool.Index, &nav_vals[unwrapped.index], resolved.val, .release); | ||
| 10812 | @atomicStore(OptionalNullTerminatedString, &nav_linksections[unwrapped.index], resolved.@"linksection", .release); | ||
| 10813 | |||
| 10814 | var bits = nav_bits[unwrapped.index]; | ||
| 10815 | bits.status = .resolved; | ||
| 10816 | bits.alignment = resolved.alignment; | ||
| 10817 | bits.@"addrspace" = resolved.@"addrspace"; | ||
| 10818 | @atomicStore(Nav.Repr.Bits, &nav_bits[unwrapped.index], bits, .release); | ||
| 10358 | } | 10819 | } |
| 10359 | 10820 | ||
| 10360 | pub fn createNamespace( | 10821 | pub fn createNamespace( |
| ... | @@ -10404,7 +10865,7 @@ pub fn destroyNamespace( | ... | @@ -10404,7 +10865,7 @@ pub fn destroyNamespace( |
| 10404 | namespace.* = .{ | 10865 | namespace.* = .{ |
| 10405 | .parent = undefined, | 10866 | .parent = undefined, |
| 10406 | .file_scope = undefined, | 10867 | .file_scope = undefined, |
| 10407 | .decl_index = undefined, | 10868 | .owner_type = undefined, |
| 10408 | }; | 10869 | }; |
| 10409 | @field(namespace, Local.namespace_next_free_field) = | 10870 | @field(namespace, Local.namespace_next_free_field) = |
| 10410 | @enumFromInt(local.mutate.namespaces.free_list); | 10871 | @enumFromInt(local.mutate.namespaces.free_list); |
| ... | @@ -10750,10 +11211,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { | ... | @@ -10750,10 +11211,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 10750 | 11211 | ||
| 10751 | .simple_type, .simple_value => unreachable, // handled via Index above | 11212 | .simple_type, .simple_value => unreachable, // handled via Index above |
| 10752 | 11213 | ||
| 10753 | inline .ptr_decl, | 11214 | inline .ptr_nav, |
| 10754 | .ptr_comptime_alloc, | 11215 | .ptr_comptime_alloc, |
| 10755 | .ptr_anon_decl, | 11216 | .ptr_uav, |
| 10756 | .ptr_anon_decl_aligned, | 11217 | .ptr_uav_aligned, |
| 10757 | .ptr_comptime_field, | 11218 | .ptr_comptime_field, |
| 10758 | .ptr_int, | 11219 | .ptr_int, |
| 10759 | .ptr_eu_payload, | 11220 | .ptr_eu_payload, |
| ... | @@ -10770,7 +11231,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { | ... | @@ -10770,7 +11231,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index { |
| 10770 | .error_union_error, | 11231 | .error_union_error, |
| 10771 | .enum_tag, | 11232 | .enum_tag, |
| 10772 | .variable, | 11233 | .variable, |
| 10773 | .extern_func, | 11234 | .@"extern", |
| 10774 | .func_decl, | 11235 | .func_decl, |
| 10775 | .func_instance, | 11236 | .func_instance, |
| 10776 | .func_coerced, | 11237 | .func_coerced, |
| ... | @@ -10892,14 +11353,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool { | ... | @@ -10892,14 +11353,14 @@ pub fn isVariable(ip: *const InternPool, val: Index) bool { |
| 10892 | return val.unwrap(ip).getTag(ip) == .variable; | 11353 | return val.unwrap(ip).getTag(ip) == .variable; |
| 10893 | } | 11354 | } |
| 10894 | 11355 | ||
| 10895 | pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex { | 11356 | pub fn getBackingNav(ip: *const InternPool, val: Index) Nav.Index.Optional { |
| 10896 | var base = val; | 11357 | var base = val; |
| 10897 | while (true) { | 11358 | while (true) { |
| 10898 | const unwrapped_base = base.unwrap(ip); | 11359 | const unwrapped_base = base.unwrap(ip); |
| 10899 | const base_item = unwrapped_base.getItem(ip); | 11360 | const base_item = unwrapped_base.getItem(ip); |
| 10900 | switch (base_item.tag) { | 11361 | switch (base_item.tag) { |
| 10901 | .ptr_decl => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[ | 11362 | .ptr_nav => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[ |
| 10902 | base_item.data + std.meta.fieldIndex(PtrDecl, "decl").? | 11363 | base_item.data + std.meta.fieldIndex(PtrNav, "nav").? |
| 10903 | ]), | 11364 | ]), |
| 10904 | inline .ptr_eu_payload, | 11365 | inline .ptr_eu_payload, |
| 10905 | .ptr_opt_payload, | 11366 | .ptr_opt_payload, |
| ... | @@ -10922,11 +11383,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta | ... | @@ -10922,11 +11383,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta |
| 10922 | const unwrapped_base = base.unwrap(ip); | 11383 | const unwrapped_base = base.unwrap(ip); |
| 10923 | const base_item = unwrapped_base.getItem(ip); | 11384 | const base_item = unwrapped_base.getItem(ip); |
| 10924 | switch (base_item.tag) { | 11385 | switch (base_item.tag) { |
| 10925 | .ptr_decl => return .decl, | 11386 | .ptr_nav => return .nav, |
| 10926 | .ptr_comptime_alloc => return .comptime_alloc, | 11387 | .ptr_comptime_alloc => return .comptime_alloc, |
| 10927 | .ptr_anon_decl, | 11388 | .ptr_uav, |
| 10928 | .ptr_anon_decl_aligned, | 11389 | .ptr_uav_aligned, |
| 10929 | => return .anon_decl, | 11390 | => return .uav, |
| 10930 | .ptr_comptime_field => return .comptime_field, | 11391 | .ptr_comptime_field => return .comptime_field, |
| 10931 | .ptr_int => return .int, | 11392 | .ptr_int => return .int, |
| 10932 | inline .ptr_eu_payload, | 11393 | inline .ptr_eu_payload, |
| ... | @@ -11098,10 +11559,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois | ... | @@ -11098,10 +11559,10 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois |
| 11098 | // values, not types | 11559 | // values, not types |
| 11099 | .undef, | 11560 | .undef, |
| 11100 | .simple_value, | 11561 | .simple_value, |
| 11101 | .ptr_decl, | 11562 | .ptr_nav, |
| 11102 | .ptr_comptime_alloc, | 11563 | .ptr_comptime_alloc, |
| 11103 | .ptr_anon_decl, | 11564 | .ptr_uav, |
| 11104 | .ptr_anon_decl_aligned, | 11565 | .ptr_uav_aligned, |
| 11105 | .ptr_comptime_field, | 11566 | .ptr_comptime_field, |
| 11106 | .ptr_int, | 11567 | .ptr_int, |
| 11107 | .ptr_eu_payload, | 11568 | .ptr_eu_payload, |
| ... | @@ -11137,7 +11598,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois | ... | @@ -11137,7 +11598,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois |
| 11137 | .float_c_longdouble_f128, | 11598 | .float_c_longdouble_f128, |
| 11138 | .float_comptime_float, | 11599 | .float_comptime_float, |
| 11139 | .variable, | 11600 | .variable, |
| 11140 | .extern_func, | 11601 | .@"extern", |
| 11141 | .func_decl, | 11602 | .func_decl, |
| 11142 | .func_instance, | 11603 | .func_instance, |
| 11143 | .func_coerced, | 11604 | .func_coerced, |
| ... | @@ -11190,18 +11651,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis { | ... | @@ -11190,18 +11651,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis { |
| 11190 | return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered); | 11651 | return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered); |
| 11191 | } | 11652 | } |
| 11192 | 11653 | ||
| 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 { | 11654 | pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void { |
| 11206 | const unwrapped_func = func.unwrap(ip); | 11655 | const unwrapped_func = func.unwrap(ip); |
| 11207 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; | 11656 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; |
| ... | @@ -11349,10 +11798,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func { | ... | @@ -11349,10 +11798,6 @@ pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func { |
| 11349 | return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data); | 11798 | return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data); |
| 11350 | } | 11799 | } |
| 11351 | 11800 | ||
| 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 { | 11801 | pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 { |
| 11357 | const unwrapped_index = index.unwrap(ip); | 11802 | const unwrapped_index = index.unwrap(ip); |
| 11358 | const extra_list = unwrapped_index.getExtra(ip); | 11803 | const extra_list = unwrapped_index.getExtra(ip); |
| ... | @@ -11409,14 +11854,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 { | ... | @@ -11409,14 +11854,6 @@ pub fn anonStructFieldsLen(ip: *const InternPool, i: Index) u32 { |
| 11409 | return @intCast(ip.indexToKey(i).anon_struct_type.types.len); | 11854 | return @intCast(ip.indexToKey(i).anon_struct_type.types.len); |
| 11410 | } | 11855 | } |
| 11411 | 11856 | ||
| 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. | 11857 | /// Returns the already-existing field with the same name, if any. |
| 11421 | pub fn addFieldName( | 11858 | pub fn addFieldName( |
| 11422 | ip: *InternPool, | 11859 | ip: *InternPool, |
| ... | @@ -11436,8 +11873,8 @@ pub fn addFieldName( | ... | @@ -11436,8 +11873,8 @@ pub fn addFieldName( |
| 11436 | return null; | 11873 | return null; |
| 11437 | } | 11874 | } |
| 11438 | 11875 | ||
| 11439 | /// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_anon_decl` | 11876 | /// Used only by `get` for pointer values, and mainly intended to use `Tag.ptr_uav` |
| 11440 | /// encoding instead of `Tag.ptr_anon_decl_aligned` when possible. | 11877 | /// encoding instead of `Tag.ptr_uav_aligned` when possible. |
| 11441 | fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool { | 11878 | fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool { |
| 11442 | if (a_ty == b_ty) return true; | 11879 | if (a_ty == b_ty) return true; |
| 11443 | const b_info = ip.indexToKey(b_ty).ptr_type; | 11880 | const b_info = ip.indexToKey(b_ty).ptr_type; |
| ... | @@ -11607,3 +12044,7 @@ pub fn getErrorValue( | ... | @@ -11607,3 +12044,7 @@ pub fn getErrorValue( |
| 11607 | pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt { | 12044 | pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt { |
| 11608 | return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null); | 12045 | return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null); |
| 11609 | } | 12046 | } |
| 12047 | |||
| 12048 | pub fn isRemoved(ip: *const InternPool, ty: Index) bool { | ||
| 12049 | return ty.unwrap(ip).getTag(ip) == .removed; | ||
| 12050 | } |
src/Sema.zig+1054-1088| ... | @@ -16,16 +16,14 @@ air_instructions: std.MultiArrayList(Air.Inst) = .{}, | ... | @@ -16,16 +16,14 @@ air_instructions: std.MultiArrayList(Air.Inst) = .{}, |
| 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 | ||
| ... | @@ -2816,7 +2802,6 @@ fn zirStructDecl( | ... | @@ -2816,7 +2802,6 @@ fn zirStructDecl( |
| 2816 | .any_default_inits = small.any_default_inits, | 2802 | .any_default_inits = small.any_default_inits, |
| 2817 | .inits_resolved = false, | 2803 | .inits_resolved = false, |
| 2818 | .any_aligned_fields = small.any_aligned_fields, | 2804 | .any_aligned_fields = small.any_aligned_fields, |
| 2819 | .has_namespace = true or decls_len > 0, // TODO: see below | ||
| 2820 | .key = .{ .declared = .{ | 2805 | .key = .{ .declared = .{ |
| 2821 | .zir_index = tracked_inst, | 2806 | .zir_index = tracked_inst, |
| 2822 | .captures = captures, | 2807 | .captures = captures, |
| ... | @@ -2831,73 +2816,65 @@ fn zirStructDecl( | ... | @@ -2831,73 +2816,65 @@ fn zirStructDecl( |
| 2831 | }); | 2816 | }); |
| 2832 | errdefer wip_ty.cancel(ip, pt.tid); | 2817 | errdefer wip_ty.cancel(ip, pt.tid); |
| 2833 | 2818 | ||
| 2834 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 2819 | wip_ty.setName(ip, try sema.createTypeName( |
| 2835 | block, | 2820 | block, |
| 2836 | Value.fromInterned(wip_ty.index), | ||
| 2837 | small.name_strategy, | 2821 | small.name_strategy, |
| 2838 | "struct", | 2822 | "struct", |
| 2839 | inst, | 2823 | inst, |
| 2840 | ); | 2824 | wip_ty.index, |
| 2841 | mod.declPtr(new_decl_index).owns_tv = true; | 2825 | )); |
| 2842 | errdefer pt.abortAnonDecl(new_decl_index); | 2826 | |
| 2827 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ | ||
| 2828 | .parent = block.namespace.toOptional(), | ||
| 2829 | .owner_type = wip_ty.index, | ||
| 2830 | .file_scope = block.getFileScopeIndex(mod), | ||
| 2831 | }); | ||
| 2832 | errdefer pt.destroyNamespace(new_namespace_index); | ||
| 2833 | |||
| 2834 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); | ||
| 2843 | 2835 | ||
| 2844 | if (pt.zcu.comp.incremental) { | 2836 | if (pt.zcu.comp.incremental) { |
| 2845 | try ip.addDependency( | 2837 | try ip.addDependency( |
| 2846 | sema.gpa, | 2838 | sema.gpa, |
| 2847 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 2839 | AnalUnit.wrap(.{ .cau = new_cau_index }), |
| 2848 | .{ .src_hash = try block.trackZir(inst) }, | 2840 | .{ .src_hash = tracked_inst }, |
| 2849 | ); | 2841 | ); |
| 2850 | } | 2842 | } |
| 2851 | 2843 | ||
| 2852 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. | 2844 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| 2853 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{ | 2845 | try pt.scanNamespace(new_namespace_index, decls); |
| 2854 | .parent = block.namespace.toOptional(), | ||
| 2855 | .decl_index = new_decl_index, | ||
| 2856 | .file_scope = block.getFileScopeIndex(mod), | ||
| 2857 | })).toOptional() else .none; | ||
| 2858 | errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); | ||
| 2859 | |||
| 2860 | if (new_namespace_index.unwrap()) |ns| { | ||
| 2861 | const decls = sema.code.bodySlice(extra_index, decls_len); | ||
| 2862 | try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); | ||
| 2863 | } | ||
| 2864 | 2846 | ||
| 2865 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 2866 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 2847 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 2867 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 2848 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index })); |
| 2868 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); | 2849 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 2850 | return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index)); | ||
| 2869 | } | 2851 | } |
| 2870 | 2852 | ||
| 2871 | fn createAnonymousDeclTypeNamed( | 2853 | fn createTypeName( |
| 2872 | sema: *Sema, | 2854 | sema: *Sema, |
| 2873 | block: *Block, | 2855 | block: *Block, |
| 2874 | val: Value, | ||
| 2875 | name_strategy: Zir.Inst.NameStrategy, | 2856 | name_strategy: Zir.Inst.NameStrategy, |
| 2876 | anon_prefix: []const u8, | 2857 | anon_prefix: []const u8, |
| 2877 | inst: ?Zir.Inst.Index, | 2858 | inst: ?Zir.Inst.Index, |
| 2878 | ) !InternPool.DeclIndex { | 2859 | /// This is used purely to give the type a unique name in the `anon` case. |
| 2860 | type_index: InternPool.Index, | ||
| 2861 | ) !InternPool.NullTerminatedString { | ||
| 2879 | const pt = sema.pt; | 2862 | const pt = sema.pt; |
| 2880 | const zcu = pt.zcu; | 2863 | const zcu = pt.zcu; |
| 2864 | const gpa = zcu.gpa; | ||
| 2881 | const ip = &zcu.intern_pool; | 2865 | const ip = &zcu.intern_pool; |
| 2882 | const gpa = sema.gpa; | ||
| 2883 | const namespace = block.namespace; | ||
| 2884 | const new_decl_index = try pt.allocateNewDecl(namespace); | ||
| 2885 | errdefer pt.destroyDecl(new_decl_index); | ||
| 2886 | 2866 | ||
| 2887 | switch (name_strategy) { | 2867 | switch (name_strategy) { |
| 2888 | .anon => {}, // handled after switch | 2868 | .anon => {}, // handled after switch |
| 2889 | .parent => { | 2869 | .parent => return block.type_name_ctx, |
| 2890 | try pt.initNewAnonDecl(new_decl_index, val, block.type_name_ctx, .none); | ||
| 2891 | return new_decl_index; | ||
| 2892 | }, | ||
| 2893 | .func => func_strat: { | 2870 | .func => func_strat: { |
| 2894 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip)); | 2871 | const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip)); |
| 2895 | const zir_tags = sema.code.instructions.items(.tag); | 2872 | const zir_tags = sema.code.instructions.items(.tag); |
| 2896 | 2873 | ||
| 2897 | var buf = std.ArrayList(u8).init(gpa); | 2874 | var buf: std.ArrayListUnmanaged(u8) = .{}; |
| 2898 | defer buf.deinit(); | 2875 | defer buf.deinit(gpa); |
| 2899 | 2876 | ||
| 2900 | const writer = buf.writer(); | 2877 | const writer = buf.writer(gpa); |
| 2901 | try writer.print("{}(", .{block.type_name_ctx.fmt(ip)}); | 2878 | try writer.print("{}(", .{block.type_name_ctx.fmt(ip)}); |
| 2902 | 2879 | ||
| 2903 | var arg_i: usize = 0; | 2880 | var arg_i: usize = 0; |
| ... | @@ -2931,23 +2908,18 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2931,23 +2908,18 @@ fn createAnonymousDeclTypeNamed( |
| 2931 | }; | 2908 | }; |
| 2932 | 2909 | ||
| 2933 | try writer.writeByte(')'); | 2910 | try writer.writeByte(')'); |
| 2934 | const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls); | 2911 | return ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls); |
| 2935 | try pt.initNewAnonDecl(new_decl_index, val, name, .none); | ||
| 2936 | return new_decl_index; | ||
| 2937 | }, | 2912 | }, |
| 2938 | .dbg_var => { | 2913 | .dbg_var => { |
| 2914 | // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions. | ||
| 2939 | const ref = inst.?.toRef(); | 2915 | const ref = inst.?.toRef(); |
| 2940 | const zir_tags = sema.code.instructions.items(.tag); | 2916 | const zir_tags = sema.code.instructions.items(.tag); |
| 2941 | const zir_data = sema.code.instructions.items(.data); | 2917 | const zir_data = sema.code.instructions.items(.data); |
| 2942 | for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) { | 2918 | for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) { |
| 2943 | .dbg_var_ptr, .dbg_var_val => { | 2919 | .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) { |
| 2944 | if (zir_data[i].str_op.operand != ref) continue; | 2920 | return ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{ |
| 2945 | |||
| 2946 | const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{ | ||
| 2947 | block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code), | 2921 | block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code), |
| 2948 | }, .no_embedded_nulls); | 2922 | }, .no_embedded_nulls); |
| 2949 | try pt.initNewAnonDecl(new_decl_index, val, name, .none); | ||
| 2950 | return new_decl_index; | ||
| 2951 | }, | 2923 | }, |
| 2952 | else => {}, | 2924 | else => {}, |
| 2953 | }; | 2925 | }; |
| ... | @@ -2955,20 +2927,19 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2955,20 +2927,19 @@ fn createAnonymousDeclTypeNamed( |
| 2955 | }, | 2927 | }, |
| 2956 | } | 2928 | } |
| 2957 | 2929 | ||
| 2958 | // anon strat handling. | 2930 | // anon strat handling |
| 2959 | 2931 | ||
| 2960 | // It would be neat to have "struct:line:column" but this name has | 2932 | // 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 | 2933 | // to survive incremental updates, where it may have been shifted down |
| 2962 | // or up to a different line, but unchanged, and thus not unnecessarily | 2934 | // or up to a different line, but unchanged, and thus not unnecessarily |
| 2963 | // semantically analyzed. | 2935 | // semantically analyzed. |
| 2964 | // This name is also used as the key in the parent namespace so it cannot be | 2936 | // TODO: that would be possible, by detecting line number changes and renaming |
| 2965 | // renamed. | 2937 | // types appropriately. However, `@typeName` becomes a problem then. If we remove |
| 2938 | // that builtin from the language, we can consider this. | ||
| 2966 | 2939 | ||
| 2967 | const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{ | 2940 | return ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{ |
| 2968 | block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index), | 2941 | block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index), |
| 2969 | }, .no_embedded_nulls) catch unreachable; | 2942 | }, .no_embedded_nulls); |
| 2970 | try pt.initNewAnonDecl(new_decl_index, val, name, .none); | ||
| 2971 | return new_decl_index; | ||
| 2972 | } | 2943 | } |
| 2973 | 2944 | ||
| 2974 | fn zirEnumDecl( | 2945 | fn zirEnumDecl( |
| ... | @@ -3040,7 +3011,6 @@ fn zirEnumDecl( | ... | @@ -3040,7 +3011,6 @@ fn zirEnumDecl( |
| 3040 | } else false; | 3011 | } else false; |
| 3041 | 3012 | ||
| 3042 | const enum_init: InternPool.EnumTypeInit = .{ | 3013 | const enum_init: InternPool.EnumTypeInit = .{ |
| 3043 | .has_namespace = true or decls_len > 0, // TODO: see below | ||
| 3044 | .has_values = any_values, | 3014 | .has_values = any_values, |
| 3045 | .tag_mode = if (small.nonexhaustive) | 3015 | .tag_mode = if (small.nonexhaustive) |
| 3046 | .nonexhaustive | 3016 | .nonexhaustive |
| ... | @@ -3068,60 +3038,50 @@ fn zirEnumDecl( | ... | @@ -3068,60 +3038,50 @@ fn zirEnumDecl( |
| 3068 | 3038 | ||
| 3069 | errdefer if (!done) wip_ty.cancel(ip, pt.tid); | 3039 | errdefer if (!done) wip_ty.cancel(ip, pt.tid); |
| 3070 | 3040 | ||
| 3071 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 3041 | const type_name = try sema.createTypeName( |
| 3072 | block, | 3042 | block, |
| 3073 | Value.fromInterned(wip_ty.index), | ||
| 3074 | small.name_strategy, | 3043 | small.name_strategy, |
| 3075 | "enum", | 3044 | "enum", |
| 3076 | inst, | 3045 | inst, |
| 3046 | wip_ty.index, | ||
| 3077 | ); | 3047 | ); |
| 3078 | const new_decl = mod.declPtr(new_decl_index); | 3048 | wip_ty.setName(ip, type_name); |
| 3079 | new_decl.owns_tv = true; | 3049 | |
| 3080 | errdefer if (!done) pt.abortAnonDecl(new_decl_index); | 3050 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 3051 | .parent = block.namespace.toOptional(), | ||
| 3052 | .owner_type = wip_ty.index, | ||
| 3053 | .file_scope = block.getFileScopeIndex(mod), | ||
| 3054 | }); | ||
| 3055 | errdefer if (!done) pt.destroyNamespace(new_namespace_index); | ||
| 3056 | |||
| 3057 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); | ||
| 3081 | 3058 | ||
| 3082 | if (pt.zcu.comp.incremental) { | 3059 | if (pt.zcu.comp.incremental) { |
| 3083 | try mod.intern_pool.addDependency( | 3060 | try mod.intern_pool.addDependency( |
| 3084 | gpa, | 3061 | gpa, |
| 3085 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 3062 | AnalUnit.wrap(.{ .cau = new_cau_index }), |
| 3086 | .{ .src_hash = try block.trackZir(inst) }, | 3063 | .{ .src_hash = try block.trackZir(inst) }, |
| 3087 | ); | 3064 | ); |
| 3088 | } | 3065 | } |
| 3089 | 3066 | ||
| 3090 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. | 3067 | try pt.scanNamespace(new_namespace_index, decls); |
| 3091 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{ | ||
| 3092 | .parent = block.namespace.toOptional(), | ||
| 3093 | .decl_index = new_decl_index, | ||
| 3094 | .file_scope = block.getFileScopeIndex(mod), | ||
| 3095 | })).toOptional() else .none; | ||
| 3096 | errdefer if (!done) if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); | ||
| 3097 | 3068 | ||
| 3098 | if (new_namespace_index.unwrap()) |ns| { | 3069 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index })); |
| 3099 | try pt.scanNamespace(ns, decls, new_decl); | 3070 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 3100 | } | ||
| 3101 | 3071 | ||
| 3102 | // We've finished the initial construction of this type, and are about to perform analysis. | 3072 | // We've finished the initial construction of this type, and are about to perform analysis. |
| 3103 | // Set the decl and namespace appropriately, and don't destroy anything on failure. | 3073 | // Set the Cau and namespace appropriately, and don't destroy anything on failure. |
| 3104 | wip_ty.prepare(ip, new_decl_index, new_namespace_index); | 3074 | wip_ty.prepare(ip, new_cau_index, new_namespace_index); |
| 3105 | done = true; | 3075 | done = true; |
| 3106 | 3076 | ||
| 3107 | const int_tag_ty = ty: { | 3077 | const int_tag_ty = ty: { |
| 3108 | // We create a block for the field type instructions because they | 3078 | // We create a block for the field type instructions because they |
| 3109 | // may need to reference Decls from inside the enum namespace. | 3079 | // may need to reference Decls from inside the enum namespace. |
| 3110 | // Within the field type, default value, and alignment expressions, the "owner decl" | 3080 | // Within the field type, default value, and alignment expressions, the owner should be the enum's `Cau`. |
| 3111 | // should be the enum itself. | ||
| 3112 | 3081 | ||
| 3113 | const prev_owner_decl = sema.owner_decl; | 3082 | const prev_owner = sema.owner; |
| 3114 | const prev_owner_decl_index = sema.owner_decl_index; | 3083 | sema.owner = AnalUnit.wrap(.{ .cau = new_cau_index }); |
| 3115 | sema.owner_decl = new_decl; | 3084 | defer sema.owner = prev_owner; |
| 3116 | sema.owner_decl_index = new_decl_index; | ||
| 3117 | defer { | ||
| 3118 | sema.owner_decl = prev_owner_decl; | ||
| 3119 | sema.owner_decl_index = prev_owner_decl_index; | ||
| 3120 | } | ||
| 3121 | |||
| 3122 | const prev_owner_func_index = sema.owner_func_index; | ||
| 3123 | sema.owner_func_index = .none; | ||
| 3124 | defer sema.owner_func_index = prev_owner_func_index; | ||
| 3125 | 3085 | ||
| 3126 | const prev_func_index = sema.func_index; | 3086 | const prev_func_index = sema.func_index; |
| 3127 | sema.func_index = .none; | 3087 | sema.func_index = .none; |
| ... | @@ -3130,12 +3090,12 @@ fn zirEnumDecl( | ... | @@ -3130,12 +3090,12 @@ fn zirEnumDecl( |
| 3130 | var enum_block: Block = .{ | 3090 | var enum_block: Block = .{ |
| 3131 | .parent = null, | 3091 | .parent = null, |
| 3132 | .sema = sema, | 3092 | .sema = sema, |
| 3133 | .namespace = new_namespace_index.unwrap() orelse block.namespace, | 3093 | .namespace = new_namespace_index, |
| 3134 | .instructions = .{}, | 3094 | .instructions = .{}, |
| 3135 | .inlining = null, | 3095 | .inlining = null, |
| 3136 | .is_comptime = true, | 3096 | .is_comptime = true, |
| 3137 | .src_base_inst = tracked_inst, | 3097 | .src_base_inst = tracked_inst, |
| 3138 | .type_name_ctx = new_decl.name, | 3098 | .type_name_ctx = type_name, |
| 3139 | }; | 3099 | }; |
| 3140 | defer enum_block.instructions.deinit(sema.gpa); | 3100 | defer enum_block.instructions.deinit(sema.gpa); |
| 3141 | 3101 | ||
| ... | @@ -3253,7 +3213,6 @@ fn zirEnumDecl( | ... | @@ -3253,7 +3213,6 @@ fn zirEnumDecl( |
| 3253 | } | 3213 | } |
| 3254 | } | 3214 | } |
| 3255 | 3215 | ||
| 3256 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 3257 | return Air.internedToRef(wip_ty.index); | 3216 | return Air.internedToRef(wip_ty.index); |
| 3258 | } | 3217 | } |
| 3259 | 3218 | ||
| ... | @@ -3317,7 +3276,6 @@ fn zirUnionDecl( | ... | @@ -3317,7 +3276,6 @@ fn zirUnionDecl( |
| 3317 | .assumed_pointer_aligned = false, | 3276 | .assumed_pointer_aligned = false, |
| 3318 | .alignment = .none, | 3277 | .alignment = .none, |
| 3319 | }, | 3278 | }, |
| 3320 | .has_namespace = true or decls_len != 0, // TODO: see below | ||
| 3321 | .fields_len = fields_len, | 3279 | .fields_len = fields_len, |
| 3322 | .enum_tag_ty = .none, // set later | 3280 | .enum_tag_ty = .none, // set later |
| 3323 | .field_types = &.{}, // set later | 3281 | .field_types = &.{}, // set later |
| ... | @@ -3336,41 +3294,38 @@ fn zirUnionDecl( | ... | @@ -3336,41 +3294,38 @@ fn zirUnionDecl( |
| 3336 | }); | 3294 | }); |
| 3337 | errdefer wip_ty.cancel(ip, pt.tid); | 3295 | errdefer wip_ty.cancel(ip, pt.tid); |
| 3338 | 3296 | ||
| 3339 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 3297 | wip_ty.setName(ip, try sema.createTypeName( |
| 3340 | block, | 3298 | block, |
| 3341 | Value.fromInterned(wip_ty.index), | ||
| 3342 | small.name_strategy, | 3299 | small.name_strategy, |
| 3343 | "union", | 3300 | "union", |
| 3344 | inst, | 3301 | inst, |
| 3345 | ); | 3302 | wip_ty.index, |
| 3346 | mod.declPtr(new_decl_index).owns_tv = true; | 3303 | )); |
| 3347 | errdefer pt.abortAnonDecl(new_decl_index); | 3304 | |
| 3305 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ | ||
| 3306 | .parent = block.namespace.toOptional(), | ||
| 3307 | .owner_type = wip_ty.index, | ||
| 3308 | .file_scope = block.getFileScopeIndex(mod), | ||
| 3309 | }); | ||
| 3310 | errdefer pt.destroyNamespace(new_namespace_index); | ||
| 3311 | |||
| 3312 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); | ||
| 3348 | 3313 | ||
| 3349 | if (pt.zcu.comp.incremental) { | 3314 | if (pt.zcu.comp.incremental) { |
| 3350 | try mod.intern_pool.addDependency( | 3315 | try mod.intern_pool.addDependency( |
| 3351 | gpa, | 3316 | gpa, |
| 3352 | AnalUnit.wrap(.{ .decl = new_decl_index }), | 3317 | AnalUnit.wrap(.{ .cau = new_cau_index }), |
| 3353 | .{ .src_hash = try block.trackZir(inst) }, | 3318 | .{ .src_hash = try block.trackZir(inst) }, |
| 3354 | ); | 3319 | ); |
| 3355 | } | 3320 | } |
| 3356 | 3321 | ||
| 3357 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. | 3322 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| 3358 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{ | 3323 | try pt.scanNamespace(new_namespace_index, decls); |
| 3359 | .parent = block.namespace.toOptional(), | ||
| 3360 | .decl_index = new_decl_index, | ||
| 3361 | .file_scope = block.getFileScopeIndex(mod), | ||
| 3362 | })).toOptional() else .none; | ||
| 3363 | errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); | ||
| 3364 | |||
| 3365 | if (new_namespace_index.unwrap()) |ns| { | ||
| 3366 | const decls = sema.code.bodySlice(extra_index, decls_len); | ||
| 3367 | try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); | ||
| 3368 | } | ||
| 3369 | 3324 | ||
| 3370 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 3371 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 3325 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 3372 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 3326 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index })); |
| 3373 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); | 3327 | try sema.declareDependency(.{ .interned = wip_ty.index }); |
| 3328 | return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index)); | ||
| 3374 | } | 3329 | } |
| 3375 | 3330 | ||
| 3376 | fn zirOpaqueDecl( | 3331 | fn zirOpaqueDecl( |
| ... | @@ -3410,7 +3365,6 @@ fn zirOpaqueDecl( | ... | @@ -3410,7 +3365,6 @@ fn zirOpaqueDecl( |
| 3410 | extra_index += captures_len; | 3365 | extra_index += captures_len; |
| 3411 | 3366 | ||
| 3412 | const opaque_init: InternPool.OpaqueTypeInit = .{ | 3367 | const opaque_init: InternPool.OpaqueTypeInit = .{ |
| 3413 | .has_namespace = decls_len != 0, | ||
| 3414 | .key = .{ .declared = .{ | 3368 | .key = .{ .declared = .{ |
| 3415 | .zir_index = tracked_inst, | 3369 | .zir_index = tracked_inst, |
| 3416 | .captures = captures, | 3370 | .captures = captures, |
| ... | @@ -3418,47 +3372,31 @@ fn zirOpaqueDecl( | ... | @@ -3418,47 +3372,31 @@ fn zirOpaqueDecl( |
| 3418 | }; | 3372 | }; |
| 3419 | // No `wrapWipTy` needed as no std.builtin types are opaque. | 3373 | // No `wrapWipTy` needed as no std.builtin types are opaque. |
| 3420 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) { | 3374 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) { |
| 3421 | .existing => |ty| wip: { | 3375 | // No `maybeRemoveOutdatedType` as opaque types are never outdated. |
| 3422 | if (!try sema.maybeRemoveOutdatedType(ty)) return Air.internedToRef(ty); | 3376 | .existing => |ty| return Air.internedToRef(ty), |
| 3423 | break :wip (try ip.getOpaqueType(gpa, pt.tid, opaque_init)).wip; | ||
| 3424 | }, | ||
| 3425 | .wip => |wip| wip, | 3377 | .wip => |wip| wip, |
| 3426 | }; | 3378 | }; |
| 3427 | errdefer wip_ty.cancel(ip, pt.tid); | 3379 | errdefer wip_ty.cancel(ip, pt.tid); |
| 3428 | 3380 | ||
| 3429 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 3381 | wip_ty.setName(ip, try sema.createTypeName( |
| 3430 | block, | 3382 | block, |
| 3431 | Value.fromInterned(wip_ty.index), | ||
| 3432 | small.name_strategy, | 3383 | small.name_strategy, |
| 3433 | "opaque", | 3384 | "opaque", |
| 3434 | inst, | 3385 | inst, |
| 3435 | ); | 3386 | wip_ty.index, |
| 3436 | mod.declPtr(new_decl_index).owns_tv = true; | 3387 | )); |
| 3437 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 3438 | 3388 | ||
| 3439 | if (pt.zcu.comp.incremental) { | 3389 | const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{ |
| 3440 | try ip.addDependency( | ||
| 3441 | gpa, | ||
| 3442 | AnalUnit.wrap(.{ .decl = new_decl_index }), | ||
| 3443 | .{ .src_hash = try block.trackZir(inst) }, | ||
| 3444 | ); | ||
| 3445 | } | ||
| 3446 | |||
| 3447 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try pt.createNamespace(.{ | ||
| 3448 | .parent = block.namespace.toOptional(), | 3390 | .parent = block.namespace.toOptional(), |
| 3449 | .decl_index = new_decl_index, | 3391 | .owner_type = wip_ty.index, |
| 3450 | .file_scope = block.getFileScopeIndex(mod), | 3392 | .file_scope = block.getFileScopeIndex(mod), |
| 3451 | })).toOptional() else .none; | 3393 | }); |
| 3452 | errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); | 3394 | errdefer pt.destroyNamespace(new_namespace_index); |
| 3453 | |||
| 3454 | if (new_namespace_index.unwrap()) |ns| { | ||
| 3455 | const decls = sema.code.bodySlice(extra_index, decls_len); | ||
| 3456 | try pt.scanNamespace(ns, decls, mod.declPtr(new_decl_index)); | ||
| 3457 | } | ||
| 3458 | 3395 | ||
| 3459 | try pt.finalizeAnonDecl(new_decl_index); | 3396 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| 3397 | try pt.scanNamespace(new_namespace_index, decls); | ||
| 3460 | 3398 | ||
| 3461 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index)); | 3399 | return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index)); |
| 3462 | } | 3400 | } |
| 3463 | 3401 | ||
| 3464 | fn zirErrorSetDecl( | 3402 | fn zirErrorSetDecl( |
| ... | @@ -3774,7 +3712,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3774,7 +3712,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3774 | // might have already done our job and created an anon decl ref. | 3712 | // might have already done our job and created an anon decl ref. |
| 3775 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { | 3713 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern())) { |
| 3776 | .ptr => |ptr| switch (ptr.base_addr) { | 3714 | .ptr => |ptr| switch (ptr.base_addr) { |
| 3777 | .anon_decl => { | 3715 | .uav => { |
| 3778 | // The comptime-ification was already done for us. | 3716 | // The comptime-ification was already done for us. |
| 3779 | // Just make sure the pointer is const. | 3717 | // Just make sure the pointer is const. |
| 3780 | return sema.makePtrConst(block, alloc); | 3718 | return sema.makePtrConst(block, alloc); |
| ... | @@ -3799,7 +3737,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -3799,7 +3737,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 3799 | // Promote the constant to an anon decl. | 3737 | // Promote the constant to an anon decl. |
| 3800 | const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{ | 3738 | const new_mut_ptr = Air.internedToRef(try pt.intern(.{ .ptr = .{ |
| 3801 | .ty = alloc_ty.toIntern(), | 3739 | .ty = alloc_ty.toIntern(), |
| 3802 | .base_addr = .{ .anon_decl = .{ | 3740 | .base_addr = .{ .uav = .{ |
| 3803 | .val = interned.toIntern(), | 3741 | .val = interned.toIntern(), |
| 3804 | .orig_ty = alloc_ty.toIntern(), | 3742 | .orig_ty = alloc_ty.toIntern(), |
| 3805 | } }, | 3743 | } }, |
| ... | @@ -4097,7 +4035,7 @@ fn finishResolveComptimeKnownAllocPtr( | ... | @@ -4097,7 +4035,7 @@ fn finishResolveComptimeKnownAllocPtr( |
| 4097 | } else { | 4035 | } else { |
| 4098 | return try pt.intern(.{ .ptr = .{ | 4036 | return try pt.intern(.{ .ptr = .{ |
| 4099 | .ty = alloc_ty.toIntern(), | 4037 | .ty = alloc_ty.toIntern(), |
| 4100 | .base_addr = .{ .anon_decl = .{ | 4038 | .base_addr = .{ .uav = .{ |
| 4101 | .orig_ty = alloc_ty.toIntern(), | 4039 | .orig_ty = alloc_ty.toIntern(), |
| 4102 | .val = result_val, | 4040 | .val = result_val, |
| 4103 | } }, | 4041 | } }, |
| ... | @@ -4250,7 +4188,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -4250,7 +4188,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 4250 | } | 4188 | } |
| 4251 | 4189 | ||
| 4252 | const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) { | 4190 | const val = switch (mod.intern_pool.indexToKey(resolved_ptr).ptr.base_addr) { |
| 4253 | .anon_decl => |a| a.val, | 4191 | .uav => |a| a.val, |
| 4254 | .comptime_alloc => |i| val: { | 4192 | .comptime_alloc => |i| val: { |
| 4255 | const alloc = sema.getComptimeAlloc(i); | 4193 | const alloc = sema.getComptimeAlloc(i); |
| 4256 | break :val (try alloc.val.intern(pt, sema.arena)).toIntern(); | 4194 | break :val (try alloc.val.intern(pt, sema.arena)).toIntern(); |
| ... | @@ -5505,22 +5443,23 @@ fn failWithBadMemberAccess( | ... | @@ -5505,22 +5443,23 @@ fn failWithBadMemberAccess( |
| 5505 | field_name: InternPool.NullTerminatedString, | 5443 | field_name: InternPool.NullTerminatedString, |
| 5506 | ) CompileError { | 5444 | ) CompileError { |
| 5507 | const pt = sema.pt; | 5445 | const pt = sema.pt; |
| 5508 | const mod = pt.zcu; | 5446 | const zcu = pt.zcu; |
| 5509 | const kw_name = switch (agg_ty.zigTypeTag(mod)) { | 5447 | const ip = &zcu.intern_pool; |
| 5448 | const kw_name = switch (agg_ty.zigTypeTag(zcu)) { | ||
| 5510 | .Union => "union", | 5449 | .Union => "union", |
| 5511 | .Struct => "struct", | 5450 | .Struct => "struct", |
| 5512 | .Opaque => "opaque", | 5451 | .Opaque => "opaque", |
| 5513 | .Enum => "enum", | 5452 | .Enum => "enum", |
| 5514 | else => unreachable, | 5453 | else => unreachable, |
| 5515 | }; | 5454 | }; |
| 5516 | if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) { | 5455 | if (agg_ty.typeDeclInst(zcu)) |inst| if (inst.resolve(ip) == .main_struct_inst) { |
| 5517 | return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{ | 5456 | return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{ |
| 5518 | agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool), | 5457 | agg_ty.fmt(pt), field_name.fmt(ip), |
| 5519 | }); | 5458 | }); |
| 5520 | }; | 5459 | }; |
| 5521 | 5460 | ||
| 5522 | return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{ | 5461 | return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{ |
| 5523 | kw_name, agg_ty.fmt(pt), field_name.fmt(&mod.intern_pool), | 5462 | kw_name, agg_ty.fmt(pt), field_name.fmt(ip), |
| 5524 | }); | 5463 | }); |
| 5525 | } | 5464 | } |
| 5526 | 5465 | ||
| ... | @@ -5535,13 +5474,12 @@ fn failWithBadStructFieldAccess( | ... | @@ -5535,13 +5474,12 @@ fn failWithBadStructFieldAccess( |
| 5535 | const pt = sema.pt; | 5474 | const pt = sema.pt; |
| 5536 | const zcu = pt.zcu; | 5475 | const zcu = pt.zcu; |
| 5537 | const ip = &zcu.intern_pool; | 5476 | const ip = &zcu.intern_pool; |
| 5538 | const decl = zcu.declPtr(struct_type.decl.unwrap().?); | ||
| 5539 | 5477 | ||
| 5540 | const msg = msg: { | 5478 | const msg = msg: { |
| 5541 | const msg = try sema.errMsg( | 5479 | const msg = try sema.errMsg( |
| 5542 | field_src, | 5480 | field_src, |
| 5543 | "no field named '{}' in struct '{}'", | 5481 | "no field named '{}' in struct '{}'", |
| 5544 | .{ field_name.fmt(ip), decl.fqn.fmt(ip) }, | 5482 | .{ field_name.fmt(ip), struct_type.name.fmt(ip) }, |
| 5545 | ); | 5483 | ); |
| 5546 | errdefer msg.destroy(sema.gpa); | 5484 | errdefer msg.destroy(sema.gpa); |
| 5547 | try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{}); | 5485 | try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{}); |
| ... | @@ -5562,13 +5500,12 @@ fn failWithBadUnionFieldAccess( | ... | @@ -5562,13 +5500,12 @@ fn failWithBadUnionFieldAccess( |
| 5562 | const zcu = pt.zcu; | 5500 | const zcu = pt.zcu; |
| 5563 | const ip = &zcu.intern_pool; | 5501 | const ip = &zcu.intern_pool; |
| 5564 | const gpa = sema.gpa; | 5502 | const gpa = sema.gpa; |
| 5565 | const decl = zcu.declPtr(union_obj.decl); | ||
| 5566 | 5503 | ||
| 5567 | const msg = msg: { | 5504 | const msg = msg: { |
| 5568 | const msg = try sema.errMsg( | 5505 | const msg = try sema.errMsg( |
| 5569 | field_src, | 5506 | field_src, |
| 5570 | "no field named '{}' in union '{}'", | 5507 | "no field named '{}' in union '{}'", |
| 5571 | .{ field_name.fmt(ip), decl.fqn.fmt(ip) }, | 5508 | .{ field_name.fmt(ip), union_obj.name.fmt(ip) }, |
| 5572 | ); | 5509 | ); |
| 5573 | errdefer msg.destroy(gpa); | 5510 | errdefer msg.destroy(gpa); |
| 5574 | try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{}); | 5511 | try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{}); |
| ... | @@ -5659,7 +5596,7 @@ fn storeToInferredAllocComptime( | ... | @@ -5659,7 +5596,7 @@ fn storeToInferredAllocComptime( |
| 5659 | if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) { | 5596 | if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) { |
| 5660 | iac.ptr = try pt.intern(.{ .ptr = .{ | 5597 | iac.ptr = try pt.intern(.{ .ptr = .{ |
| 5661 | .ty = alloc_ty.toIntern(), | 5598 | .ty = alloc_ty.toIntern(), |
| 5662 | .base_addr = .{ .anon_decl = .{ | 5599 | .base_addr = .{ .uav = .{ |
| 5663 | .val = operand_val.toIntern(), | 5600 | .val = operand_val.toIntern(), |
| 5664 | .orig_ty = alloc_ty.toIntern(), | 5601 | .orig_ty = alloc_ty.toIntern(), |
| 5665 | } }, | 5602 | } }, |
| ... | @@ -5748,11 +5685,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air. | ... | @@ -5748,11 +5685,11 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air. |
| 5748 | .ty = array_ty.toIntern(), | 5685 | .ty = array_ty.toIntern(), |
| 5749 | .storage = .{ .bytes = string }, | 5686 | .storage = .{ .bytes = string }, |
| 5750 | } }); | 5687 | } }); |
| 5751 | return anonDeclRef(sema, val); | 5688 | return sema.uavRef(val); |
| 5752 | } | 5689 | } |
| 5753 | 5690 | ||
| 5754 | fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref { | 5691 | fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref { |
| 5755 | return Air.internedToRef(try refValue(sema, val)); | 5692 | return Air.internedToRef(try sema.refValue(val)); |
| 5756 | } | 5693 | } |
| 5757 | 5694 | ||
| 5758 | fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { | 5695 | fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { |
| ... | @@ -5767,7 +5704,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { | ... | @@ -5767,7 +5704,7 @@ fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index { |
| 5767 | })).toIntern(); | 5704 | })).toIntern(); |
| 5768 | return pt.intern(.{ .ptr = .{ | 5705 | return pt.intern(.{ .ptr = .{ |
| 5769 | .ty = ptr_ty, | 5706 | .ty = ptr_ty, |
| 5770 | .base_addr = .{ .anon_decl = .{ | 5707 | .base_addr = .{ .uav = .{ |
| 5771 | .val = val, | 5708 | .val = val, |
| 5772 | .orig_ty = ptr_ty, | 5709 | .orig_ty = ptr_ty, |
| 5773 | } }, | 5710 | } }, |
| ... | @@ -5866,7 +5803,7 @@ fn zirCompileLog( | ... | @@ -5866,7 +5803,7 @@ fn zirCompileLog( |
| 5866 | } | 5803 | } |
| 5867 | try writer.print("\n", .{}); | 5804 | try writer.print("\n", .{}); |
| 5868 | 5805 | ||
| 5869 | const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.ownerUnit()); | 5806 | const gop = try mod.compile_log_sources.getOrPut(sema.gpa, sema.owner); |
| 5870 | if (!gop.found_existing) gop.value_ptr.* = .{ | 5807 | if (!gop.found_existing) gop.value_ptr.* = .{ |
| 5871 | .base_node_inst = block.src_base_inst, | 5808 | .base_node_inst = block.src_base_inst, |
| 5872 | .node_offset = src_node, | 5809 | .node_offset = src_node, |
| ... | @@ -6021,7 +5958,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6021,7 +5958,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 6021 | if (!comp.config.link_libc) | 5958 | if (!comp.config.link_libc) |
| 6022 | try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{}); | 5959 | try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{}); |
| 6023 | 5960 | ||
| 6024 | const gop = try zcu.cimport_errors.getOrPut(gpa, sema.ownerUnit()); | 5961 | const gop = try zcu.cimport_errors.getOrPut(gpa, sema.owner); |
| 6025 | if (!gop.found_existing) { | 5962 | if (!gop.found_existing) { |
| 6026 | gop.value_ptr.* = c_import_res.errors; | 5963 | gop.value_ptr.* = c_import_res.errors; |
| 6027 | c_import_res.errors = std.zig.ErrorBundle.empty; | 5964 | c_import_res.errors = std.zig.ErrorBundle.empty; |
| ... | @@ -6069,13 +6006,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6069,13 +6006,15 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 6069 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6006 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 6070 | 6007 | ||
| 6071 | const path_digest = zcu.filePathDigest(result.file_index); | 6008 | const path_digest = zcu.filePathDigest(result.file_index); |
| 6072 | const root_decl = zcu.fileRootDecl(result.file_index); | 6009 | const old_root_type = zcu.fileRootType(result.file_index); |
| 6073 | pt.astGenFile(result.file, path_digest, root_decl) catch |err| | 6010 | pt.astGenFile(result.file, path_digest, old_root_type) catch |err| |
| 6074 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6011 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 6075 | 6012 | ||
| 6013 | // TODO: register some kind of dependency on the file. | ||
| 6014 | // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to | ||
| 6015 | // trigger re-analysis later. | ||
| 6076 | try pt.ensureFileAnalyzed(result.file_index); | 6016 | try pt.ensureFileAnalyzed(result.file_index); |
| 6077 | const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; | 6017 | return Air.internedToRef(zcu.fileRootType(result.file_index)); |
| 6078 | return sema.analyzeDeclVal(parent_block, src, file_root_decl_index); | ||
| 6079 | } | 6018 | } |
| 6080 | 6019 | ||
| 6081 | fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6020 | fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -6423,36 +6362,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void | ... | @@ -6423,36 +6362,40 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 6423 | defer tracy.end(); | 6362 | defer tracy.end(); |
| 6424 | 6363 | ||
| 6425 | const pt = sema.pt; | 6364 | const pt = sema.pt; |
| 6426 | const mod = pt.zcu; | 6365 | const zcu = pt.zcu; |
| 6366 | const ip = &zcu.intern_pool; | ||
| 6427 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 6367 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 6428 | const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; | 6368 | const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; |
| 6429 | const src = block.nodeOffset(inst_data.src_node); | 6369 | const src = block.nodeOffset(inst_data.src_node); |
| 6430 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); | 6370 | const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0); |
| 6431 | const options_src = block.builtinCallArgSrc(inst_data.src_node, 1); | 6371 | const options_src = block.builtinCallArgSrc(inst_data.src_node, 1); |
| 6432 | const decl_name = try mod.intern_pool.getOrPutString( | 6372 | const decl_name = try ip.getOrPutString( |
| 6433 | mod.gpa, | 6373 | zcu.gpa, |
| 6434 | pt.tid, | 6374 | pt.tid, |
| 6435 | sema.code.nullTerminatedString(extra.decl_name), | 6375 | sema.code.nullTerminatedString(extra.decl_name), |
| 6436 | .no_embedded_nulls, | 6376 | .no_embedded_nulls, |
| 6437 | ); | 6377 | ); |
| 6438 | const decl_index = if (extra.namespace != .none) index_blk: { | 6378 | const nav_index = if (extra.namespace != .none) index_blk: { |
| 6439 | const container_ty = try sema.resolveType(block, operand_src, extra.namespace); | 6379 | const container_ty = try sema.resolveType(block, operand_src, extra.namespace); |
| 6440 | const container_namespace = container_ty.getNamespaceIndex(mod); | 6380 | const container_namespace = container_ty.getNamespaceIndex(zcu); |
| 6441 | 6381 | ||
| 6442 | const maybe_index = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false); | 6382 | const lookup = try sema.lookupInNamespace(block, operand_src, container_namespace, decl_name, false) orelse |
| 6443 | break :index_blk maybe_index orelse | ||
| 6444 | return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name); | 6383 | return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name); |
| 6384 | |||
| 6385 | break :index_blk lookup.nav; | ||
| 6445 | } else try sema.lookupIdentifier(block, operand_src, decl_name); | 6386 | } else try sema.lookupIdentifier(block, operand_src, decl_name); |
| 6446 | const options = try sema.resolveExportOptions(block, options_src, extra.options); | 6387 | const options = try sema.resolveExportOptions(block, options_src, extra.options); |
| 6447 | { | 6388 | |
| 6448 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index })); | 6389 | try sema.ensureNavResolved(src, nav_index); |
| 6449 | try sema.ensureDeclAnalyzed(decl_index); | 6390 | |
| 6450 | const exported_decl = mod.declPtr(decl_index); | 6391 | // Make sure to export the owner Nav if applicable. |
| 6451 | if (exported_decl.val.getFunction(mod)) |function| { | 6392 | const exported_nav = switch (ip.indexToKey(ip.getNav(nav_index).status.resolved.val)) { |
| 6452 | return sema.analyzeExport(block, src, options, function.owner_decl); | 6393 | .variable => |v| v.owner_nav, |
| 6453 | } | 6394 | .@"extern" => |e| e.owner_nav, |
| 6454 | } | 6395 | .func => |f| f.owner_nav, |
| 6455 | try sema.analyzeExport(block, src, options, decl_index); | 6396 | else => nav_index, |
| 6397 | }; | ||
| 6398 | try sema.analyzeExport(block, src, options, exported_nav); | ||
| 6456 | } | 6399 | } |
| 6457 | 6400 | ||
| 6458 | fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 6401 | fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -6460,7 +6403,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6460,7 +6403,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6460 | defer tracy.end(); | 6403 | defer tracy.end(); |
| 6461 | 6404 | ||
| 6462 | const pt = sema.pt; | 6405 | const pt = sema.pt; |
| 6463 | const mod = pt.zcu; | 6406 | const zcu = pt.zcu; |
| 6407 | const ip = &zcu.intern_pool; | ||
| 6464 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 6408 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 6465 | const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data; | 6409 | const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data; |
| 6466 | const src = block.nodeOffset(inst_data.src_node); | 6410 | const src = block.nodeOffset(inst_data.src_node); |
| ... | @@ -6472,17 +6416,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6472,17 +6416,24 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6472 | const options = try sema.resolveExportOptions(block, options_src, extra.options); | 6416 | const options = try sema.resolveExportOptions(block, options_src, extra.options); |
| 6473 | if (options.linkage == .internal) | 6417 | if (options.linkage == .internal) |
| 6474 | return; | 6418 | return; |
| 6475 | if (operand.getFunction(mod)) |function| { | ||
| 6476 | const decl_index = function.owner_decl; | ||
| 6477 | return sema.analyzeExport(block, src, options, decl_index); | ||
| 6478 | } | ||
| 6479 | 6419 | ||
| 6480 | try sema.exports.append(mod.gpa, .{ | 6420 | // If the value has an owner Nav, export that instead. |
| 6481 | .opts = options, | 6421 | const maybe_owner_nav = switch (ip.indexToKey(operand.toIntern())) { |
| 6482 | .src = src, | 6422 | .variable => |v| v.owner_nav, |
| 6483 | .exported = .{ .value = operand.toIntern() }, | 6423 | .@"extern" => |e| e.owner_nav, |
| 6484 | .status = .in_progress, | 6424 | .func => |f| f.owner_nav, |
| 6485 | }); | 6425 | else => null, |
| 6426 | }; | ||
| 6427 | if (maybe_owner_nav) |owner_nav| { | ||
| 6428 | return sema.analyzeExport(block, src, options, owner_nav); | ||
| 6429 | } else { | ||
| 6430 | try sema.exports.append(zcu.gpa, .{ | ||
| 6431 | .opts = options, | ||
| 6432 | .src = src, | ||
| 6433 | .exported = .{ .uav = operand.toIntern() }, | ||
| 6434 | .status = .in_progress, | ||
| 6435 | }); | ||
| 6436 | } | ||
| 6486 | } | 6437 | } |
| 6487 | 6438 | ||
| 6488 | pub fn analyzeExport( | 6439 | pub fn analyzeExport( |
| ... | @@ -6490,22 +6441,22 @@ pub fn analyzeExport( | ... | @@ -6490,22 +6441,22 @@ pub fn analyzeExport( |
| 6490 | block: *Block, | 6441 | block: *Block, |
| 6491 | src: LazySrcLoc, | 6442 | src: LazySrcLoc, |
| 6492 | options: Module.Export.Options, | 6443 | options: Module.Export.Options, |
| 6493 | exported_decl_index: InternPool.DeclIndex, | 6444 | exported_nav_index: InternPool.Nav.Index, |
| 6494 | ) !void { | 6445 | ) !void { |
| 6495 | const gpa = sema.gpa; | 6446 | const gpa = sema.gpa; |
| 6496 | const pt = sema.pt; | 6447 | const pt = sema.pt; |
| 6497 | const mod = pt.zcu; | 6448 | const zcu = pt.zcu; |
| 6449 | const ip = &zcu.intern_pool; | ||
| 6498 | 6450 | ||
| 6499 | if (options.linkage == .internal) | 6451 | if (options.linkage == .internal) |
| 6500 | return; | 6452 | return; |
| 6501 | 6453 | ||
| 6502 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = exported_decl_index })); | 6454 | try sema.ensureNavResolved(src, exported_nav_index); |
| 6503 | try sema.ensureDeclAnalyzed(exported_decl_index); | 6455 | const exported_nav = ip.getNav(exported_nav_index); |
| 6504 | const exported_decl = mod.declPtr(exported_decl_index); | 6456 | const export_ty = Type.fromInterned(exported_nav.typeOf(ip)); |
| 6505 | const export_ty = exported_decl.typeOf(mod); | ||
| 6506 | 6457 | ||
| 6507 | if (!try sema.validateExternType(export_ty, .other)) { | 6458 | if (!try sema.validateExternType(export_ty, .other)) { |
| 6508 | const msg = msg: { | 6459 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 6509 | const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)}); | 6460 | const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(pt)}); |
| 6510 | errdefer msg.destroy(gpa); | 6461 | errdefer msg.destroy(gpa); |
| 6511 | 6462 | ||
| ... | @@ -6513,59 +6464,50 @@ pub fn analyzeExport( | ... | @@ -6513,59 +6464,50 @@ pub fn analyzeExport( |
| 6513 | 6464 | ||
| 6514 | try sema.addDeclaredHereNote(msg, export_ty); | 6465 | try sema.addDeclaredHereNote(msg, export_ty); |
| 6515 | break :msg msg; | 6466 | break :msg msg; |
| 6516 | }; | 6467 | }); |
| 6517 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 6518 | } | 6468 | } |
| 6519 | 6469 | ||
| 6520 | // TODO: some backends might support re-exporting extern decls | 6470 | // TODO: some backends might support re-exporting extern decls |
| 6521 | if (exported_decl.isExtern(mod)) { | 6471 | if (exported_nav.isExtern(ip)) { |
| 6522 | return sema.fail(block, src, "export target cannot be extern", .{}); | 6472 | return sema.fail(block, src, "export target cannot be extern", .{}); |
| 6523 | } | 6473 | } |
| 6524 | 6474 | ||
| 6525 | try sema.maybeQueueFuncBodyAnalysis(src, exported_decl_index); | 6475 | try sema.maybeQueueFuncBodyAnalysis(src, exported_nav_index); |
| 6526 | 6476 | ||
| 6527 | try sema.exports.append(gpa, .{ | 6477 | try sema.exports.append(gpa, .{ |
| 6528 | .opts = options, | 6478 | .opts = options, |
| 6529 | .src = src, | 6479 | .src = src, |
| 6530 | .exported = .{ .decl_index = exported_decl_index }, | 6480 | .exported = .{ .nav = exported_nav_index }, |
| 6531 | .status = .in_progress, | 6481 | .status = .in_progress, |
| 6532 | }); | 6482 | }); |
| 6533 | } | 6483 | } |
| 6534 | 6484 | ||
| 6535 | fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6485 | fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| 6536 | const pt = sema.pt; | 6486 | const pt = sema.pt; |
| 6537 | const mod = pt.zcu; | 6487 | const zcu = pt.zcu; |
| 6538 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 6488 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 6539 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | 6489 | const operand_src = block.builtinCallArgSrc(extra.node, 0); |
| 6540 | const src = block.nodeOffset(extra.node); | 6490 | const src = block.nodeOffset(extra.node); |
| 6541 | const alignment = try sema.resolveAlign(block, operand_src, extra.operand); | 6491 | const alignment = try sema.resolveAlign(block, operand_src, extra.operand); |
| 6492 | |||
| 6493 | const func = switch (sema.owner.unwrap()) { | ||
| 6494 | .func => |func| func, | ||
| 6495 | .cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}), | ||
| 6496 | }; | ||
| 6497 | |||
| 6542 | if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) { | 6498 | if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) { |
| 6543 | return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{ | 6499 | return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{ |
| 6544 | alignment.toByteUnits().?, | 6500 | alignment.toByteUnits().?, |
| 6545 | }); | 6501 | }); |
| 6546 | } | 6502 | } |
| 6547 | 6503 | ||
| 6548 | const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index); | 6504 | switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) { |
| 6549 | switch (fn_owner_decl.typeOf(mod).fnCallingConvention(mod)) { | ||
| 6550 | .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), | 6505 | .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), |
| 6551 | .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), | 6506 | .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), |
| 6552 | else => if (block.inlining != null) { | 6507 | else => {}, |
| 6553 | return sema.fail(block, src, "@setAlignStack in inline call", .{}); | ||
| 6554 | }, | ||
| 6555 | } | ||
| 6556 | |||
| 6557 | if (sema.prev_stack_alignment_src) |prev_src| { | ||
| 6558 | const msg = msg: { | ||
| 6559 | const msg = try sema.errMsg(src, "multiple @setAlignStack in the same function body", .{}); | ||
| 6560 | errdefer msg.destroy(sema.gpa); | ||
| 6561 | try sema.errNote(prev_src, msg, "other instance here", .{}); | ||
| 6562 | break :msg msg; | ||
| 6563 | }; | ||
| 6564 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 6565 | } | 6508 | } |
| 6566 | sema.prev_stack_alignment_src = src; | ||
| 6567 | 6509 | ||
| 6568 | mod.intern_pool.funcMaxStackAlignment(sema.func_index, alignment); | 6510 | zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment); |
| 6569 | } | 6511 | } |
| 6570 | 6512 | ||
| 6571 | fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6513 | fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| ... | @@ -6577,16 +6519,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) | ... | @@ -6577,16 +6519,24 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) |
| 6577 | const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{ | 6519 | const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{ |
| 6578 | .needed_comptime_reason = "operand to @setCold must be comptime-known", | 6520 | .needed_comptime_reason = "operand to @setCold must be comptime-known", |
| 6579 | }); | 6521 | }); |
| 6580 | if (sema.func_index == .none) return; // does nothing outside a function | 6522 | // TODO: should `@setCold` apply to the parent in an inline call? |
| 6581 | ip.funcSetCold(sema.func_index, is_cold); | 6523 | // See also #20642 and friends. |
| 6524 | const func = switch (sema.owner.unwrap()) { | ||
| 6525 | .func => |func| func, | ||
| 6526 | .cau => return, // does nothing outside a function | ||
| 6527 | }; | ||
| 6528 | ip.funcSetCold(func, is_cold); | ||
| 6582 | } | 6529 | } |
| 6583 | 6530 | ||
| 6584 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { | 6531 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { |
| 6585 | const pt = sema.pt; | 6532 | const pt = sema.pt; |
| 6586 | const mod = pt.zcu; | 6533 | const mod = pt.zcu; |
| 6587 | const ip = &mod.intern_pool; | 6534 | const ip = &mod.intern_pool; |
| 6588 | if (sema.func_index == .none) return; // does nothing outside a function | 6535 | const func = switch (sema.owner.unwrap()) { |
| 6589 | ip.funcSetDisableInstrumentation(sema.func_index); | 6536 | .func => |func| func, |
| 6537 | .cau => return, // does nothing outside a function | ||
| 6538 | }; | ||
| 6539 | ip.funcSetDisableInstrumentation(func); | ||
| 6590 | } | 6540 | } |
| 6591 | 6541 | ||
| 6592 | fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | 6542 | fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { |
| ... | @@ -6760,8 +6710,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -6760,8 +6710,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6760 | inst_data.get(sema.code), | 6710 | inst_data.get(sema.code), |
| 6761 | .no_embedded_nulls, | 6711 | .no_embedded_nulls, |
| 6762 | ); | 6712 | ); |
| 6763 | const decl_index = try sema.lookupIdentifier(block, src, decl_name); | 6713 | const nav_index = try sema.lookupIdentifier(block, src, decl_name); |
| 6764 | return sema.analyzeDeclRef(src, decl_index); | 6714 | return sema.analyzeNavRef(src, nav_index); |
| 6765 | } | 6715 | } |
| 6766 | 6716 | ||
| 6767 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6717 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -6775,17 +6725,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -6775,17 +6725,18 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 6775 | inst_data.get(sema.code), | 6725 | inst_data.get(sema.code), |
| 6776 | .no_embedded_nulls, | 6726 | .no_embedded_nulls, |
| 6777 | ); | 6727 | ); |
| 6778 | const decl = try sema.lookupIdentifier(block, src, decl_name); | 6728 | const nav = try sema.lookupIdentifier(block, src, decl_name); |
| 6779 | return sema.analyzeDeclVal(block, src, decl); | 6729 | return sema.analyzeNavVal(block, src, nav); |
| 6780 | } | 6730 | } |
| 6781 | 6731 | ||
| 6782 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.DeclIndex { | 6732 | fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.Nav.Index { |
| 6783 | const pt = sema.pt; | 6733 | const pt = sema.pt; |
| 6784 | const mod = pt.zcu; | 6734 | const mod = pt.zcu; |
| 6785 | var namespace = block.namespace; | 6735 | var namespace = block.namespace; |
| 6786 | while (true) { | 6736 | while (true) { |
| 6787 | if (try sema.lookupInNamespace(block, src, namespace.toOptional(), name, false)) |decl_index| { | 6737 | if (try sema.lookupInNamespace(block, src, namespace, name, false)) |lookup| { |
| 6788 | return decl_index; | 6738 | assert(lookup.accessible); |
| 6739 | return lookup.nav; | ||
| 6789 | } | 6740 | } |
| 6790 | namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break; | 6741 | namespace = mod.namespacePtr(namespace).parent.unwrap() orelse break; |
| 6791 | } | 6742 | } |
| ... | @@ -6798,69 +6749,74 @@ fn lookupInNamespace( | ... | @@ -6798,69 +6749,74 @@ fn lookupInNamespace( |
| 6798 | sema: *Sema, | 6749 | sema: *Sema, |
| 6799 | block: *Block, | 6750 | block: *Block, |
| 6800 | src: LazySrcLoc, | 6751 | src: LazySrcLoc, |
| 6801 | opt_namespace_index: InternPool.OptionalNamespaceIndex, | 6752 | namespace_index: InternPool.NamespaceIndex, |
| 6802 | ident_name: InternPool.NullTerminatedString, | 6753 | ident_name: InternPool.NullTerminatedString, |
| 6803 | observe_usingnamespace: bool, | 6754 | observe_usingnamespace: bool, |
| 6804 | ) CompileError!?InternPool.DeclIndex { | 6755 | ) CompileError!?struct { |
| 6756 | nav: InternPool.Nav.Index, | ||
| 6757 | /// If `false`, the declaration is in a different file and is not `pub`. | ||
| 6758 | /// We still return the declaration for better error reporting. | ||
| 6759 | accessible: bool, | ||
| 6760 | } { | ||
| 6805 | const pt = sema.pt; | 6761 | const pt = sema.pt; |
| 6806 | const mod = pt.zcu; | 6762 | const zcu = pt.zcu; |
| 6763 | const ip = &zcu.intern_pool; | ||
| 6807 | 6764 | ||
| 6808 | const namespace_index = opt_namespace_index.unwrap() orelse return null; | 6765 | const namespace = zcu.namespacePtr(namespace_index); |
| 6809 | const namespace = mod.namespacePtr(namespace_index); | ||
| 6810 | const namespace_decl = mod.declPtr(namespace.decl_index); | ||
| 6811 | if (namespace_decl.analysis == .file_failure) { | ||
| 6812 | return error.AnalysisFail; | ||
| 6813 | } | ||
| 6814 | 6766 | ||
| 6815 | if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) { | 6767 | const adapter: Zcu.Namespace.NameAdapter = .{ .zcu = zcu }; |
| 6816 | const src_file = mod.namespacePtr(block.namespace).file_scope; | ||
| 6817 | 6768 | ||
| 6769 | const src_file = zcu.namespacePtr(block.namespace).file_scope; | ||
| 6770 | |||
| 6771 | if (observe_usingnamespace and (namespace.pub_usingnamespace.items.len != 0 or namespace.priv_usingnamespace.items.len != 0)) { | ||
| 6818 | const gpa = sema.gpa; | 6772 | const gpa = sema.gpa; |
| 6819 | var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{}; | 6773 | var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{}; |
| 6820 | defer checked_namespaces.deinit(gpa); | 6774 | defer checked_namespaces.deinit(gpa); |
| 6821 | 6775 | ||
| 6822 | // Keep track of name conflicts for error notes. | 6776 | // Keep track of name conflicts for error notes. |
| 6823 | var candidates: std.ArrayListUnmanaged(InternPool.DeclIndex) = .{}; | 6777 | var candidates: std.ArrayListUnmanaged(InternPool.Nav.Index) = .{}; |
| 6824 | defer candidates.deinit(gpa); | 6778 | defer candidates.deinit(gpa); |
| 6825 | 6779 | ||
| 6826 | try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file); | 6780 | try checked_namespaces.put(gpa, namespace, {}); |
| 6827 | var check_i: usize = 0; | 6781 | var check_i: usize = 0; |
| 6828 | 6782 | ||
| 6829 | while (check_i < checked_namespaces.count()) : (check_i += 1) { | 6783 | while (check_i < checked_namespaces.count()) : (check_i += 1) { |
| 6830 | const check_ns = checked_namespaces.keys()[check_i]; | 6784 | const check_ns = checked_namespaces.keys()[check_i]; |
| 6831 | if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| { | 6785 | const Pass = enum { @"pub", priv }; |
| 6832 | // Skip decls which are not marked pub, which are in a different | 6786 | for ([2]Pass{ .@"pub", .priv }) |pass| { |
| 6833 | // file than the `a.b`/`@hasDecl` syntax. | 6787 | if (pass == .priv and src_file != check_ns.file_scope) { |
| 6834 | const decl = mod.declPtr(decl_index); | ||
| 6835 | if (decl.is_pub or (src_file == decl.getFileScopeIndex(mod) and | ||
| 6836 | checked_namespaces.values()[check_i])) | ||
| 6837 | { | ||
| 6838 | try candidates.append(gpa, decl_index); | ||
| 6839 | } | ||
| 6840 | } | ||
| 6841 | var it = check_ns.usingnamespace_set.iterator(); | ||
| 6842 | while (it.next()) |entry| { | ||
| 6843 | const sub_usingnamespace_decl_index = entry.key_ptr.*; | ||
| 6844 | // Skip the decl we're currently analysing. | ||
| 6845 | if (sub_usingnamespace_decl_index == sema.owner_decl_index) continue; | ||
| 6846 | const sub_usingnamespace_decl = mod.declPtr(sub_usingnamespace_decl_index); | ||
| 6847 | const sub_is_pub = entry.value_ptr.*; | ||
| 6848 | if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScopeIndex(mod)) { | ||
| 6849 | // Skip usingnamespace decls which are not marked pub, which are in | ||
| 6850 | // a different file than the `a.b`/`@hasDecl` syntax. | ||
| 6851 | continue; | 6788 | continue; |
| 6852 | } | 6789 | } |
| 6853 | try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index); | 6790 | |
| 6854 | const ns_ty = sub_usingnamespace_decl.val.toType(); | 6791 | const decls, const usingnamespaces = switch (pass) { |
| 6855 | const sub_ns = mod.namespacePtrUnwrap(ns_ty.getNamespaceIndex(mod)) orelse continue; | 6792 | .@"pub" => .{ &check_ns.pub_decls, &check_ns.pub_usingnamespace }, |
| 6856 | try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScopeIndex(mod)); | 6793 | .priv => .{ &check_ns.priv_decls, &check_ns.priv_usingnamespace }, |
| 6794 | }; | ||
| 6795 | |||
| 6796 | if (decls.getKeyAdapted(ident_name, adapter)) |nav_index| { | ||
| 6797 | try candidates.append(gpa, nav_index); | ||
| 6798 | } | ||
| 6799 | |||
| 6800 | for (usingnamespaces.items) |sub_ns_nav| { | ||
| 6801 | try sema.ensureNavResolved(src, sub_ns_nav); | ||
| 6802 | const sub_ns_ty = Type.fromInterned(ip.getNav(sub_ns_nav).status.resolved.val); | ||
| 6803 | const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu)); | ||
| 6804 | try checked_namespaces.put(gpa, sub_ns, {}); | ||
| 6805 | } | ||
| 6857 | } | 6806 | } |
| 6858 | } | 6807 | } |
| 6859 | 6808 | ||
| 6860 | { | 6809 | ignore_self: { |
| 6810 | const skip_nav = switch (sema.owner.unwrap()) { | ||
| 6811 | .func => break :ignore_self, | ||
| 6812 | .cau => |cau| switch (ip.getCau(cau).owner.unwrap()) { | ||
| 6813 | .none, .type => break :ignore_self, | ||
| 6814 | .nav => |nav| nav, | ||
| 6815 | }, | ||
| 6816 | }; | ||
| 6861 | var i: usize = 0; | 6817 | var i: usize = 0; |
| 6862 | while (i < candidates.items.len) { | 6818 | while (i < candidates.items.len) { |
| 6863 | if (candidates.items[i] == sema.owner_decl_index) { | 6819 | if (candidates.items[i] == skip_nav) { |
| 6864 | _ = candidates.orderedRemove(i); | 6820 | _ = candidates.orderedRemove(i); |
| 6865 | } else { | 6821 | } else { |
| 6866 | i += 1; | 6822 | i += 1; |
| ... | @@ -6870,48 +6826,50 @@ fn lookupInNamespace( | ... | @@ -6870,48 +6826,50 @@ fn lookupInNamespace( |
| 6870 | 6826 | ||
| 6871 | switch (candidates.items.len) { | 6827 | switch (candidates.items.len) { |
| 6872 | 0 => {}, | 6828 | 0 => {}, |
| 6873 | 1 => { | 6829 | 1 => return .{ |
| 6874 | const decl_index = candidates.items[0]; | 6830 | .nav = candidates.items[0], |
| 6875 | return decl_index; | 6831 | .accessible = true, |
| 6876 | }, | ||
| 6877 | else => { | ||
| 6878 | const msg = msg: { | ||
| 6879 | const msg = try sema.errMsg(src, "ambiguous reference", .{}); | ||
| 6880 | errdefer msg.destroy(gpa); | ||
| 6881 | for (candidates.items) |candidate_index| { | ||
| 6882 | const candidate = mod.declPtr(candidate_index); | ||
| 6883 | try sema.errNote(.{ | ||
| 6884 | .base_node_inst = candidate.zir_decl_index.unwrap().?, | ||
| 6885 | .offset = LazySrcLoc.Offset.nodeOffset(0), | ||
| 6886 | }, msg, "declared here", .{}); | ||
| 6887 | } | ||
| 6888 | break :msg msg; | ||
| 6889 | }; | ||
| 6890 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 6891 | }, | 6832 | }, |
| 6833 | else => return sema.failWithOwnedErrorMsg(block, msg: { | ||
| 6834 | const msg = try sema.errMsg(src, "ambiguous reference", .{}); | ||
| 6835 | errdefer msg.destroy(gpa); | ||
| 6836 | for (candidates.items) |candidate| { | ||
| 6837 | try sema.errNote(zcu.navSrcLoc(candidate), msg, "declared here", .{}); | ||
| 6838 | } | ||
| 6839 | break :msg msg; | ||
| 6840 | }), | ||
| 6892 | } | 6841 | } |
| 6893 | } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| { | 6842 | } else if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| { |
| 6894 | return decl_index; | 6843 | return .{ |
| 6844 | .nav = nav_index, | ||
| 6845 | .accessible = true, | ||
| 6846 | }; | ||
| 6847 | } else if (namespace.priv_decls.getKeyAdapted(ident_name, adapter)) |nav_index| { | ||
| 6848 | return .{ | ||
| 6849 | .nav = nav_index, | ||
| 6850 | .accessible = src_file == namespace.file_scope, | ||
| 6851 | }; | ||
| 6895 | } | 6852 | } |
| 6896 | 6853 | ||
| 6897 | return null; | 6854 | return null; |
| 6898 | } | 6855 | } |
| 6899 | 6856 | ||
| 6900 | fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { | 6857 | fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedInst.Index { |
| 6901 | const pt = sema.pt; | 6858 | const pt = sema.pt; |
| 6902 | const mod = pt.zcu; | 6859 | const zcu = pt.zcu; |
| 6903 | const func_val = (try sema.resolveValue(func_inst)) orelse return null; | 6860 | const ip = &zcu.intern_pool; |
| 6904 | if (func_val.isUndef(mod)) return null; | 6861 | const func_val = try sema.resolveValue(func_inst) orelse return null; |
| 6905 | const owner_decl_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { | 6862 | if (func_val.isUndef(zcu)) return null; |
| 6906 | .extern_func => |extern_func| extern_func.decl, | 6863 | const nav = switch (ip.indexToKey(func_val.toIntern())) { |
| 6907 | .func => |func| func.owner_decl, | 6864 | .@"extern" => |e| e.owner_nav, |
| 6865 | .func => |f| f.owner_nav, | ||
| 6908 | .ptr => |ptr| switch (ptr.base_addr) { | 6866 | .ptr => |ptr| switch (ptr.base_addr) { |
| 6909 | .decl => |decl| if (ptr.byte_offset == 0) mod.declPtr(decl).val.getFunction(mod).?.owner_decl else return null, | 6867 | .nav => |nav| if (ptr.byte_offset == 0) nav else return null, |
| 6910 | else => return null, | 6868 | else => return null, |
| 6911 | }, | 6869 | }, |
| 6912 | else => return null, | 6870 | else => return null, |
| 6913 | }; | 6871 | }; |
| 6914 | return mod.declPtr(owner_decl_index); | 6872 | return ip.getNav(nav).srcInst(ip); |
| 6915 | } | 6873 | } |
| 6916 | 6874 | ||
| 6917 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { | 6875 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { |
| ... | @@ -7100,11 +7058,12 @@ fn zirCall( | ... | @@ -7100,11 +7058,12 @@ fn zirCall( |
| 7100 | const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1); | 7058 | const call_dbg_node: Zir.Inst.Index = @enumFromInt(@intFromEnum(inst) - 1); |
| 7101 | const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call); | 7059 | const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call); |
| 7102 | 7060 | ||
| 7103 | if (sema.owner_func_index == .none or | 7061 | switch (sema.owner.unwrap()) { |
| 7104 | !mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) | 7062 | .cau => input_is_error = false, |
| 7105 | { | 7063 | .func => |owner_func| if (!mod.intern_pool.funcAnalysisUnordered(owner_func).calls_or_awaits_errorable_fn) { |
| 7106 | // No errorable fn actually called; we have no error return trace | 7064 | // No errorable fn actually called; we have no error return trace |
| 7107 | input_is_error = false; | 7065 | input_is_error = false; |
| 7066 | }, | ||
| 7108 | } | 7067 | } |
| 7109 | 7068 | ||
| 7110 | if (block.ownerModule().error_tracing and | 7069 | if (block.ownerModule().error_tracing and |
| ... | @@ -7199,7 +7158,7 @@ fn checkCallArgumentCount( | ... | @@ -7199,7 +7158,7 @@ fn checkCallArgumentCount( |
| 7199 | return func_ty; | 7158 | return func_ty; |
| 7200 | } | 7159 | } |
| 7201 | 7160 | ||
| 7202 | const maybe_decl = try sema.funcDeclSrc(func); | 7161 | const maybe_func_inst = try sema.funcDeclSrcInst(func); |
| 7203 | const member_str = if (member_fn) "member function " else ""; | 7162 | const member_str = if (member_fn) "member function " else ""; |
| 7204 | const variadic_str = if (func_ty_info.is_var_args) "at least " else ""; | 7163 | const variadic_str = if (func_ty_info.is_var_args) "at least " else ""; |
| 7205 | const msg = msg: { | 7164 | const msg = msg: { |
| ... | @@ -7215,9 +7174,9 @@ fn checkCallArgumentCount( | ... | @@ -7215,9 +7174,9 @@ fn checkCallArgumentCount( |
| 7215 | ); | 7174 | ); |
| 7216 | errdefer msg.destroy(sema.gpa); | 7175 | errdefer msg.destroy(sema.gpa); |
| 7217 | 7176 | ||
| 7218 | if (maybe_decl) |fn_decl| { | 7177 | if (maybe_func_inst) |func_inst| { |
| 7219 | try sema.errNote(.{ | 7178 | try sema.errNote(.{ |
| 7220 | .base_node_inst = fn_decl.zir_decl_index.unwrap().?, | 7179 | .base_node_inst = func_inst, |
| 7221 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 7180 | .offset = LazySrcLoc.Offset.nodeOffset(0), |
| 7222 | }, msg, "function declared here", .{}); | 7181 | }, msg, "function declared here", .{}); |
| 7223 | } | 7182 | } |
| ... | @@ -7544,7 +7503,7 @@ fn analyzeCall( | ... | @@ -7544,7 +7503,7 @@ fn analyzeCall( |
| 7544 | if (func_val.isUndef(mod)) | 7503 | if (func_val.isUndef(mod)) |
| 7545 | return sema.failWithUseOfUndef(block, call_src); | 7504 | return sema.failWithUseOfUndef(block, call_src); |
| 7546 | if (cc == .Naked) { | 7505 | if (cc == .Naked) { |
| 7547 | const maybe_decl = try sema.funcDeclSrc(func); | 7506 | const maybe_func_inst = try sema.funcDeclSrcInst(func); |
| 7548 | const msg = msg: { | 7507 | const msg = msg: { |
| 7549 | const msg = try sema.errMsg( | 7508 | const msg = try sema.errMsg( |
| 7550 | func_src, | 7509 | func_src, |
| ... | @@ -7553,8 +7512,8 @@ fn analyzeCall( | ... | @@ -7553,8 +7512,8 @@ fn analyzeCall( |
| 7553 | ); | 7512 | ); |
| 7554 | errdefer msg.destroy(sema.gpa); | 7513 | errdefer msg.destroy(sema.gpa); |
| 7555 | 7514 | ||
| 7556 | if (maybe_decl) |fn_decl| try sema.errNote(.{ | 7515 | if (maybe_func_inst) |func_inst| try sema.errNote(.{ |
| 7557 | .base_node_inst = fn_decl.zir_decl_index.unwrap().?, | 7516 | .base_node_inst = func_inst, |
| 7558 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 7517 | .offset = LazySrcLoc.Offset.nodeOffset(0), |
| 7559 | }, msg, "function declared here", .{}); | 7518 | }, msg, "function declared here", .{}); |
| 7560 | break :msg msg; | 7519 | break :msg msg; |
| ... | @@ -7654,33 +7613,32 @@ fn analyzeCall( | ... | @@ -7654,33 +7613,32 @@ fn analyzeCall( |
| 7654 | .block_comptime_reason = comptime_reason, | 7613 | .block_comptime_reason = comptime_reason, |
| 7655 | }); | 7614 | }); |
| 7656 | const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { | 7615 | const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { |
| 7657 | .extern_func => return sema.fail(block, call_src, "{s} call of extern function", .{ | 7616 | .@"extern" => return sema.fail(block, call_src, "{s} call of extern function", .{ |
| 7658 | @as([]const u8, if (is_comptime_call) "comptime" else "inline"), | 7617 | @as([]const u8, if (is_comptime_call) "comptime" else "inline"), |
| 7659 | }), | 7618 | }), |
| 7660 | .func => func_val.toIntern(), | 7619 | .func => func_val.toIntern(), |
| 7661 | .ptr => |ptr| blk: { | 7620 | .ptr => |ptr| blk: { |
| 7662 | switch (ptr.base_addr) { | 7621 | switch (ptr.base_addr) { |
| 7663 | .decl => |decl| if (ptr.byte_offset == 0) { | 7622 | .nav => |nav_index| if (ptr.byte_offset == 0) { |
| 7664 | const func_val_ptr = mod.declPtr(decl).val.toIntern(); | 7623 | const nav = ip.getNav(nav_index); |
| 7665 | const intern_index = mod.intern_pool.indexToKey(func_val_ptr); | 7624 | if (nav.isExtern(ip)) |
| 7666 | if (intern_index == .extern_func or (intern_index == .variable and intern_index.variable.is_extern)) | ||
| 7667 | return sema.fail(block, call_src, "{s} call of extern function pointer", .{ | 7625 | return sema.fail(block, call_src, "{s} call of extern function pointer", .{ |
| 7668 | @as([]const u8, if (is_comptime_call) "comptime" else "inline"), | 7626 | if (is_comptime_call) "comptime" else "inline", |
| 7669 | }); | 7627 | }); |
| 7670 | break :blk func_val_ptr; | 7628 | break :blk nav.status.resolved.val; |
| 7671 | }, | 7629 | }, |
| 7672 | else => {}, | 7630 | else => {}, |
| 7673 | } | 7631 | } |
| 7674 | assert(callee_ty.isPtrAtRuntime(mod)); | 7632 | assert(callee_ty.isPtrAtRuntime(mod)); |
| 7675 | return sema.fail(block, call_src, "{s} call of function pointer", .{ | 7633 | return sema.fail(block, call_src, "{s} call of function pointer", .{ |
| 7676 | @as([]const u8, if (is_comptime_call) "comptime" else "inline"), | 7634 | if (is_comptime_call) "comptime" else "inline", |
| 7677 | }); | 7635 | }); |
| 7678 | }, | 7636 | }, |
| 7679 | else => unreachable, | 7637 | else => unreachable, |
| 7680 | }; | 7638 | }; |
| 7681 | if (func_ty_info.is_var_args) { | 7639 | if (func_ty_info.is_var_args) { |
| 7682 | return sema.fail(block, call_src, "{s} call of variadic function", .{ | 7640 | return sema.fail(block, call_src, "{s} call of variadic function", .{ |
| 7683 | @as([]const u8, if (is_comptime_call) "comptime" else "inline"), | 7641 | if (is_comptime_call) "comptime" else "inline", |
| 7684 | }); | 7642 | }); |
| 7685 | } | 7643 | } |
| 7686 | 7644 | ||
| ... | @@ -7712,7 +7670,12 @@ fn analyzeCall( | ... | @@ -7712,7 +7670,12 @@ fn analyzeCall( |
| 7712 | }; | 7670 | }; |
| 7713 | 7671 | ||
| 7714 | const module_fn = mod.funcInfo(module_fn_index); | 7672 | const module_fn = mod.funcInfo(module_fn_index); |
| 7715 | const fn_owner_decl = mod.declPtr(module_fn.owner_decl); | 7673 | |
| 7674 | // This is not a function instance, so the function's `Nav` has a | ||
| 7675 | // `Cau` -- we don't need to check `generic_owner`. | ||
| 7676 | const fn_nav = ip.getNav(module_fn.owner_nav); | ||
| 7677 | const fn_cau_index = fn_nav.analysis_owner.unwrap().?; | ||
| 7678 | const fn_cau = ip.getCau(fn_cau_index); | ||
| 7716 | 7679 | ||
| 7717 | // We effectively want a child Sema here, but can't literally do that, because we need AIR | 7680 | // 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 | 7681 | // to be shared. InlineCallSema is a wrapper which handles this for us. While `ics` is in |
| ... | @@ -7720,7 +7683,7 @@ fn analyzeCall( | ... | @@ -7720,7 +7683,7 @@ fn analyzeCall( |
| 7720 | // whenever performing an operation where the difference matters. | 7683 | // whenever performing an operation where the difference matters. |
| 7721 | var ics = InlineCallSema.init( | 7684 | var ics = InlineCallSema.init( |
| 7722 | sema, | 7685 | sema, |
| 7723 | fn_owner_decl.getFileScope(mod).zir, | 7686 | mod.cauFileScope(fn_cau_index).zir, |
| 7724 | module_fn_index, | 7687 | module_fn_index, |
| 7725 | block.error_return_trace_index, | 7688 | block.error_return_trace_index, |
| 7726 | ); | 7689 | ); |
| ... | @@ -7729,7 +7692,8 @@ fn analyzeCall( | ... | @@ -7729,7 +7692,8 @@ fn analyzeCall( |
| 7729 | var child_block: Block = .{ | 7692 | var child_block: Block = .{ |
| 7730 | .parent = null, | 7693 | .parent = null, |
| 7731 | .sema = sema, | 7694 | .sema = sema, |
| 7732 | .namespace = fn_owner_decl.src_namespace, | 7695 | // The function body exists in the same namespace as the corresponding function declaration. |
| 7696 | .namespace = fn_cau.namespace, | ||
| 7733 | .instructions = .{}, | 7697 | .instructions = .{}, |
| 7734 | .label = null, | 7698 | .label = null, |
| 7735 | .inlining = &inlining, | 7699 | .inlining = &inlining, |
| ... | @@ -7740,8 +7704,8 @@ fn analyzeCall( | ... | @@ -7740,8 +7704,8 @@ fn analyzeCall( |
| 7740 | .runtime_cond = block.runtime_cond, | 7704 | .runtime_cond = block.runtime_cond, |
| 7741 | .runtime_loop = block.runtime_loop, | 7705 | .runtime_loop = block.runtime_loop, |
| 7742 | .runtime_index = block.runtime_index, | 7706 | .runtime_index = block.runtime_index, |
| 7743 | .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?, | 7707 | .src_base_inst = fn_cau.zir_index, |
| 7744 | .type_name_ctx = fn_owner_decl.name, | 7708 | .type_name_ctx = fn_nav.fqn, |
| 7745 | }; | 7709 | }; |
| 7746 | 7710 | ||
| 7747 | const merges = &child_block.inlining.?.merges; | 7711 | const merges = &child_block.inlining.?.merges; |
| ... | @@ -7759,7 +7723,7 @@ fn analyzeCall( | ... | @@ -7759,7 +7723,7 @@ fn analyzeCall( |
| 7759 | // comptime memory is mutated. | 7723 | // comptime memory is mutated. |
| 7760 | const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); | 7724 | const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| 7761 | 7725 | ||
| 7762 | const owner_info = mod.typeToFunc(fn_owner_decl.typeOf(mod)).?; | 7726 | const owner_info = mod.typeToFunc(Type.fromInterned(module_fn.ty)).?; |
| 7763 | const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len); | 7727 | const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len); |
| 7764 | var new_fn_info: InternPool.GetFuncTypeKey = .{ | 7728 | var new_fn_info: InternPool.GetFuncTypeKey = .{ |
| 7765 | .param_types = new_param_types, | 7729 | .param_types = new_param_types, |
| ... | @@ -7809,9 +7773,6 @@ fn analyzeCall( | ... | @@ -7809,9 +7773,6 @@ fn analyzeCall( |
| 7809 | _ = ics.callee(); | 7773 | _ = ics.callee(); |
| 7810 | 7774 | ||
| 7811 | if (!inlining.has_comptime_args) { | 7775 | if (!inlining.has_comptime_args) { |
| 7812 | if (module_fn.analysisUnordered(ip).state == .sema_failure) | ||
| 7813 | return error.AnalysisFail; | ||
| 7814 | |||
| 7815 | var block_it = block; | 7776 | var block_it = block; |
| 7816 | while (block_it.inlining) |parent_inlining| { | 7777 | while (block_it.inlining) |parent_inlining| { |
| 7817 | if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) { | 7778 | if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) { |
| ... | @@ -7957,8 +7918,11 @@ fn analyzeCall( | ... | @@ -7957,8 +7918,11 @@ fn analyzeCall( |
| 7957 | 7918 | ||
| 7958 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); | 7919 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); |
| 7959 | 7920 | ||
| 7960 | if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) { | 7921 | switch (sema.owner.unwrap()) { |
| 7961 | ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index); | 7922 | .cau => {}, |
| 7923 | .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(mod)) { | ||
| 7924 | ip.funcSetCallsOrAwaitsErrorableFn(owner_func); | ||
| 7925 | }, | ||
| 7962 | } | 7926 | } |
| 7963 | 7927 | ||
| 7964 | if (try sema.resolveValue(func)) |func_val| { | 7928 | if (try sema.resolveValue(func)) |func_val| { |
| ... | @@ -7994,7 +7958,7 @@ fn analyzeCall( | ... | @@ -7994,7 +7958,7 @@ fn analyzeCall( |
| 7994 | switch (mod.intern_pool.indexToKey(func_val.toIntern())) { | 7958 | switch (mod.intern_pool.indexToKey(func_val.toIntern())) { |
| 7995 | .func => break :skip_safety, | 7959 | .func => break :skip_safety, |
| 7996 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { | 7960 | .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) { |
| 7997 | .decl => |decl| if (!mod.declPtr(decl).isExtern(mod)) break :skip_safety, | 7961 | .nav => |nav| if (!ip.getNav(nav).isExtern(ip)) break :skip_safety, |
| 7998 | else => {}, | 7962 | else => {}, |
| 7999 | }, | 7963 | }, |
| 8000 | else => {}, | 7964 | else => {}, |
| ... | @@ -8018,18 +7982,18 @@ fn analyzeCall( | ... | @@ -8018,18 +7982,18 @@ fn analyzeCall( |
| 8018 | 7982 | ||
| 8019 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { | 7983 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { |
| 8020 | const pt = sema.pt; | 7984 | const pt = sema.pt; |
| 8021 | const mod = pt.zcu; | 7985 | const zcu = pt.zcu; |
| 8022 | const target = mod.getTarget(); | 7986 | const target = zcu.getTarget(); |
| 8023 | const backend = mod.comp.getZigBackend(); | 7987 | const backend = zcu.comp.getZigBackend(); |
| 8024 | if (!target_util.supportsTailCall(target, backend)) { | 7988 | if (!target_util.supportsTailCall(target, backend)) { |
| 8025 | return sema.fail(block, call_src, "unable to perform tail call: compiler backend '{s}' does not support tail calls on target architecture '{s}' with the selected CPU feature flags", .{ | 7989 | return sema.fail(block, call_src, "unable to perform tail call: compiler backend '{s}' does not support tail calls on target architecture '{s}' with the selected CPU feature flags", .{ |
| 8026 | @tagName(backend), @tagName(target.cpu.arch), | 7990 | @tagName(backend), @tagName(target.cpu.arch), |
| 8027 | }); | 7991 | }); |
| 8028 | } | 7992 | } |
| 8029 | const func_decl = mod.funcOwnerDeclPtr(sema.owner_func_index); | 7993 | const owner_func_ty = Type.fromInterned(zcu.funcInfo(sema.owner.unwrap().func).ty); |
| 8030 | if (!func_ty.eql(func_decl.typeOf(mod), mod)) { | 7994 | if (owner_func_ty.toIntern() != func_ty.toIntern()) { |
| 8031 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ | 7995 | return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ |
| 8032 | func_ty.fmt(pt), func_decl.typeOf(mod).fmt(pt), | 7996 | func_ty.fmt(pt), owner_func_ty.fmt(pt), |
| 8033 | }); | 7997 | }); |
| 8034 | } | 7998 | } |
| 8035 | _ = try block.addUnOp(.ret, result); | 7999 | _ = try block.addUnOp(.ret, result); |
| ... | @@ -8191,7 +8155,7 @@ fn instantiateGenericCall( | ... | @@ -8191,7 +8155,7 @@ fn instantiateGenericCall( |
| 8191 | }); | 8155 | }); |
| 8192 | const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) { | 8156 | const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) { |
| 8193 | .func => func_val.toIntern(), | 8157 | .func => func_val.toIntern(), |
| 8194 | .ptr => |ptr| zcu.declPtr(ptr.base_addr.decl).val.toIntern(), | 8158 | .ptr => |ptr| ip.getNav(ptr.base_addr.nav).status.resolved.val, |
| 8195 | else => unreachable, | 8159 | else => unreachable, |
| 8196 | }; | 8160 | }; |
| 8197 | const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func; | 8161 | const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func; |
| ... | @@ -8207,10 +8171,10 @@ fn instantiateGenericCall( | ... | @@ -8207,10 +8171,10 @@ fn instantiateGenericCall( |
| 8207 | // The actual monomorphization happens via adding `func_instance` to | 8171 | // The actual monomorphization happens via adding `func_instance` to |
| 8208 | // `InternPool`. | 8172 | // `InternPool`. |
| 8209 | 8173 | ||
| 8210 | const fn_owner_decl = zcu.declPtr(generic_owner_func.owner_decl); | 8174 | // Since we are looking at the generic owner here, it has a `Cau`. |
| 8211 | const namespace_index = fn_owner_decl.src_namespace; | 8175 | const fn_nav = ip.getNav(generic_owner_func.owner_nav); |
| 8212 | const namespace = zcu.namespacePtr(namespace_index); | 8176 | const fn_cau = ip.getCau(fn_nav.analysis_owner.unwrap().?); |
| 8213 | const fn_zir = namespace.fileScope(zcu).zir; | 8177 | const fn_zir = zcu.namespacePtr(fn_cau.namespace).fileScope(zcu).zir; |
| 8214 | const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip)); | 8178 | const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip)); |
| 8215 | 8179 | ||
| 8216 | const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count()); | 8180 | const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count()); |
| ... | @@ -8232,15 +8196,13 @@ fn instantiateGenericCall( | ... | @@ -8232,15 +8196,13 @@ fn instantiateGenericCall( |
| 8232 | // We pass the generic callsite's owner decl here because whatever `Decl` | 8196 | // We pass the generic callsite's owner decl here because whatever `Decl` |
| 8233 | // dependencies are chased at this point should be attached to the | 8197 | // dependencies are chased at this point should be attached to the |
| 8234 | // callsite, not the `Decl` associated with the `func_instance`. | 8198 | // callsite, not the `Decl` associated with the `func_instance`. |
| 8235 | .owner_decl = sema.owner_decl, | 8199 | .owner = sema.owner, |
| 8236 | .owner_decl_index = sema.owner_decl_index, | 8200 | .func_index = sema.func_index, |
| 8237 | .func_index = sema.owner_func_index, | ||
| 8238 | // This may not be known yet, since the calling convention could be generic, but there | 8201 | // This may not be known yet, since the calling convention could be generic, but there |
| 8239 | // should be no illegal instructions encountered while creating the function anyway. | 8202 | // should be no illegal instructions encountered while creating the function anyway. |
| 8240 | .func_is_naked = false, | 8203 | .func_is_naked = false, |
| 8241 | .fn_ret_ty = Type.void, | 8204 | .fn_ret_ty = Type.void, |
| 8242 | .fn_ret_ty_ies = null, | 8205 | .fn_ret_ty_ies = null, |
| 8243 | .owner_func_index = .none, | ||
| 8244 | .comptime_args = comptime_args, | 8206 | .comptime_args = comptime_args, |
| 8245 | .generic_owner = generic_owner, | 8207 | .generic_owner = generic_owner, |
| 8246 | .generic_call_src = call_src, | 8208 | .generic_call_src = call_src, |
| ... | @@ -8253,12 +8215,12 @@ fn instantiateGenericCall( | ... | @@ -8253,12 +8215,12 @@ fn instantiateGenericCall( |
| 8253 | var child_block: Block = .{ | 8215 | var child_block: Block = .{ |
| 8254 | .parent = null, | 8216 | .parent = null, |
| 8255 | .sema = &child_sema, | 8217 | .sema = &child_sema, |
| 8256 | .namespace = namespace_index, | 8218 | .namespace = fn_cau.namespace, |
| 8257 | .instructions = .{}, | 8219 | .instructions = .{}, |
| 8258 | .inlining = null, | 8220 | .inlining = null, |
| 8259 | .is_comptime = true, | 8221 | .is_comptime = true, |
| 8260 | .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?, | 8222 | .src_base_inst = fn_cau.zir_index, |
| 8261 | .type_name_ctx = fn_owner_decl.name, | 8223 | .type_name_ctx = fn_nav.fqn, |
| 8262 | }; | 8224 | }; |
| 8263 | defer child_block.instructions.deinit(gpa); | 8225 | defer child_block.instructions.deinit(gpa); |
| 8264 | 8226 | ||
| ... | @@ -8421,10 +8383,11 @@ fn instantiateGenericCall( | ... | @@ -8421,10 +8383,11 @@ fn instantiateGenericCall( |
| 8421 | 8383 | ||
| 8422 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); | 8384 | if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); |
| 8423 | 8385 | ||
| 8424 | if (sema.owner_func_index != .none and | 8386 | switch (sema.owner.unwrap()) { |
| 8425 | Type.fromInterned(func_ty_info.return_type).isError(zcu)) | 8387 | .cau => {}, |
| 8426 | { | 8388 | .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) { |
| 8427 | ip.funcSetCallsOrAwaitsErrorableFn(sema.owner_func_index); | 8389 | ip.funcSetCallsOrAwaitsErrorableFn(owner_func); |
| 8390 | }, | ||
| 8428 | } | 8391 | } |
| 8429 | 8392 | ||
| 8430 | try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index })); | 8393 | try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index })); |
| ... | @@ -9366,10 +9329,11 @@ fn zirFunc( | ... | @@ -9366,10 +9329,11 @@ fn zirFunc( |
| 9366 | inferred_error_set: bool, | 9329 | inferred_error_set: bool, |
| 9367 | ) CompileError!Air.Inst.Ref { | 9330 | ) CompileError!Air.Inst.Ref { |
| 9368 | const pt = sema.pt; | 9331 | const pt = sema.pt; |
| 9369 | const mod = pt.zcu; | 9332 | const zcu = pt.zcu; |
| 9333 | const ip = &zcu.intern_pool; | ||
| 9370 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; | 9334 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; |
| 9371 | const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index); | 9335 | const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index); |
| 9372 | const target = mod.getTarget(); | 9336 | const target = zcu.getTarget(); |
| 9373 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node }); | 9337 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node }); |
| 9374 | 9338 | ||
| 9375 | var extra_index = extra.end; | 9339 | var extra_index = extra.end; |
| ... | @@ -9410,11 +9374,17 @@ fn zirFunc( | ... | @@ -9410,11 +9374,17 @@ fn zirFunc( |
| 9410 | // the callconv based on whether it is exported. Otherwise, the callconv defaults | 9374 | // the callconv based on whether it is exported. Otherwise, the callconv defaults |
| 9411 | // to `.Unspecified`. | 9375 | // to `.Unspecified`. |
| 9412 | const cc: std.builtin.CallingConvention = if (has_body) cc: { | 9376 | const cc: std.builtin.CallingConvention = if (has_body) cc: { |
| 9413 | const fn_is_exported = if (sema.generic_owner != .none) exported: { | 9377 | const func_decl_cau = if (sema.generic_owner != .none) cau: { |
| 9414 | const generic_owner_fn = mod.funcInfo(sema.generic_owner); | 9378 | const generic_owner_fn = zcu.funcInfo(sema.generic_owner); |
| 9415 | const generic_owner_decl = mod.declPtr(generic_owner_fn.owner_decl); | 9379 | // The generic owner definitely has a `Cau` for the corresponding function declaration. |
| 9416 | break :exported generic_owner_decl.is_exported; | 9380 | const generic_owner_nav = ip.getNav(generic_owner_fn.owner_nav); |
| 9417 | } else sema.owner_decl.is_exported; | 9381 | break :cau generic_owner_nav.analysis_owner.unwrap().?; |
| 9382 | } else sema.owner.unwrap().cau; | ||
| 9383 | const fn_is_exported = exported: { | ||
| 9384 | const decl_inst = ip.getCau(func_decl_cau).zir_index.resolve(ip); | ||
| 9385 | const zir_decl = sema.code.getDeclaration(decl_inst)[0]; | ||
| 9386 | break :exported zir_decl.flags.is_export; | ||
| 9387 | }; | ||
| 9418 | break :cc if (fn_is_exported) .C else .Unspecified; | 9388 | break :cc if (fn_is_exported) .C else .Unspecified; |
| 9419 | } else .Unspecified; | 9389 | } else .Unspecified; |
| 9420 | 9390 | ||
| ... | @@ -9613,10 +9583,10 @@ fn funcCommon( | ... | @@ -9613,10 +9583,10 @@ fn funcCommon( |
| 9613 | is_noinline: bool, | 9583 | is_noinline: bool, |
| 9614 | ) CompileError!Air.Inst.Ref { | 9584 | ) CompileError!Air.Inst.Ref { |
| 9615 | const pt = sema.pt; | 9585 | const pt = sema.pt; |
| 9616 | const mod = pt.zcu; | 9586 | const zcu = pt.zcu; |
| 9617 | const gpa = sema.gpa; | 9587 | const gpa = sema.gpa; |
| 9618 | const target = mod.getTarget(); | 9588 | const target = zcu.getTarget(); |
| 9619 | const ip = &mod.intern_pool; | 9589 | const ip = &zcu.intern_pool; |
| 9620 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset }); | 9590 | const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset }); |
| 9621 | const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset }); | 9591 | const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset }); |
| 9622 | const func_src = block.nodeOffset(src_node_offset); | 9592 | const func_src = block.nodeOffset(src_node_offset); |
| ... | @@ -9664,8 +9634,8 @@ fn funcCommon( | ... | @@ -9664,8 +9634,8 @@ fn funcCommon( |
| 9664 | if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) { | 9634 | if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) { |
| 9665 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); | 9635 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); |
| 9666 | } | 9636 | } |
| 9667 | if (!param_ty.isValidParamType(mod)) { | 9637 | if (!param_ty.isValidParamType(zcu)) { |
| 9668 | const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else ""; | 9638 | const opaque_str = if (param_ty.zigTypeTag(zcu) == .Opaque) "opaque " else ""; |
| 9669 | return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{ | 9639 | return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{ |
| 9670 | opaque_str, param_ty.fmt(pt), | 9640 | opaque_str, param_ty.fmt(pt), |
| 9671 | }); | 9641 | }); |
| ... | @@ -9699,7 +9669,7 @@ fn funcCommon( | ... | @@ -9699,7 +9669,7 @@ fn funcCommon( |
| 9699 | return sema.failWithOwnedErrorMsg(block, msg); | 9669 | return sema.failWithOwnedErrorMsg(block, msg); |
| 9700 | } | 9670 | } |
| 9701 | if (is_source_decl and !this_generic and is_noalias and | 9671 | if (is_source_decl and !this_generic and is_noalias and |
| 9702 | !(param_ty.zigTypeTag(mod) == .Pointer or param_ty.isPtrLikeOptional(mod))) | 9672 | !(param_ty.zigTypeTag(zcu) == .Pointer or param_ty.isPtrLikeOptional(zcu))) |
| 9703 | { | 9673 | { |
| 9704 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); | 9674 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); |
| 9705 | } | 9675 | } |
| ... | @@ -9707,7 +9677,7 @@ fn funcCommon( | ... | @@ -9707,7 +9677,7 @@ fn funcCommon( |
| 9707 | .Interrupt => if (target.cpu.arch.isX86()) { | 9677 | .Interrupt => if (target.cpu.arch.isX86()) { |
| 9708 | const err_code_size = target.ptrBitWidth(); | 9678 | const err_code_size = target.ptrBitWidth(); |
| 9709 | switch (i) { | 9679 | switch (i) { |
| 9710 | 0 => if (param_ty.zigTypeTag(mod) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}), | 9680 | 0 => if (param_ty.zigTypeTag(zcu) != .Pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}), |
| 9711 | 1 => if (param_ty.bitSize(pt) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), | 9681 | 1 => if (param_ty.bitSize(pt) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), |
| 9712 | else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}), | 9682 | else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}), |
| 9713 | } | 9683 | } |
| ... | @@ -9769,14 +9739,11 @@ fn funcCommon( | ... | @@ -9769,14 +9739,11 @@ fn funcCommon( |
| 9769 | ); | 9739 | ); |
| 9770 | } | 9740 | } |
| 9771 | 9741 | ||
| 9772 | // extern_func and func_decl functions take ownership of `sema.owner_decl`. | 9742 | const section_name: InternPool.OptionalNullTerminatedString = switch (section) { |
| 9773 | sema.owner_decl.@"linksection" = switch (section) { | ||
| 9774 | .generic => .none, | 9743 | .generic => .none, |
| 9775 | .default => .none, | 9744 | .default => .none, |
| 9776 | .explicit => |section_name| section_name.toOptional(), | 9745 | .explicit => |name| name.toOptional(), |
| 9777 | }; | 9746 | }; |
| 9778 | sema.owner_decl.alignment = alignment orelse .none; | ||
| 9779 | sema.owner_decl.@"addrspace" = address_space orelse .generic; | ||
| 9780 | 9747 | ||
| 9781 | if (inferred_error_set) { | 9748 | if (inferred_error_set) { |
| 9782 | assert(!is_extern); | 9749 | assert(!is_extern); |
| ... | @@ -9784,7 +9751,7 @@ fn funcCommon( | ... | @@ -9784,7 +9751,7 @@ fn funcCommon( |
| 9784 | if (!ret_poison) | 9751 | if (!ret_poison) |
| 9785 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); | 9752 | try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src); |
| 9786 | const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{ | 9753 | const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{ |
| 9787 | .owner_decl = sema.owner_decl_index, | 9754 | .owner_nav = sema.getOwnerCauNav(), |
| 9788 | 9755 | ||
| 9789 | .param_types = param_types, | 9756 | .param_types = param_types, |
| 9790 | .noalias_bits = noalias_bits, | 9757 | .noalias_bits = noalias_bits, |
| ... | @@ -9804,6 +9771,13 @@ fn funcCommon( | ... | @@ -9804,6 +9771,13 @@ fn funcCommon( |
| 9804 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), | 9771 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| 9805 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), | 9772 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), |
| 9806 | }); | 9773 | }); |
| 9774 | // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`. | ||
| 9775 | ip.resolveNavValue(sema.getOwnerCauNav(), .{ | ||
| 9776 | .val = func_index, | ||
| 9777 | .alignment = alignment orelse .none, | ||
| 9778 | .@"linksection" = section_name, | ||
| 9779 | .@"addrspace" = address_space orelse .generic, | ||
| 9780 | }); | ||
| 9807 | return finishFunc( | 9781 | return finishFunc( |
| 9808 | sema, | 9782 | sema, |
| 9809 | block, | 9783 | block, |
| ... | @@ -9846,11 +9820,20 @@ fn funcCommon( | ... | @@ -9846,11 +9820,20 @@ fn funcCommon( |
| 9846 | if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{ | 9820 | if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{ |
| 9847 | .node_offset_lib_name = src_node_offset, | 9821 | .node_offset_lib_name = src_node_offset, |
| 9848 | }), lib_name); | 9822 | }), lib_name); |
| 9849 | const func_index = try ip.getExternFunc(gpa, pt.tid, .{ | 9823 | const func_index = try pt.getExtern(.{ |
| 9824 | .name = sema.getOwnerCauNavName(), | ||
| 9850 | .ty = func_ty, | 9825 | .ty = func_ty, |
| 9851 | .decl = sema.owner_decl_index, | 9826 | .lib_name = try ip.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls), |
| 9852 | .lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, pt.tid, opt_lib_name, .no_embedded_nulls), | 9827 | .is_const = true, |
| 9828 | .is_threadlocal = false, | ||
| 9829 | .is_weak_linkage = false, | ||
| 9830 | .alignment = alignment orelse .none, | ||
| 9831 | .@"addrspace" = address_space orelse .generic, | ||
| 9832 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | ||
| 9833 | .owner_nav = undefined, // ignored by `getExtern` | ||
| 9853 | }); | 9834 | }); |
| 9835 | // Note that unlike function declaration, extern functions don't touch the | ||
| 9836 | // Sema's owner Cau's owner Nav. The alignment etc were passed above. | ||
| 9854 | return finishFunc( | 9837 | return finishFunc( |
| 9855 | sema, | 9838 | sema, |
| 9856 | block, | 9839 | block, |
| ... | @@ -9872,7 +9855,7 @@ fn funcCommon( | ... | @@ -9872,7 +9855,7 @@ fn funcCommon( |
| 9872 | 9855 | ||
| 9873 | if (has_body) { | 9856 | if (has_body) { |
| 9874 | const func_index = try ip.getFuncDecl(gpa, pt.tid, .{ | 9857 | const func_index = try ip.getFuncDecl(gpa, pt.tid, .{ |
| 9875 | .owner_decl = sema.owner_decl_index, | 9858 | .owner_nav = sema.getOwnerCauNav(), |
| 9876 | .ty = func_ty, | 9859 | .ty = func_ty, |
| 9877 | .cc = cc, | 9860 | .cc = cc, |
| 9878 | .is_noinline = is_noinline, | 9861 | .is_noinline = is_noinline, |
| ... | @@ -9882,6 +9865,13 @@ fn funcCommon( | ... | @@ -9882,6 +9865,13 @@ fn funcCommon( |
| 9882 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), | 9865 | .lbrace_column = @as(u16, @truncate(src_locs.columns)), |
| 9883 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), | 9866 | .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)), |
| 9884 | }); | 9867 | }); |
| 9868 | // func_decl functions take ownership of the `Nav` of Sema'a owner `Cau`. | ||
| 9869 | ip.resolveNavValue(sema.getOwnerCauNav(), .{ | ||
| 9870 | .val = func_index, | ||
| 9871 | .alignment = alignment orelse .none, | ||
| 9872 | .@"linksection" = section_name, | ||
| 9873 | .@"addrspace" = address_space orelse .generic, | ||
| 9874 | }); | ||
| 9885 | return finishFunc( | 9875 | return finishFunc( |
| 9886 | sema, | 9876 | sema, |
| 9887 | block, | 9877 | block, |
| ... | @@ -11179,7 +11169,7 @@ const SwitchProngAnalysis = struct { | ... | @@ -11179,7 +11169,7 @@ const SwitchProngAnalysis = struct { |
| 11179 | return block.addStructFieldVal(spa.operand, field_index, field_ty); | 11169 | return block.addStructFieldVal(spa.operand, field_index, field_ty); |
| 11180 | } | 11170 | } |
| 11181 | } else if (capture_byref) { | 11171 | } else if (capture_byref) { |
| 11182 | return anonDeclRef(sema, item_val.toIntern()); | 11172 | return sema.uavRef(item_val.toIntern()); |
| 11183 | } else { | 11173 | } else { |
| 11184 | return inline_case_capture; | 11174 | return inline_case_capture; |
| 11185 | } | 11175 | } |
| ... | @@ -13946,10 +13936,9 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -13946,10 +13936,9 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13946 | } }); | 13936 | } }); |
| 13947 | } | 13937 | } |
| 13948 | 13938 | ||
| 13949 | const namespace = container_type.getNamespaceIndex(mod); | 13939 | const namespace = container_type.getNamespace(mod).unwrap() orelse return .bool_false; |
| 13950 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl_index| { | 13940 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| { |
| 13951 | const decl = mod.declPtr(decl_index); | 13941 | if (lookup.accessible) { |
| 13952 | if (decl.is_pub or decl.getFileScope(mod) == block.getFileScope(mod)) { | ||
| 13953 | return .bool_true; | 13942 | return .bool_true; |
| 13954 | } | 13943 | } |
| 13955 | } | 13944 | } |
| ... | @@ -13981,9 +13970,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13981,9 +13970,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13981 | return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); | 13970 | return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); |
| 13982 | }, | 13971 | }, |
| 13983 | }; | 13972 | }; |
| 13973 | // TODO: register some kind of dependency on the file. | ||
| 13974 | // That way, if this returns `error.AnalysisFail`, we have the dependency banked ready to | ||
| 13975 | // trigger re-analysis later. | ||
| 13984 | try pt.ensureFileAnalyzed(result.file_index); | 13976 | try pt.ensureFileAnalyzed(result.file_index); |
| 13985 | const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; | 13977 | return Air.internedToRef(zcu.fileRootType(result.file_index)); |
| 13986 | return sema.analyzeDeclVal(block, operand_src, file_root_decl_index); | ||
| 13987 | } | 13978 | } |
| 13988 | 13979 | ||
| 13989 | fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13980 | fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -16970,7 +16961,7 @@ fn analyzeArithmetic( | ... | @@ -16970,7 +16961,7 @@ fn analyzeArithmetic( |
| 16970 | if (block.wantSafety() and want_safety and scalar_tag == .Int) { | 16961 | if (block.wantSafety() and want_safety and scalar_tag == .Int) { |
| 16971 | if (mod.backendSupportsFeature(.safety_checked_instructions)) { | 16962 | if (mod.backendSupportsFeature(.safety_checked_instructions)) { |
| 16972 | if (air_tag != air_tag_safe) { | 16963 | if (air_tag != air_tag_safe) { |
| 16973 | _ = try sema.preparePanicId(block, .integer_overflow); | 16964 | _ = try sema.preparePanicId(block, src, .integer_overflow); |
| 16974 | } | 16965 | } |
| 16975 | return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); | 16966 | return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); |
| 16976 | } else { | 16967 | } else { |
| ... | @@ -17158,13 +17149,11 @@ fn zirAsm( | ... | @@ -17158,13 +17149,11 @@ fn zirAsm( |
| 17158 | if (is_volatile) { | 17149 | if (is_volatile) { |
| 17159 | return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{}); | 17150 | return sema.fail(block, src, "volatile keyword is redundant on module-level assembly", .{}); |
| 17160 | } | 17151 | } |
| 17161 | try mod.addGlobalAssembly(sema.owner_decl_index, asm_source); | 17152 | try mod.addGlobalAssembly(sema.owner.unwrap().cau, asm_source); |
| 17162 | return .void_value; | 17153 | return .void_value; |
| 17163 | } | 17154 | } |
| 17164 | 17155 | ||
| 17165 | if (block.is_comptime) { | 17156 | try sema.requireRuntimeBlock(block, src, null); |
| 17166 | try sema.requireRuntimeBlock(block, src, null); | ||
| 17167 | } | ||
| 17168 | 17157 | ||
| 17169 | var extra_i = extra.end; | 17158 | var extra_i = extra.end; |
| 17170 | var output_type_bits = extra.data.output_type_bits; | 17159 | var output_type_bits = extra.data.output_type_bits; |
| ... | @@ -17646,18 +17635,17 @@ fn zirThis( | ... | @@ -17646,18 +17635,17 @@ fn zirThis( |
| 17646 | block: *Block, | 17635 | block: *Block, |
| 17647 | extended: Zir.Inst.Extended.InstData, | 17636 | extended: Zir.Inst.Extended.InstData, |
| 17648 | ) CompileError!Air.Inst.Ref { | 17637 | ) CompileError!Air.Inst.Ref { |
| 17638 | _ = extended; | ||
| 17649 | const pt = sema.pt; | 17639 | const pt = sema.pt; |
| 17650 | const mod = pt.zcu; | 17640 | const namespace = pt.zcu.namespacePtr(block.namespace); |
| 17651 | const this_decl_index = mod.namespacePtr(block.namespace).decl_index; | 17641 | return Air.internedToRef(namespace.owner_type); |
| 17652 | const src = block.nodeOffset(@bitCast(extended.operand)); | ||
| 17653 | return sema.analyzeDeclVal(block, src, this_decl_index); | ||
| 17654 | } | 17642 | } |
| 17655 | 17643 | ||
| 17656 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 17644 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 17657 | const pt = sema.pt; | 17645 | const pt = sema.pt; |
| 17658 | const mod = pt.zcu; | 17646 | const mod = pt.zcu; |
| 17659 | const ip = &mod.intern_pool; | 17647 | const ip = &mod.intern_pool; |
| 17660 | const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod); | 17648 | const captures = Type.fromInterned(mod.namespacePtr(block.namespace).owner_type).getCaptures(mod); |
| 17661 | 17649 | ||
| 17662 | const src_node: i32 = @bitCast(extended.operand); | 17650 | const src_node: i32 = @bitCast(extended.operand); |
| 17663 | const src = block.nodeOffset(src_node); | 17651 | const src = block.nodeOffset(src_node); |
| ... | @@ -17665,8 +17653,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17665,8 +17653,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17665 | const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) { | 17653 | const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) { |
| 17666 | .@"comptime" => |index| return Air.internedToRef(index), | 17654 | .@"comptime" => |index| return Air.internedToRef(index), |
| 17667 | .runtime => |index| index, | 17655 | .runtime => |index| index, |
| 17668 | .decl_val => |decl_index| return sema.analyzeDeclVal(block, src, decl_index), | 17656 | .nav_val => |nav| return sema.analyzeNavVal(block, src, nav), |
| 17669 | .decl_ref => |decl_index| return sema.analyzeDeclRef(src, decl_index), | 17657 | .nav_ref => |nav| return sema.analyzeNavRef(src, nav), |
| 17670 | }; | 17658 | }; |
| 17671 | 17659 | ||
| 17672 | // The comptime case is handled already above. Runtime case below. | 17660 | // The comptime case is handled already above. Runtime case below. |
| ... | @@ -17764,20 +17752,19 @@ fn zirBuiltinSrc( | ... | @@ -17764,20 +17752,19 @@ fn zirBuiltinSrc( |
| 17764 | block: *Block, | 17752 | block: *Block, |
| 17765 | extended: Zir.Inst.Extended.InstData, | 17753 | extended: Zir.Inst.Extended.InstData, |
| 17766 | ) CompileError!Air.Inst.Ref { | 17754 | ) CompileError!Air.Inst.Ref { |
| 17767 | _ = block; | ||
| 17768 | const tracy = trace(@src()); | 17755 | const tracy = trace(@src()); |
| 17769 | defer tracy.end(); | 17756 | defer tracy.end(); |
| 17770 | 17757 | ||
| 17771 | const pt = sema.pt; | 17758 | const pt = sema.pt; |
| 17772 | const zcu = pt.zcu; | 17759 | const zcu = pt.zcu; |
| 17773 | const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data; | ||
| 17774 | const fn_owner_decl = zcu.funcOwnerDeclPtr(sema.func_index); | ||
| 17775 | const ip = &zcu.intern_pool; | 17760 | const ip = &zcu.intern_pool; |
| 17761 | const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data; | ||
| 17762 | const fn_name = ip.getNav(zcu.funcInfo(sema.func_index).owner_nav).name; | ||
| 17776 | const gpa = sema.gpa; | 17763 | const gpa = sema.gpa; |
| 17777 | const file_scope = fn_owner_decl.getFileScope(zcu); | 17764 | const file_scope = block.getFileScope(zcu); |
| 17778 | 17765 | ||
| 17779 | const func_name_val = v: { | 17766 | const func_name_val = v: { |
| 17780 | const func_name_len = fn_owner_decl.name.length(ip); | 17767 | const func_name_len = fn_name.length(ip); |
| 17781 | const array_ty = try pt.intern(.{ .array_type = .{ | 17768 | const array_ty = try pt.intern(.{ .array_type = .{ |
| 17782 | .len = func_name_len, | 17769 | .len = func_name_len, |
| 17783 | .sentinel = .zero_u8, | 17770 | .sentinel = .zero_u8, |
| ... | @@ -17787,11 +17774,11 @@ fn zirBuiltinSrc( | ... | @@ -17787,11 +17774,11 @@ fn zirBuiltinSrc( |
| 17787 | .ty = .slice_const_u8_sentinel_0_type, | 17774 | .ty = .slice_const_u8_sentinel_0_type, |
| 17788 | .ptr = try pt.intern(.{ .ptr = .{ | 17775 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17789 | .ty = .manyptr_const_u8_sentinel_0_type, | 17776 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17790 | .base_addr = .{ .anon_decl = .{ | 17777 | .base_addr = .{ .uav = .{ |
| 17791 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17778 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 17792 | .val = try pt.intern(.{ .aggregate = .{ | 17779 | .val = try pt.intern(.{ .aggregate = .{ |
| 17793 | .ty = array_ty, | 17780 | .ty = array_ty, |
| 17794 | .storage = .{ .bytes = fn_owner_decl.name.toString() }, | 17781 | .storage = .{ .bytes = fn_name.toString() }, |
| 17795 | } }), | 17782 | } }), |
| 17796 | } }, | 17783 | } }, |
| 17797 | .byte_offset = 0, | 17784 | .byte_offset = 0, |
| ... | @@ -17811,7 +17798,7 @@ fn zirBuiltinSrc( | ... | @@ -17811,7 +17798,7 @@ fn zirBuiltinSrc( |
| 17811 | .ty = .slice_const_u8_sentinel_0_type, | 17798 | .ty = .slice_const_u8_sentinel_0_type, |
| 17812 | .ptr = try pt.intern(.{ .ptr = .{ | 17799 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17813 | .ty = .manyptr_const_u8_sentinel_0_type, | 17800 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17814 | .base_addr = .{ .anon_decl = .{ | 17801 | .base_addr = .{ .uav = .{ |
| 17815 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17802 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 17816 | .val = try pt.intern(.{ .aggregate = .{ | 17803 | .val = try pt.intern(.{ .aggregate = .{ |
| 17817 | .ty = array_ty, | 17804 | .ty = array_ty, |
| ... | @@ -17837,7 +17824,7 @@ fn zirBuiltinSrc( | ... | @@ -17837,7 +17824,7 @@ fn zirBuiltinSrc( |
| 17837 | .ty = .slice_const_u8_sentinel_0_type, | 17824 | .ty = .slice_const_u8_sentinel_0_type, |
| 17838 | .ptr = try pt.intern(.{ .ptr = .{ | 17825 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17839 | .ty = .manyptr_const_u8_sentinel_0_type, | 17826 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 17840 | .base_addr = .{ .anon_decl = .{ | 17827 | .base_addr = .{ .uav = .{ |
| 17841 | .orig_ty = .slice_const_u8_sentinel_0_type, | 17828 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 17842 | .val = try pt.intern(.{ .aggregate = .{ | 17829 | .val = try pt.intern(.{ .aggregate = .{ |
| 17843 | .ty = array_ty, | 17830 | .ty = array_ty, |
| ... | @@ -17902,25 +17889,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17902,25 +17889,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17902 | .val = .void_value, | 17889 | .val = .void_value, |
| 17903 | } }))), | 17890 | } }))), |
| 17904 | .Fn => { | 17891 | .Fn => { |
| 17905 | const fn_info_decl_index = (try sema.namespaceLookup( | 17892 | const fn_info_nav = try sema.namespaceLookup( |
| 17906 | block, | 17893 | block, |
| 17907 | src, | 17894 | src, |
| 17908 | type_info_ty.getNamespaceIndex(mod), | 17895 | type_info_ty.getNamespaceIndex(mod), |
| 17909 | try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls), | 17896 | try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls), |
| 17910 | )).?; | 17897 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 17911 | try sema.ensureDeclAnalyzed(fn_info_decl_index); | 17898 | try sema.ensureNavResolved(src, fn_info_nav); |
| 17912 | const fn_info_decl = mod.declPtr(fn_info_decl_index); | 17899 | const fn_info_ty = Type.fromInterned(ip.getNav(fn_info_nav).status.resolved.val); |
| 17913 | const fn_info_ty = fn_info_decl.val.toType(); | ||
| 17914 | 17900 | ||
| 17915 | const param_info_decl_index = (try sema.namespaceLookup( | 17901 | const param_info_nav = try sema.namespaceLookup( |
| 17916 | block, | 17902 | block, |
| 17917 | src, | 17903 | src, |
| 17918 | fn_info_ty.getNamespaceIndex(mod), | 17904 | fn_info_ty.getNamespaceIndex(mod), |
| 17919 | try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls), | 17905 | try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls), |
| 17920 | )).?; | 17906 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 17921 | try sema.ensureDeclAnalyzed(param_info_decl_index); | 17907 | try sema.ensureNavResolved(src, param_info_nav); |
| 17922 | const param_info_decl = mod.declPtr(param_info_decl_index); | 17908 | const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val); |
| 17923 | const param_info_ty = param_info_decl.val.toType(); | ||
| 17924 | 17909 | ||
| 17925 | const func_ty_info = mod.typeToFunc(ty).?; | 17910 | const func_ty_info = mod.typeToFunc(ty).?; |
| 17926 | const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); | 17911 | const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); |
| ... | @@ -17972,7 +17957,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -17972,7 +17957,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17972 | .ty = slice_ty, | 17957 | .ty = slice_ty, |
| 17973 | .ptr = try pt.intern(.{ .ptr = .{ | 17958 | .ptr = try pt.intern(.{ .ptr = .{ |
| 17974 | .ty = manyptr_ty, | 17959 | .ty = manyptr_ty, |
| 17975 | .base_addr = .{ .anon_decl = .{ | 17960 | .base_addr = .{ .uav = .{ |
| 17976 | .orig_ty = manyptr_ty, | 17961 | .orig_ty = manyptr_ty, |
| 17977 | .val = new_decl_val, | 17962 | .val = new_decl_val, |
| 17978 | } }, | 17963 | } }, |
| ... | @@ -18014,15 +17999,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18014,15 +17999,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18014 | } }))); | 17999 | } }))); |
| 18015 | }, | 18000 | }, |
| 18016 | .Int => { | 18001 | .Int => { |
| 18017 | const int_info_decl_index = (try sema.namespaceLookup( | 18002 | const int_info_nav = try sema.namespaceLookup( |
| 18018 | block, | 18003 | block, |
| 18019 | src, | 18004 | src, |
| 18020 | type_info_ty.getNamespaceIndex(mod), | 18005 | type_info_ty.getNamespaceIndex(mod), |
| 18021 | try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls), | 18006 | try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls), |
| 18022 | )).?; | 18007 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18023 | try sema.ensureDeclAnalyzed(int_info_decl_index); | 18008 | try sema.ensureNavResolved(src, int_info_nav); |
| 18024 | const int_info_decl = mod.declPtr(int_info_decl_index); | 18009 | const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val); |
| 18025 | const int_info_ty = int_info_decl.val.toType(); | ||
| 18026 | 18010 | ||
| 18027 | const signedness_ty = try pt.getBuiltinType("Signedness"); | 18011 | const signedness_ty = try pt.getBuiltinType("Signedness"); |
| 18028 | const info = ty.intInfo(mod); | 18012 | const info = ty.intInfo(mod); |
| ... | @@ -18042,15 +18026,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18042,15 +18026,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18042 | } }))); | 18026 | } }))); |
| 18043 | }, | 18027 | }, |
| 18044 | .Float => { | 18028 | .Float => { |
| 18045 | const float_info_decl_index = (try sema.namespaceLookup( | 18029 | const float_info_nav = try sema.namespaceLookup( |
| 18046 | block, | 18030 | block, |
| 18047 | src, | 18031 | src, |
| 18048 | type_info_ty.getNamespaceIndex(mod), | 18032 | type_info_ty.getNamespaceIndex(mod), |
| 18049 | try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls), | 18033 | try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls), |
| 18050 | )).?; | 18034 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18051 | try sema.ensureDeclAnalyzed(float_info_decl_index); | 18035 | try sema.ensureNavResolved(src, float_info_nav); |
| 18052 | const float_info_decl = mod.declPtr(float_info_decl_index); | 18036 | const float_info_ty = Type.fromInterned(ip.getNav(float_info_nav).status.resolved.val); |
| 18053 | const float_info_ty = float_info_decl.val.toType(); | ||
| 18054 | 18037 | ||
| 18055 | const field_vals = .{ | 18038 | const field_vals = .{ |
| 18056 | // bits: u16, | 18039 | // bits: u16, |
| ... | @@ -18074,26 +18057,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18074,26 +18057,24 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18074 | 18057 | ||
| 18075 | const addrspace_ty = try pt.getBuiltinType("AddressSpace"); | 18058 | const addrspace_ty = try pt.getBuiltinType("AddressSpace"); |
| 18076 | const pointer_ty = t: { | 18059 | const pointer_ty = t: { |
| 18077 | const decl_index = (try sema.namespaceLookup( | 18060 | const nav = try sema.namespaceLookup( |
| 18078 | block, | 18061 | block, |
| 18079 | src, | 18062 | src, |
| 18080 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), | 18063 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), |
| 18081 | try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls), | 18064 | try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls), |
| 18082 | )).?; | 18065 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18083 | try sema.ensureDeclAnalyzed(decl_index); | 18066 | try sema.ensureNavResolved(src, nav); |
| 18084 | const decl = mod.declPtr(decl_index); | 18067 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18085 | break :t decl.val.toType(); | ||
| 18086 | }; | 18068 | }; |
| 18087 | const ptr_size_ty = t: { | 18069 | const ptr_size_ty = t: { |
| 18088 | const decl_index = (try sema.namespaceLookup( | 18070 | const nav = try sema.namespaceLookup( |
| 18089 | block, | 18071 | block, |
| 18090 | src, | 18072 | src, |
| 18091 | pointer_ty.getNamespaceIndex(mod), | 18073 | pointer_ty.getNamespaceIndex(mod), |
| 18092 | try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls), | 18074 | try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls), |
| 18093 | )).?; | 18075 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18094 | try sema.ensureDeclAnalyzed(decl_index); | 18076 | try sema.ensureNavResolved(src, nav); |
| 18095 | const decl = mod.declPtr(decl_index); | 18077 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18096 | break :t decl.val.toType(); | ||
| 18097 | }; | 18078 | }; |
| 18098 | 18079 | ||
| 18099 | const field_values = .{ | 18080 | const field_values = .{ |
| ... | @@ -18128,15 +18109,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18128,15 +18109,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18128 | }, | 18109 | }, |
| 18129 | .Array => { | 18110 | .Array => { |
| 18130 | const array_field_ty = t: { | 18111 | const array_field_ty = t: { |
| 18131 | const array_field_ty_decl_index = (try sema.namespaceLookup( | 18112 | const nav = try sema.namespaceLookup( |
| 18132 | block, | 18113 | block, |
| 18133 | src, | 18114 | src, |
| 18134 | type_info_ty.getNamespaceIndex(mod), | 18115 | type_info_ty.getNamespaceIndex(mod), |
| 18135 | try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls), | 18116 | try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls), |
| 18136 | )).?; | 18117 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18137 | try sema.ensureDeclAnalyzed(array_field_ty_decl_index); | 18118 | try sema.ensureNavResolved(src, nav); |
| 18138 | const array_field_ty_decl = mod.declPtr(array_field_ty_decl_index); | 18119 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18139 | break :t array_field_ty_decl.val.toType(); | ||
| 18140 | }; | 18120 | }; |
| 18141 | 18121 | ||
| 18142 | const info = ty.arrayInfo(mod); | 18122 | const info = ty.arrayInfo(mod); |
| ... | @@ -18159,15 +18139,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18159,15 +18139,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18159 | }, | 18139 | }, |
| 18160 | .Vector => { | 18140 | .Vector => { |
| 18161 | const vector_field_ty = t: { | 18141 | const vector_field_ty = t: { |
| 18162 | const vector_field_ty_decl_index = (try sema.namespaceLookup( | 18142 | const nav = try sema.namespaceLookup( |
| 18163 | block, | 18143 | block, |
| 18164 | src, | 18144 | src, |
| 18165 | type_info_ty.getNamespaceIndex(mod), | 18145 | type_info_ty.getNamespaceIndex(mod), |
| 18166 | try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls), | 18146 | try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls), |
| 18167 | )).?; | 18147 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18168 | try sema.ensureDeclAnalyzed(vector_field_ty_decl_index); | 18148 | try sema.ensureNavResolved(src, nav); |
| 18169 | const vector_field_ty_decl = mod.declPtr(vector_field_ty_decl_index); | 18149 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18170 | break :t vector_field_ty_decl.val.toType(); | ||
| 18171 | }; | 18150 | }; |
| 18172 | 18151 | ||
| 18173 | const info = ty.arrayInfo(mod); | 18152 | const info = ty.arrayInfo(mod); |
| ... | @@ -18188,15 +18167,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18188,15 +18167,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18188 | }, | 18167 | }, |
| 18189 | .Optional => { | 18168 | .Optional => { |
| 18190 | const optional_field_ty = t: { | 18169 | const optional_field_ty = t: { |
| 18191 | const optional_field_ty_decl_index = (try sema.namespaceLookup( | 18170 | const nav = try sema.namespaceLookup( |
| 18192 | block, | 18171 | block, |
| 18193 | src, | 18172 | src, |
| 18194 | type_info_ty.getNamespaceIndex(mod), | 18173 | type_info_ty.getNamespaceIndex(mod), |
| 18195 | try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls), | 18174 | try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls), |
| 18196 | )).?; | 18175 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18197 | try sema.ensureDeclAnalyzed(optional_field_ty_decl_index); | 18176 | try sema.ensureNavResolved(src, nav); |
| 18198 | const optional_field_ty_decl = mod.declPtr(optional_field_ty_decl_index); | 18177 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18199 | break :t optional_field_ty_decl.val.toType(); | ||
| 18200 | }; | 18178 | }; |
| 18201 | 18179 | ||
| 18202 | const field_values = .{ | 18180 | const field_values = .{ |
| ... | @@ -18215,15 +18193,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18215,15 +18193,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18215 | .ErrorSet => { | 18193 | .ErrorSet => { |
| 18216 | // Get the Error type | 18194 | // Get the Error type |
| 18217 | const error_field_ty = t: { | 18195 | const error_field_ty = t: { |
| 18218 | const set_field_ty_decl_index = (try sema.namespaceLookup( | 18196 | const nav = try sema.namespaceLookup( |
| 18219 | block, | 18197 | block, |
| 18220 | src, | 18198 | src, |
| 18221 | type_info_ty.getNamespaceIndex(mod), | 18199 | type_info_ty.getNamespaceIndex(mod), |
| 18222 | try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls), | 18200 | try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls), |
| 18223 | )).?; | 18201 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18224 | try sema.ensureDeclAnalyzed(set_field_ty_decl_index); | 18202 | try sema.ensureNavResolved(src, nav); |
| 18225 | const set_field_ty_decl = mod.declPtr(set_field_ty_decl_index); | 18203 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18226 | break :t set_field_ty_decl.val.toType(); | ||
| 18227 | }; | 18204 | }; |
| 18228 | 18205 | ||
| 18229 | // Build our list of Error values | 18206 | // Build our list of Error values |
| ... | @@ -18251,7 +18228,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18251,7 +18228,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18251 | .ty = .slice_const_u8_sentinel_0_type, | 18228 | .ty = .slice_const_u8_sentinel_0_type, |
| 18252 | .ptr = try pt.intern(.{ .ptr = .{ | 18229 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18253 | .ty = .manyptr_const_u8_sentinel_0_type, | 18230 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18254 | .base_addr = .{ .anon_decl = .{ | 18231 | .base_addr = .{ .uav = .{ |
| 18255 | .val = new_decl_val, | 18232 | .val = new_decl_val, |
| 18256 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18233 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 18257 | } }, | 18234 | } }, |
| ... | @@ -18298,7 +18275,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18298,7 +18275,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18298 | .ty = slice_errors_ty.toIntern(), | 18275 | .ty = slice_errors_ty.toIntern(), |
| 18299 | .ptr = try pt.intern(.{ .ptr = .{ | 18276 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18300 | .ty = manyptr_errors_ty, | 18277 | .ty = manyptr_errors_ty, |
| 18301 | .base_addr = .{ .anon_decl = .{ | 18278 | .base_addr = .{ .uav = .{ |
| 18302 | .orig_ty = manyptr_errors_ty, | 18279 | .orig_ty = manyptr_errors_ty, |
| 18303 | .val = new_decl_val, | 18280 | .val = new_decl_val, |
| 18304 | } }, | 18281 | } }, |
| ... | @@ -18321,15 +18298,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18321,15 +18298,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18321 | }, | 18298 | }, |
| 18322 | .ErrorUnion => { | 18299 | .ErrorUnion => { |
| 18323 | const error_union_field_ty = t: { | 18300 | const error_union_field_ty = t: { |
| 18324 | const error_union_field_ty_decl_index = (try sema.namespaceLookup( | 18301 | const nav = try sema.namespaceLookup( |
| 18325 | block, | 18302 | block, |
| 18326 | src, | 18303 | src, |
| 18327 | type_info_ty.getNamespaceIndex(mod), | 18304 | type_info_ty.getNamespaceIndex(mod), |
| 18328 | try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls), | 18305 | try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls), |
| 18329 | )).?; | 18306 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18330 | try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index); | 18307 | try sema.ensureNavResolved(src, nav); |
| 18331 | const error_union_field_ty_decl = mod.declPtr(error_union_field_ty_decl_index); | 18308 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18332 | break :t error_union_field_ty_decl.val.toType(); | ||
| 18333 | }; | 18309 | }; |
| 18334 | 18310 | ||
| 18335 | const field_values = .{ | 18311 | const field_values = .{ |
| ... | @@ -18351,15 +18327,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18351,15 +18327,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18351 | const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive); | 18327 | const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive); |
| 18352 | 18328 | ||
| 18353 | const enum_field_ty = t: { | 18329 | const enum_field_ty = t: { |
| 18354 | const enum_field_ty_decl_index = (try sema.namespaceLookup( | 18330 | const nav = try sema.namespaceLookup( |
| 18355 | block, | 18331 | block, |
| 18356 | src, | 18332 | src, |
| 18357 | type_info_ty.getNamespaceIndex(mod), | 18333 | type_info_ty.getNamespaceIndex(mod), |
| 18358 | try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls), | 18334 | try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls), |
| 18359 | )).?; | 18335 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18360 | try sema.ensureDeclAnalyzed(enum_field_ty_decl_index); | 18336 | try sema.ensureNavResolved(src, nav); |
| 18361 | const enum_field_ty_decl = mod.declPtr(enum_field_ty_decl_index); | 18337 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18362 | break :t enum_field_ty_decl.val.toType(); | ||
| 18363 | }; | 18338 | }; |
| 18364 | 18339 | ||
| 18365 | const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len); | 18340 | const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len); |
| ... | @@ -18392,7 +18367,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18392,7 +18367,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18392 | .ty = .slice_const_u8_sentinel_0_type, | 18367 | .ty = .slice_const_u8_sentinel_0_type, |
| 18393 | .ptr = try pt.intern(.{ .ptr = .{ | 18368 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18394 | .ty = .manyptr_const_u8_sentinel_0_type, | 18369 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18395 | .base_addr = .{ .anon_decl = .{ | 18370 | .base_addr = .{ .uav = .{ |
| 18396 | .val = new_decl_val, | 18371 | .val = new_decl_val, |
| 18397 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18372 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 18398 | } }, | 18373 | } }, |
| ... | @@ -18435,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18435,7 +18410,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18435 | .ty = slice_ty, | 18410 | .ty = slice_ty, |
| 18436 | .ptr = try pt.intern(.{ .ptr = .{ | 18411 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18437 | .ty = manyptr_ty, | 18412 | .ty = manyptr_ty, |
| 18438 | .base_addr = .{ .anon_decl = .{ | 18413 | .base_addr = .{ .uav = .{ |
| 18439 | .val = new_decl_val, | 18414 | .val = new_decl_val, |
| 18440 | .orig_ty = manyptr_ty, | 18415 | .orig_ty = manyptr_ty, |
| 18441 | } }, | 18416 | } }, |
| ... | @@ -18445,18 +18420,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18445,18 +18420,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18445 | } }); | 18420 | } }); |
| 18446 | }; | 18421 | }; |
| 18447 | 18422 | ||
| 18448 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace); | 18423 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional()); |
| 18449 | 18424 | ||
| 18450 | const type_enum_ty = t: { | 18425 | const type_enum_ty = t: { |
| 18451 | const type_enum_ty_decl_index = (try sema.namespaceLookup( | 18426 | const nav = try sema.namespaceLookup( |
| 18452 | block, | 18427 | block, |
| 18453 | src, | 18428 | src, |
| 18454 | type_info_ty.getNamespaceIndex(mod), | 18429 | type_info_ty.getNamespaceIndex(mod), |
| 18455 | try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls), | 18430 | try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls), |
| 18456 | )).?; | 18431 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18457 | try sema.ensureDeclAnalyzed(type_enum_ty_decl_index); | 18432 | try sema.ensureNavResolved(src, nav); |
| 18458 | const type_enum_ty_decl = mod.declPtr(type_enum_ty_decl_index); | 18433 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18459 | break :t type_enum_ty_decl.val.toType(); | ||
| 18460 | }; | 18434 | }; |
| 18461 | 18435 | ||
| 18462 | const field_values = .{ | 18436 | const field_values = .{ |
| ... | @@ -18480,27 +18454,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18480,27 +18454,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18480 | }, | 18454 | }, |
| 18481 | .Union => { | 18455 | .Union => { |
| 18482 | const type_union_ty = t: { | 18456 | const type_union_ty = t: { |
| 18483 | const type_union_ty_decl_index = (try sema.namespaceLookup( | 18457 | const nav = try sema.namespaceLookup( |
| 18484 | block, | 18458 | block, |
| 18485 | src, | 18459 | src, |
| 18486 | type_info_ty.getNamespaceIndex(mod), | 18460 | type_info_ty.getNamespaceIndex(mod), |
| 18487 | try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls), | 18461 | try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls), |
| 18488 | )).?; | 18462 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18489 | try sema.ensureDeclAnalyzed(type_union_ty_decl_index); | 18463 | try sema.ensureNavResolved(src, nav); |
| 18490 | const type_union_ty_decl = mod.declPtr(type_union_ty_decl_index); | 18464 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18491 | break :t type_union_ty_decl.val.toType(); | ||
| 18492 | }; | 18465 | }; |
| 18493 | 18466 | ||
| 18494 | const union_field_ty = t: { | 18467 | const union_field_ty = t: { |
| 18495 | const union_field_ty_decl_index = (try sema.namespaceLookup( | 18468 | const nav = try sema.namespaceLookup( |
| 18496 | block, | 18469 | block, |
| 18497 | src, | 18470 | src, |
| 18498 | type_info_ty.getNamespaceIndex(mod), | 18471 | type_info_ty.getNamespaceIndex(mod), |
| 18499 | try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls), | 18472 | try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls), |
| 18500 | )).?; | 18473 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18501 | try sema.ensureDeclAnalyzed(union_field_ty_decl_index); | 18474 | try sema.ensureNavResolved(src, nav); |
| 18502 | const union_field_ty_decl = mod.declPtr(union_field_ty_decl_index); | 18475 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18503 | break :t union_field_ty_decl.val.toType(); | ||
| 18504 | }; | 18476 | }; |
| 18505 | 18477 | ||
| 18506 | try ty.resolveLayout(pt); // Getting alignment requires type layout | 18478 | try ty.resolveLayout(pt); // Getting alignment requires type layout |
| ... | @@ -18528,7 +18500,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18528,7 +18500,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18528 | .ty = .slice_const_u8_sentinel_0_type, | 18500 | .ty = .slice_const_u8_sentinel_0_type, |
| 18529 | .ptr = try pt.intern(.{ .ptr = .{ | 18501 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18530 | .ty = .manyptr_const_u8_sentinel_0_type, | 18502 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18531 | .base_addr = .{ .anon_decl = .{ | 18503 | .base_addr = .{ .uav = .{ |
| 18532 | .val = new_decl_val, | 18504 | .val = new_decl_val, |
| 18533 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18505 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 18534 | } }, | 18506 | } }, |
| ... | @@ -18579,7 +18551,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18579,7 +18551,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18579 | .ty = slice_ty, | 18551 | .ty = slice_ty, |
| 18580 | .ptr = try pt.intern(.{ .ptr = .{ | 18552 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18581 | .ty = manyptr_ty, | 18553 | .ty = manyptr_ty, |
| 18582 | .base_addr = .{ .anon_decl = .{ | 18554 | .base_addr = .{ .uav = .{ |
| 18583 | .orig_ty = manyptr_ty, | 18555 | .orig_ty = manyptr_ty, |
| 18584 | .val = new_decl_val, | 18556 | .val = new_decl_val, |
| 18585 | } }, | 18557 | } }, |
| ... | @@ -18589,7 +18561,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18589,7 +18561,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18589 | } }); | 18561 | } }); |
| 18590 | }; | 18562 | }; |
| 18591 | 18563 | ||
| 18592 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); | 18564 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod).toOptional()); |
| 18593 | 18565 | ||
| 18594 | const enum_tag_ty_val = try pt.intern(.{ .opt = .{ | 18566 | const enum_tag_ty_val = try pt.intern(.{ .opt = .{ |
| 18595 | .ty = (try pt.optionalType(.type_type)).toIntern(), | 18567 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| ... | @@ -18597,15 +18569,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18597,15 +18569,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18597 | } }); | 18569 | } }); |
| 18598 | 18570 | ||
| 18599 | const container_layout_ty = t: { | 18571 | const container_layout_ty = t: { |
| 18600 | const decl_index = (try sema.namespaceLookup( | 18572 | const nav = try sema.namespaceLookup( |
| 18601 | block, | 18573 | block, |
| 18602 | src, | 18574 | src, |
| 18603 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), | 18575 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), |
| 18604 | try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls), | 18576 | try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls), |
| 18605 | )).?; | 18577 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18606 | try sema.ensureDeclAnalyzed(decl_index); | 18578 | try sema.ensureNavResolved(src, nav); |
| 18607 | const decl = mod.declPtr(decl_index); | 18579 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18608 | break :t decl.val.toType(); | ||
| 18609 | }; | 18580 | }; |
| 18610 | 18581 | ||
| 18611 | const field_values = .{ | 18582 | const field_values = .{ |
| ... | @@ -18630,27 +18601,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18630,27 +18601,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18630 | }, | 18601 | }, |
| 18631 | .Struct => { | 18602 | .Struct => { |
| 18632 | const type_struct_ty = t: { | 18603 | const type_struct_ty = t: { |
| 18633 | const type_struct_ty_decl_index = (try sema.namespaceLookup( | 18604 | const nav = try sema.namespaceLookup( |
| 18634 | block, | 18605 | block, |
| 18635 | src, | 18606 | src, |
| 18636 | type_info_ty.getNamespaceIndex(mod), | 18607 | type_info_ty.getNamespaceIndex(mod), |
| 18637 | try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls), | 18608 | try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls), |
| 18638 | )).?; | 18609 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18639 | try sema.ensureDeclAnalyzed(type_struct_ty_decl_index); | 18610 | try sema.ensureNavResolved(src, nav); |
| 18640 | const type_struct_ty_decl = mod.declPtr(type_struct_ty_decl_index); | 18611 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18641 | break :t type_struct_ty_decl.val.toType(); | ||
| 18642 | }; | 18612 | }; |
| 18643 | 18613 | ||
| 18644 | const struct_field_ty = t: { | 18614 | const struct_field_ty = t: { |
| 18645 | const struct_field_ty_decl_index = (try sema.namespaceLookup( | 18615 | const nav = try sema.namespaceLookup( |
| 18646 | block, | 18616 | block, |
| 18647 | src, | 18617 | src, |
| 18648 | type_info_ty.getNamespaceIndex(mod), | 18618 | type_info_ty.getNamespaceIndex(mod), |
| 18649 | try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls), | 18619 | try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls), |
| 18650 | )).?; | 18620 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18651 | try sema.ensureDeclAnalyzed(struct_field_ty_decl_index); | 18621 | try sema.ensureNavResolved(src, nav); |
| 18652 | const struct_field_ty_decl = mod.declPtr(struct_field_ty_decl_index); | 18622 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18653 | break :t struct_field_ty_decl.val.toType(); | ||
| 18654 | }; | 18623 | }; |
| 18655 | 18624 | ||
| 18656 | try ty.resolveLayout(pt); // Getting alignment requires type layout | 18625 | try ty.resolveLayout(pt); // Getting alignment requires type layout |
| ... | @@ -18683,7 +18652,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18683,7 +18652,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18683 | .ty = .slice_const_u8_sentinel_0_type, | 18652 | .ty = .slice_const_u8_sentinel_0_type, |
| 18684 | .ptr = try pt.intern(.{ .ptr = .{ | 18653 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18685 | .ty = .manyptr_const_u8_sentinel_0_type, | 18654 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18686 | .base_addr = .{ .anon_decl = .{ | 18655 | .base_addr = .{ .uav = .{ |
| 18687 | .val = new_decl_val, | 18656 | .val = new_decl_val, |
| 18688 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18657 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 18689 | } }, | 18658 | } }, |
| ... | @@ -18747,7 +18716,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18747,7 +18716,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18747 | .ty = .slice_const_u8_sentinel_0_type, | 18716 | .ty = .slice_const_u8_sentinel_0_type, |
| 18748 | .ptr = try pt.intern(.{ .ptr = .{ | 18717 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18749 | .ty = .manyptr_const_u8_sentinel_0_type, | 18718 | .ty = .manyptr_const_u8_sentinel_0_type, |
| 18750 | .base_addr = .{ .anon_decl = .{ | 18719 | .base_addr = .{ .uav = .{ |
| 18751 | .val = new_decl_val, | 18720 | .val = new_decl_val, |
| 18752 | .orig_ty = .slice_const_u8_sentinel_0_type, | 18721 | .orig_ty = .slice_const_u8_sentinel_0_type, |
| 18753 | } }, | 18722 | } }, |
| ... | @@ -18809,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18809,7 +18778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18809 | .ty = slice_ty, | 18778 | .ty = slice_ty, |
| 18810 | .ptr = try pt.intern(.{ .ptr = .{ | 18779 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18811 | .ty = manyptr_ty, | 18780 | .ty = manyptr_ty, |
| 18812 | .base_addr = .{ .anon_decl = .{ | 18781 | .base_addr = .{ .uav = .{ |
| 18813 | .orig_ty = manyptr_ty, | 18782 | .orig_ty = manyptr_ty, |
| 18814 | .val = new_decl_val, | 18783 | .val = new_decl_val, |
| 18815 | } }, | 18784 | } }, |
| ... | @@ -18819,7 +18788,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18819,7 +18788,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18819 | } }); | 18788 | } }); |
| 18820 | }; | 18789 | }; |
| 18821 | 18790 | ||
| 18822 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); | 18791 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(mod)); |
| 18823 | 18792 | ||
| 18824 | const backing_integer_val = try pt.intern(.{ .opt = .{ | 18793 | const backing_integer_val = try pt.intern(.{ .opt = .{ |
| 18825 | .ty = (try pt.optionalType(.type_type)).toIntern(), | 18794 | .ty = (try pt.optionalType(.type_type)).toIntern(), |
| ... | @@ -18830,15 +18799,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18830,15 +18799,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18830 | } }); | 18799 | } }); |
| 18831 | 18800 | ||
| 18832 | const container_layout_ty = t: { | 18801 | const container_layout_ty = t: { |
| 18833 | const decl_index = (try sema.namespaceLookup( | 18802 | const nav = try sema.namespaceLookup( |
| 18834 | block, | 18803 | block, |
| 18835 | src, | 18804 | src, |
| 18836 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), | 18805 | (try pt.getBuiltinType("Type")).getNamespaceIndex(mod), |
| 18837 | try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls), | 18806 | try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls), |
| 18838 | )).?; | 18807 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18839 | try sema.ensureDeclAnalyzed(decl_index); | 18808 | try sema.ensureNavResolved(src, nav); |
| 18840 | const decl = mod.declPtr(decl_index); | 18809 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18841 | break :t decl.val.toType(); | ||
| 18842 | }; | 18810 | }; |
| 18843 | 18811 | ||
| 18844 | const layout = ty.containerLayout(mod); | 18812 | const layout = ty.containerLayout(mod); |
| ... | @@ -18866,19 +18834,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18866,19 +18834,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18866 | }, | 18834 | }, |
| 18867 | .Opaque => { | 18835 | .Opaque => { |
| 18868 | const type_opaque_ty = t: { | 18836 | const type_opaque_ty = t: { |
| 18869 | const type_opaque_ty_decl_index = (try sema.namespaceLookup( | 18837 | const nav = try sema.namespaceLookup( |
| 18870 | block, | 18838 | block, |
| 18871 | src, | 18839 | src, |
| 18872 | type_info_ty.getNamespaceIndex(mod), | 18840 | type_info_ty.getNamespaceIndex(mod), |
| 18873 | try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls), | 18841 | try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls), |
| 18874 | )).?; | 18842 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18875 | try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index); | 18843 | try sema.ensureNavResolved(src, nav); |
| 18876 | const type_opaque_ty_decl = mod.declPtr(type_opaque_ty_decl_index); | 18844 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18877 | break :t type_opaque_ty_decl.val.toType(); | ||
| 18878 | }; | 18845 | }; |
| 18879 | 18846 | ||
| 18880 | try ty.resolveFields(pt); | 18847 | try ty.resolveFields(pt); |
| 18881 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); | 18848 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(mod)); |
| 18882 | 18849 | ||
| 18883 | const field_values = .{ | 18850 | const field_values = .{ |
| 18884 | // decls: []const Declaration, | 18851 | // decls: []const Declaration, |
| ... | @@ -18906,19 +18873,19 @@ fn typeInfoDecls( | ... | @@ -18906,19 +18873,19 @@ fn typeInfoDecls( |
| 18906 | opt_namespace: InternPool.OptionalNamespaceIndex, | 18873 | opt_namespace: InternPool.OptionalNamespaceIndex, |
| 18907 | ) CompileError!InternPool.Index { | 18874 | ) CompileError!InternPool.Index { |
| 18908 | const pt = sema.pt; | 18875 | const pt = sema.pt; |
| 18909 | const mod = pt.zcu; | 18876 | const zcu = pt.zcu; |
| 18877 | const ip = &zcu.intern_pool; | ||
| 18910 | const gpa = sema.gpa; | 18878 | const gpa = sema.gpa; |
| 18911 | 18879 | ||
| 18912 | const declaration_ty = t: { | 18880 | const declaration_ty = t: { |
| 18913 | const declaration_ty_decl_index = (try sema.namespaceLookup( | 18881 | const nav = try sema.namespaceLookup( |
| 18914 | block, | 18882 | block, |
| 18915 | src, | 18883 | src, |
| 18916 | type_info_ty.getNamespaceIndex(mod), | 18884 | type_info_ty.getNamespaceIndex(zcu), |
| 18917 | try mod.intern_pool.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls), | 18885 | try ip.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls), |
| 18918 | )).?; | 18886 | ) orelse @panic("std.builtin.Type is corrupt"); |
| 18919 | try sema.ensureDeclAnalyzed(declaration_ty_decl_index); | 18887 | try sema.ensureNavResolved(src, nav); |
| 18920 | const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index); | 18888 | break :t Type.fromInterned(ip.getNav(nav).status.resolved.val); |
| 18921 | break :t declaration_ty_decl.val.toType(); | ||
| 18922 | }; | 18889 | }; |
| 18923 | 18890 | ||
| 18924 | var decl_vals = std.ArrayList(InternPool.Index).init(gpa); | 18891 | var decl_vals = std.ArrayList(InternPool.Index).init(gpa); |
| ... | @@ -18927,7 +18894,7 @@ fn typeInfoDecls( | ... | @@ -18927,7 +18894,7 @@ fn typeInfoDecls( |
| 18927 | var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa); | 18894 | var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa); |
| 18928 | defer seen_namespaces.deinit(); | 18895 | defer seen_namespaces.deinit(); |
| 18929 | 18896 | ||
| 18930 | try sema.typeInfoNamespaceDecls(block, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces); | 18897 | try sema.typeInfoNamespaceDecls(block, src, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces); |
| 18931 | 18898 | ||
| 18932 | const array_decl_ty = try pt.arrayType(.{ | 18899 | const array_decl_ty = try pt.arrayType(.{ |
| 18933 | .len = decl_vals.items.len, | 18900 | .len = decl_vals.items.len, |
| ... | @@ -18944,12 +18911,12 @@ fn typeInfoDecls( | ... | @@ -18944,12 +18911,12 @@ fn typeInfoDecls( |
| 18944 | .is_const = true, | 18911 | .is_const = true, |
| 18945 | }, | 18912 | }, |
| 18946 | })).toIntern(); | 18913 | })).toIntern(); |
| 18947 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(mod).toIntern(); | 18914 | const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); |
| 18948 | return try pt.intern(.{ .slice = .{ | 18915 | return try pt.intern(.{ .slice = .{ |
| 18949 | .ty = slice_ty, | 18916 | .ty = slice_ty, |
| 18950 | .ptr = try pt.intern(.{ .ptr = .{ | 18917 | .ptr = try pt.intern(.{ .ptr = .{ |
| 18951 | .ty = manyptr_ty, | 18918 | .ty = manyptr_ty, |
| 18952 | .base_addr = .{ .anon_decl = .{ | 18919 | .base_addr = .{ .uav = .{ |
| 18953 | .orig_ty = manyptr_ty, | 18920 | .orig_ty = manyptr_ty, |
| 18954 | .val = new_decl_val, | 18921 | .val = new_decl_val, |
| 18955 | } }, | 18922 | } }, |
| ... | @@ -18962,59 +18929,54 @@ fn typeInfoDecls( | ... | @@ -18962,59 +18929,54 @@ fn typeInfoDecls( |
| 18962 | fn typeInfoNamespaceDecls( | 18929 | fn typeInfoNamespaceDecls( |
| 18963 | sema: *Sema, | 18930 | sema: *Sema, |
| 18964 | block: *Block, | 18931 | block: *Block, |
| 18932 | src: LazySrcLoc, | ||
| 18965 | opt_namespace_index: InternPool.OptionalNamespaceIndex, | 18933 | opt_namespace_index: InternPool.OptionalNamespaceIndex, |
| 18966 | declaration_ty: Type, | 18934 | declaration_ty: Type, |
| 18967 | decl_vals: *std.ArrayList(InternPool.Index), | 18935 | decl_vals: *std.ArrayList(InternPool.Index), |
| 18968 | seen_namespaces: *std.AutoHashMap(*Namespace, void), | 18936 | seen_namespaces: *std.AutoHashMap(*Namespace, void), |
| 18969 | ) !void { | 18937 | ) !void { |
| 18970 | const pt = sema.pt; | 18938 | const pt = sema.pt; |
| 18971 | const mod = pt.zcu; | 18939 | const zcu = pt.zcu; |
| 18972 | const ip = &mod.intern_pool; | 18940 | const ip = &zcu.intern_pool; |
| 18973 | 18941 | ||
| 18974 | const namespace_index = opt_namespace_index.unwrap() orelse return; | 18942 | const namespace_index = opt_namespace_index.unwrap() orelse return; |
| 18975 | const namespace = mod.namespacePtr(namespace_index); | 18943 | const namespace = zcu.namespacePtr(namespace_index); |
| 18976 | 18944 | ||
| 18977 | const gop = try seen_namespaces.getOrPut(namespace); | 18945 | const gop = try seen_namespaces.getOrPut(namespace); |
| 18978 | if (gop.found_existing) return; | 18946 | if (gop.found_existing) return; |
| 18979 | 18947 | ||
| 18980 | const decls = namespace.decls.keys(); | 18948 | for (namespace.pub_decls.keys()) |nav| { |
| 18981 | for (decls) |decl_index| { | 18949 | const name = ip.getNav(nav).name; |
| 18982 | const decl = mod.declPtr(decl_index); | 18950 | const name_val = name_val: { |
| 18983 | if (!decl.is_pub) continue; | 18951 | const name_len = name.length(ip); |
| 18984 | if (decl.kind == .@"usingnamespace") { | 18952 | const array_ty = try pt.arrayType(.{ |
| 18985 | if (decl.analysis == .in_progress) continue; | 18953 | .len = name_len, |
| 18986 | try sema.ensureDeclAnalyzed(decl_index); | ||
| 18987 | try sema.typeInfoNamespaceDecls(block, decl.val.toType().getNamespaceIndex(mod), declaration_ty, decl_vals, seen_namespaces); | ||
| 18988 | continue; | ||
| 18989 | } | ||
| 18990 | if (decl.kind != .named) continue; | ||
| 18991 | const name_val = v: { | ||
| 18992 | const decl_name_len = decl.name.length(ip); | ||
| 18993 | const new_decl_ty = try pt.arrayType(.{ | ||
| 18994 | .len = decl_name_len, | ||
| 18995 | .sentinel = .zero_u8, | 18954 | .sentinel = .zero_u8, |
| 18996 | .child = .u8_type, | 18955 | .child = .u8_type, |
| 18997 | }); | 18956 | }); |
| 18998 | const new_decl_val = try pt.intern(.{ .aggregate = .{ | 18957 | const array_val = try pt.intern(.{ .aggregate = .{ |
| 18999 | .ty = new_decl_ty.toIntern(), | 18958 | .ty = array_ty.toIntern(), |
| 19000 | .storage = .{ .bytes = decl.name.toString() }, | 18959 | .storage = .{ .bytes = name.toString() }, |
| 19001 | } }); | ||
| 19002 | break :v try pt.intern(.{ .slice = .{ | ||
| 19003 | .ty = .slice_const_u8_sentinel_0_type, | ||
| 19004 | .ptr = try pt.intern(.{ .ptr = .{ | ||
| 19005 | .ty = .manyptr_const_u8_sentinel_0_type, | ||
| 19006 | .base_addr = .{ .anon_decl = .{ | ||
| 19007 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 19008 | .val = new_decl_val, | ||
| 19009 | } }, | ||
| 19010 | .byte_offset = 0, | ||
| 19011 | } }), | ||
| 19012 | .len = (try pt.intValue(Type.usize, decl_name_len)).toIntern(), | ||
| 19013 | } }); | 18960 | } }); |
| 18961 | break :name_val try pt.intern(.{ | ||
| 18962 | .slice = .{ | ||
| 18963 | .ty = .slice_const_u8_sentinel_0_type, // [:0]const u8 | ||
| 18964 | .ptr = try pt.intern(.{ | ||
| 18965 | .ptr = .{ | ||
| 18966 | .ty = .manyptr_const_u8_sentinel_0_type, // [*:0]const u8 | ||
| 18967 | .base_addr = .{ .uav = .{ | ||
| 18968 | .orig_ty = .slice_const_u8_sentinel_0_type, | ||
| 18969 | .val = array_val, | ||
| 18970 | } }, | ||
| 18971 | .byte_offset = 0, | ||
| 18972 | }, | ||
| 18973 | }), | ||
| 18974 | .len = (try pt.intValue(Type.usize, name_len)).toIntern(), | ||
| 18975 | }, | ||
| 18976 | }); | ||
| 19014 | }; | 18977 | }; |
| 19015 | 18978 | const fields = [_]InternPool.Index{ | |
| 19016 | const fields = .{ | 18979 | // name: [:0]const u8, |
| 19017 | //name: [:0]const u8, | ||
| 19018 | name_val, | 18980 | name_val, |
| 19019 | }; | 18981 | }; |
| 19020 | try decl_vals.append(try pt.intern(.{ .aggregate = .{ | 18982 | try decl_vals.append(try pt.intern(.{ .aggregate = .{ |
| ... | @@ -19022,6 +18984,17 @@ fn typeInfoNamespaceDecls( | ... | @@ -19022,6 +18984,17 @@ fn typeInfoNamespaceDecls( |
| 19022 | .storage = .{ .elems = &fields }, | 18984 | .storage = .{ .elems = &fields }, |
| 19023 | } })); | 18985 | } })); |
| 19024 | } | 18986 | } |
| 18987 | |||
| 18988 | for (namespace.pub_usingnamespace.items) |nav| { | ||
| 18989 | if (ip.getNav(nav).analysis_owner.unwrap()) |cau| { | ||
| 18990 | if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .cau = cau }))) { | ||
| 18991 | continue; | ||
| 18992 | } | ||
| 18993 | } | ||
| 18994 | try sema.ensureNavResolved(src, nav); | ||
| 18995 | const namespace_ty = Type.fromInterned(ip.getNav(nav).status.resolved.val); | ||
| 18996 | try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces); | ||
| 18997 | } | ||
| 19025 | } | 18998 | } |
| 19026 | 18999 | ||
| 19027 | fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19000 | fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -19906,7 +19879,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ | ... | @@ -19906,7 +19879,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_ |
| 19906 | return; | 19879 | return; |
| 19907 | } | 19880 | } |
| 19908 | 19881 | ||
| 19909 | if (!mod.intern_pool.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn) return; | 19882 | if (!mod.intern_pool.funcAnalysisUnordered(sema.owner.unwrap().func).calls_or_awaits_errorable_fn) return; |
| 19910 | if (!start_block.ownerModule().error_tracing) return; | 19883 | if (!start_block.ownerModule().error_tracing) return; |
| 19911 | 19884 | ||
| 19912 | assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere | 19885 | assert(saved_index != .none); // The .error_return_trace_index field was dropped somewhere |
| ... | @@ -19928,7 +19901,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { | ... | @@ -19928,7 +19901,7 @@ fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { |
| 19928 | }, | 19901 | }, |
| 19929 | else => if (ip.isInferredErrorSetType(err_set_ty)) { | 19902 | else => if (ip.isInferredErrorSetType(err_set_ty)) { |
| 19930 | const ies = sema.fn_ret_ty_ies.?; | 19903 | const ies = sema.fn_ret_ty_ies.?; |
| 19931 | assert(ies.func == sema.func_index); | 19904 | assert(ies.func == sema.owner.unwrap().func); |
| 19932 | try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand)); | 19905 | try sema.addToInferredErrorSetPtr(ies, sema.typeOf(uncasted_operand)); |
| 19933 | }, | 19906 | }, |
| 19934 | } | 19907 | } |
| ... | @@ -20232,7 +20205,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is | ... | @@ -20232,7 +20205,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is |
| 20232 | 20205 | ||
| 20233 | if (is_byref) { | 20206 | if (is_byref) { |
| 20234 | const init_val = (try sema.resolveValue(init_ref)).?; | 20207 | const init_val = (try sema.resolveValue(init_ref)).?; |
| 20235 | return anonDeclRef(sema, init_val.toIntern()); | 20208 | return sema.uavRef(init_val.toIntern()); |
| 20236 | } else { | 20209 | } else { |
| 20237 | return init_ref; | 20210 | return init_ref; |
| 20238 | } | 20211 | } |
| ... | @@ -21056,7 +21029,7 @@ fn arrayInitAnon( | ... | @@ -21056,7 +21029,7 @@ fn arrayInitAnon( |
| 21056 | } | 21029 | } |
| 21057 | 21030 | ||
| 21058 | fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref { | 21031 | 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); | 21032 | return if (is_ref) sema.uavRef(val) else Air.internedToRef(val); |
| 21060 | } | 21033 | } |
| 21061 | 21034 | ||
| 21062 | fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 21035 | fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -21163,16 +21136,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -21163,16 +21136,16 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 21163 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); | 21136 | const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty); |
| 21164 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); | 21137 | const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern()); |
| 21165 | 21138 | ||
| 21166 | if (sema.owner_func_index != .none and | 21139 | switch (sema.owner.unwrap()) { |
| 21167 | ip.funcAnalysisUnordered(sema.owner_func_index).calls_or_awaits_errorable_fn and | 21140 | .func => |func| if (ip.funcAnalysisUnordered(func).calls_or_awaits_errorable_fn and block.ownerModule().error_tracing) { |
| 21168 | block.ownerModule().error_tracing) | 21141 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 21169 | { | 21142 | }, |
| 21170 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); | 21143 | .cau => {}, |
| 21171 | } | 21144 | } |
| 21172 | return Air.internedToRef((try pt.intern(.{ .opt = .{ | 21145 | return Air.internedToRef(try pt.intern(.{ .opt = .{ |
| 21173 | .ty = opt_ptr_stack_trace_ty.toIntern(), | 21146 | .ty = opt_ptr_stack_trace_ty.toIntern(), |
| 21174 | .val = .none, | 21147 | .val = .none, |
| 21175 | } }))); | 21148 | } })); |
| 21176 | } | 21149 | } |
| 21177 | 21150 | ||
| 21178 | fn zirFrame( | 21151 | fn zirFrame( |
| ... | @@ -21369,24 +21342,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21369,24 +21342,24 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21369 | const operand = try sema.resolveInst(inst_data.operand); | 21342 | const operand = try sema.resolveInst(inst_data.operand); |
| 21370 | const operand_ty = sema.typeOf(operand); | 21343 | const operand_ty = sema.typeOf(operand); |
| 21371 | const pt = sema.pt; | 21344 | const pt = sema.pt; |
| 21372 | const mod = pt.zcu; | 21345 | const zcu = pt.zcu; |
| 21373 | const ip = &mod.intern_pool; | 21346 | const ip = &zcu.intern_pool; |
| 21374 | 21347 | ||
| 21375 | try operand_ty.resolveLayout(pt); | 21348 | try operand_ty.resolveLayout(pt); |
| 21376 | const enum_ty = switch (operand_ty.zigTypeTag(mod)) { | 21349 | const enum_ty = switch (operand_ty.zigTypeTag(zcu)) { |
| 21377 | .EnumLiteral => { | 21350 | .EnumLiteral => { |
| 21378 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined); | 21351 | const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined); |
| 21379 | const tag_name = ip.indexToKey(val.toIntern()).enum_literal; | 21352 | const tag_name = ip.indexToKey(val.toIntern()).enum_literal; |
| 21380 | return sema.addNullTerminatedStrLit(tag_name); | 21353 | return sema.addNullTerminatedStrLit(tag_name); |
| 21381 | }, | 21354 | }, |
| 21382 | .Enum => operand_ty, | 21355 | .Enum => operand_ty, |
| 21383 | .Union => operand_ty.unionTagType(mod) orelse | 21356 | .Union => operand_ty.unionTagType(zcu) orelse |
| 21384 | return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}), | 21357 | return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(pt)}), |
| 21385 | else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{ | 21358 | else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{ |
| 21386 | operand_ty.fmt(pt), | 21359 | operand_ty.fmt(pt), |
| 21387 | }), | 21360 | }), |
| 21388 | }; | 21361 | }; |
| 21389 | if (enum_ty.enumFieldCount(mod) == 0) { | 21362 | if (enum_ty.enumFieldCount(zcu) == 0) { |
| 21390 | // TODO I don't think this is the correct way to handle this but | 21363 | // TODO I don't think this is the correct way to handle this but |
| 21391 | // it prevents a crash. | 21364 | // it prevents a crash. |
| 21392 | // https://github.com/ziglang/zig/issues/15909 | 21365 | // https://github.com/ziglang/zig/issues/15909 |
| ... | @@ -21394,26 +21367,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -21394,26 +21367,25 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 21394 | enum_ty.fmt(pt), | 21367 | enum_ty.fmt(pt), |
| 21395 | }); | 21368 | }); |
| 21396 | } | 21369 | } |
| 21397 | const enum_decl_index = enum_ty.getOwnerDecl(mod); | ||
| 21398 | const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src); | 21370 | const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src); |
| 21399 | if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| { | 21371 | if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| { |
| 21400 | const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse { | 21372 | const field_index = enum_ty.enumTagFieldIndex(val, zcu) orelse { |
| 21401 | const msg = msg: { | 21373 | const msg = msg: { |
| 21402 | const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{ | 21374 | const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{ |
| 21403 | val.fmtValueSema(pt, sema), mod.declPtr(enum_decl_index).name.fmt(ip), | 21375 | val.fmtValueSema(pt, sema), enum_ty.fmt(pt), |
| 21404 | }); | 21376 | }); |
| 21405 | errdefer msg.destroy(sema.gpa); | 21377 | errdefer msg.destroy(sema.gpa); |
| 21406 | try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{}); | 21378 | try sema.errNote(enum_ty.srcLoc(zcu), msg, "declared here", .{}); |
| 21407 | break :msg msg; | 21379 | break :msg msg; |
| 21408 | }; | 21380 | }; |
| 21409 | return sema.failWithOwnedErrorMsg(block, msg); | 21381 | return sema.failWithOwnedErrorMsg(block, msg); |
| 21410 | }; | 21382 | }; |
| 21411 | // TODO: write something like getCoercedInts to avoid needing to dupe | 21383 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 21412 | const field_name = enum_ty.enumFieldName(field_index, mod); | 21384 | const field_name = enum_ty.enumFieldName(field_index, zcu); |
| 21413 | return sema.addNullTerminatedStrLit(field_name); | 21385 | return sema.addNullTerminatedStrLit(field_name); |
| 21414 | } | 21386 | } |
| 21415 | try sema.requireRuntimeBlock(block, src, operand_src); | 21387 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 21416 | if (block.wantSafety() and mod.backendSupportsFeature(.is_named_enum_value)) { | 21388 | if (block.wantSafety() and zcu.backendSupportsFeature(.is_named_enum_value)) { |
| 21417 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); | 21389 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); |
| 21418 | try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); | 21390 | try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); |
| 21419 | } | 21391 | } |
| ... | @@ -21810,7 +21782,6 @@ fn zirReify( | ... | @@ -21810,7 +21782,6 @@ fn zirReify( |
| 21810 | } | 21782 | } |
| 21811 | 21783 | ||
| 21812 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{ | 21784 | const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{ |
| 21813 | .has_namespace = false, | ||
| 21814 | .key = .{ .reified = .{ | 21785 | .key = .{ .reified = .{ |
| 21815 | .zir_index = try block.trackZir(inst), | 21786 | .zir_index = try block.trackZir(inst), |
| 21816 | } }, | 21787 | } }, |
| ... | @@ -21820,19 +21791,21 @@ fn zirReify( | ... | @@ -21820,19 +21791,21 @@ fn zirReify( |
| 21820 | }; | 21791 | }; |
| 21821 | errdefer wip_ty.cancel(ip, pt.tid); | 21792 | errdefer wip_ty.cancel(ip, pt.tid); |
| 21822 | 21793 | ||
| 21823 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 21794 | wip_ty.setName(ip, try sema.createTypeName( |
| 21824 | block, | 21795 | block, |
| 21825 | Value.fromInterned(wip_ty.index), | ||
| 21826 | name_strategy, | 21796 | name_strategy, |
| 21827 | "opaque", | 21797 | "opaque", |
| 21828 | inst, | 21798 | inst, |
| 21829 | ); | 21799 | wip_ty.index, |
| 21830 | mod.declPtr(new_decl_index).owns_tv = true; | 21800 | )); |
| 21831 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 21832 | 21801 | ||
| 21833 | try pt.finalizeAnonDecl(new_decl_index); | 21802 | const new_namespace_index = try pt.createNamespace(.{ |
| 21803 | .parent = block.namespace.toOptional(), | ||
| 21804 | .owner_type = wip_ty.index, | ||
| 21805 | .file_scope = block.getFileScopeIndex(mod), | ||
| 21806 | }); | ||
| 21834 | 21807 | ||
| 21835 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); | 21808 | return Air.internedToRef(wip_ty.finish(ip, .none, new_namespace_index)); |
| 21836 | }, | 21809 | }, |
| 21837 | .Union => { | 21810 | .Union => { |
| 21838 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); | 21811 | const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); |
| ... | @@ -22001,13 +21974,14 @@ fn reifyEnum( | ... | @@ -22001,13 +21974,14 @@ fn reifyEnum( |
| 22001 | }); | 21974 | }); |
| 22002 | } | 21975 | } |
| 22003 | 21976 | ||
| 21977 | const tracked_inst = try block.trackZir(inst); | ||
| 21978 | |||
| 22004 | const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{ | 21979 | const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{ |
| 22005 | .has_namespace = false, | ||
| 22006 | .has_values = true, | 21980 | .has_values = true, |
| 22007 | .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive, | 21981 | .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive, |
| 22008 | .fields_len = fields_len, | 21982 | .fields_len = fields_len, |
| 22009 | .key = .{ .reified = .{ | 21983 | .key = .{ .reified = .{ |
| 22010 | .zir_index = try block.trackZir(inst), | 21984 | .zir_index = tracked_inst, |
| 22011 | .type_hash = hasher.final(), | 21985 | .type_hash = hasher.final(), |
| 22012 | } }, | 21986 | } }, |
| 22013 | })) { | 21987 | })) { |
| ... | @@ -22020,17 +21994,23 @@ fn reifyEnum( | ... | @@ -22020,17 +21994,23 @@ fn reifyEnum( |
| 22020 | return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{}); | 21994 | return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{}); |
| 22021 | } | 21995 | } |
| 22022 | 21996 | ||
| 22023 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 21997 | wip_ty.setName(ip, try sema.createTypeName( |
| 22024 | block, | 21998 | block, |
| 22025 | Value.fromInterned(wip_ty.index), | ||
| 22026 | name_strategy, | 21999 | name_strategy, |
| 22027 | "enum", | 22000 | "enum", |
| 22028 | inst, | 22001 | inst, |
| 22029 | ); | 22002 | wip_ty.index, |
| 22030 | mod.declPtr(new_decl_index).owns_tv = true; | 22003 | )); |
| 22031 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 22032 | 22004 | ||
| 22033 | wip_ty.prepare(ip, new_decl_index, .none); | 22005 | const new_namespace_index = try pt.createNamespace(.{ |
| 22006 | .parent = block.namespace.toOptional(), | ||
| 22007 | .owner_type = wip_ty.index, | ||
| 22008 | .file_scope = block.getFileScopeIndex(mod), | ||
| 22009 | }); | ||
| 22010 | |||
| 22011 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); | ||
| 22012 | |||
| 22013 | wip_ty.prepare(ip, new_cau_index, new_namespace_index); | ||
| 22034 | wip_ty.setTagTy(ip, tag_ty.toIntern()); | 22014 | wip_ty.setTagTy(ip, tag_ty.toIntern()); |
| 22035 | 22015 | ||
| 22036 | for (0..fields_len) |field_idx| { | 22016 | for (0..fields_len) |field_idx| { |
| ... | @@ -22076,7 +22056,6 @@ fn reifyEnum( | ... | @@ -22076,7 +22056,6 @@ fn reifyEnum( |
| 22076 | return sema.fail(block, src, "non-exhaustive enum specified every value", .{}); | 22056 | return sema.fail(block, src, "non-exhaustive enum specified every value", .{}); |
| 22077 | } | 22057 | } |
| 22078 | 22058 | ||
| 22079 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 22080 | return Air.internedToRef(wip_ty.index); | 22059 | return Air.internedToRef(wip_ty.index); |
| 22081 | } | 22060 | } |
| 22082 | 22061 | ||
| ... | @@ -22134,6 +22113,8 @@ fn reifyUnion( | ... | @@ -22134,6 +22113,8 @@ fn reifyUnion( |
| 22134 | } | 22113 | } |
| 22135 | } | 22114 | } |
| 22136 | 22115 | ||
| 22116 | const tracked_inst = try block.trackZir(inst); | ||
| 22117 | |||
| 22137 | const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{ | 22118 | const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{ |
| 22138 | .flags = .{ | 22119 | .flags = .{ |
| 22139 | .layout = layout, | 22120 | .layout = layout, |
| ... | @@ -22152,13 +22133,12 @@ fn reifyUnion( | ... | @@ -22152,13 +22133,12 @@ fn reifyUnion( |
| 22152 | .assumed_pointer_aligned = false, | 22133 | .assumed_pointer_aligned = false, |
| 22153 | .alignment = .none, | 22134 | .alignment = .none, |
| 22154 | }, | 22135 | }, |
| 22155 | .has_namespace = false, | ||
| 22156 | .fields_len = fields_len, | 22136 | .fields_len = fields_len, |
| 22157 | .enum_tag_ty = .none, // set later because not yet validated | 22137 | .enum_tag_ty = .none, // set later because not yet validated |
| 22158 | .field_types = &.{}, // set later | 22138 | .field_types = &.{}, // set later |
| 22159 | .field_aligns = &.{}, // set later | 22139 | .field_aligns = &.{}, // set later |
| 22160 | .key = .{ .reified = .{ | 22140 | .key = .{ .reified = .{ |
| 22161 | .zir_index = try block.trackZir(inst), | 22141 | .zir_index = tracked_inst, |
| 22162 | .type_hash = hasher.final(), | 22142 | .type_hash = hasher.final(), |
| 22163 | } }, | 22143 | } }, |
| 22164 | })) { | 22144 | })) { |
| ... | @@ -22167,15 +22147,14 @@ fn reifyUnion( | ... | @@ -22167,15 +22147,14 @@ fn reifyUnion( |
| 22167 | }; | 22147 | }; |
| 22168 | errdefer wip_ty.cancel(ip, pt.tid); | 22148 | errdefer wip_ty.cancel(ip, pt.tid); |
| 22169 | 22149 | ||
| 22170 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 22150 | const type_name = try sema.createTypeName( |
| 22171 | block, | 22151 | block, |
| 22172 | Value.fromInterned(wip_ty.index), | ||
| 22173 | name_strategy, | 22152 | name_strategy, |
| 22174 | "union", | 22153 | "union", |
| 22175 | inst, | 22154 | inst, |
| 22155 | wip_ty.index, | ||
| 22176 | ); | 22156 | ); |
| 22177 | mod.declPtr(new_decl_index).owns_tv = true; | 22157 | wip_ty.setName(ip, type_name); |
| 22178 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 22179 | 22158 | ||
| 22180 | const field_types = try sema.arena.alloc(InternPool.Index, fields_len); | 22159 | const field_types = try sema.arena.alloc(InternPool.Index, fields_len); |
| 22181 | const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; | 22160 | const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; |
| ... | @@ -22268,7 +22247,7 @@ fn reifyUnion( | ... | @@ -22268,7 +22247,7 @@ fn reifyUnion( |
| 22268 | } | 22247 | } |
| 22269 | } | 22248 | } |
| 22270 | 22249 | ||
| 22271 | const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index)); | 22250 | const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), wip_ty.index, type_name); |
| 22272 | break :tag_ty .{ enum_tag_ty, false }; | 22251 | break :tag_ty .{ enum_tag_ty, false }; |
| 22273 | }; | 22252 | }; |
| 22274 | errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error | 22253 | errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error |
| ... | @@ -22315,10 +22294,17 @@ fn reifyUnion( | ... | @@ -22315,10 +22294,17 @@ fn reifyUnion( |
| 22315 | loaded_union.setTagType(ip, enum_tag_ty); | 22294 | loaded_union.setTagType(ip, enum_tag_ty); |
| 22316 | loaded_union.setStatus(ip, .have_field_types); | 22295 | loaded_union.setStatus(ip, .have_field_types); |
| 22317 | 22296 | ||
| 22318 | try pt.finalizeAnonDecl(new_decl_index); | 22297 | const new_namespace_index = try pt.createNamespace(.{ |
| 22298 | .parent = block.namespace.toOptional(), | ||
| 22299 | .owner_type = wip_ty.index, | ||
| 22300 | .file_scope = block.getFileScopeIndex(mod), | ||
| 22301 | }); | ||
| 22302 | |||
| 22303 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); | ||
| 22304 | |||
| 22319 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 22305 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 22320 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 22306 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index })); |
| 22321 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); | 22307 | return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index)); |
| 22322 | } | 22308 | } |
| 22323 | 22309 | ||
| 22324 | fn reifyStruct( | 22310 | fn reifyStruct( |
| ... | @@ -22399,6 +22385,8 @@ fn reifyStruct( | ... | @@ -22399,6 +22385,8 @@ fn reifyStruct( |
| 22399 | } | 22385 | } |
| 22400 | } | 22386 | } |
| 22401 | 22387 | ||
| 22388 | const tracked_inst = try block.trackZir(inst); | ||
| 22389 | |||
| 22402 | const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{ | 22390 | const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{ |
| 22403 | .layout = layout, | 22391 | .layout = layout, |
| 22404 | .fields_len = fields_len, | 22392 | .fields_len = fields_len, |
| ... | @@ -22409,9 +22397,8 @@ fn reifyStruct( | ... | @@ -22409,9 +22397,8 @@ fn reifyStruct( |
| 22409 | .any_default_inits = any_default_inits, | 22397 | .any_default_inits = any_default_inits, |
| 22410 | .any_aligned_fields = any_aligned_fields, | 22398 | .any_aligned_fields = any_aligned_fields, |
| 22411 | .inits_resolved = true, | 22399 | .inits_resolved = true, |
| 22412 | .has_namespace = false, | ||
| 22413 | .key = .{ .reified = .{ | 22400 | .key = .{ .reified = .{ |
| 22414 | .zir_index = try block.trackZir(inst), | 22401 | .zir_index = tracked_inst, |
| 22415 | .type_hash = hasher.final(), | 22402 | .type_hash = hasher.final(), |
| 22416 | } }, | 22403 | } }, |
| 22417 | })) { | 22404 | })) { |
| ... | @@ -22426,15 +22413,13 @@ fn reifyStruct( | ... | @@ -22426,15 +22413,13 @@ fn reifyStruct( |
| 22426 | .auto => {}, | 22413 | .auto => {}, |
| 22427 | }; | 22414 | }; |
| 22428 | 22415 | ||
| 22429 | const new_decl_index = try sema.createAnonymousDeclTypeNamed( | 22416 | wip_ty.setName(ip, try sema.createTypeName( |
| 22430 | block, | 22417 | block, |
| 22431 | Value.fromInterned(wip_ty.index), | ||
| 22432 | name_strategy, | 22418 | name_strategy, |
| 22433 | "struct", | 22419 | "struct", |
| 22434 | inst, | 22420 | inst, |
| 22435 | ); | 22421 | wip_ty.index, |
| 22436 | mod.declPtr(new_decl_index).owns_tv = true; | 22422 | )); |
| 22437 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 22438 | 22423 | ||
| 22439 | const struct_type = ip.loadStructType(wip_ty.index); | 22424 | const struct_type = ip.loadStructType(wip_ty.index); |
| 22440 | 22425 | ||
| ... | @@ -22582,10 +22567,17 @@ fn reifyStruct( | ... | @@ -22582,10 +22567,17 @@ fn reifyStruct( |
| 22582 | } | 22567 | } |
| 22583 | } | 22568 | } |
| 22584 | 22569 | ||
| 22585 | try pt.finalizeAnonDecl(new_decl_index); | 22570 | const new_namespace_index = try pt.createNamespace(.{ |
| 22571 | .parent = block.namespace.toOptional(), | ||
| 22572 | .owner_type = wip_ty.index, | ||
| 22573 | .file_scope = block.getFileScopeIndex(mod), | ||
| 22574 | }); | ||
| 22575 | |||
| 22576 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, new_namespace_index, wip_ty.index); | ||
| 22577 | |||
| 22586 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 22578 | try mod.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 22587 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = new_decl_index })); | 22579 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .cau = new_cau_index })); |
| 22588 | return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none)); | 22580 | return Air.internedToRef(wip_ty.finish(ip, new_cau_index.toOptional(), new_namespace_index)); |
| 22589 | } | 22581 | } |
| 22590 | 22582 | ||
| 22591 | fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref { | 22583 | fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref { |
| ... | @@ -26028,7 +26020,8 @@ fn zirVarExtended( | ... | @@ -26028,7 +26020,8 @@ fn zirVarExtended( |
| 26028 | extended: Zir.Inst.Extended.InstData, | 26020 | extended: Zir.Inst.Extended.InstData, |
| 26029 | ) CompileError!Air.Inst.Ref { | 26021 | ) CompileError!Air.Inst.Ref { |
| 26030 | const pt = sema.pt; | 26022 | const pt = sema.pt; |
| 26031 | const mod = pt.zcu; | 26023 | const zcu = pt.zcu; |
| 26024 | const ip = &zcu.intern_pool; | ||
| 26032 | const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand); | 26025 | const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand); |
| 26033 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); | 26026 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); |
| 26034 | const init_src = block.src(.{ .node_offset_var_decl_init = 0 }); | 26027 | const init_src = block.src(.{ .node_offset_var_decl_init = 0 }); |
| ... | @@ -26075,16 +26068,62 @@ fn zirVarExtended( | ... | @@ -26075,16 +26068,62 @@ fn zirVarExtended( |
| 26075 | 26068 | ||
| 26076 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); | 26069 | try sema.validateVarType(block, ty_src, var_ty, small.is_extern); |
| 26077 | 26070 | ||
| 26078 | return Air.internedToRef((try pt.intern(.{ .variable = .{ | 26071 | if (small.is_extern) { |
| 26072 | // We need to resolve the alignment and addrspace early. | ||
| 26073 | // Keep in sync with logic in `Zcu.PerThread.semaCau`. | ||
| 26074 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); | ||
| 26075 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); | ||
| 26076 | |||
| 26077 | const decl_inst, const decl_bodies = decl: { | ||
| 26078 | const decl_inst = sema.getOwnerCauDeclInst().resolve(ip); | ||
| 26079 | const zir_decl, const extra_end = sema.code.getDeclaration(decl_inst); | ||
| 26080 | break :decl .{ decl_inst, zir_decl.getBodies(extra_end, sema.code) }; | ||
| 26081 | }; | ||
| 26082 | |||
| 26083 | const alignment: InternPool.Alignment = a: { | ||
| 26084 | const align_body = decl_bodies.align_body orelse break :a .none; | ||
| 26085 | const align_ref = try sema.resolveInlineBody(block, align_body, decl_inst); | ||
| 26086 | break :a try sema.analyzeAsAlign(block, align_src, align_ref); | ||
| 26087 | }; | ||
| 26088 | |||
| 26089 | const @"addrspace": std.builtin.AddressSpace = as: { | ||
| 26090 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(var_ty.toIntern())) { | ||
| 26091 | .func_type => .function, | ||
| 26092 | else => .variable, | ||
| 26093 | }; | ||
| 26094 | const target = zcu.getTarget(); | ||
| 26095 | const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) { | ||
| 26096 | .function => target_util.defaultAddressSpace(target, .function), | ||
| 26097 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | ||
| 26098 | .constant => target_util.defaultAddressSpace(target, .global_constant), | ||
| 26099 | else => unreachable, | ||
| 26100 | }; | ||
| 26101 | const addrspace_ref = try sema.resolveInlineBody(block, addrspace_body, decl_inst); | ||
| 26102 | break :as try sema.analyzeAsAddressSpace(block, addrspace_src, addrspace_ref, addrspace_ctx); | ||
| 26103 | }; | ||
| 26104 | |||
| 26105 | return Air.internedToRef(try pt.getExtern(.{ | ||
| 26106 | .name = sema.getOwnerCauNavName(), | ||
| 26107 | .ty = var_ty.toIntern(), | ||
| 26108 | .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls), | ||
| 26109 | .is_const = small.is_const, | ||
| 26110 | .is_threadlocal = small.is_threadlocal, | ||
| 26111 | .is_weak_linkage = false, | ||
| 26112 | .alignment = alignment, | ||
| 26113 | .@"addrspace" = @"addrspace", | ||
| 26114 | .zir_index = sema.getOwnerCauDeclInst(), // `declaration` instruction | ||
| 26115 | .owner_nav = undefined, // ignored by `getExtern` | ||
| 26116 | })); | ||
| 26117 | } | ||
| 26118 | assert(!small.is_const); // non-const non-extern variable is not legal | ||
| 26119 | return Air.internedToRef(try pt.intern(.{ .variable = .{ | ||
| 26079 | .ty = var_ty.toIntern(), | 26120 | .ty = var_ty.toIntern(), |
| 26080 | .init = init_val, | 26121 | .init = init_val, |
| 26081 | .decl = sema.owner_decl_index, | 26122 | .owner_nav = sema.getOwnerCauNav(), |
| 26082 | .lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls), | 26123 | .lib_name = try ip.getOrPutStringOpt(sema.gpa, pt.tid, lib_name, .no_embedded_nulls), |
| 26083 | .is_extern = small.is_extern, | ||
| 26084 | .is_const = small.is_const, | ||
| 26085 | .is_threadlocal = small.is_threadlocal, | 26124 | .is_threadlocal = small.is_threadlocal, |
| 26086 | .is_weak_linkage = false, | 26125 | .is_weak_linkage = false, |
| 26087 | } }))); | 26126 | } })); |
| 26088 | } | 26127 | } |
| 26089 | 26128 | ||
| 26090 | fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 26129 | fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -26255,10 +26294,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -26255,10 +26294,23 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26255 | else => |e| return e, | 26294 | else => |e| return e, |
| 26256 | }; | 26295 | }; |
| 26257 | break :blk mod.toEnum(std.builtin.CallingConvention, cc_val); | 26296 | break :blk mod.toEnum(std.builtin.CallingConvention, cc_val); |
| 26258 | } else if (sema.owner_decl.is_exported and has_body) | 26297 | } else cc: { |
| 26259 | .C | 26298 | if (has_body) { |
| 26260 | else | 26299 | const decl_inst = if (sema.generic_owner != .none) decl_inst: { |
| 26261 | .Unspecified; | 26300 | // Generic instance -- use the original function declaration to |
| 26301 | // look for the `export` syntax. | ||
| 26302 | const nav = mod.intern_pool.getNav(mod.funcInfo(sema.generic_owner).owner_nav); | ||
| 26303 | const cau = mod.intern_pool.getCau(nav.analysis_owner.unwrap().?); | ||
| 26304 | break :decl_inst cau.zir_index; | ||
| 26305 | } else sema.getOwnerCauDeclInst(); // not an instantiation so we're analyzing a function declaration Cau | ||
| 26306 | |||
| 26307 | const zir_decl = sema.code.getDeclaration(decl_inst.resolve(&mod.intern_pool))[0]; | ||
| 26308 | if (zir_decl.flags.is_export) { | ||
| 26309 | break :cc .C; | ||
| 26310 | } | ||
| 26311 | } | ||
| 26312 | break :cc .Unspecified; | ||
| 26313 | }; | ||
| 26262 | 26314 | ||
| 26263 | const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: { | 26315 | const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: { |
| 26264 | const body_len = sema.code.extra[extra_index]; | 26316 | const body_len = sema.code.extra[extra_index]; |
| ... | @@ -26600,42 +26652,32 @@ fn zirBuiltinExtern( | ... | @@ -26600,42 +26652,32 @@ fn zirBuiltinExtern( |
| 26600 | 26652 | ||
| 26601 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); | 26653 | const options = try sema.resolveExternOptions(block, options_src, extra.rhs); |
| 26602 | 26654 | ||
| 26655 | // TODO: error for threadlocal functions, non-const functions, etc | ||
| 26656 | |||
| 26603 | if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) { | 26657 | if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) { |
| 26604 | ty = try pt.optionalType(ty.toIntern()); | 26658 | ty = try pt.optionalType(ty.toIntern()); |
| 26605 | } | 26659 | } |
| 26606 | const ptr_info = ty.ptrInfo(mod); | 26660 | const ptr_info = ty.ptrInfo(mod); |
| 26607 | 26661 | ||
| 26608 | const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace); | 26662 | const extern_val = try pt.getExtern(.{ |
| 26609 | errdefer pt.destroyDecl(new_decl_index); | 26663 | .name = options.name, |
| 26610 | const new_decl = mod.declPtr(new_decl_index); | 26664 | .ty = ptr_info.child, |
| 26611 | try pt.initNewAnonDecl( | 26665 | .lib_name = options.library_name, |
| 26612 | new_decl_index, | 26666 | .is_const = ptr_info.flags.is_const, |
| 26613 | Value.fromInterned( | 26667 | .is_threadlocal = options.is_thread_local, |
| 26614 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) | 26668 | .is_weak_linkage = options.linkage == .weak, |
| 26615 | try ip.getExternFunc(sema.gpa, pt.tid, .{ | 26669 | .alignment = ptr_info.flags.alignment, |
| 26616 | .ty = ptr_info.child, | 26670 | .@"addrspace" = ptr_info.flags.address_space, |
| 26617 | .decl = new_decl_index, | 26671 | // This instruction is just for source locations. |
| 26618 | .lib_name = options.library_name, | 26672 | // `builtin_extern` doesn't provide enough information, and isn't currently tracked. |
| 26619 | }) | 26673 | // So, for now, just use our containing `declaration`. |
| 26620 | else | 26674 | .zir_index = switch (sema.owner.unwrap()) { |
| 26621 | try pt.intern(.{ .variable = .{ | 26675 | .cau => sema.getOwnerCauDeclInst(), |
| 26622 | .ty = ptr_info.child, | 26676 | .func => sema.getOwnerFuncDeclInst(), |
| 26623 | .init = .none, | 26677 | }, |
| 26624 | .decl = new_decl_index, | 26678 | .owner_nav = undefined, // ignored by `getExtern` |
| 26625 | .lib_name = options.library_name, | 26679 | }); |
| 26626 | .is_extern = true, | 26680 | const extern_nav = ip.indexToKey(extern_val).@"extern".owner_nav; |
| 26627 | .is_const = ptr_info.flags.is_const, | ||
| 26628 | .is_threadlocal = options.is_thread_local, | ||
| 26629 | .is_weak_linkage = options.linkage == .weak, | ||
| 26630 | } }), | ||
| 26631 | ), | ||
| 26632 | options.name, | ||
| 26633 | .none, | ||
| 26634 | ); | ||
| 26635 | new_decl.owns_tv = true; | ||
| 26636 | // Note that this will queue the anon decl for codegen, so that the backend can | ||
| 26637 | // correctly handle the extern, including duplicate detection. | ||
| 26638 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 26639 | 26681 | ||
| 26640 | return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{ | 26682 | return Air.internedToRef((try pt.getCoerced(Value.fromInterned(try pt.intern(.{ .ptr = .{ |
| 26641 | .ty = switch (ip.indexToKey(ty.toIntern())) { | 26683 | .ty = switch (ip.indexToKey(ty.toIntern())) { |
| ... | @@ -26643,7 +26685,7 @@ fn zirBuiltinExtern( | ... | @@ -26643,7 +26685,7 @@ fn zirBuiltinExtern( |
| 26643 | .opt_type => |child_type| child_type, | 26685 | .opt_type => |child_type| child_type, |
| 26644 | else => unreachable, | 26686 | else => unreachable, |
| 26645 | }, | 26687 | }, |
| 26646 | .base_addr = .{ .decl = new_decl_index }, | 26688 | .base_addr = .{ .nav = extern_nav }, |
| 26647 | .byte_offset = 0, | 26689 | .byte_offset = 0, |
| 26648 | } })), ty)).toIntern()); | 26690 | } })), ty)).toIntern()); |
| 26649 | } | 26691 | } |
| ... | @@ -27129,17 +27171,15 @@ fn explainWhyTypeIsNotPacked( | ... | @@ -27129,17 +27171,15 @@ fn explainWhyTypeIsNotPacked( |
| 27129 | } | 27171 | } |
| 27130 | } | 27172 | } |
| 27131 | 27173 | ||
| 27132 | fn prepareSimplePanic(sema: *Sema) !void { | 27174 | fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void { |
| 27133 | const pt = sema.pt; | 27175 | const pt = sema.pt; |
| 27134 | const mod = pt.zcu; | 27176 | const mod = pt.zcu; |
| 27135 | 27177 | ||
| 27136 | if (mod.panic_func_index == .none) { | 27178 | if (mod.panic_func_index == .none) { |
| 27137 | const decl_index = (try pt.getBuiltinDecl("panic")); | 27179 | const fn_ref = try sema.analyzeNavVal(block, src, try pt.getBuiltinNav("panic")); |
| 27138 | // decl_index may be an alias; we must find the decl that actually | 27180 | const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{ |
| 27139 | // owns the function. | 27181 | .needed_comptime_reason = "panic handler must be comptime-known", |
| 27140 | try sema.ensureDeclAnalyzed(decl_index); | 27182 | }); |
| 27141 | const fn_val = try mod.declPtr(decl_index).valueOrFail(); | ||
| 27142 | try sema.declareDependency(.{ .decl_val = decl_index }); | ||
| 27143 | assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn); | 27183 | assert(fn_val.typeOf(mod).zigTypeTag(mod) == .Fn); |
| 27144 | assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod))); | 27184 | assert(try sema.fnHasRuntimeBits(fn_val.typeOf(mod))); |
| 27145 | try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern()); | 27185 | try mod.ensureFuncBodyAnalysisQueued(fn_val.toIntern()); |
| ... | @@ -27167,16 +27207,16 @@ fn prepareSimplePanic(sema: *Sema) !void { | ... | @@ -27167,16 +27207,16 @@ fn prepareSimplePanic(sema: *Sema) !void { |
| 27167 | /// Backends depend on panic decls being available when lowering safety-checked | 27207 | /// Backends depend on panic decls being available when lowering safety-checked |
| 27168 | /// instructions. This function ensures the panic function will be available to | 27208 | /// instructions. This function ensures the panic function will be available to |
| 27169 | /// be called during that time. | 27209 | /// be called during that time. |
| 27170 | fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternPool.DeclIndex { | 27210 | fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) !InternPool.Nav.Index { |
| 27171 | const pt = sema.pt; | 27211 | const pt = sema.pt; |
| 27172 | const mod = pt.zcu; | 27212 | const mod = pt.zcu; |
| 27173 | const gpa = sema.gpa; | 27213 | const gpa = sema.gpa; |
| 27174 | if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x; | 27214 | if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x; |
| 27175 | 27215 | ||
| 27176 | try sema.prepareSimplePanic(); | 27216 | try sema.prepareSimplePanic(block, src); |
| 27177 | 27217 | ||
| 27178 | const panic_messages_ty = try pt.getBuiltinType("panic_messages"); | 27218 | const panic_messages_ty = try pt.getBuiltinType("panic_messages"); |
| 27179 | const msg_decl_index = (sema.namespaceLookup( | 27219 | const msg_nav_index = (sema.namespaceLookup( |
| 27180 | block, | 27220 | block, |
| 27181 | LazySrcLoc.unneeded, | 27221 | LazySrcLoc.unneeded, |
| 27182 | panic_messages_ty.getNamespaceIndex(mod), | 27222 | panic_messages_ty.getNamespaceIndex(mod), |
| ... | @@ -27186,9 +27226,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP | ... | @@ -27186,9 +27226,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP |
| 27186 | error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, | 27226 | error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, |
| 27187 | error.OutOfMemory => |e| return e, | 27227 | error.OutOfMemory => |e| return e, |
| 27188 | }).?; | 27228 | }).?; |
| 27189 | try sema.ensureDeclAnalyzed(msg_decl_index); | 27229 | try sema.ensureNavResolved(src, msg_nav_index); |
| 27190 | mod.panic_messages[@intFromEnum(panic_id)] = msg_decl_index.toOptional(); | 27230 | mod.panic_messages[@intFromEnum(panic_id)] = msg_nav_index.toOptional(); |
| 27191 | return msg_decl_index; | 27231 | return msg_nav_index; |
| 27192 | } | 27232 | } |
| 27193 | 27233 | ||
| 27194 | fn addSafetyCheck( | 27234 | fn addSafetyCheck( |
| ... | @@ -27282,10 +27322,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst. | ... | @@ -27282,10 +27322,10 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst. |
| 27282 | return; | 27322 | return; |
| 27283 | } | 27323 | } |
| 27284 | 27324 | ||
| 27285 | try sema.prepareSimplePanic(); | 27325 | try sema.prepareSimplePanic(block, src); |
| 27286 | 27326 | ||
| 27287 | const panic_func = mod.funcInfo(mod.panic_func_index); | 27327 | const panic_func = mod.funcInfo(mod.panic_func_index); |
| 27288 | const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl); | 27328 | const panic_fn = try sema.analyzeNavVal(block, src, panic_func.owner_nav); |
| 27289 | const null_stack_trace = Air.internedToRef(mod.null_stack_trace); | 27329 | const null_stack_trace = Air.internedToRef(mod.null_stack_trace); |
| 27290 | 27330 | ||
| 27291 | const opt_usize_ty = try pt.optionalType(.usize_type); | 27331 | const opt_usize_ty = try pt.optionalType(.usize_type); |
| ... | @@ -27455,8 +27495,8 @@ fn safetyCheckFormatted( | ... | @@ -27455,8 +27495,8 @@ fn safetyCheckFormatted( |
| 27455 | } | 27495 | } |
| 27456 | 27496 | ||
| 27457 | fn safetyPanic(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Module.PanicId) CompileError!void { | 27497 | 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); | 27498 | const msg_nav_index = try sema.preparePanicId(block, src, panic_id); |
| 27459 | const msg_inst = try sema.analyzeDeclVal(block, src, msg_decl_index); | 27499 | const msg_inst = try sema.analyzeNavVal(block, src, msg_nav_index); |
| 27460 | try sema.panicWithMsg(block, src, msg_inst, .@"safety check"); | 27500 | try sema.panicWithMsg(block, src, msg_inst, .@"safety check"); |
| 27461 | } | 27501 | } |
| 27462 | 27502 | ||
| ... | @@ -27628,21 +27668,21 @@ fn fieldVal( | ... | @@ -27628,21 +27668,21 @@ fn fieldVal( |
| 27628 | return Air.internedToRef(enum_val.toIntern()); | 27668 | return Air.internedToRef(enum_val.toIntern()); |
| 27629 | }, | 27669 | }, |
| 27630 | .Struct, .Opaque => { | 27670 | .Struct, .Opaque => { |
| 27631 | if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | 27671 | switch (child_type.toIntern()) { |
| 27632 | return inst; | 27672 | .empty_struct_type, .anyopaque_type => {}, // no namespace |
| 27673 | else => if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | ||
| 27674 | return inst; | ||
| 27675 | }, | ||
| 27633 | } | 27676 | } |
| 27634 | return sema.failWithBadMemberAccess(block, child_type, src, field_name); | 27677 | return sema.failWithBadMemberAccess(block, child_type, src, field_name); |
| 27635 | }, | 27678 | }, |
| 27636 | else => { | 27679 | else => return sema.failWithOwnedErrorMsg(block, msg: { |
| 27637 | const msg = msg: { | 27680 | const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)}); |
| 27638 | const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(pt)}); | 27681 | errdefer msg.destroy(sema.gpa); |
| 27639 | errdefer msg.destroy(sema.gpa); | 27682 | if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); |
| 27640 | if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{}); | 27683 | if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{}); |
| 27641 | if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{}); | 27684 | break :msg msg; |
| 27642 | break :msg msg; | 27685 | }), |
| 27643 | }; | ||
| 27644 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 27645 | }, | ||
| 27646 | } | 27686 | } |
| 27647 | }, | 27687 | }, |
| 27648 | .Struct => if (is_pointer_to) { | 27688 | .Struct => if (is_pointer_to) { |
| ... | @@ -27700,7 +27740,7 @@ fn fieldPtr( | ... | @@ -27700,7 +27740,7 @@ fn fieldPtr( |
| 27700 | .Array => { | 27740 | .Array => { |
| 27701 | if (field_name.eqlSlice("len", ip)) { | 27741 | if (field_name.eqlSlice("len", ip)) { |
| 27702 | const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod)); | 27742 | const int_val = try pt.intValue(Type.usize, inner_ty.arrayLen(mod)); |
| 27703 | return anonDeclRef(sema, int_val.toIntern()); | 27743 | return uavRef(sema, int_val.toIntern()); |
| 27704 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { | 27744 | } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) { |
| 27705 | const ptr_info = object_ty.ptrInfo(mod); | 27745 | const ptr_info = object_ty.ptrInfo(mod); |
| 27706 | const new_ptr_ty = try pt.ptrTypeSema(.{ | 27746 | const new_ptr_ty = try pt.ptrTypeSema(.{ |
| ... | @@ -27839,7 +27879,7 @@ fn fieldPtr( | ... | @@ -27839,7 +27879,7 @@ fn fieldPtr( |
| 27839 | child_type | 27879 | child_type |
| 27840 | else | 27880 | else |
| 27841 | try pt.singleErrorSetType(field_name); | 27881 | try pt.singleErrorSetType(field_name); |
| 27842 | return anonDeclRef(sema, try pt.intern(.{ .err = .{ | 27882 | return uavRef(sema, try pt.intern(.{ .err = .{ |
| 27843 | .ty = error_set_type.toIntern(), | 27883 | .ty = error_set_type.toIntern(), |
| 27844 | .name = field_name, | 27884 | .name = field_name, |
| 27845 | } })); | 27885 | } })); |
| ... | @@ -27853,7 +27893,7 @@ fn fieldPtr( | ... | @@ -27853,7 +27893,7 @@ fn fieldPtr( |
| 27853 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| { | 27893 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| { |
| 27854 | const field_index_u32: u32 = @intCast(field_index); | 27894 | const field_index_u32: u32 = @intCast(field_index); |
| 27855 | const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32); | 27895 | const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32); |
| 27856 | return anonDeclRef(sema, idx_val.toIntern()); | 27896 | return uavRef(sema, idx_val.toIntern()); |
| 27857 | } | 27897 | } |
| 27858 | } | 27898 | } |
| 27859 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); | 27899 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| ... | @@ -27867,7 +27907,7 @@ fn fieldPtr( | ... | @@ -27867,7 +27907,7 @@ fn fieldPtr( |
| 27867 | }; | 27907 | }; |
| 27868 | const field_index_u32: u32 = @intCast(field_index); | 27908 | const field_index_u32: u32 = @intCast(field_index); |
| 27869 | const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32); | 27909 | const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32); |
| 27870 | return anonDeclRef(sema, idx_val.toIntern()); | 27910 | return uavRef(sema, idx_val.toIntern()); |
| 27871 | }, | 27911 | }, |
| 27872 | .Struct, .Opaque => { | 27912 | .Struct, .Opaque => { |
| 27873 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { | 27913 | if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| { |
| ... | @@ -27923,18 +27963,18 @@ fn fieldCallBind( | ... | @@ -27923,18 +27963,18 @@ fn fieldCallBind( |
| 27923 | // in `fieldVal`. This function takes a pointer and returns a pointer. | 27963 | // in `fieldVal`. This function takes a pointer and returns a pointer. |
| 27924 | 27964 | ||
| 27925 | const pt = sema.pt; | 27965 | const pt = sema.pt; |
| 27926 | const mod = pt.zcu; | 27966 | const zcu = pt.zcu; |
| 27927 | const ip = &mod.intern_pool; | 27967 | const ip = &zcu.intern_pool; |
| 27928 | const raw_ptr_src = src; // TODO better source location | 27968 | const raw_ptr_src = src; // TODO better source location |
| 27929 | const raw_ptr_ty = sema.typeOf(raw_ptr); | 27969 | const raw_ptr_ty = sema.typeOf(raw_ptr); |
| 27930 | const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C)) | 27970 | const inner_ty = if (raw_ptr_ty.zigTypeTag(zcu) == .Pointer and (raw_ptr_ty.ptrSize(zcu) == .One or raw_ptr_ty.ptrSize(zcu) == .C)) |
| 27931 | raw_ptr_ty.childType(mod) | 27971 | raw_ptr_ty.childType(zcu) |
| 27932 | else | 27972 | else |
| 27933 | return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)}); | 27973 | return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(pt)}); |
| 27934 | 27974 | ||
| 27935 | // Optionally dereference a second pointer to get the concrete type. | 27975 | // Optionally dereference a second pointer to get the concrete type. |
| 27936 | const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One; | 27976 | const is_double_ptr = inner_ty.zigTypeTag(zcu) == .Pointer and inner_ty.ptrSize(zcu) == .One; |
| 27937 | const concrete_ty = if (is_double_ptr) inner_ty.childType(mod) else inner_ty; | 27977 | const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty; |
| 27938 | const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty; | 27978 | const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty; |
| 27939 | const object_ptr = if (is_double_ptr) | 27979 | const object_ptr = if (is_double_ptr) |
| 27940 | try sema.analyzeLoad(block, src, raw_ptr, src) | 27980 | try sema.analyzeLoad(block, src, raw_ptr, src) |
| ... | @@ -27942,36 +27982,36 @@ fn fieldCallBind( | ... | @@ -27942,36 +27982,36 @@ fn fieldCallBind( |
| 27942 | raw_ptr; | 27982 | raw_ptr; |
| 27943 | 27983 | ||
| 27944 | find_field: { | 27984 | find_field: { |
| 27945 | switch (concrete_ty.zigTypeTag(mod)) { | 27985 | switch (concrete_ty.zigTypeTag(zcu)) { |
| 27946 | .Struct => { | 27986 | .Struct => { |
| 27947 | try concrete_ty.resolveFields(pt); | 27987 | try concrete_ty.resolveFields(pt); |
| 27948 | if (mod.typeToStruct(concrete_ty)) |struct_type| { | 27988 | if (zcu.typeToStruct(concrete_ty)) |struct_type| { |
| 27949 | const field_index = struct_type.nameIndex(ip, field_name) orelse | 27989 | const field_index = struct_type.nameIndex(ip, field_name) orelse |
| 27950 | break :find_field; | 27990 | break :find_field; |
| 27951 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); | 27991 | const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); |
| 27952 | 27992 | ||
| 27953 | return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr); | 27993 | return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr); |
| 27954 | } else if (concrete_ty.isTuple(mod)) { | 27994 | } else if (concrete_ty.isTuple(zcu)) { |
| 27955 | if (field_name.eqlSlice("len", ip)) { | 27995 | if (field_name.eqlSlice("len", ip)) { |
| 27956 | return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(mod)) }; | 27996 | return .{ .direct = try pt.intRef(Type.usize, concrete_ty.structFieldCount(zcu)) }; |
| 27957 | } | 27997 | } |
| 27958 | if (field_name.toUnsigned(ip)) |field_index| { | 27998 | if (field_name.toUnsigned(ip)) |field_index| { |
| 27959 | if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field; | 27999 | if (field_index >= concrete_ty.structFieldCount(zcu)) break :find_field; |
| 27960 | return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, mod), field_index, object_ptr); | 28000 | return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, zcu), field_index, object_ptr); |
| 27961 | } | 28001 | } |
| 27962 | } else { | 28002 | } else { |
| 27963 | const max = concrete_ty.structFieldCount(mod); | 28003 | const max = concrete_ty.structFieldCount(zcu); |
| 27964 | for (0..max) |i_usize| { | 28004 | for (0..max) |i_usize| { |
| 27965 | const i: u32 = @intCast(i_usize); | 28005 | const i: u32 = @intCast(i_usize); |
| 27966 | if (field_name == concrete_ty.structFieldName(i, mod).unwrap().?) { | 28006 | if (field_name == concrete_ty.structFieldName(i, zcu).unwrap().?) { |
| 27967 | return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, mod), i, object_ptr); | 28007 | return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, zcu), i, object_ptr); |
| 27968 | } | 28008 | } |
| 27969 | } | 28009 | } |
| 27970 | } | 28010 | } |
| 27971 | }, | 28011 | }, |
| 27972 | .Union => { | 28012 | .Union => { |
| 27973 | try concrete_ty.resolveFields(pt); | 28013 | try concrete_ty.resolveFields(pt); |
| 27974 | const union_obj = mod.typeToUnion(concrete_ty).?; | 28014 | const union_obj = zcu.typeToUnion(concrete_ty).?; |
| 27975 | _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field; | 28015 | _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field; |
| 27976 | const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false); | 28016 | const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false); |
| 27977 | return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) }; | 28017 | return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) }; |
| ... | @@ -27985,23 +28025,23 @@ fn fieldCallBind( | ... | @@ -27985,23 +28025,23 @@ fn fieldCallBind( |
| 27985 | } | 28025 | } |
| 27986 | 28026 | ||
| 27987 | // If we get here, we need to look for a decl in the struct type instead. | 28027 | // If we get here, we need to look for a decl in the struct type instead. |
| 27988 | const found_decl = found_decl: { | 28028 | const found_nav = found_nav: { |
| 27989 | const namespace = concrete_ty.getNamespace(mod) orelse | 28029 | const namespace = concrete_ty.getNamespace(zcu).unwrap() orelse |
| 27990 | break :found_decl null; | 28030 | break :found_nav null; |
| 27991 | const decl_idx = (try sema.namespaceLookup(block, src, namespace, field_name)) orelse | 28031 | const nav_index = try sema.namespaceLookup(block, src, namespace, field_name) orelse |
| 27992 | break :found_decl null; | 28032 | break :found_nav null; |
| 27993 | 28033 | ||
| 27994 | const decl_val = try sema.analyzeDeclVal(block, src, decl_idx); | 28034 | const decl_val = try sema.analyzeNavVal(block, src, nav_index); |
| 27995 | const decl_type = sema.typeOf(decl_val); | 28035 | const decl_type = sema.typeOf(decl_val); |
| 27996 | if (mod.typeToFunc(decl_type)) |func_type| f: { | 28036 | if (zcu.typeToFunc(decl_type)) |func_type| f: { |
| 27997 | if (func_type.param_types.len == 0) break :f; | 28037 | if (func_type.param_types.len == 0) break :f; |
| 27998 | 28038 | ||
| 27999 | const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]); | 28039 | const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]); |
| 28000 | if (first_param_type.isGenericPoison() or | 28040 | if (first_param_type.isGenericPoison() or |
| 28001 | (first_param_type.zigTypeTag(mod) == .Pointer and | 28041 | (first_param_type.zigTypeTag(zcu) == .Pointer and |
| 28002 | (first_param_type.ptrSize(mod) == .One or | 28042 | (first_param_type.ptrSize(zcu) == .One or |
| 28003 | first_param_type.ptrSize(mod) == .C) and | 28043 | first_param_type.ptrSize(zcu) == .C) and |
| 28004 | first_param_type.childType(mod).eql(concrete_ty, mod))) | 28044 | first_param_type.childType(zcu).eql(concrete_ty, zcu))) |
| 28005 | { | 28045 | { |
| 28006 | // Note that if the param type is generic poison, we know that it must | 28046 | // 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 | 28047 | // specifically be `anytype` since it's the first parameter, meaning we |
| ... | @@ -28012,31 +28052,31 @@ fn fieldCallBind( | ... | @@ -28012,31 +28052,31 @@ fn fieldCallBind( |
| 28012 | .func_inst = decl_val, | 28052 | .func_inst = decl_val, |
| 28013 | .arg0_inst = object_ptr, | 28053 | .arg0_inst = object_ptr, |
| 28014 | } }; | 28054 | } }; |
| 28015 | } else if (first_param_type.eql(concrete_ty, mod)) { | 28055 | } else if (first_param_type.eql(concrete_ty, zcu)) { |
| 28016 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); | 28056 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); |
| 28017 | return .{ .method = .{ | 28057 | return .{ .method = .{ |
| 28018 | .func_inst = decl_val, | 28058 | .func_inst = decl_val, |
| 28019 | .arg0_inst = deref, | 28059 | .arg0_inst = deref, |
| 28020 | } }; | 28060 | } }; |
| 28021 | } else if (first_param_type.zigTypeTag(mod) == .Optional) { | 28061 | } else if (first_param_type.zigTypeTag(zcu) == .Optional) { |
| 28022 | const child = first_param_type.optionalChild(mod); | 28062 | const child = first_param_type.optionalChild(zcu); |
| 28023 | if (child.eql(concrete_ty, mod)) { | 28063 | if (child.eql(concrete_ty, zcu)) { |
| 28024 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); | 28064 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); |
| 28025 | return .{ .method = .{ | 28065 | return .{ .method = .{ |
| 28026 | .func_inst = decl_val, | 28066 | .func_inst = decl_val, |
| 28027 | .arg0_inst = deref, | 28067 | .arg0_inst = deref, |
| 28028 | } }; | 28068 | } }; |
| 28029 | } else if (child.zigTypeTag(mod) == .Pointer and | 28069 | } else if (child.zigTypeTag(zcu) == .Pointer and |
| 28030 | child.ptrSize(mod) == .One and | 28070 | child.ptrSize(zcu) == .One and |
| 28031 | child.childType(mod).eql(concrete_ty, mod)) | 28071 | child.childType(zcu).eql(concrete_ty, zcu)) |
| 28032 | { | 28072 | { |
| 28033 | return .{ .method = .{ | 28073 | return .{ .method = .{ |
| 28034 | .func_inst = decl_val, | 28074 | .func_inst = decl_val, |
| 28035 | .arg0_inst = object_ptr, | 28075 | .arg0_inst = object_ptr, |
| 28036 | } }; | 28076 | } }; |
| 28037 | } | 28077 | } |
| 28038 | } else if (first_param_type.zigTypeTag(mod) == .ErrorUnion and | 28078 | } else if (first_param_type.zigTypeTag(zcu) == .ErrorUnion and |
| 28039 | first_param_type.errorUnionPayload(mod).eql(concrete_ty, mod)) | 28079 | first_param_type.errorUnionPayload(zcu).eql(concrete_ty, zcu)) |
| 28040 | { | 28080 | { |
| 28041 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); | 28081 | const deref = try sema.analyzeLoad(block, src, object_ptr, src); |
| 28042 | return .{ .method = .{ | 28082 | return .{ .method = .{ |
| ... | @@ -28045,7 +28085,7 @@ fn fieldCallBind( | ... | @@ -28045,7 +28085,7 @@ fn fieldCallBind( |
| 28045 | } }; | 28085 | } }; |
| 28046 | } | 28086 | } |
| 28047 | } | 28087 | } |
| 28048 | break :found_decl decl_idx; | 28088 | break :found_nav nav_index; |
| 28049 | }; | 28089 | }; |
| 28050 | 28090 | ||
| 28051 | const msg = msg: { | 28091 | const msg = msg: { |
| ... | @@ -28055,14 +28095,15 @@ fn fieldCallBind( | ... | @@ -28055,14 +28095,15 @@ fn fieldCallBind( |
| 28055 | }); | 28095 | }); |
| 28056 | errdefer msg.destroy(sema.gpa); | 28096 | errdefer msg.destroy(sema.gpa); |
| 28057 | try sema.addDeclaredHereNote(msg, concrete_ty); | 28097 | try sema.addDeclaredHereNote(msg, concrete_ty); |
| 28058 | if (found_decl) |decl_idx| { | 28098 | if (found_nav) |nav_index| { |
| 28059 | const decl = mod.declPtr(decl_idx); | 28099 | try sema.errNote( |
| 28060 | try sema.errNote(.{ | 28100 | zcu.navSrcLoc(nav_index), |
| 28061 | .base_node_inst = decl.zir_decl_index.unwrap().?, | 28101 | msg, |
| 28062 | .offset = LazySrcLoc.Offset.nodeOffset(0), | 28102 | "'{}' is not a member function", |
| 28063 | }, msg, "'{}' is not a member function", .{field_name.fmt(ip)}); | 28103 | .{field_name.fmt(ip)}, |
| 28104 | ); | ||
| 28064 | } | 28105 | } |
| 28065 | if (concrete_ty.zigTypeTag(mod) == .ErrorUnion) { | 28106 | if (concrete_ty.zigTypeTag(zcu) == .ErrorUnion) { |
| 28066 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); | 28107 | try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{}); |
| 28067 | } | 28108 | } |
| 28068 | if (is_double_ptr) { | 28109 | if (is_double_ptr) { |
| ... | @@ -28117,29 +28158,24 @@ fn namespaceLookup( | ... | @@ -28117,29 +28158,24 @@ fn namespaceLookup( |
| 28117 | sema: *Sema, | 28158 | sema: *Sema, |
| 28118 | block: *Block, | 28159 | block: *Block, |
| 28119 | src: LazySrcLoc, | 28160 | src: LazySrcLoc, |
| 28120 | opt_namespace: InternPool.OptionalNamespaceIndex, | 28161 | namespace: InternPool.NamespaceIndex, |
| 28121 | decl_name: InternPool.NullTerminatedString, | 28162 | decl_name: InternPool.NullTerminatedString, |
| 28122 | ) CompileError!?InternPool.DeclIndex { | 28163 | ) CompileError!?InternPool.Nav.Index { |
| 28123 | const pt = sema.pt; | 28164 | const pt = sema.pt; |
| 28124 | const mod = pt.zcu; | 28165 | const zcu = pt.zcu; |
| 28125 | const gpa = sema.gpa; | 28166 | const gpa = sema.gpa; |
| 28126 | if (try sema.lookupInNamespace(block, src, opt_namespace, decl_name, true)) |decl_index| { | 28167 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| { |
| 28127 | const decl = mod.declPtr(decl_index); | 28168 | if (!lookup.accessible) { |
| 28128 | if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) { | 28169 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 28129 | const msg = msg: { | ||
| 28130 | const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{ | 28170 | const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{ |
| 28131 | decl_name.fmt(&mod.intern_pool), | 28171 | decl_name.fmt(&zcu.intern_pool), |
| 28132 | }); | 28172 | }); |
| 28133 | errdefer msg.destroy(gpa); | 28173 | errdefer msg.destroy(gpa); |
| 28134 | try sema.errNote(.{ | 28174 | try sema.errNote(zcu.navSrcLoc(lookup.nav), msg, "declared here", .{}); |
| 28135 | .base_node_inst = decl.zir_decl_index.unwrap().?, | ||
| 28136 | .offset = LazySrcLoc.Offset.nodeOffset(0), | ||
| 28137 | }, msg, "declared here", .{}); | ||
| 28138 | break :msg msg; | 28175 | break :msg msg; |
| 28139 | }; | 28176 | }); |
| 28140 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 28141 | } | 28177 | } |
| 28142 | return decl_index; | 28178 | return lookup.nav; |
| 28143 | } | 28179 | } |
| 28144 | return null; | 28180 | return null; |
| 28145 | } | 28181 | } |
| ... | @@ -28148,22 +28184,22 @@ fn namespaceLookupRef( | ... | @@ -28148,22 +28184,22 @@ fn namespaceLookupRef( |
| 28148 | sema: *Sema, | 28184 | sema: *Sema, |
| 28149 | block: *Block, | 28185 | block: *Block, |
| 28150 | src: LazySrcLoc, | 28186 | src: LazySrcLoc, |
| 28151 | opt_namespace: InternPool.OptionalNamespaceIndex, | 28187 | namespace: InternPool.NamespaceIndex, |
| 28152 | decl_name: InternPool.NullTerminatedString, | 28188 | decl_name: InternPool.NullTerminatedString, |
| 28153 | ) CompileError!?Air.Inst.Ref { | 28189 | ) CompileError!?Air.Inst.Ref { |
| 28154 | const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null; | 28190 | const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null; |
| 28155 | return try sema.analyzeDeclRef(src, decl); | 28191 | return try sema.analyzeNavRef(src, nav); |
| 28156 | } | 28192 | } |
| 28157 | 28193 | ||
| 28158 | fn namespaceLookupVal( | 28194 | fn namespaceLookupVal( |
| 28159 | sema: *Sema, | 28195 | sema: *Sema, |
| 28160 | block: *Block, | 28196 | block: *Block, |
| 28161 | src: LazySrcLoc, | 28197 | src: LazySrcLoc, |
| 28162 | opt_namespace: InternPool.OptionalNamespaceIndex, | 28198 | namespace: InternPool.NamespaceIndex, |
| 28163 | decl_name: InternPool.NullTerminatedString, | 28199 | decl_name: InternPool.NullTerminatedString, |
| 28164 | ) CompileError!?Air.Inst.Ref { | 28200 | ) CompileError!?Air.Inst.Ref { |
| 28165 | const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null; | 28201 | const nav = try sema.namespaceLookup(block, src, namespace, decl_name) orelse return null; |
| 28166 | return try sema.analyzeDeclVal(block, src, decl); | 28202 | return try sema.analyzeNavVal(block, src, nav); |
| 28167 | } | 28203 | } |
| 28168 | 28204 | ||
| 28169 | fn structFieldPtr( | 28205 | fn structFieldPtr( |
| ... | @@ -29200,9 +29236,9 @@ const CoerceOpts = struct { | ... | @@ -29200,9 +29236,9 @@ const CoerceOpts = struct { |
| 29200 | 29236 | ||
| 29201 | fn get(info: @This(), sema: *Sema) !?LazySrcLoc { | 29237 | fn get(info: @This(), sema: *Sema) !?LazySrcLoc { |
| 29202 | if (info.func_inst == .none) return null; | 29238 | if (info.func_inst == .none) return null; |
| 29203 | const fn_decl = try sema.funcDeclSrc(info.func_inst) orelse return null; | 29239 | const func_inst = try sema.funcDeclSrcInst(info.func_inst) orelse return null; |
| 29204 | return .{ | 29240 | return .{ |
| 29205 | .base_node_inst = fn_decl.zir_decl_index.unwrap().?, | 29241 | .base_node_inst = func_inst, |
| 29206 | .offset = .{ .fn_proto_param_type = .{ | 29242 | .offset = .{ .fn_proto_param_type = .{ |
| 29207 | .fn_proto_node_offset = 0, | 29243 | .fn_proto_node_offset = 0, |
| 29208 | .param_index = info.param_i, | 29244 | .param_index = info.param_i, |
| ... | @@ -29303,8 +29339,12 @@ fn coerceExtra( | ... | @@ -29303,8 +29339,12 @@ fn coerceExtra( |
| 29303 | // Function body to function pointer. | 29339 | // Function body to function pointer. |
| 29304 | if (inst_ty.zigTypeTag(zcu) == .Fn) { | 29340 | if (inst_ty.zigTypeTag(zcu) == .Fn) { |
| 29305 | const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); | 29341 | const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); |
| 29306 | const fn_decl = fn_val.pointerDecl(zcu).?; | 29342 | const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) { |
| 29307 | const inst_as_ptr = try sema.analyzeDeclRef(inst_src, fn_decl); | 29343 | .func => |f| f.owner_nav, |
| 29344 | .@"extern" => |e| e.owner_nav, | ||
| 29345 | else => unreachable, | ||
| 29346 | }; | ||
| 29347 | const inst_as_ptr = try sema.analyzeNavRef(inst_src, fn_nav); | ||
| 29308 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); | 29348 | return sema.coerce(block, dest_ty, inst_as_ptr, inst_src); |
| 29309 | } | 29349 | } |
| 29310 | 29350 | ||
| ... | @@ -29846,7 +29886,7 @@ fn coerceExtra( | ... | @@ -29846,7 +29886,7 @@ fn coerceExtra( |
| 29846 | errdefer msg.destroy(sema.gpa); | 29886 | errdefer msg.destroy(sema.gpa); |
| 29847 | 29887 | ||
| 29848 | const ret_ty_src: LazySrcLoc = .{ | 29888 | const ret_ty_src: LazySrcLoc = .{ |
| 29849 | .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?, | 29889 | .base_node_inst = sema.getOwnerFuncDeclInst(), |
| 29850 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 29890 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, |
| 29851 | }; | 29891 | }; |
| 29852 | try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{}); | 29892 | try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{}); |
| ... | @@ -29879,10 +29919,10 @@ fn coerceExtra( | ... | @@ -29879,10 +29919,10 @@ fn coerceExtra( |
| 29879 | 29919 | ||
| 29880 | // Add notes about function return type | 29920 | // Add notes about function return type |
| 29881 | if (opts.is_ret and | 29921 | if (opts.is_ret and |
| 29882 | zcu.test_functions.get(zcu.funcOwnerDeclIndex(sema.func_index)) == null) | 29922 | !zcu.test_functions.contains(zcu.funcInfo(sema.owner.unwrap().func).owner_nav)) |
| 29883 | { | 29923 | { |
| 29884 | const ret_ty_src: LazySrcLoc = .{ | 29924 | const ret_ty_src: LazySrcLoc = .{ |
| 29885 | .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?, | 29925 | .base_node_inst = sema.getOwnerFuncDeclInst(), |
| 29886 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, | 29926 | .offset = .{ .node_offset_fn_type_ret_ty = 0 }, |
| 29887 | }; | 29927 | }; |
| 29888 | if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) { | 29928 | if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) { |
| ... | @@ -30885,9 +30925,9 @@ fn coerceVarArgParam( | ... | @@ -30885,9 +30925,9 @@ fn coerceVarArgParam( |
| 30885 | if (block.is_typeof) return inst; | 30925 | if (block.is_typeof) return inst; |
| 30886 | 30926 | ||
| 30887 | const pt = sema.pt; | 30927 | const pt = sema.pt; |
| 30888 | const mod = pt.zcu; | 30928 | const zcu = pt.zcu; |
| 30889 | const uncasted_ty = sema.typeOf(inst); | 30929 | const uncasted_ty = sema.typeOf(inst); |
| 30890 | const coerced = switch (uncasted_ty.zigTypeTag(mod)) { | 30930 | const coerced = switch (uncasted_ty.zigTypeTag(zcu)) { |
| 30891 | // TODO consider casting to c_int/f64 if they fit | 30931 | // TODO consider casting to c_int/f64 if they fit |
| 30892 | .ComptimeInt, .ComptimeFloat => return sema.fail( | 30932 | .ComptimeInt, .ComptimeFloat => return sema.fail( |
| 30893 | block, | 30933 | block, |
| ... | @@ -30897,12 +30937,12 @@ fn coerceVarArgParam( | ... | @@ -30897,12 +30937,12 @@ fn coerceVarArgParam( |
| 30897 | ), | 30937 | ), |
| 30898 | .Fn => fn_ptr: { | 30938 | .Fn => fn_ptr: { |
| 30899 | const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); | 30939 | const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined); |
| 30900 | const fn_decl = fn_val.pointerDecl(mod).?; | 30940 | const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav; |
| 30901 | break :fn_ptr try sema.analyzeDeclRef(inst_src, fn_decl); | 30941 | break :fn_ptr try sema.analyzeNavRef(inst_src, fn_nav); |
| 30902 | }, | 30942 | }, |
| 30903 | .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), | 30943 | .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), |
| 30904 | .Float => float: { | 30944 | .Float => float: { |
| 30905 | const target = mod.getTarget(); | 30945 | const target = zcu.getTarget(); |
| 30906 | const double_bits = target.c_type_bit_size(.double); | 30946 | const double_bits = target.c_type_bit_size(.double); |
| 30907 | const inst_bits = uncasted_ty.floatBits(target); | 30947 | const inst_bits = uncasted_ty.floatBits(target); |
| 30908 | if (inst_bits >= double_bits) break :float inst; | 30948 | if (inst_bits >= double_bits) break :float inst; |
| ... | @@ -30912,10 +30952,10 @@ fn coerceVarArgParam( | ... | @@ -30912,10 +30952,10 @@ fn coerceVarArgParam( |
| 30912 | else => unreachable, | 30952 | else => unreachable, |
| 30913 | } | 30953 | } |
| 30914 | }, | 30954 | }, |
| 30915 | else => if (uncasted_ty.isAbiInt(mod)) int: { | 30955 | else => if (uncasted_ty.isAbiInt(zcu)) int: { |
| 30916 | if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst; | 30956 | if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst; |
| 30917 | const target = mod.getTarget(); | 30957 | const target = zcu.getTarget(); |
| 30918 | const uncasted_info = uncasted_ty.intInfo(mod); | 30958 | const uncasted_info = uncasted_ty.intInfo(zcu); |
| 30919 | if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { | 30959 | if (uncasted_info.bits <= target.c_type_bit_size(switch (uncasted_info.signedness) { |
| 30920 | .signed => .int, | 30960 | .signed => .int, |
| 30921 | .unsigned => .uint, | 30961 | .unsigned => .uint, |
| ... | @@ -32117,23 +32157,14 @@ fn coerceTupleToTuple( | ... | @@ -32117,23 +32157,14 @@ fn coerceTupleToTuple( |
| 32117 | } }))); | 32157 | } }))); |
| 32118 | } | 32158 | } |
| 32119 | 32159 | ||
| 32120 | fn analyzeDeclVal( | 32160 | fn analyzeNavVal( |
| 32121 | sema: *Sema, | 32161 | sema: *Sema, |
| 32122 | block: *Block, | 32162 | block: *Block, |
| 32123 | src: LazySrcLoc, | 32163 | src: LazySrcLoc, |
| 32124 | decl_index: InternPool.DeclIndex, | 32164 | nav_index: InternPool.Nav.Index, |
| 32125 | ) CompileError!Air.Inst.Ref { | 32165 | ) CompileError!Air.Inst.Ref { |
| 32126 | if (sema.decl_val_table.get(decl_index)) |result| { | 32166 | const ref = try sema.analyzeNavRefInner(src, nav_index, false); |
| 32127 | return result; | 32167 | return sema.analyzeLoad(block, src, ref, src); |
| 32128 | } | ||
| 32129 | const decl_ref = try sema.analyzeDeclRefInner(src, decl_index, false); | ||
| 32130 | const result = try sema.analyzeLoad(block, src, decl_ref, src); | ||
| 32131 | if (result.toInterned() != null) { | ||
| 32132 | if (!block.is_typeof) { | ||
| 32133 | try sema.decl_val_table.put(sema.gpa, decl_index, result); | ||
| 32134 | } | ||
| 32135 | } | ||
| 32136 | return result; | ||
| 32137 | } | 32168 | } |
| 32138 | 32169 | ||
| 32139 | fn addReferenceEntry( | 32170 | fn addReferenceEntry( |
| ... | @@ -32148,44 +32179,37 @@ fn addReferenceEntry( | ... | @@ -32148,44 +32179,37 @@ fn addReferenceEntry( |
| 32148 | // TODO: we need to figure out how to model inline calls here. | 32179 | // TODO: we need to figure out how to model inline calls here. |
| 32149 | // They aren't references in the analysis sense, but ought to show up in the reference trace! | 32180 | // They aren't references in the analysis sense, but ought to show up in the reference trace! |
| 32150 | // Would representing inline calls in the reference table cause excessive memory usage? | 32181 | // Would representing inline calls in the reference table cause excessive memory usage? |
| 32151 | try zcu.addUnitReference(sema.ownerUnit(), referenced_unit, src); | 32182 | try zcu.addUnitReference(sema.owner, referenced_unit, src); |
| 32152 | } | 32183 | } |
| 32153 | 32184 | ||
| 32154 | pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) CompileError!void { | 32185 | pub fn ensureNavResolved(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!void { |
| 32155 | const pt = sema.pt; | 32186 | const pt = sema.pt; |
| 32156 | const mod = pt.zcu; | 32187 | const zcu = pt.zcu; |
| 32157 | const ip = &mod.intern_pool; | 32188 | const ip = &zcu.intern_pool; |
| 32158 | const decl = mod.declPtr(decl_index); | ||
| 32159 | if (decl.analysis == .in_progress) { | ||
| 32160 | const msg = try sema.errMsg(.{ | ||
| 32161 | .base_node_inst = decl.zir_decl_index.unwrap().?, | ||
| 32162 | .offset = LazySrcLoc.Offset.nodeOffset(0), | ||
| 32163 | }, "dependency loop detected", .{}); | ||
| 32164 | return sema.failWithOwnedErrorMsg(null, msg); | ||
| 32165 | } | ||
| 32166 | 32189 | ||
| 32167 | pt.ensureDeclAnalyzed(decl_index) catch |err| { | 32190 | const nav = ip.getNav(nav_index); |
| 32168 | if (sema.owner_func_index != .none) { | ||
| 32169 | ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure); | ||
| 32170 | } else { | ||
| 32171 | sema.owner_decl.analysis = .dependency_failure; | ||
| 32172 | } | ||
| 32173 | return err; | ||
| 32174 | }; | ||
| 32175 | } | ||
| 32176 | 32191 | ||
| 32177 | fn ensureFuncBodyAnalyzed(sema: *Sema, func: InternPool.Index) CompileError!void { | 32192 | const cau_index = nav.analysis_owner.unwrap() orelse { |
| 32178 | const pt = sema.pt; | 32193 | assert(nav.status == .resolved); |
| 32179 | const mod = pt.zcu; | 32194 | return; |
| 32180 | const ip = &mod.intern_pool; | ||
| 32181 | pt.ensureFuncBodyAnalyzed(func) catch |err| { | ||
| 32182 | if (sema.owner_func_index != .none) { | ||
| 32183 | ip.funcSetAnalysisState(sema.owner_func_index, .dependency_failure); | ||
| 32184 | } else { | ||
| 32185 | sema.owner_decl.analysis = .dependency_failure; | ||
| 32186 | } | ||
| 32187 | return err; | ||
| 32188 | }; | 32195 | }; |
| 32196 | |||
| 32197 | // Note that even if `nav.status == .resolved`, we must still trigger `ensureCauAnalyzed` | ||
| 32198 | // to make sure the value is up-to-date on incremental updates. | ||
| 32199 | |||
| 32200 | assert(ip.getCau(cau_index).owner.unwrap().nav == nav_index); | ||
| 32201 | |||
| 32202 | const anal_unit = AnalUnit.wrap(.{ .cau = cau_index }); | ||
| 32203 | try sema.addReferenceEntry(src, anal_unit); | ||
| 32204 | |||
| 32205 | if (zcu.analysis_in_progress.contains(anal_unit)) { | ||
| 32206 | return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{ | ||
| 32207 | .base_node_inst = ip.getCau(cau_index).zir_index, | ||
| 32208 | .offset = LazySrcLoc.Offset.nodeOffset(0), | ||
| 32209 | }, "dependency loop detected", .{})); | ||
| 32210 | } | ||
| 32211 | |||
| 32212 | return pt.ensureCauAnalyzed(cau_index); | ||
| 32189 | } | 32213 | } |
| 32190 | 32214 | ||
| 32191 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { | 32215 | fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { |
| ... | @@ -32200,55 +32224,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { | ... | @@ -32200,55 +32224,57 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value { |
| 32200 | } })); | 32224 | } })); |
| 32201 | } | 32225 | } |
| 32202 | 32226 | ||
| 32203 | fn analyzeDeclRef(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) CompileError!Air.Inst.Ref { | 32227 | fn analyzeNavRef(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) CompileError!Air.Inst.Ref { |
| 32204 | return sema.analyzeDeclRefInner(src, decl_index, true); | 32228 | return sema.analyzeNavRefInner(src, nav_index, true); |
| 32205 | } | 32229 | } |
| 32206 | 32230 | ||
| 32207 | /// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but | 32231 | /// Analyze a reference to the `Nav` at the given index. Ensures the underlying `Nav` is analyzed, but |
| 32208 | /// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a | 32232 | /// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a |
| 32209 | /// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps | 32233 | /// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeNavRef` wraps |
| 32210 | /// this function with `analyze_fn_body` set to true. | 32234 | /// 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 { | 32235 | 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; | 32236 | const pt = sema.pt; |
| 32213 | const mod = pt.zcu; | 32237 | const zcu = pt.zcu; |
| 32214 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .decl = decl_index })); | 32238 | const ip = &zcu.intern_pool; |
| 32215 | try sema.ensureDeclAnalyzed(decl_index); | ||
| 32216 | 32239 | ||
| 32217 | const decl_val = try mod.declPtr(decl_index).valueOrFail(); | 32240 | // TODO: if this is a `decl_ref` of a non-variable Nav, only depend on Nav type |
| 32218 | const owner_decl = mod.declPtr(switch (mod.intern_pool.indexToKey(decl_val.toIntern())) { | 32241 | try sema.declareDependency(.{ .nav_val = orig_nav_index }); |
| 32219 | .variable => |variable| variable.decl, | 32242 | try sema.ensureNavResolved(src, orig_nav_index); |
| 32220 | .extern_func => |extern_func| extern_func.decl, | 32243 | |
| 32221 | .func => |func| func.owner_decl, | 32244 | const nav_val = zcu.navValue(orig_nav_index); |
| 32222 | else => decl_index, | 32245 | const nav_index, const is_const = switch (ip.indexToKey(nav_val.toIntern())) { |
| 32223 | }); | 32246 | .variable => |v| .{ v.owner_nav, false }, |
| 32224 | // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type | 32247 | .func => |f| .{ f.owner_nav, true }, |
| 32225 | try sema.declareDependency(.{ .decl_val = decl_index }); | 32248 | .@"extern" => |e| .{ e.owner_nav, e.is_const }, |
| 32249 | else => .{ orig_nav_index, true }, | ||
| 32250 | }; | ||
| 32251 | const nav_info = ip.getNav(nav_index).status.resolved; | ||
| 32226 | const ptr_ty = try pt.ptrTypeSema(.{ | 32252 | const ptr_ty = try pt.ptrTypeSema(.{ |
| 32227 | .child = decl_val.typeOf(mod).toIntern(), | 32253 | .child = nav_val.typeOf(zcu).toIntern(), |
| 32228 | .flags = .{ | 32254 | .flags = .{ |
| 32229 | .alignment = owner_decl.alignment, | 32255 | .alignment = nav_info.alignment, |
| 32230 | .is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true, | 32256 | .is_const = is_const, |
| 32231 | .address_space = owner_decl.@"addrspace", | 32257 | .address_space = nav_info.@"addrspace", |
| 32232 | }, | 32258 | }, |
| 32233 | }); | 32259 | }); |
| 32234 | if (analyze_fn_body) { | 32260 | if (analyze_fn_body) { |
| 32235 | try sema.maybeQueueFuncBodyAnalysis(src, decl_index); | 32261 | try sema.maybeQueueFuncBodyAnalysis(src, nav_index); |
| 32236 | } | 32262 | } |
| 32237 | return Air.internedToRef((try pt.intern(.{ .ptr = .{ | 32263 | return Air.internedToRef((try pt.intern(.{ .ptr = .{ |
| 32238 | .ty = ptr_ty.toIntern(), | 32264 | .ty = ptr_ty.toIntern(), |
| 32239 | .base_addr = .{ .decl = decl_index }, | 32265 | .base_addr = .{ .nav = nav_index }, |
| 32240 | .byte_offset = 0, | 32266 | .byte_offset = 0, |
| 32241 | } }))); | 32267 | } }))); |
| 32242 | } | 32268 | } |
| 32243 | 32269 | ||
| 32244 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.DeclIndex) !void { | 32270 | fn maybeQueueFuncBodyAnalysis(sema: *Sema, src: LazySrcLoc, nav_index: InternPool.Nav.Index) !void { |
| 32245 | const mod = sema.pt.zcu; | 32271 | const zcu = sema.pt.zcu; |
| 32246 | const decl = mod.declPtr(decl_index); | 32272 | const ip = &zcu.intern_pool; |
| 32247 | const decl_val = try decl.valueOrFail(); | 32273 | const nav_val = zcu.navValue(nav_index); |
| 32248 | if (!mod.intern_pool.isFuncBody(decl_val.toIntern())) return; | 32274 | if (!ip.isFuncBody(nav_val.toIntern())) return; |
| 32249 | if (!try sema.fnHasRuntimeBits(decl_val.typeOf(mod))) return; | 32275 | if (!try sema.fnHasRuntimeBits(nav_val.typeOf(zcu))) return; |
| 32250 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = decl_val.toIntern() })); | 32276 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = nav_val.toIntern() })); |
| 32251 | try mod.ensureFuncBodyAnalysisQueued(decl_val.toIntern()); | 32277 | try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern()); |
| 32252 | } | 32278 | } |
| 32253 | 32279 | ||
| 32254 | fn analyzeRef( | 32280 | fn analyzeRef( |
| ... | @@ -32263,9 +32289,9 @@ fn analyzeRef( | ... | @@ -32263,9 +32289,9 @@ fn analyzeRef( |
| 32263 | 32289 | ||
| 32264 | if (try sema.resolveValue(operand)) |val| { | 32290 | if (try sema.resolveValue(operand)) |val| { |
| 32265 | switch (mod.intern_pool.indexToKey(val.toIntern())) { | 32291 | switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 32266 | .extern_func => |extern_func| return sema.analyzeDeclRef(src, extern_func.decl), | 32292 | .@"extern" => |e| return sema.analyzeNavRef(src, e.owner_nav), |
| 32267 | .func => |func| return sema.analyzeDeclRef(src, func.owner_decl), | 32293 | .func => |f| return sema.analyzeNavRef(src, f.owner_nav), |
| 32268 | else => return anonDeclRef(sema, val.toIntern()), | 32294 | else => return uavRef(sema, val.toIntern()), |
| 32269 | } | 32295 | } |
| 32270 | } | 32296 | } |
| 32271 | 32297 | ||
| ... | @@ -35198,7 +35224,7 @@ pub fn resolveStructAlignment( | ... | @@ -35198,7 +35224,7 @@ pub fn resolveStructAlignment( |
| 35198 | const ip = &mod.intern_pool; | 35224 | const ip = &mod.intern_pool; |
| 35199 | const target = mod.getTarget(); | 35225 | const target = mod.getTarget(); |
| 35200 | 35226 | ||
| 35201 | assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?); | 35227 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35202 | 35228 | ||
| 35203 | assert(struct_type.layout != .@"packed"); | 35229 | assert(struct_type.layout != .@"packed"); |
| 35204 | assert(struct_type.flagsUnordered(ip).alignment == .none); | 35230 | assert(struct_type.flagsUnordered(ip).alignment == .none); |
| ... | @@ -35242,7 +35268,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35242,7 +35268,7 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35242 | const ip = &zcu.intern_pool; | 35268 | const ip = &zcu.intern_pool; |
| 35243 | const struct_type = zcu.typeToStruct(ty) orelse return; | 35269 | const struct_type = zcu.typeToStruct(ty) orelse return; |
| 35244 | 35270 | ||
| 35245 | assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?); | 35271 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35246 | 35272 | ||
| 35247 | if (struct_type.haveLayout(ip)) | 35273 | if (struct_type.haveLayout(ip)) |
| 35248 | return; | 35274 | return; |
| ... | @@ -35384,8 +35410,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp | ... | @@ -35384,8 +35410,7 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp |
| 35384 | const gpa = zcu.gpa; | 35410 | const gpa = zcu.gpa; |
| 35385 | const ip = &zcu.intern_pool; | 35411 | const ip = &zcu.intern_pool; |
| 35386 | 35412 | ||
| 35387 | const decl_index = struct_type.decl.unwrap().?; | 35413 | const cau_index = struct_type.cau.unwrap().?; |
| 35388 | const decl = zcu.declPtr(decl_index); | ||
| 35389 | 35414 | ||
| 35390 | const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir; | 35415 | const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir; |
| 35391 | 35416 | ||
| ... | @@ -35400,13 +35425,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp | ... | @@ -35400,13 +35425,11 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp |
| 35400 | .gpa = gpa, | 35425 | .gpa = gpa, |
| 35401 | .arena = analysis_arena.allocator(), | 35426 | .arena = analysis_arena.allocator(), |
| 35402 | .code = zir, | 35427 | .code = zir, |
| 35403 | .owner_decl = decl, | 35428 | .owner = AnalUnit.wrap(.{ .cau = cau_index }), |
| 35404 | .owner_decl_index = decl_index, | ||
| 35405 | .func_index = .none, | 35429 | .func_index = .none, |
| 35406 | .func_is_naked = false, | 35430 | .func_is_naked = false, |
| 35407 | .fn_ret_ty = Type.void, | 35431 | .fn_ret_ty = Type.void, |
| 35408 | .fn_ret_ty_ies = null, | 35432 | .fn_ret_ty_ies = null, |
| 35409 | .owner_func_index = .none, | ||
| 35410 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 35433 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 35411 | }; | 35434 | }; |
| 35412 | defer sema.deinit(); | 35435 | defer sema.deinit(); |
| ... | @@ -35414,12 +35437,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp | ... | @@ -35414,12 +35437,12 @@ fn semaBackingIntType(pt: Zcu.PerThread, struct_type: InternPool.LoadedStructTyp |
| 35414 | var block: Block = .{ | 35437 | var block: Block = .{ |
| 35415 | .parent = null, | 35438 | .parent = null, |
| 35416 | .sema = &sema, | 35439 | .sema = &sema, |
| 35417 | .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace, | 35440 | .namespace = ip.getCau(cau_index).namespace, |
| 35418 | .instructions = .{}, | 35441 | .instructions = .{}, |
| 35419 | .inlining = null, | 35442 | .inlining = null, |
| 35420 | .is_comptime = true, | 35443 | .is_comptime = true, |
| 35421 | .src_base_inst = struct_type.zir_index.unwrap().?, | 35444 | .src_base_inst = struct_type.zir_index.unwrap().?, |
| 35422 | .type_name_ctx = decl.name, | 35445 | .type_name_ctx = struct_type.name, |
| 35423 | }; | 35446 | }; |
| 35424 | defer assert(block.instructions.items.len == 0); | 35447 | defer assert(block.instructions.items.len == 0); |
| 35425 | 35448 | ||
| ... | @@ -35544,7 +35567,7 @@ pub fn resolveUnionAlignment( | ... | @@ -35544,7 +35567,7 @@ pub fn resolveUnionAlignment( |
| 35544 | const ip = &zcu.intern_pool; | 35567 | const ip = &zcu.intern_pool; |
| 35545 | const target = zcu.getTarget(); | 35568 | const target = zcu.getTarget(); |
| 35546 | 35569 | ||
| 35547 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35570 | assert(sema.owner.unwrap().cau == union_type.cau); |
| 35548 | 35571 | ||
| 35549 | assert(!union_type.haveLayout(ip)); | 35572 | assert(!union_type.haveLayout(ip)); |
| 35550 | 35573 | ||
| ... | @@ -35584,7 +35607,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35584,7 +35607,7 @@ pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void { |
| 35584 | // Load again, since the tag type might have changed due to resolution. | 35607 | // Load again, since the tag type might have changed due to resolution. |
| 35585 | const union_type = ip.loadUnionType(ty.ip_index); | 35608 | const union_type = ip.loadUnionType(ty.ip_index); |
| 35586 | 35609 | ||
| 35587 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35610 | assert(sema.owner.unwrap().cau == union_type.cau); |
| 35588 | 35611 | ||
| 35589 | const old_flags = union_type.flagsUnordered(ip); | 35612 | const old_flags = union_type.flagsUnordered(ip); |
| 35590 | switch (old_flags.status) { | 35613 | switch (old_flags.status) { |
| ... | @@ -35697,7 +35720,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35697,7 +35720,7 @@ pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void { |
| 35697 | const ip = &mod.intern_pool; | 35720 | const ip = &mod.intern_pool; |
| 35698 | const struct_type = mod.typeToStruct(ty).?; | 35721 | const struct_type = mod.typeToStruct(ty).?; |
| 35699 | 35722 | ||
| 35700 | assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?); | 35723 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35701 | 35724 | ||
| 35702 | if (struct_type.setFullyResolved(ip)) return; | 35725 | if (struct_type.setFullyResolved(ip)) return; |
| 35703 | errdefer struct_type.clearFullyResolved(ip); | 35726 | errdefer struct_type.clearFullyResolved(ip); |
| ... | @@ -35720,7 +35743,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35720,7 +35743,7 @@ pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void { |
| 35720 | const ip = &mod.intern_pool; | 35743 | const ip = &mod.intern_pool; |
| 35721 | const union_obj = mod.typeToUnion(ty).?; | 35744 | const union_obj = mod.typeToUnion(ty).?; |
| 35722 | 35745 | ||
| 35723 | assert(sema.ownerUnit().unwrap().decl == union_obj.decl); | 35746 | assert(sema.owner.unwrap().cau == union_obj.cau); |
| 35724 | 35747 | ||
| 35725 | switch (union_obj.flagsUnordered(ip).status) { | 35748 | switch (union_obj.flagsUnordered(ip).status) { |
| 35726 | .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, | 35749 | .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, |
| ... | @@ -35754,21 +35777,8 @@ pub fn resolveTypeFieldsStruct( | ... | @@ -35754,21 +35777,8 @@ pub fn resolveTypeFieldsStruct( |
| 35754 | const pt = sema.pt; | 35777 | const pt = sema.pt; |
| 35755 | const zcu = pt.zcu; | 35778 | const zcu = pt.zcu; |
| 35756 | const ip = &zcu.intern_pool; | 35779 | const ip = &zcu.intern_pool; |
| 35757 | // If there is no owner decl it means the struct has no fields. | ||
| 35758 | const owner_decl = struct_type.decl.unwrap() orelse return; | ||
| 35759 | 35780 | ||
| 35760 | assert(sema.ownerUnit().unwrap().decl == owner_decl); | 35781 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35761 | |||
| 35762 | switch (zcu.declPtr(owner_decl).analysis) { | ||
| 35763 | .file_failure, | ||
| 35764 | .dependency_failure, | ||
| 35765 | .sema_failure, | ||
| 35766 | => { | ||
| 35767 | sema.owner_decl.analysis = .dependency_failure; | ||
| 35768 | return error.AnalysisFail; | ||
| 35769 | }, | ||
| 35770 | else => {}, | ||
| 35771 | } | ||
| 35772 | 35782 | ||
| 35773 | if (struct_type.haveFieldTypes(ip)) return; | 35783 | if (struct_type.haveFieldTypes(ip)) return; |
| 35774 | 35784 | ||
| ... | @@ -35783,13 +35793,7 @@ pub fn resolveTypeFieldsStruct( | ... | @@ -35783,13 +35793,7 @@ pub fn resolveTypeFieldsStruct( |
| 35783 | defer struct_type.clearFieldTypesWip(ip); | 35793 | defer struct_type.clearFieldTypesWip(ip); |
| 35784 | 35794 | ||
| 35785 | semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) { | 35795 | semaStructFields(pt, sema.arena, struct_type) catch |err| switch (err) { |
| 35786 | error.AnalysisFail => { | 35796 | error.AnalysisFail, error.OutOfMemory => |e| return e, |
| 35787 | if (zcu.declPtr(owner_decl).analysis == .complete) { | ||
| 35788 | zcu.declPtr(owner_decl).analysis = .dependency_failure; | ||
| 35789 | } | ||
| 35790 | return error.AnalysisFail; | ||
| 35791 | }, | ||
| 35792 | error.OutOfMemory => return error.OutOfMemory, | ||
| 35793 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, | 35797 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, |
| 35794 | }; | 35798 | }; |
| 35795 | } | 35799 | } |
| ... | @@ -35799,9 +35803,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35799,9 +35803,8 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { |
| 35799 | const zcu = pt.zcu; | 35803 | const zcu = pt.zcu; |
| 35800 | const ip = &zcu.intern_pool; | 35804 | const ip = &zcu.intern_pool; |
| 35801 | const struct_type = zcu.typeToStruct(ty) orelse return; | 35805 | const struct_type = zcu.typeToStruct(ty) orelse return; |
| 35802 | const owner_decl = struct_type.decl.unwrap() orelse return; | ||
| 35803 | 35806 | ||
| 35804 | assert(sema.ownerUnit().unwrap().decl == owner_decl); | 35807 | assert(sema.owner.unwrap().cau == struct_type.cau.unwrap().?); |
| 35805 | 35808 | ||
| 35806 | // Inits can start as resolved | 35809 | // Inits can start as resolved |
| 35807 | if (struct_type.haveFieldInits(ip)) return; | 35810 | if (struct_type.haveFieldInits(ip)) return; |
| ... | @@ -35819,13 +35822,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { | ... | @@ -35819,13 +35822,7 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void { |
| 35819 | defer struct_type.clearInitsWip(ip); | 35822 | defer struct_type.clearInitsWip(ip); |
| 35820 | 35823 | ||
| 35821 | semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) { | 35824 | semaStructFieldInits(pt, sema.arena, struct_type) catch |err| switch (err) { |
| 35822 | error.AnalysisFail => { | 35825 | error.AnalysisFail, error.OutOfMemory => |e| return e, |
| 35823 | if (zcu.declPtr(owner_decl).analysis == .complete) { | ||
| 35824 | zcu.declPtr(owner_decl).analysis = .dependency_failure; | ||
| 35825 | } | ||
| 35826 | return error.AnalysisFail; | ||
| 35827 | }, | ||
| 35828 | error.OutOfMemory => return error.OutOfMemory, | ||
| 35829 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, | 35826 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, |
| 35830 | }; | 35827 | }; |
| 35831 | struct_type.setHaveFieldInits(ip); | 35828 | struct_type.setHaveFieldInits(ip); |
| ... | @@ -35835,20 +35832,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load | ... | @@ -35835,20 +35832,9 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load |
| 35835 | const pt = sema.pt; | 35832 | const pt = sema.pt; |
| 35836 | const zcu = pt.zcu; | 35833 | const zcu = pt.zcu; |
| 35837 | const ip = &zcu.intern_pool; | 35834 | const ip = &zcu.intern_pool; |
| 35838 | const owner_decl = zcu.declPtr(union_type.decl); | ||
| 35839 | 35835 | ||
| 35840 | assert(sema.ownerUnit().unwrap().decl == union_type.decl); | 35836 | assert(sema.owner.unwrap().cau == union_type.cau); |
| 35841 | 35837 | ||
| 35842 | switch (owner_decl.analysis) { | ||
| 35843 | .file_failure, | ||
| 35844 | .dependency_failure, | ||
| 35845 | .sema_failure, | ||
| 35846 | => { | ||
| 35847 | sema.owner_decl.analysis = .dependency_failure; | ||
| 35848 | return error.AnalysisFail; | ||
| 35849 | }, | ||
| 35850 | else => {}, | ||
| 35851 | } | ||
| 35852 | switch (union_type.flagsUnordered(ip).status) { | 35838 | switch (union_type.flagsUnordered(ip).status) { |
| 35853 | .none => {}, | 35839 | .none => {}, |
| 35854 | .field_types_wip => { | 35840 | .field_types_wip => { |
| ... | @@ -35869,14 +35855,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load | ... | @@ -35869,14 +35855,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load |
| 35869 | 35855 | ||
| 35870 | union_type.setStatus(ip, .field_types_wip); | 35856 | union_type.setStatus(ip, .field_types_wip); |
| 35871 | errdefer union_type.setStatus(ip, .none); | 35857 | errdefer union_type.setStatus(ip, .none); |
| 35872 | semaUnionFields(pt, sema.arena, union_type) catch |err| switch (err) { | 35858 | semaUnionFields(pt, sema.arena, ty.toIntern(), union_type) catch |err| switch (err) { |
| 35873 | error.AnalysisFail => { | 35859 | error.AnalysisFail, error.OutOfMemory => |e| return e, |
| 35874 | if (owner_decl.analysis == .complete) { | ||
| 35875 | owner_decl.analysis = .dependency_failure; | ||
| 35876 | } | ||
| 35877 | return error.AnalysisFail; | ||
| 35878 | }, | ||
| 35879 | error.OutOfMemory => return error.OutOfMemory, | ||
| 35880 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, | 35860 | error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable, |
| 35881 | }; | 35861 | }; |
| 35882 | union_type.setStatus(ip, .have_field_types); | 35862 | union_type.setStatus(ip, .have_field_types); |
| ... | @@ -35891,28 +35871,28 @@ fn resolveInferredErrorSet( | ... | @@ -35891,28 +35871,28 @@ fn resolveInferredErrorSet( |
| 35891 | ies_index: InternPool.Index, | 35871 | ies_index: InternPool.Index, |
| 35892 | ) CompileError!InternPool.Index { | 35872 | ) CompileError!InternPool.Index { |
| 35893 | const pt = sema.pt; | 35873 | const pt = sema.pt; |
| 35894 | const mod = pt.zcu; | 35874 | const zcu = pt.zcu; |
| 35895 | const ip = &mod.intern_pool; | 35875 | const ip = &zcu.intern_pool; |
| 35896 | const func_index = ip.iesFuncIndex(ies_index); | 35876 | const func_index = ip.iesFuncIndex(ies_index); |
| 35897 | const func = mod.funcInfo(func_index); | 35877 | const func = zcu.funcInfo(func_index); |
| 35898 | 35878 | ||
| 35899 | try sema.declareDependency(.{ .func_ies = func_index }); | 35879 | try sema.declareDependency(.{ .interned = func_index }); // resolved IES |
| 35900 | 35880 | ||
| 35901 | // TODO: during an incremental update this might not be `.none`, but the | 35881 | // TODO: during an incremental update this might not be `.none`, but the |
| 35902 | // function might be out-of-date! | 35882 | // function might be out-of-date! |
| 35903 | const resolved_ty = func.resolvedErrorSetUnordered(ip); | 35883 | const resolved_ty = func.resolvedErrorSetUnordered(ip); |
| 35904 | if (resolved_ty != .none) return resolved_ty; | 35884 | if (resolved_ty != .none) return resolved_ty; |
| 35905 | 35885 | ||
| 35906 | if (func.analysisUnordered(ip).state == .in_progress) | 35886 | if (zcu.analysis_in_progress.contains(AnalUnit.wrap(.{ .func = func_index }))) { |
| 35907 | return sema.fail(block, src, "unable to resolve inferred error set", .{}); | 35887 | return sema.fail(block, src, "unable to resolve inferred error set", .{}); |
| 35888 | } | ||
| 35908 | 35889 | ||
| 35909 | // In order to ensure that all dependencies are properly added to the set, | 35890 | // In order to ensure that all dependencies are properly added to the set, |
| 35910 | // we need to ensure the function body is analyzed of the inferred error | 35891 | // 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 | 35892 | // set. However, in the case of comptime/inline function calls with |
| 35912 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which | 35893 | // inferred error sets, each call gets an adhoc InferredErrorSet object, which |
| 35913 | // has no corresponding function body. | 35894 | // has no corresponding function body. |
| 35914 | const ies_func_owner_decl = mod.declPtr(func.owner_decl); | 35895 | const ies_func_info = zcu.typeToFunc(Type.fromInterned(func.ty)).?; |
| 35915 | const ies_func_info = mod.typeToFunc(ies_func_owner_decl.typeOf(mod)).?; | ||
| 35916 | // if ies declared by a inline function with generic return type, the return_type should be generic_poison, | 35896 | // if ies declared by a inline function with generic return type, the return_type should be generic_poison, |
| 35917 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, | 35897 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, |
| 35918 | // so here we can simply skip this case. | 35898 | // so here we can simply skip this case. |
| ... | @@ -35920,22 +35900,17 @@ fn resolveInferredErrorSet( | ... | @@ -35920,22 +35900,17 @@ fn resolveInferredErrorSet( |
| 35920 | assert(ies_func_info.cc == .Inline); | 35900 | assert(ies_func_info.cc == .Inline); |
| 35921 | } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) { | 35901 | } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) { |
| 35922 | if (ies_func_info.is_generic) { | 35902 | if (ies_func_info.is_generic) { |
| 35923 | const msg = msg: { | 35903 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 35924 | const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{}); | 35904 | const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{}); |
| 35925 | errdefer msg.destroy(sema.gpa); | 35905 | errdefer msg.destroy(sema.gpa); |
| 35926 | 35906 | try sema.errNote(zcu.navSrcLoc(func.owner_nav), msg, "generic function declared here", .{}); | |
| 35927 | try sema.errNote(.{ | ||
| 35928 | .base_node_inst = ies_func_owner_decl.zir_decl_index.unwrap().?, | ||
| 35929 | .offset = LazySrcLoc.Offset.nodeOffset(0), | ||
| 35930 | }, msg, "generic function declared here", .{}); | ||
| 35931 | break :msg msg; | 35907 | break :msg msg; |
| 35932 | }; | 35908 | }); |
| 35933 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 35934 | } | 35909 | } |
| 35935 | // In this case we are dealing with the actual InferredErrorSet object that | 35910 | // In this case we are dealing with the actual InferredErrorSet object that |
| 35936 | // corresponds to the function, not one created to track an inline/comptime call. | 35911 | // corresponds to the function, not one created to track an inline/comptime call. |
| 35937 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index })); | 35912 | try sema.addReferenceEntry(src, AnalUnit.wrap(.{ .func = func_index })); |
| 35938 | try sema.ensureFuncBodyAnalyzed(func_index); | 35913 | try pt.ensureFuncBodyAnalyzed(func_index); |
| 35939 | } | 35914 | } |
| 35940 | 35915 | ||
| 35941 | // This will now have been resolved by the logic at the end of `Module.analyzeFnBody` | 35916 | // This will now have been resolved by the logic at the end of `Module.analyzeFnBody` |
| ... | @@ -36092,9 +36067,8 @@ fn semaStructFields( | ... | @@ -36092,9 +36067,8 @@ fn semaStructFields( |
| 36092 | const zcu = pt.zcu; | 36067 | const zcu = pt.zcu; |
| 36093 | const gpa = zcu.gpa; | 36068 | const gpa = zcu.gpa; |
| 36094 | const ip = &zcu.intern_pool; | 36069 | const ip = &zcu.intern_pool; |
| 36095 | const decl_index = struct_type.decl.unwrap() orelse return; | 36070 | const cau_index = struct_type.cau.unwrap().?; |
| 36096 | const decl = zcu.declPtr(decl_index); | 36071 | const namespace_index = ip.getCau(cau_index).namespace; |
| 36097 | const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; | ||
| 36098 | const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir; | 36072 | const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir; |
| 36099 | const zir_index = struct_type.zir_index.unwrap().?.resolve(ip); | 36073 | const zir_index = struct_type.zir_index.unwrap().?.resolve(ip); |
| 36100 | 36074 | ||
| ... | @@ -36119,13 +36093,11 @@ fn semaStructFields( | ... | @@ -36119,13 +36093,11 @@ fn semaStructFields( |
| 36119 | .gpa = gpa, | 36093 | .gpa = gpa, |
| 36120 | .arena = arena, | 36094 | .arena = arena, |
| 36121 | .code = zir, | 36095 | .code = zir, |
| 36122 | .owner_decl = decl, | 36096 | .owner = AnalUnit.wrap(.{ .cau = cau_index }), |
| 36123 | .owner_decl_index = decl_index, | ||
| 36124 | .func_index = .none, | 36097 | .func_index = .none, |
| 36125 | .func_is_naked = false, | 36098 | .func_is_naked = false, |
| 36126 | .fn_ret_ty = Type.void, | 36099 | .fn_ret_ty = Type.void, |
| 36127 | .fn_ret_ty_ies = null, | 36100 | .fn_ret_ty_ies = null, |
| 36128 | .owner_func_index = .none, | ||
| 36129 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 36101 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 36130 | }; | 36102 | }; |
| 36131 | defer sema.deinit(); | 36103 | defer sema.deinit(); |
| ... | @@ -36138,7 +36110,7 @@ fn semaStructFields( | ... | @@ -36138,7 +36110,7 @@ fn semaStructFields( |
| 36138 | .inlining = null, | 36110 | .inlining = null, |
| 36139 | .is_comptime = true, | 36111 | .is_comptime = true, |
| 36140 | .src_base_inst = struct_type.zir_index.unwrap().?, | 36112 | .src_base_inst = struct_type.zir_index.unwrap().?, |
| 36141 | .type_name_ctx = decl.name, | 36113 | .type_name_ctx = struct_type.name, |
| 36142 | }; | 36114 | }; |
| 36143 | defer assert(block_scope.instructions.items.len == 0); | 36115 | defer assert(block_scope.instructions.items.len == 0); |
| 36144 | 36116 | ||
| ... | @@ -36318,9 +36290,8 @@ fn semaStructFieldInits( | ... | @@ -36318,9 +36290,8 @@ fn semaStructFieldInits( |
| 36318 | 36290 | ||
| 36319 | assert(!struct_type.haveFieldInits(ip)); | 36291 | assert(!struct_type.haveFieldInits(ip)); |
| 36320 | 36292 | ||
| 36321 | const decl_index = struct_type.decl.unwrap() orelse return; | 36293 | const cau_index = struct_type.cau.unwrap().?; |
| 36322 | const decl = zcu.declPtr(decl_index); | 36294 | const namespace_index = ip.getCau(cau_index).namespace; |
| 36323 | const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; | ||
| 36324 | const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir; | 36295 | const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir; |
| 36325 | const zir_index = struct_type.zir_index.unwrap().?.resolve(ip); | 36296 | const zir_index = struct_type.zir_index.unwrap().?.resolve(ip); |
| 36326 | const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); | 36297 | const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); |
| ... | @@ -36333,13 +36304,11 @@ fn semaStructFieldInits( | ... | @@ -36333,13 +36304,11 @@ fn semaStructFieldInits( |
| 36333 | .gpa = gpa, | 36304 | .gpa = gpa, |
| 36334 | .arena = arena, | 36305 | .arena = arena, |
| 36335 | .code = zir, | 36306 | .code = zir, |
| 36336 | .owner_decl = decl, | 36307 | .owner = AnalUnit.wrap(.{ .cau = cau_index }), |
| 36337 | .owner_decl_index = decl_index, | ||
| 36338 | .func_index = .none, | 36308 | .func_index = .none, |
| 36339 | .func_is_naked = false, | 36309 | .func_is_naked = false, |
| 36340 | .fn_ret_ty = Type.void, | 36310 | .fn_ret_ty = Type.void, |
| 36341 | .fn_ret_ty_ies = null, | 36311 | .fn_ret_ty_ies = null, |
| 36342 | .owner_func_index = .none, | ||
| 36343 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 36312 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 36344 | }; | 36313 | }; |
| 36345 | defer sema.deinit(); | 36314 | defer sema.deinit(); |
| ... | @@ -36352,7 +36321,7 @@ fn semaStructFieldInits( | ... | @@ -36352,7 +36321,7 @@ fn semaStructFieldInits( |
| 36352 | .inlining = null, | 36321 | .inlining = null, |
| 36353 | .is_comptime = true, | 36322 | .is_comptime = true, |
| 36354 | .src_base_inst = struct_type.zir_index.unwrap().?, | 36323 | .src_base_inst = struct_type.zir_index.unwrap().?, |
| 36355 | .type_name_ctx = decl.name, | 36324 | .type_name_ctx = struct_type.name, |
| 36356 | }; | 36325 | }; |
| 36357 | defer assert(block_scope.instructions.items.len == 0); | 36326 | defer assert(block_scope.instructions.items.len == 0); |
| 36358 | 36327 | ||
| ... | @@ -36449,15 +36418,15 @@ fn semaStructFieldInits( | ... | @@ -36449,15 +36418,15 @@ fn semaStructFieldInits( |
| 36449 | try sema.flushExports(); | 36418 | try sema.flushExports(); |
| 36450 | } | 36419 | } |
| 36451 | 36420 | ||
| 36452 | fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void { | 36421 | fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_ty: InternPool.Index, union_type: InternPool.LoadedUnionType) CompileError!void { |
| 36453 | const tracy = trace(@src()); | 36422 | const tracy = trace(@src()); |
| 36454 | defer tracy.end(); | 36423 | defer tracy.end(); |
| 36455 | 36424 | ||
| 36456 | const zcu = pt.zcu; | 36425 | const zcu = pt.zcu; |
| 36457 | const gpa = zcu.gpa; | 36426 | const gpa = zcu.gpa; |
| 36458 | const ip = &zcu.intern_pool; | 36427 | const ip = &zcu.intern_pool; |
| 36459 | const decl_index = union_type.decl; | 36428 | const cau_index = union_type.cau; |
| 36460 | const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir; | 36429 | const zir = zcu.namespacePtr(union_type.namespace).fileScope(zcu).zir; |
| 36461 | const zir_index = union_type.zir_index.resolve(ip); | 36430 | const zir_index = union_type.zir_index.resolve(ip); |
| 36462 | const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; | 36431 | const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; |
| 36463 | assert(extended.opcode == .union_decl); | 36432 | assert(extended.opcode == .union_decl); |
| ... | @@ -36501,8 +36470,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L | ... | @@ -36501,8 +36470,6 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L |
| 36501 | const body = zir.bodySlice(extra_index, body_len); | 36470 | const body = zir.bodySlice(extra_index, body_len); |
| 36502 | extra_index += body.len; | 36471 | extra_index += body.len; |
| 36503 | 36472 | ||
| 36504 | const decl = zcu.declPtr(decl_index); | ||
| 36505 | |||
| 36506 | var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa); | 36473 | var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa); |
| 36507 | defer comptime_err_ret_trace.deinit(); | 36474 | defer comptime_err_ret_trace.deinit(); |
| 36508 | 36475 | ||
| ... | @@ -36511,13 +36478,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L | ... | @@ -36511,13 +36478,11 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L |
| 36511 | .gpa = gpa, | 36478 | .gpa = gpa, |
| 36512 | .arena = arena, | 36479 | .arena = arena, |
| 36513 | .code = zir, | 36480 | .code = zir, |
| 36514 | .owner_decl = decl, | 36481 | .owner = AnalUnit.wrap(.{ .cau = cau_index }), |
| 36515 | .owner_decl_index = decl_index, | ||
| 36516 | .func_index = .none, | 36482 | .func_index = .none, |
| 36517 | .func_is_naked = false, | 36483 | .func_is_naked = false, |
| 36518 | .fn_ret_ty = Type.void, | 36484 | .fn_ret_ty = Type.void, |
| 36519 | .fn_ret_ty_ies = null, | 36485 | .fn_ret_ty_ies = null, |
| 36520 | .owner_func_index = .none, | ||
| 36521 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 36486 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 36522 | }; | 36487 | }; |
| 36523 | defer sema.deinit(); | 36488 | defer sema.deinit(); |
| ... | @@ -36525,12 +36490,12 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L | ... | @@ -36525,12 +36490,12 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L |
| 36525 | var block_scope: Block = .{ | 36490 | var block_scope: Block = .{ |
| 36526 | .parent = null, | 36491 | .parent = null, |
| 36527 | .sema = &sema, | 36492 | .sema = &sema, |
| 36528 | .namespace = union_type.namespace.unwrap().?, | 36493 | .namespace = union_type.namespace, |
| 36529 | .instructions = .{}, | 36494 | .instructions = .{}, |
| 36530 | .inlining = null, | 36495 | .inlining = null, |
| 36531 | .is_comptime = true, | 36496 | .is_comptime = true, |
| 36532 | .src_base_inst = union_type.zir_index, | 36497 | .src_base_inst = union_type.zir_index, |
| 36533 | .type_name_ctx = decl.name, | 36498 | .type_name_ctx = union_type.name, |
| 36534 | }; | 36499 | }; |
| 36535 | defer assert(block_scope.instructions.items.len == 0); | 36500 | defer assert(block_scope.instructions.items.len == 0); |
| 36536 | 36501 | ||
| ... | @@ -36817,10 +36782,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L | ... | @@ -36817,10 +36782,10 @@ fn semaUnionFields(pt: Zcu.PerThread, arena: Allocator, union_type: InternPool.L |
| 36817 | return sema.failWithOwnedErrorMsg(&block_scope, msg); | 36782 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| 36818 | } | 36783 | } |
| 36819 | } else if (enum_field_vals.count() > 0) { | 36784 | } else if (enum_field_vals.count() > 0) { |
| 36820 | const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl)); | 36785 | const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), union_ty, union_type.name); |
| 36821 | union_type.setTagType(ip, enum_ty); | 36786 | union_type.setTagType(ip, enum_ty); |
| 36822 | } else { | 36787 | } else { |
| 36823 | const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl)); | 36788 | const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, union_ty, union_type.name); |
| 36824 | union_type.setTagType(ip, enum_ty); | 36789 | union_type.setTagType(ip, enum_ty); |
| 36825 | } | 36790 | } |
| 36826 | 36791 | ||
| ... | @@ -36839,36 +36804,25 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36839,36 +36804,25 @@ fn generateUnionTagTypeNumbered( |
| 36839 | block: *Block, | 36804 | block: *Block, |
| 36840 | enum_field_names: []const InternPool.NullTerminatedString, | 36805 | enum_field_names: []const InternPool.NullTerminatedString, |
| 36841 | enum_field_vals: []const InternPool.Index, | 36806 | enum_field_vals: []const InternPool.Index, |
| 36842 | union_owner_decl: *Module.Decl, | 36807 | union_type: InternPool.Index, |
| 36808 | union_name: InternPool.NullTerminatedString, | ||
| 36843 | ) !InternPool.Index { | 36809 | ) !InternPool.Index { |
| 36844 | const pt = sema.pt; | 36810 | const pt = sema.pt; |
| 36845 | const mod = pt.zcu; | 36811 | const mod = pt.zcu; |
| 36846 | const gpa = sema.gpa; | 36812 | const gpa = sema.gpa; |
| 36847 | const ip = &mod.intern_pool; | 36813 | const ip = &mod.intern_pool; |
| 36848 | 36814 | ||
| 36849 | const new_decl_index = try pt.allocateNewDecl(block.namespace); | ||
| 36850 | errdefer pt.destroyDecl(new_decl_index); | ||
| 36851 | const name = try ip.getOrPutStringFmt( | 36815 | const name = try ip.getOrPutStringFmt( |
| 36852 | gpa, | 36816 | gpa, |
| 36853 | pt.tid, | 36817 | pt.tid, |
| 36854 | "@typeInfo({}).Union.tag_type.?", | 36818 | "@typeInfo({}).Union.tag_type.?", |
| 36855 | .{union_owner_decl.fqn.fmt(ip)}, | 36819 | .{union_name.fmt(ip)}, |
| 36856 | .no_embedded_nulls, | 36820 | .no_embedded_nulls, |
| 36857 | ); | 36821 | ); |
| 36858 | try pt.initNewAnonDecl( | ||
| 36859 | new_decl_index, | ||
| 36860 | Value.@"unreachable", | ||
| 36861 | name, | ||
| 36862 | name.toOptional(), | ||
| 36863 | ); | ||
| 36864 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 36865 | |||
| 36866 | const new_decl = mod.declPtr(new_decl_index); | ||
| 36867 | new_decl.owns_tv = true; | ||
| 36868 | 36822 | ||
| 36869 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ | 36823 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ |
| 36870 | .decl = new_decl_index, | 36824 | .name = name, |
| 36871 | .owner_union_ty = union_owner_decl.val.toIntern(), | 36825 | .owner_union_ty = union_type, |
| 36872 | .tag_ty = if (enum_field_vals.len == 0) | 36826 | .tag_ty = if (enum_field_vals.len == 0) |
| 36873 | (try pt.intType(.unsigned, 0)).toIntern() | 36827 | (try pt.intType(.unsigned, 0)).toIntern() |
| 36874 | else | 36828 | else |
| ... | @@ -36876,11 +36830,9 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36876,11 +36830,9 @@ fn generateUnionTagTypeNumbered( |
| 36876 | .names = enum_field_names, | 36830 | .names = enum_field_names, |
| 36877 | .values = enum_field_vals, | 36831 | .values = enum_field_vals, |
| 36878 | .tag_mode = .explicit, | 36832 | .tag_mode = .explicit, |
| 36833 | .parent_namespace = block.namespace, | ||
| 36879 | }); | 36834 | }); |
| 36880 | 36835 | ||
| 36881 | new_decl.val = Value.fromInterned(enum_ty); | ||
| 36882 | |||
| 36883 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 36884 | return enum_ty; | 36836 | return enum_ty; |
| 36885 | } | 36837 | } |
| 36886 | 36838 | ||
| ... | @@ -36888,36 +36840,25 @@ fn generateUnionTagTypeSimple( | ... | @@ -36888,36 +36840,25 @@ fn generateUnionTagTypeSimple( |
| 36888 | sema: *Sema, | 36840 | sema: *Sema, |
| 36889 | block: *Block, | 36841 | block: *Block, |
| 36890 | enum_field_names: []const InternPool.NullTerminatedString, | 36842 | enum_field_names: []const InternPool.NullTerminatedString, |
| 36891 | union_owner_decl: *Module.Decl, | 36843 | union_type: InternPool.Index, |
| 36844 | union_name: InternPool.NullTerminatedString, | ||
| 36892 | ) !InternPool.Index { | 36845 | ) !InternPool.Index { |
| 36893 | const pt = sema.pt; | 36846 | const pt = sema.pt; |
| 36894 | const mod = pt.zcu; | 36847 | const mod = pt.zcu; |
| 36895 | const ip = &mod.intern_pool; | 36848 | const ip = &mod.intern_pool; |
| 36896 | const gpa = sema.gpa; | 36849 | const gpa = sema.gpa; |
| 36897 | 36850 | ||
| 36898 | const new_decl_index = new_decl_index: { | 36851 | const name = try ip.getOrPutStringFmt( |
| 36899 | const new_decl_index = try pt.allocateNewDecl(block.namespace); | 36852 | gpa, |
| 36900 | errdefer pt.destroyDecl(new_decl_index); | 36853 | pt.tid, |
| 36901 | const name = try ip.getOrPutStringFmt( | 36854 | "@typeInfo({}).Union.tag_type.?", |
| 36902 | gpa, | 36855 | .{union_name.fmt(ip)}, |
| 36903 | pt.tid, | 36856 | .no_embedded_nulls, |
| 36904 | "@typeInfo({}).Union.tag_type.?", | 36857 | ); |
| 36905 | .{union_owner_decl.fqn.fmt(ip)}, | ||
| 36906 | .no_embedded_nulls, | ||
| 36907 | ); | ||
| 36908 | try pt.initNewAnonDecl( | ||
| 36909 | new_decl_index, | ||
| 36910 | Value.@"unreachable", | ||
| 36911 | name, | ||
| 36912 | name.toOptional(), | ||
| 36913 | ); | ||
| 36914 | break :new_decl_index new_decl_index; | ||
| 36915 | }; | ||
| 36916 | errdefer pt.abortAnonDecl(new_decl_index); | ||
| 36917 | 36858 | ||
| 36918 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ | 36859 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ |
| 36919 | .decl = new_decl_index, | 36860 | .name = name, |
| 36920 | .owner_union_ty = union_owner_decl.val.toIntern(), | 36861 | .owner_union_ty = union_type, |
| 36921 | .tag_ty = if (enum_field_names.len == 0) | 36862 | .tag_ty = if (enum_field_names.len == 0) |
| 36922 | (try pt.intType(.unsigned, 0)).toIntern() | 36863 | (try pt.intType(.unsigned, 0)).toIntern() |
| 36923 | else | 36864 | else |
| ... | @@ -36925,13 +36866,9 @@ fn generateUnionTagTypeSimple( | ... | @@ -36925,13 +36866,9 @@ fn generateUnionTagTypeSimple( |
| 36925 | .names = enum_field_names, | 36866 | .names = enum_field_names, |
| 36926 | .values = &.{}, | 36867 | .values = &.{}, |
| 36927 | .tag_mode = .auto, | 36868 | .tag_mode = .auto, |
| 36869 | .parent_namespace = block.namespace, | ||
| 36928 | }); | 36870 | }); |
| 36929 | 36871 | ||
| 36930 | const new_decl = mod.declPtr(new_decl_index); | ||
| 36931 | new_decl.owns_tv = true; | ||
| 36932 | new_decl.val = Value.fromInterned(enum_ty); | ||
| 36933 | |||
| 36934 | try pt.finalizeAnonDecl(new_decl_index); | ||
| 36935 | return enum_ty; | 36872 | return enum_ty; |
| 36936 | } | 36873 | } |
| 36937 | 36874 | ||
| ... | @@ -37057,9 +36994,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -37057,9 +36994,9 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 37057 | // values, not types | 36994 | // values, not types |
| 37058 | .undef, | 36995 | .undef, |
| 37059 | .simple_value, | 36996 | .simple_value, |
| 37060 | .ptr_decl, | 36997 | .ptr_nav, |
| 37061 | .ptr_anon_decl, | 36998 | .ptr_uav, |
| 37062 | .ptr_anon_decl_aligned, | 36999 | .ptr_uav_aligned, |
| 37063 | .ptr_comptime_alloc, | 37000 | .ptr_comptime_alloc, |
| 37064 | .ptr_comptime_field, | 37001 | .ptr_comptime_field, |
| 37065 | .ptr_int, | 37002 | .ptr_int, |
| ... | @@ -37096,7 +37033,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -37096,7 +37033,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 37096 | .float_c_longdouble_f128, | 37033 | .float_c_longdouble_f128, |
| 37097 | .float_comptime_float, | 37034 | .float_comptime_float, |
| 37098 | .variable, | 37035 | .variable, |
| 37099 | .extern_func, | 37036 | .@"extern", |
| 37100 | .func_decl, | 37037 | .func_decl, |
| 37101 | .func_instance, | 37038 | .func_instance, |
| 37102 | .func_coerced, | 37039 | .func_coerced, |
| ... | @@ -37965,7 +37902,7 @@ fn intFitsInType( | ... | @@ -37965,7 +37902,7 @@ fn intFitsInType( |
| 37965 | .zero_usize, .zero_u8 => return true, | 37902 | .zero_usize, .zero_u8 => return true, |
| 37966 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { | 37903 | else => switch (mod.intern_pool.indexToKey(val.toIntern())) { |
| 37967 | .undef => return true, | 37904 | .undef => return true, |
| 37968 | .variable, .extern_func, .func, .ptr => { | 37905 | .variable, .@"extern", .func, .ptr => { |
| 37969 | const target = mod.getTarget(); | 37906 | const target = mod.getTarget(); |
| 37970 | const ptr_bits = target.ptrBitWidth(); | 37907 | const ptr_bits = target.ptrBitWidth(); |
| 37971 | return switch (info.signedness) { | 37908 | return switch (info.signedness) { |
| ... | @@ -38240,24 +38177,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void { | ... | @@ -38240,24 +38177,24 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void { |
| 38240 | // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would | 38177 | // 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 | 38178 | // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve |
| 38242 | // the loop. | 38179 | // the loop. |
| 38243 | if (sema.owner_func_index == .none and dependee == .decl_val and dependee.decl_val == sema.owner_decl_index) { | 38180 | switch (sema.owner.unwrap()) { |
| 38244 | return; | 38181 | .cau => |cau| switch (dependee) { |
| 38182 | .nav_val => |nav| if (zcu.intern_pool.getNav(nav).analysis_owner == cau.toOptional()) { | ||
| 38183 | return; | ||
| 38184 | }, | ||
| 38185 | else => {}, | ||
| 38186 | }, | ||
| 38187 | .func => {}, | ||
| 38245 | } | 38188 | } |
| 38246 | 38189 | ||
| 38247 | const depender = AnalUnit.wrap( | 38190 | try zcu.intern_pool.addDependency(sema.gpa, sema.owner, dependee); |
| 38248 | if (sema.owner_func_index != .none) | ||
| 38249 | .{ .func = sema.owner_func_index } | ||
| 38250 | else | ||
| 38251 | .{ .decl = sema.owner_decl_index }, | ||
| 38252 | ); | ||
| 38253 | try zcu.intern_pool.addDependency(sema.gpa, depender, dependee); | ||
| 38254 | } | 38191 | } |
| 38255 | 38192 | ||
| 38256 | fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { | 38193 | fn isComptimeMutablePtr(sema: *Sema, val: Value) bool { |
| 38257 | return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) { | 38194 | return switch (sema.pt.zcu.intern_pool.indexToKey(val.toIntern())) { |
| 38258 | .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)), | 38195 | .slice => |slice| sema.isComptimeMutablePtr(Value.fromInterned(slice.ptr)), |
| 38259 | .ptr => |ptr| switch (ptr.base_addr) { | 38196 | .ptr => |ptr| switch (ptr.base_addr) { |
| 38260 | .anon_decl, .decl, .int => false, | 38197 | .uav, .nav, .int => false, |
| 38261 | .comptime_field => true, | 38198 | .comptime_field => true, |
| 38262 | .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const, | 38199 | .comptime_alloc => |alloc_index| !sema.getComptimeAlloc(alloc_index).is_const, |
| 38263 | .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)), | 38200 | .eu_payload, .opt_payload => |base| sema.isComptimeMutablePtr(Value.fromInterned(base)), |
| ... | @@ -38388,19 +38325,17 @@ pub fn flushExports(sema: *Sema) !void { | ... | @@ -38388,19 +38325,17 @@ pub fn flushExports(sema: *Sema) !void { |
| 38388 | const zcu = sema.pt.zcu; | 38325 | const zcu = sema.pt.zcu; |
| 38389 | const gpa = zcu.gpa; | 38326 | const gpa = zcu.gpa; |
| 38390 | 38327 | ||
| 38391 | const unit = sema.ownerUnit(); | ||
| 38392 | |||
| 38393 | // There may be existing exports. For instance, a struct may export | 38328 | // There may be existing exports. For instance, a struct may export |
| 38394 | // things during both field type resolution and field default resolution. | 38329 | // things during both field type resolution and field default resolution. |
| 38395 | // | 38330 | // |
| 38396 | // So, pick up and delete any existing exports. This strategy performs | 38331 | // So, pick up and delete any existing exports. This strategy performs |
| 38397 | // redundant work, but that's okay, because this case is exceedingly rare. | 38332 | // redundant work, but that's okay, because this case is exceedingly rare. |
| 38398 | if (zcu.single_exports.get(unit)) |export_idx| { | 38333 | if (zcu.single_exports.get(sema.owner)) |export_idx| { |
| 38399 | try sema.exports.append(gpa, zcu.all_exports.items[export_idx]); | 38334 | try sema.exports.append(gpa, zcu.all_exports.items[export_idx]); |
| 38400 | } else if (zcu.multi_exports.get(unit)) |info| { | 38335 | } else if (zcu.multi_exports.get(sema.owner)) |info| { |
| 38401 | try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]); | 38336 | try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]); |
| 38402 | } | 38337 | } |
| 38403 | zcu.deleteUnitExports(unit); | 38338 | zcu.deleteUnitExports(sema.owner); |
| 38404 | 38339 | ||
| 38405 | // `sema.exports` is completed; store the data into the `Zcu`. | 38340 | // `sema.exports` is completed; store the data into the `Zcu`. |
| 38406 | if (sema.exports.items.len == 1) { | 38341 | if (sema.exports.items.len == 1) { |
| ... | @@ -38410,24 +38345,55 @@ pub fn flushExports(sema: *Sema) !void { | ... | @@ -38410,24 +38345,55 @@ pub fn flushExports(sema: *Sema) !void { |
| 38410 | break :idx zcu.all_exports.items.len - 1; | 38345 | break :idx zcu.all_exports.items.len - 1; |
| 38411 | }; | 38346 | }; |
| 38412 | zcu.all_exports.items[export_idx] = sema.exports.items[0]; | 38347 | zcu.all_exports.items[export_idx] = sema.exports.items[0]; |
| 38413 | zcu.single_exports.putAssumeCapacityNoClobber(unit, @intCast(export_idx)); | 38348 | zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, @intCast(export_idx)); |
| 38414 | } else { | 38349 | } else { |
| 38415 | try zcu.multi_exports.ensureUnusedCapacity(gpa, 1); | 38350 | try zcu.multi_exports.ensureUnusedCapacity(gpa, 1); |
| 38416 | const exports_base = zcu.all_exports.items.len; | 38351 | const exports_base = zcu.all_exports.items.len; |
| 38417 | try zcu.all_exports.appendSlice(gpa, sema.exports.items); | 38352 | try zcu.all_exports.appendSlice(gpa, sema.exports.items); |
| 38418 | zcu.multi_exports.putAssumeCapacityNoClobber(unit, .{ | 38353 | zcu.multi_exports.putAssumeCapacityNoClobber(sema.owner, .{ |
| 38419 | .index = @intCast(exports_base), | 38354 | .index = @intCast(exports_base), |
| 38420 | .len = @intCast(sema.exports.items.len), | 38355 | .len = @intCast(sema.exports.items.len), |
| 38421 | }); | 38356 | }); |
| 38422 | } | 38357 | } |
| 38423 | } | 38358 | } |
| 38424 | 38359 | ||
| 38425 | pub fn ownerUnit(sema: Sema) AnalUnit { | 38360 | /// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches |
| 38426 | if (sema.owner_func_index != .none) { | 38361 | /// the corresponding `Nav`. |
| 38427 | return AnalUnit.wrap(.{ .func = sema.owner_func_index }); | 38362 | fn getOwnerCauNav(sema: *Sema) InternPool.Nav.Index { |
| 38428 | } else { | 38363 | const cau = sema.owner.unwrap().cau; |
| 38429 | return AnalUnit.wrap(.{ .decl = sema.owner_decl_index }); | 38364 | return sema.pt.zcu.intern_pool.getCau(cau).owner.unwrap().nav; |
| 38430 | } | 38365 | } |
| 38366 | |||
| 38367 | /// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches | ||
| 38368 | /// the declaration name from its corresponding `Nav`. | ||
| 38369 | fn getOwnerCauNavName(sema: *Sema) InternPool.NullTerminatedString { | ||
| 38370 | const nav = sema.getOwnerCauNav(); | ||
| 38371 | return sema.pt.zcu.intern_pool.getNav(nav).name; | ||
| 38372 | } | ||
| 38373 | |||
| 38374 | /// Given that this `Sema` is owned by the `Cau` of a `declaration`, fetches | ||
| 38375 | /// the `TrackedInst` corresponding to this `declaration` instruction. | ||
| 38376 | fn getOwnerCauDeclInst(sema: *Sema) InternPool.TrackedInst.Index { | ||
| 38377 | const ip = &sema.pt.zcu.intern_pool; | ||
| 38378 | const cau = ip.getCau(sema.owner.unwrap().cau); | ||
| 38379 | assert(cau.owner.unwrap() == .nav); | ||
| 38380 | return cau.zir_index; | ||
| 38381 | } | ||
| 38382 | |||
| 38383 | /// Given that this `Sema` is owned by a runtime function, fetches the | ||
| 38384 | /// `TrackedInst` corresponding to its `declaration` instruction. | ||
| 38385 | fn getOwnerFuncDeclInst(sema: *Sema) InternPool.TrackedInst.Index { | ||
| 38386 | const zcu = sema.pt.zcu; | ||
| 38387 | const ip = &zcu.intern_pool; | ||
| 38388 | const func = sema.owner.unwrap().func; | ||
| 38389 | const func_info = zcu.funcInfo(func); | ||
| 38390 | const cau = if (func_info.generic_owner == .none) cau: { | ||
| 38391 | break :cau ip.getNav(func_info.owner_nav).analysis_owner.unwrap().?; | ||
| 38392 | } else cau: { | ||
| 38393 | const generic_owner = zcu.funcInfo(func_info.generic_owner); | ||
| 38394 | break :cau ip.getNav(generic_owner.owner_nav).analysis_owner.unwrap().?; | ||
| 38395 | }; | ||
| 38396 | return ip.getCau(cau).zir_index; | ||
| 38431 | } | 38397 | } |
| 38432 | 38398 | ||
| 38433 | pub const bitCastVal = @import("Sema/bitcast.zig").bitCast; | 38399 | 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+102-90| ... | @@ -268,9 +268,9 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error | ... | @@ -268,9 +268,9 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 268 | return; | 268 | return; |
| 269 | }, | 269 | }, |
| 270 | .inferred_error_set_type => |func_index| { | 270 | .inferred_error_set_type => |func_index| { |
| 271 | const owner_decl = mod.funcOwnerDeclPtr(func_index); | 271 | const func_nav = ip.getNav(mod.funcInfo(func_index).owner_nav); |
| 272 | try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{ | 272 | try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{ |
| 273 | owner_decl.fqn.fmt(ip), | 273 | func_nav.fqn.fmt(ip), |
| 274 | }); | 274 | }); |
| 275 | }, | 275 | }, |
| 276 | .error_set_type => |error_set_type| { | 276 | .error_set_type => |error_set_type| { |
| ... | @@ -331,15 +331,11 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error | ... | @@ -331,15 +331,11 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 331 | .generic_poison => unreachable, | 331 | .generic_poison => unreachable, |
| 332 | }, | 332 | }, |
| 333 | .struct_type => { | 333 | .struct_type => { |
| 334 | const struct_type = ip.loadStructType(ty.toIntern()); | 334 | const name = ip.loadStructType(ty.toIntern()).name; |
| 335 | if (struct_type.decl.unwrap()) |decl_index| { | 335 | if (name == .empty) { |
| 336 | const decl = mod.declPtr(decl_index); | ||
| 337 | try writer.print("{}", .{decl.fqn.fmt(ip)}); | ||
| 338 | } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| { | ||
| 339 | const namespace = mod.namespacePtr(namespace_index); | ||
| 340 | try namespace.renderFullyQualifiedName(ip, .empty, writer); | ||
| 341 | } else { | ||
| 342 | try writer.writeAll("@TypeOf(.{})"); | 336 | try writer.writeAll("@TypeOf(.{})"); |
| 337 | } else { | ||
| 338 | try writer.print("{}", .{name.fmt(ip)}); | ||
| 343 | } | 339 | } |
| 344 | }, | 340 | }, |
| 345 | .anon_struct_type => |anon_struct| { | 341 | .anon_struct_type => |anon_struct| { |
| ... | @@ -366,16 +362,16 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error | ... | @@ -366,16 +362,16 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 366 | }, | 362 | }, |
| 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, |
| ... | @@ -2972,41 +2968,27 @@ pub fn indexableHasLen(ty: Type, mod: *Module) bool { | ... | @@ -2972,41 +2968,27 @@ pub fn indexableHasLen(ty: Type, mod: *Module) bool { |
| 2972 | } | 2968 | } |
| 2973 | 2969 | ||
| 2974 | /// Asserts that the type can have a namespace. | 2970 | /// Asserts that the type can have a namespace. |
| 2975 | pub fn getNamespaceIndex(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex { | 2971 | pub fn getNamespaceIndex(ty: Type, zcu: *Zcu) InternPool.NamespaceIndex { |
| 2976 | return ty.getNamespace(zcu).?; | 2972 | return ty.getNamespace(zcu).unwrap().?; |
| 2977 | } | 2973 | } |
| 2978 | 2974 | ||
| 2979 | /// Returns null if the type has no namespace. | 2975 | /// Returns null if the type has no namespace. |
| 2980 | pub fn getNamespace(ty: Type, zcu: *Zcu) ?InternPool.OptionalNamespaceIndex { | 2976 | pub fn getNamespace(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex { |
| 2981 | const ip = &zcu.intern_pool; | 2977 | const ip = &zcu.intern_pool; |
| 2982 | return switch (ip.indexToKey(ty.toIntern())) { | 2978 | return switch (ip.indexToKey(ty.toIntern())) { |
| 2983 | .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace, | 2979 | .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(), |
| 2984 | .struct_type => ip.loadStructType(ty.toIntern()).namespace, | 2980 | .struct_type => ip.loadStructType(ty.toIntern()).namespace, |
| 2985 | .union_type => ip.loadUnionType(ty.toIntern()).namespace, | 2981 | .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(), |
| 2986 | .enum_type => ip.loadEnumType(ty.toIntern()).namespace, | 2982 | .enum_type => ip.loadEnumType(ty.toIntern()).namespace.toOptional(), |
| 2987 | 2983 | else => .none, | |
| 2988 | .anon_struct_type => .none, | ||
| 2989 | .simple_type => |s| switch (s) { | ||
| 2990 | .anyopaque, | ||
| 2991 | .atomic_order, | ||
| 2992 | .atomic_rmw_op, | ||
| 2993 | .calling_convention, | ||
| 2994 | .address_space, | ||
| 2995 | .float_mode, | ||
| 2996 | .reduce_op, | ||
| 2997 | .call_modifier, | ||
| 2998 | .prefetch_options, | ||
| 2999 | .export_options, | ||
| 3000 | .extern_options, | ||
| 3001 | .type_info, | ||
| 3002 | => .none, | ||
| 3003 | else => null, | ||
| 3004 | }, | ||
| 3005 | |||
| 3006 | else => null, | ||
| 3007 | }; | 2984 | }; |
| 3008 | } | 2985 | } |
| 3009 | 2986 | ||
| 2987 | // TODO: new dwarf structure will also need the enclosing code block for types created in imperative scopes | ||
| 2988 | pub fn getParentNamespace(ty: Type, zcu: *Zcu) InternPool.OptionalNamespaceIndex { | ||
| 2989 | return zcu.namespacePtr(ty.getNamespace(zcu).unwrap() orelse return .none).parent; | ||
| 2990 | } | ||
| 2991 | |||
| 3010 | // Works for vectors and vectors of integers. | 2992 | // Works for vectors and vectors of integers. |
| 3011 | pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { | 2993 | pub fn minInt(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value { |
| 3012 | const mod = pt.zcu; | 2994 | const mod = pt.zcu; |
| ... | @@ -3321,21 +3303,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { | ... | @@ -3321,21 +3303,6 @@ pub fn structFieldOffset(ty: Type, index: usize, pt: Zcu.PerThread) u64 { |
| 3321 | } | 3303 | } |
| 3322 | } | 3304 | } |
| 3323 | 3305 | ||
| 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 { | 3306 | pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc { |
| 3340 | const ip = &zcu.intern_pool; | 3307 | const ip = &zcu.intern_pool; |
| 3341 | return .{ | 3308 | return .{ |
| ... | @@ -3366,7 +3333,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool { | ... | @@ -3366,7 +3333,7 @@ pub fn isTuple(ty: Type, mod: *Module) bool { |
| 3366 | .struct_type => { | 3333 | .struct_type => { |
| 3367 | const struct_type = ip.loadStructType(ty.toIntern()); | 3334 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 3368 | if (struct_type.layout == .@"packed") return false; | 3335 | if (struct_type.layout == .@"packed") return false; |
| 3369 | if (struct_type.decl == .none) return false; | 3336 | if (struct_type.cau == .none) return false; |
| 3370 | return struct_type.flagsUnordered(ip).is_tuple; | 3337 | return struct_type.flagsUnordered(ip).is_tuple; |
| 3371 | }, | 3338 | }, |
| 3372 | .anon_struct_type => |anon_struct| anon_struct.names.len == 0, | 3339 | .anon_struct_type => |anon_struct| anon_struct.names.len == 0, |
| ... | @@ -3388,7 +3355,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool { | ... | @@ -3388,7 +3355,7 @@ pub fn isTupleOrAnonStruct(ty: Type, mod: *Module) bool { |
| 3388 | .struct_type => { | 3355 | .struct_type => { |
| 3389 | const struct_type = ip.loadStructType(ty.toIntern()); | 3356 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 3390 | if (struct_type.layout == .@"packed") return false; | 3357 | if (struct_type.layout == .@"packed") return false; |
| 3391 | if (struct_type.decl == .none) return false; | 3358 | if (struct_type.cau == .none) return false; |
| 3392 | return struct_type.flagsUnordered(ip).is_tuple; | 3359 | return struct_type.flagsUnordered(ip).is_tuple; |
| 3393 | }, | 3360 | }, |
| 3394 | .anon_struct_type => true, | 3361 | .anon_struct_type => true, |
| ... | @@ -3444,6 +3411,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index { | ... | @@ -3444,6 +3411,21 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index { |
| 3444 | }; | 3411 | }; |
| 3445 | } | 3412 | } |
| 3446 | 3413 | ||
| 3414 | pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index { | ||
| 3415 | const ip = &zcu.intern_pool; | ||
| 3416 | return switch (ip.indexToKey(ty.toIntern())) { | ||
| 3417 | .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(), | ||
| 3418 | .union_type => ip.loadUnionType(ty.toIntern()).zir_index, | ||
| 3419 | .enum_type => |e| switch (e) { | ||
| 3420 | .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?, | ||
| 3421 | .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index, | ||
| 3422 | .empty_struct => unreachable, | ||
| 3423 | }, | ||
| 3424 | .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index, | ||
| 3425 | else => null, | ||
| 3426 | }; | ||
| 3427 | } | ||
| 3428 | |||
| 3447 | pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 { | 3429 | pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 { |
| 3448 | const ip = &zcu.intern_pool; | 3430 | const ip = &zcu.intern_pool; |
| 3449 | const tracked = switch (ip.indexToKey(ty.toIntern())) { | 3431 | const tracked = switch (ip.indexToKey(ty.toIntern())) { |
| ... | @@ -3471,7 +3453,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 { | ... | @@ -3471,7 +3453,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 { |
| 3471 | }; | 3453 | }; |
| 3472 | } | 3454 | } |
| 3473 | 3455 | ||
| 3474 | /// Given a namespace type, returns its list of caotured values. | 3456 | /// Given a namespace type, returns its list of captured values. |
| 3475 | pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice { | 3457 | pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice { |
| 3476 | const ip = &zcu.intern_pool; | 3458 | const ip = &zcu.intern_pool; |
| 3477 | return switch (ip.indexToKey(ty.toIntern())) { | 3459 | return switch (ip.indexToKey(ty.toIntern())) { |
| ... | @@ -3773,7 +3755,11 @@ fn resolveStructInner( | ... | @@ -3773,7 +3755,11 @@ fn resolveStructInner( |
| 3773 | const gpa = zcu.gpa; | 3755 | const gpa = zcu.gpa; |
| 3774 | 3756 | ||
| 3775 | const struct_obj = zcu.typeToStruct(ty).?; | 3757 | const struct_obj = zcu.typeToStruct(ty).?; |
| 3776 | const owner_decl_index = struct_obj.decl.unwrap() orelse return; | 3758 | const owner = InternPool.AnalUnit.wrap(.{ .cau = struct_obj.cau.unwrap() orelse return }); |
| 3759 | |||
| 3760 | if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) { | ||
| 3761 | return error.AnalysisFail; | ||
| 3762 | } | ||
| 3777 | 3763 | ||
| 3778 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); | 3764 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); |
| 3779 | defer analysis_arena.deinit(); | 3765 | defer analysis_arena.deinit(); |
| ... | @@ -3786,24 +3772,30 @@ fn resolveStructInner( | ... | @@ -3786,24 +3772,30 @@ fn resolveStructInner( |
| 3786 | .gpa = gpa, | 3772 | .gpa = gpa, |
| 3787 | .arena = analysis_arena.allocator(), | 3773 | .arena = analysis_arena.allocator(), |
| 3788 | .code = undefined, // This ZIR will not be used. | 3774 | .code = undefined, // This ZIR will not be used. |
| 3789 | .owner_decl = zcu.declPtr(owner_decl_index), | 3775 | .owner = owner, |
| 3790 | .owner_decl_index = owner_decl_index, | ||
| 3791 | .func_index = .none, | 3776 | .func_index = .none, |
| 3792 | .func_is_naked = false, | 3777 | .func_is_naked = false, |
| 3793 | .fn_ret_ty = Type.void, | 3778 | .fn_ret_ty = Type.void, |
| 3794 | .fn_ret_ty_ies = null, | 3779 | .fn_ret_ty_ies = null, |
| 3795 | .owner_func_index = .none, | ||
| 3796 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 3780 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 3797 | }; | 3781 | }; |
| 3798 | defer sema.deinit(); | 3782 | defer sema.deinit(); |
| 3799 | 3783 | ||
| 3800 | switch (resolution) { | 3784 | (switch (resolution) { |
| 3801 | .fields => return sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj), | 3785 | .fields => sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj), |
| 3802 | .inits => return sema.resolveStructFieldInits(ty), | 3786 | .inits => sema.resolveStructFieldInits(ty), |
| 3803 | .alignment => return sema.resolveStructAlignment(ty.toIntern(), struct_obj), | 3787 | .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj), |
| 3804 | .layout => return sema.resolveStructLayout(ty), | 3788 | .layout => sema.resolveStructLayout(ty), |
| 3805 | .full => return sema.resolveStructFully(ty), | 3789 | .full => sema.resolveStructFully(ty), |
| 3806 | } | 3790 | }) catch |err| switch (err) { |
| 3791 | error.AnalysisFail => { | ||
| 3792 | if (!zcu.failed_analysis.contains(owner)) { | ||
| 3793 | try zcu.transitive_failed_analysis.put(gpa, owner, {}); | ||
| 3794 | } | ||
| 3795 | return error.AnalysisFail; | ||
| 3796 | }, | ||
| 3797 | error.OutOfMemory => |e| return e, | ||
| 3798 | }; | ||
| 3807 | } | 3799 | } |
| 3808 | 3800 | ||
| 3809 | /// `ty` must be a union. | 3801 | /// `ty` must be a union. |
| ... | @@ -3816,7 +3808,11 @@ fn resolveUnionInner( | ... | @@ -3816,7 +3808,11 @@ fn resolveUnionInner( |
| 3816 | const gpa = zcu.gpa; | 3808 | const gpa = zcu.gpa; |
| 3817 | 3809 | ||
| 3818 | const union_obj = zcu.typeToUnion(ty).?; | 3810 | const union_obj = zcu.typeToUnion(ty).?; |
| 3819 | const owner_decl_index = union_obj.decl; | 3811 | const owner = InternPool.AnalUnit.wrap(.{ .cau = union_obj.cau }); |
| 3812 | |||
| 3813 | if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) { | ||
| 3814 | return error.AnalysisFail; | ||
| 3815 | } | ||
| 3820 | 3816 | ||
| 3821 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); | 3817 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); |
| 3822 | defer analysis_arena.deinit(); | 3818 | defer analysis_arena.deinit(); |
| ... | @@ -3829,23 +3825,29 @@ fn resolveUnionInner( | ... | @@ -3829,23 +3825,29 @@ fn resolveUnionInner( |
| 3829 | .gpa = gpa, | 3825 | .gpa = gpa, |
| 3830 | .arena = analysis_arena.allocator(), | 3826 | .arena = analysis_arena.allocator(), |
| 3831 | .code = undefined, // This ZIR will not be used. | 3827 | .code = undefined, // This ZIR will not be used. |
| 3832 | .owner_decl = zcu.declPtr(owner_decl_index), | 3828 | .owner = owner, |
| 3833 | .owner_decl_index = owner_decl_index, | ||
| 3834 | .func_index = .none, | 3829 | .func_index = .none, |
| 3835 | .func_is_naked = false, | 3830 | .func_is_naked = false, |
| 3836 | .fn_ret_ty = Type.void, | 3831 | .fn_ret_ty = Type.void, |
| 3837 | .fn_ret_ty_ies = null, | 3832 | .fn_ret_ty_ies = null, |
| 3838 | .owner_func_index = .none, | ||
| 3839 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 3833 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 3840 | }; | 3834 | }; |
| 3841 | defer sema.deinit(); | 3835 | defer sema.deinit(); |
| 3842 | 3836 | ||
| 3843 | switch (resolution) { | 3837 | (switch (resolution) { |
| 3844 | .fields => return sema.resolveTypeFieldsUnion(ty, union_obj), | 3838 | .fields => sema.resolveTypeFieldsUnion(ty, union_obj), |
| 3845 | .alignment => return sema.resolveUnionAlignment(ty, union_obj), | 3839 | .alignment => sema.resolveUnionAlignment(ty, union_obj), |
| 3846 | .layout => return sema.resolveUnionLayout(ty), | 3840 | .layout => sema.resolveUnionLayout(ty), |
| 3847 | .full => return sema.resolveUnionFully(ty), | 3841 | .full => sema.resolveUnionFully(ty), |
| 3848 | } | 3842 | }) catch |err| switch (err) { |
| 3843 | error.AnalysisFail => { | ||
| 3844 | if (!zcu.failed_analysis.contains(owner)) { | ||
| 3845 | try zcu.transitive_failed_analysis.put(gpa, owner, {}); | ||
| 3846 | } | ||
| 3847 | return error.AnalysisFail; | ||
| 3848 | }, | ||
| 3849 | error.OutOfMemory => |e| return e, | ||
| 3850 | }; | ||
| 3849 | } | 3851 | } |
| 3850 | 3852 | ||
| 3851 | /// Fully resolves a simple type. This is usually a nop, but for builtin types with | 3853 | /// Fully resolves a simple type. This is usually a nop, but for builtin types with |
| ... | @@ -3945,6 +3947,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type { | ... | @@ -3945,6 +3947,16 @@ pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type { |
| 3945 | }); | 3947 | }); |
| 3946 | } | 3948 | } |
| 3947 | 3949 | ||
| 3950 | pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString { | ||
| 3951 | return switch (ip.indexToKey(ty.toIntern())) { | ||
| 3952 | .struct_type => ip.loadStructType(ty.toIntern()).name, | ||
| 3953 | .union_type => ip.loadUnionType(ty.toIntern()).name, | ||
| 3954 | .enum_type => ip.loadEnumType(ty.toIntern()).name, | ||
| 3955 | .opaque_type => ip.loadOpaqueType(ty.toIntern()).name, | ||
| 3956 | else => unreachable, | ||
| 3957 | }; | ||
| 3958 | } | ||
| 3959 | |||
| 3948 | pub const @"u1": Type = .{ .ip_index = .u1_type }; | 3960 | pub const @"u1": Type = .{ .ip_index = .u1_type }; |
| 3949 | pub const @"u8": Type = .{ .ip_index = .u8_type }; | 3961 | pub const @"u8": Type = .{ .ip_index = .u8_type }; |
| 3950 | pub const @"u16": Type = .{ .ip_index = .u16_type }; | 3962 | 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+834-844| ... | @@ -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; |
| ... | @@ -901,7 +887,6 @@ fn getFileRootStruct( | ... | @@ -901,7 +887,6 @@ fn getFileRootStruct( |
| 901 | .any_default_inits = small.any_default_inits, | 887 | .any_default_inits = small.any_default_inits, |
| 902 | .inits_resolved = false, | 888 | .inits_resolved = false, |
| 903 | .any_aligned_fields = small.any_aligned_fields, | 889 | .any_aligned_fields = small.any_aligned_fields, |
| 904 | .has_namespace = true, | ||
| 905 | .key = .{ .declared = .{ | 890 | .key = .{ .declared = .{ |
| 906 | .zir_index = tracked_inst, | 891 | .zir_index = tracked_inst, |
| 907 | .captures = &.{}, | 892 | .captures = &.{}, |
| ... | @@ -912,34 +897,37 @@ fn getFileRootStruct( | ... | @@ -912,34 +897,37 @@ fn getFileRootStruct( |
| 912 | }; | 897 | }; |
| 913 | errdefer wip_ty.cancel(ip, pt.tid); | 898 | errdefer wip_ty.cancel(ip, pt.tid); |
| 914 | 899 | ||
| 900 | wip_ty.setName(ip, try file.internFullyQualifiedName(pt)); | ||
| 901 | ip.namespacePtr(namespace_index).owner_type = wip_ty.index; | ||
| 902 | const new_cau_index = try ip.createTypeCau(gpa, pt.tid, tracked_inst, namespace_index, wip_ty.index); | ||
| 903 | |||
| 915 | if (zcu.comp.incremental) { | 904 | if (zcu.comp.incremental) { |
| 916 | try ip.addDependency( | 905 | try ip.addDependency( |
| 917 | gpa, | 906 | gpa, |
| 918 | InternPool.AnalUnit.wrap(.{ .decl = decl_index }), | 907 | InternPool.AnalUnit.wrap(.{ .cau = new_cau_index }), |
| 919 | .{ .src_hash = tracked_inst }, | 908 | .{ .src_hash = tracked_inst }, |
| 920 | ); | 909 | ); |
| 921 | } | 910 | } |
| 922 | 911 | ||
| 923 | const decl = zcu.declPtr(decl_index); | 912 | try pt.scanNamespace(namespace_index, decls); |
| 924 | decl.val = Value.fromInterned(wip_ty.index); | ||
| 925 | decl.has_tv = true; | ||
| 926 | decl.owns_tv = true; | ||
| 927 | decl.analysis = .complete; | ||
| 928 | |||
| 929 | try pt.scanNamespace(namespace_index, decls, decl); | ||
| 930 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 913 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 931 | return wip_ty.finish(ip, decl_index, namespace_index.toOptional()); | 914 | zcu.setFileRootType(file_index, wip_ty.index); |
| 915 | return wip_ty.finish(ip, new_cau_index.toOptional(), namespace_index); | ||
| 932 | } | 916 | } |
| 933 | 917 | ||
| 934 | /// Re-analyze the root Decl of a file on an incremental update. | 918 | /// Re-analyze the root type of a file on an incremental update. |
| 935 | /// If `type_outdated`, the struct type itself is considered outdated and is | 919 | /// If `type_outdated`, the struct type itself is considered outdated and is |
| 936 | /// reconstructed at a new InternPool index. Otherwise, the namespace is just | 920 | /// reconstructed at a new InternPool index. Otherwise, the namespace is just |
| 937 | /// re-analyzed. Returns whether the decl's tyval was invalidated. | 921 | /// re-analyzed. Returns whether the decl's tyval was invalidated. |
| 922 | /// Returns `error.AnalysisFail` if the file has an error. | ||
| 938 | fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool { | 923 | fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: bool) Zcu.SemaError!bool { |
| 939 | const zcu = pt.zcu; | 924 | const zcu = pt.zcu; |
| 940 | const ip = &zcu.intern_pool; | 925 | const ip = &zcu.intern_pool; |
| 941 | const file = zcu.fileByIndex(file_index); | 926 | const file = zcu.fileByIndex(file_index); |
| 942 | const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?); | 927 | const file_root_type = zcu.fileRootType(file_index); |
| 928 | const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu); | ||
| 929 | |||
| 930 | assert(file_root_type != .none); | ||
| 943 | 931 | ||
| 944 | log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{ | 932 | log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{ |
| 945 | file.mod.fully_qualified_name, | 933 | file.mod.fully_qualified_name, |
| ... | @@ -948,33 +936,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: | ... | @@ -948,33 +936,18 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: |
| 948 | }); | 936 | }); |
| 949 | 937 | ||
| 950 | if (file.status != .success_zir) { | 938 | if (file.status != .success_zir) { |
| 951 | if (decl.analysis == .file_failure) { | 939 | return error.AnalysisFail; |
| 952 | return false; | ||
| 953 | } else { | ||
| 954 | decl.analysis = .file_failure; | ||
| 955 | return true; | ||
| 956 | } | ||
| 957 | } | ||
| 958 | |||
| 959 | if (decl.analysis == .file_failure) { | ||
| 960 | // No struct type currently exists. Create one! | ||
| 961 | const root_decl = zcu.fileRootDecl(file_index); | ||
| 962 | _ = try pt.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index); | ||
| 963 | return true; | ||
| 964 | } | 940 | } |
| 965 | 941 | ||
| 966 | assert(decl.has_tv); | ||
| 967 | assert(decl.owns_tv); | ||
| 968 | |||
| 969 | if (type_outdated) { | 942 | if (type_outdated) { |
| 970 | // Invalidate the existing type, reusing the decl and namespace. | 943 | // Invalidate the existing type, reusing its namespace. |
| 971 | const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?; | 944 | const file_root_type_cau = ip.loadStructType(file_root_type).cau.unwrap().?; |
| 972 | ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ | 945 | ip.removeDependenciesForDepender( |
| 973 | .decl = file_root_decl, | 946 | zcu.gpa, |
| 974 | })); | 947 | InternPool.AnalUnit.wrap(.{ .cau = file_root_type_cau }), |
| 975 | ip.remove(pt.tid, decl.val.toIntern()); | 948 | ); |
| 976 | decl.val = undefined; | 949 | ip.remove(pt.tid, file_root_type); |
| 977 | _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index); | 950 | _ = try pt.createFileRootStruct(file_index, namespace_index); |
| 978 | return true; | 951 | return true; |
| 979 | } | 952 | } |
| 980 | 953 | ||
| ... | @@ -994,7 +967,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: | ... | @@ -994,7 +967,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated: |
| 994 | const decls = file.zir.bodySlice(extra_index, decls_len); | 967 | const decls = file.zir.bodySlice(extra_index, decls_len); |
| 995 | 968 | ||
| 996 | if (!type_outdated) { | 969 | if (!type_outdated) { |
| 997 | try pt.scanNamespace(decl.src_namespace, decls, decl); | 970 | try pt.scanNamespace(namespace_index, decls); |
| 998 | } | 971 | } |
| 999 | 972 | ||
| 1000 | return false; | 973 | return false; |
| ... | @@ -1009,43 +982,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1009,43 +982,19 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1009 | const zcu = pt.zcu; | 982 | const zcu = pt.zcu; |
| 1010 | const gpa = zcu.gpa; | 983 | const gpa = zcu.gpa; |
| 1011 | const file = zcu.fileByIndex(file_index); | 984 | const file = zcu.fileByIndex(file_index); |
| 1012 | assert(zcu.fileRootDecl(file_index) == .none); | 985 | assert(zcu.fileRootType(file_index) == .none); |
| 1013 | log.debug("semaFile zcu={s} sub_file_path={s}", .{ | ||
| 1014 | file.mod.fully_qualified_name, file.sub_file_path, | ||
| 1015 | }); | ||
| 1016 | |||
| 1017 | // Because these three things each reference each other, `undefined` | ||
| 1018 | // placeholders are used before being set after the struct type gains an | ||
| 1019 | // InternPool index. | ||
| 1020 | const new_namespace_index = try pt.createNamespace(.{ | ||
| 1021 | .parent = .none, | ||
| 1022 | .decl_index = undefined, | ||
| 1023 | .file_scope = file_index, | ||
| 1024 | }); | ||
| 1025 | errdefer pt.destroyNamespace(new_namespace_index); | ||
| 1026 | |||
| 1027 | const new_decl_index = try pt.allocateNewDecl(new_namespace_index); | ||
| 1028 | const new_decl = zcu.declPtr(new_decl_index); | ||
| 1029 | errdefer @panic("TODO error handling"); | ||
| 1030 | |||
| 1031 | zcu.setFileRootDecl(file_index, new_decl_index.toOptional()); | ||
| 1032 | zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index; | ||
| 1033 | |||
| 1034 | new_decl.fqn = try file.internFullyQualifiedName(pt); | ||
| 1035 | new_decl.name = new_decl.fqn; | ||
| 1036 | new_decl.is_pub = true; | ||
| 1037 | new_decl.is_exported = false; | ||
| 1038 | new_decl.alignment = .none; | ||
| 1039 | new_decl.@"linksection" = .none; | ||
| 1040 | new_decl.analysis = .in_progress; | ||
| 1041 | 986 | ||
| 1042 | if (file.status != .success_zir) { | 987 | if (file.status != .success_zir) { |
| 1043 | new_decl.analysis = .file_failure; | 988 | return error.AnalysisFail; |
| 1044 | return; | ||
| 1045 | } | 989 | } |
| 1046 | assert(file.zir_loaded); | 990 | assert(file.zir_loaded); |
| 1047 | 991 | ||
| 1048 | const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index); | 992 | const new_namespace_index = try pt.createNamespace(.{ |
| 993 | .parent = .none, | ||
| 994 | .owner_type = undefined, // set in `createFileRootStruct` | ||
| 995 | .file_scope = file_index, | ||
| 996 | }); | ||
| 997 | const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index); | ||
| 1049 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); | 998 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); |
| 1050 | 999 | ||
| 1051 | switch (zcu.comp.cache_use) { | 1000 | switch (zcu.comp.cache_use) { |
| ... | @@ -1067,98 +1016,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1067,98 +1016,121 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1067 | 1016 | ||
| 1068 | whole.cache_manifest_mutex.lock(); | 1017 | whole.cache_manifest_mutex.lock(); |
| 1069 | defer whole.cache_manifest_mutex.unlock(); | 1018 | defer whole.cache_manifest_mutex.unlock(); |
| 1070 | try man.addFilePostContents(resolved_path, source.bytes, source.stat); | 1019 | man.addFilePostContents(resolved_path, source.bytes, source.stat) catch |err| switch (err) { |
| 1020 | error.OutOfMemory => |e| return e, | ||
| 1021 | else => { | ||
| 1022 | try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)}); | ||
| 1023 | return error.AnalysisFail; | ||
| 1024 | }, | ||
| 1025 | }; | ||
| 1071 | }, | 1026 | }, |
| 1072 | .incremental => {}, | 1027 | .incremental => {}, |
| 1073 | } | 1028 | } |
| 1074 | } | 1029 | } |
| 1075 | 1030 | ||
| 1076 | fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { | 1031 | const SemaCauResult = packed struct { |
| 1077 | const tracy = trace(@src()); | 1032 | /// Whether the value of a `decl_val` of the corresponding Nav changed. |
| 1078 | defer tracy.end(); | 1033 | invalidate_decl_val: bool, |
| 1034 | /// Whether the type of a `decl_ref` of the corresponding Nav changed. | ||
| 1035 | invalidate_decl_ref: bool, | ||
| 1036 | }; | ||
| 1079 | 1037 | ||
| 1038 | /// Performs semantic analysis on the given `Cau`, storing results to its owner `Nav` if needed. | ||
| 1039 | /// If analysis fails, returns `error.AnalysisFail`, storing an error in `zcu.failed_analysis` unless | ||
| 1040 | /// the error is transitive. | ||
| 1041 | /// On success, returns information about whether the `Nav` value changed. | ||
| 1042 | fn semaCau(pt: Zcu.PerThread, cau_index: InternPool.Cau.Index) !SemaCauResult { | ||
| 1080 | const zcu = pt.zcu; | 1043 | const zcu = pt.zcu; |
| 1081 | const decl = zcu.declPtr(decl_index); | 1044 | const gpa = zcu.gpa; |
| 1082 | const ip = &zcu.intern_pool; | 1045 | const ip = &zcu.intern_pool; |
| 1083 | 1046 | ||
| 1084 | if (decl.getFileScope(zcu).status != .success_zir) { | 1047 | const anal_unit = InternPool.AnalUnit.wrap(.{ .cau = cau_index }); |
| 1085 | return error.AnalysisFail; | ||
| 1086 | } | ||
| 1087 | 1048 | ||
| 1088 | assert(!zcu.declIsRoot(decl_index)); | 1049 | const cau = ip.getCau(cau_index); |
| 1050 | const inst_info = cau.zir_index.resolveFull(ip); | ||
| 1051 | const file = zcu.fileByIndex(inst_info.file); | ||
| 1052 | const zir = file.zir; | ||
| 1089 | 1053 | ||
| 1090 | if (decl.zir_decl_index == .none and decl.owns_tv) { | 1054 | if (file.status != .success_zir) { |
| 1091 | // We are re-analyzing an anonymous owner Decl (for a function or a namespace type). | 1055 | return error.AnalysisFail; |
| 1092 | return pt.semaAnonOwnerDecl(decl_index); | ||
| 1093 | } | 1056 | } |
| 1094 | 1057 | ||
| 1095 | log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)}); | 1058 | // We are about to re-analyze this `Cau`; drop its depenndencies. |
| 1096 | log.debug("decl name '{}'", .{decl.fqn.fmt(ip)}); | 1059 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); |
| 1097 | defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)}); | ||
| 1098 | 1060 | ||
| 1099 | const old_has_tv = decl.has_tv; | 1061 | const builtin_type_target_index: InternPool.Index = switch (cau.owner.unwrap()) { |
| 1100 | // The following values are ignored if `!old_has_tv` | 1062 | .none => ip_index: { |
| 1101 | const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined; | 1063 | // `comptime` decl -- we will re-analyze its body. |
| 1102 | const old_val = decl.val; | 1064 | // This declaration has no value so is definitely not a std.builtin type. |
| 1103 | const old_align = decl.alignment; | 1065 | break :ip_index .none; |
| 1104 | const old_linksection = decl.@"linksection"; | 1066 | }, |
| 1105 | const old_addrspace = decl.@"addrspace"; | 1067 | .type => |ty| { |
| 1106 | const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func| | 1068 | // This is an incremental update, and this type is being re-analyzed because it is outdated. |
| 1107 | prev_func.analysisUnordered(ip).state == .inline_only | 1069 | // The type must be recreated at a new `InternPool.Index`. |
| 1108 | else | 1070 | // Remove it from the InternPool and mark it outdated so that creation sites are re-analyzed. |
| 1109 | false; | 1071 | ip.remove(pt.tid, ty); |
| 1110 | 1072 | return .{ | |
| 1111 | const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip); | 1073 | .invalidate_decl_val = true, |
| 1074 | .invalidate_decl_ref = true, | ||
| 1075 | }; | ||
| 1076 | }, | ||
| 1077 | .nav => |nav| ip_index: { | ||
| 1078 | // Other decl -- we will re-analyze its value. | ||
| 1079 | // This might be a type in `builtin.zig` -- check. | ||
| 1080 | if (file.mod != zcu.std_mod) break :ip_index .none; | ||
| 1081 | // We're in the std module. | ||
| 1082 | const nav_name = ip.getNav(nav).name; | ||
| 1083 | const std_file_imported = try pt.importPkg(zcu.std_mod); | ||
| 1084 | const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index)); | ||
| 1085 | const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?); | ||
| 1086 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); | ||
| 1087 | const builtin_nav = ip.getNav(std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse break :ip_index .none); | ||
| 1088 | const builtin_namespace = switch (builtin_nav.status) { | ||
| 1089 | .unresolved => break :ip_index .none, | ||
| 1090 | .resolved => |r| Type.fromInterned(r.val).getNamespace(zcu).unwrap().?, | ||
| 1091 | }; | ||
| 1092 | if (cau.namespace != builtin_namespace) break :ip_index .none; | ||
| 1093 | // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index. | ||
| 1094 | for ([_][]const u8{ | ||
| 1095 | "AtomicOrder", | ||
| 1096 | "AtomicRmwOp", | ||
| 1097 | "CallingConvention", | ||
| 1098 | "AddressSpace", | ||
| 1099 | "FloatMode", | ||
| 1100 | "ReduceOp", | ||
| 1101 | "CallModifier", | ||
| 1102 | "PrefetchOptions", | ||
| 1103 | "ExportOptions", | ||
| 1104 | "ExternOptions", | ||
| 1105 | "Type", | ||
| 1106 | }, [_]InternPool.Index{ | ||
| 1107 | .atomic_order_type, | ||
| 1108 | .atomic_rmw_op_type, | ||
| 1109 | .calling_convention_type, | ||
| 1110 | .address_space_type, | ||
| 1111 | .float_mode_type, | ||
| 1112 | .reduce_op_type, | ||
| 1113 | .call_modifier_type, | ||
| 1114 | .prefetch_options_type, | ||
| 1115 | .export_options_type, | ||
| 1116 | .extern_options_type, | ||
| 1117 | .type_info_type, | ||
| 1118 | }) |type_name, type_ip| { | ||
| 1119 | if (nav_name.eqlSlice(type_name, ip)) break :ip_index type_ip; | ||
| 1120 | } | ||
| 1121 | break :ip_index .none; | ||
| 1122 | }, | ||
| 1123 | }; | ||
| 1112 | 1124 | ||
| 1113 | const gpa = zcu.gpa; | 1125 | const is_usingnamespace = switch (cau.owner.unwrap()) { |
| 1114 | const zir = decl.getFileScope(zcu).zir; | 1126 | .nav => |nav| ip.getNav(nav).is_usingnamespace, |
| 1115 | 1127 | .none, .type => false, | |
| 1116 | const builtin_type_target_index: InternPool.Index = ip_index: { | ||
| 1117 | const std_mod = zcu.std_mod; | ||
| 1118 | if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none; | ||
| 1119 | // We're in the std module. | ||
| 1120 | const std_file_imported = try pt.importPkg(std_mod); | ||
| 1121 | const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index); | ||
| 1122 | const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?); | ||
| 1123 | const std_namespace = std_decl.getInnerNamespace(zcu).?; | ||
| 1124 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); | ||
| 1125 | const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none); | ||
| 1126 | const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none; | ||
| 1127 | if (decl.src_namespace != builtin_namespace) break :ip_index .none; | ||
| 1128 | // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index. | ||
| 1129 | for ([_][]const u8{ | ||
| 1130 | "AtomicOrder", | ||
| 1131 | "AtomicRmwOp", | ||
| 1132 | "CallingConvention", | ||
| 1133 | "AddressSpace", | ||
| 1134 | "FloatMode", | ||
| 1135 | "ReduceOp", | ||
| 1136 | "CallModifier", | ||
| 1137 | "PrefetchOptions", | ||
| 1138 | "ExportOptions", | ||
| 1139 | "ExternOptions", | ||
| 1140 | "Type", | ||
| 1141 | }, [_]InternPool.Index{ | ||
| 1142 | .atomic_order_type, | ||
| 1143 | .atomic_rmw_op_type, | ||
| 1144 | .calling_convention_type, | ||
| 1145 | .address_space_type, | ||
| 1146 | .float_mode_type, | ||
| 1147 | .reduce_op_type, | ||
| 1148 | .call_modifier_type, | ||
| 1149 | .prefetch_options_type, | ||
| 1150 | .export_options_type, | ||
| 1151 | .extern_options_type, | ||
| 1152 | .type_info_type, | ||
| 1153 | }) |type_name, type_ip| { | ||
| 1154 | if (decl.name.eqlSlice(type_name, ip)) break :ip_index type_ip; | ||
| 1155 | } | ||
| 1156 | break :ip_index .none; | ||
| 1157 | }; | 1128 | }; |
| 1158 | 1129 | ||
| 1159 | zcu.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | 1130 | log.debug("semaCau '{d}'", .{@intFromEnum(cau_index)}); |
| 1160 | 1131 | ||
| 1161 | decl.analysis = .in_progress; | 1132 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); |
| 1133 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); | ||
| 1162 | 1134 | ||
| 1163 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); | 1135 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); |
| 1164 | defer analysis_arena.deinit(); | 1136 | defer analysis_arena.deinit(); |
| ... | @@ -1171,224 +1143,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { | ... | @@ -1171,224 +1143,216 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { |
| 1171 | .gpa = gpa, | 1143 | .gpa = gpa, |
| 1172 | .arena = analysis_arena.allocator(), | 1144 | .arena = analysis_arena.allocator(), |
| 1173 | .code = zir, | 1145 | .code = zir, |
| 1174 | .owner_decl = decl, | 1146 | .owner = anal_unit, |
| 1175 | .owner_decl_index = decl_index, | ||
| 1176 | .func_index = .none, | 1147 | .func_index = .none, |
| 1177 | .func_is_naked = false, | 1148 | .func_is_naked = false, |
| 1178 | .fn_ret_ty = Type.void, | 1149 | .fn_ret_ty = Type.void, |
| 1179 | .fn_ret_ty_ies = null, | 1150 | .fn_ret_ty_ies = null, |
| 1180 | .owner_func_index = .none, | ||
| 1181 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 1151 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 1182 | .builtin_type_target_index = builtin_type_target_index, | 1152 | .builtin_type_target_index = builtin_type_target_index, |
| 1183 | }; | 1153 | }; |
| 1184 | defer sema.deinit(); | 1154 | defer sema.deinit(); |
| 1185 | 1155 | ||
| 1186 | // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source. | 1156 | // Every `Cau` has a dependency on the source of its own ZIR instruction. |
| 1187 | try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{ | 1157 | try sema.declareDependency(.{ .src_hash = cau.zir_index }); |
| 1188 | .file = decl.getFileScopeIndex(zcu), | ||
| 1189 | .inst = decl_inst, | ||
| 1190 | }) }); | ||
| 1191 | 1158 | ||
| 1192 | var block_scope: Sema.Block = .{ | 1159 | var block: Sema.Block = .{ |
| 1193 | .parent = null, | 1160 | .parent = null, |
| 1194 | .sema = &sema, | 1161 | .sema = &sema, |
| 1195 | .namespace = decl.src_namespace, | 1162 | .namespace = cau.namespace, |
| 1196 | .instructions = .{}, | 1163 | .instructions = .{}, |
| 1197 | .inlining = null, | 1164 | .inlining = null, |
| 1198 | .is_comptime = true, | 1165 | .is_comptime = true, |
| 1199 | .src_base_inst = decl.zir_decl_index.unwrap().?, | 1166 | .src_base_inst = cau.zir_index, |
| 1200 | .type_name_ctx = decl.name, | 1167 | .type_name_ctx = switch (cau.owner.unwrap()) { |
| 1168 | .nav => |nav| ip.getNav(nav).fqn, | ||
| 1169 | .type => |ty| Type.fromInterned(ty).containerTypeName(ip), | ||
| 1170 | .none => try ip.getOrPutStringFmt(gpa, pt.tid, "{}.comptime", .{ | ||
| 1171 | Type.fromInterned(zcu.namespacePtr(cau.namespace).owner_type).containerTypeName(ip).fmt(ip), | ||
| 1172 | }, .no_embedded_nulls), | ||
| 1173 | }, | ||
| 1174 | }; | ||
| 1175 | defer block.instructions.deinit(gpa); | ||
| 1176 | |||
| 1177 | const zir_decl: Zir.Inst.Declaration, const decl_bodies: Zir.Inst.Declaration.Bodies = decl: { | ||
| 1178 | const decl, const extra_end = zir.getDeclaration(inst_info.inst); | ||
| 1179 | break :decl .{ decl, decl.getBodies(extra_end, zir) }; | ||
| 1180 | }; | ||
| 1181 | |||
| 1182 | // We have to fetch this state before resolving the body because of the `nav_already_populated` | ||
| 1183 | // case below. We might change the language in future so that align/linksection/etc for functions | ||
| 1184 | // work in a way more in line with other declarations, in which case that logic will go away. | ||
| 1185 | const old_nav_info = switch (cau.owner.unwrap()) { | ||
| 1186 | .none, .type => undefined, // we'll never use `old_nav_info` | ||
| 1187 | .nav => |nav| ip.getNav(nav), | ||
| 1201 | }; | 1188 | }; |
| 1202 | defer block_scope.instructions.deinit(gpa); | ||
| 1203 | 1189 | ||
| 1204 | const decl_bodies = decl.zirBodies(zcu); | 1190 | const result_ref = try sema.resolveInlineBody(&block, decl_bodies.value_body, inst_info.inst); |
| 1205 | 1191 | ||
| 1206 | const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst); | 1192 | const nav_index = switch (cau.owner.unwrap()) { |
| 1207 | // We'll do some other bits with the Sema. Clear the type target index just | 1193 | .none => { |
| 1208 | // in case they analyze any type. | 1194 | // This is a `comptime` decl, so we are done -- the side effects are all we care about. |
| 1195 | // Just make sure to `flushExports`. | ||
| 1196 | try sema.flushExports(); | ||
| 1197 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); | ||
| 1198 | return .{ | ||
| 1199 | .invalidate_decl_val = false, | ||
| 1200 | .invalidate_decl_ref = false, | ||
| 1201 | }; | ||
| 1202 | }, | ||
| 1203 | .nav => |nav| nav, // We will resolve this `Nav` below. | ||
| 1204 | .type => unreachable, // Handled at top of function. | ||
| 1205 | }; | ||
| 1206 | |||
| 1207 | // We'll do more work with the Sema. Clear the target type index just in case we analyze any type. | ||
| 1209 | sema.builtin_type_target_index = .none; | 1208 | sema.builtin_type_target_index = .none; |
| 1210 | const align_src = block_scope.src(.{ .node_offset_var_decl_align = 0 }); | 1209 | |
| 1211 | const section_src = block_scope.src(.{ .node_offset_var_decl_section = 0 }); | 1210 | const align_src = block.src(.{ .node_offset_var_decl_align = 0 }); |
| 1212 | const address_space_src = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 }); | 1211 | const section_src = block.src(.{ .node_offset_var_decl_section = 0 }); |
| 1213 | const ty_src = block_scope.src(.{ .node_offset_var_decl_ty = 0 }); | 1212 | const addrspace_src = block.src(.{ .node_offset_var_decl_addrspace = 0 }); |
| 1214 | const init_src = block_scope.src(.{ .node_offset_var_decl_init = 0 }); | 1213 | const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 }); |
| 1215 | const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref); | 1214 | const init_src = block.src(.{ .node_offset_var_decl_init = 0 }); |
| 1215 | |||
| 1216 | const decl_val = try sema.resolveFinalDeclValue(&block, init_src, result_ref); | ||
| 1216 | const decl_ty = decl_val.typeOf(zcu); | 1217 | const decl_ty = decl_val.typeOf(zcu); |
| 1217 | 1218 | ||
| 1218 | // Note this resolves the type of the Decl, not the value; if this Decl | 1219 | switch (decl_val.toIntern()) { |
| 1219 | // is a struct, for example, this resolves `type` (which needs no resolution), | 1220 | .generic_poison => unreachable, // assertion failure |
| 1220 | // not the struct itself. | 1221 | .unreachable_value => unreachable, // assertion failure |
| 1222 | else => {}, | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | // This resolves the type of the resolved value, not that value itself. If `decl_val` is a struct type, | ||
| 1226 | // this resolves the type `type` (which needs no resolution), not the struct itself. | ||
| 1221 | try decl_ty.resolveLayout(pt); | 1227 | try decl_ty.resolveLayout(pt); |
| 1222 | 1228 | ||
| 1223 | if (decl.kind == .@"usingnamespace") { | 1229 | // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`. |
| 1224 | if (!decl_ty.eql(Type.type, zcu)) { | 1230 | if (is_usingnamespace) { |
| 1225 | return sema.fail(&block_scope, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)}); | 1231 | if (decl_ty.toIntern() != .type_type) { |
| 1232 | return sema.fail(&block, ty_src, "expected type, found {}", .{decl_ty.fmt(pt)}); | ||
| 1226 | } | 1233 | } |
| 1227 | const ty = decl_val.toType(); | 1234 | if (decl_val.toType().getNamespace(zcu) == .none) { |
| 1228 | if (ty.getNamespace(zcu) == null) { | 1235 | return sema.fail(&block, ty_src, "type {} has no namespace", .{decl_val.toType().fmt(pt)}); |
| 1229 | return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(pt)}); | ||
| 1230 | } | 1236 | } |
| 1231 | 1237 | ip.resolveNavValue(nav_index, .{ | |
| 1232 | decl.val = ty.toValue(); | 1238 | .val = decl_val.toIntern(), |
| 1233 | decl.alignment = .none; | 1239 | .alignment = .none, |
| 1234 | decl.@"linksection" = .none; | 1240 | .@"linksection" = .none, |
| 1235 | decl.has_tv = true; | 1241 | .@"addrspace" = .generic, |
| 1236 | decl.owns_tv = false; | 1242 | }); |
| 1237 | decl.analysis = .complete; | 1243 | // TODO: usingnamespace cannot participate in incremental compilation |
| 1238 | 1244 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); | |
| 1239 | // TODO: usingnamespace cannot currently participate in incremental compilation | ||
| 1240 | return .{ | 1245 | return .{ |
| 1241 | .invalidate_decl_val = true, | 1246 | .invalidate_decl_val = true, |
| 1242 | .invalidate_decl_ref = true, | 1247 | .invalidate_decl_ref = true, |
| 1243 | }; | 1248 | }; |
| 1244 | } | 1249 | } |
| 1245 | 1250 | ||
| 1246 | var queue_linker_work = true; | 1251 | const nav_already_populated, const queue_linker_work = switch (ip.indexToKey(decl_val.toIntern())) { |
| 1247 | var is_func = false; | 1252 | .func => |f| .{ f.owner_nav == nav_index, false }, |
| 1248 | var is_inline = false; | 1253 | .variable => |v| .{ false, v.owner_nav == nav_index }, |
| 1249 | switch (decl_val.toIntern()) { | 1254 | .@"extern" => .{ false, false }, |
| 1250 | .generic_poison => unreachable, | 1255 | else => .{ false, true }, |
| 1251 | .unreachable_value => unreachable, | 1256 | }; |
| 1252 | else => switch (ip.indexToKey(decl_val.toIntern())) { | ||
| 1253 | .variable => |variable| { | ||
| 1254 | decl.owns_tv = variable.decl == decl_index; | ||
| 1255 | queue_linker_work = decl.owns_tv; | ||
| 1256 | }, | ||
| 1257 | |||
| 1258 | .extern_func => |extern_func| { | ||
| 1259 | decl.owns_tv = extern_func.decl == decl_index; | ||
| 1260 | queue_linker_work = decl.owns_tv; | ||
| 1261 | is_func = decl.owns_tv; | ||
| 1262 | }, | ||
| 1263 | |||
| 1264 | .func => |func| { | ||
| 1265 | decl.owns_tv = func.owner_decl == decl_index; | ||
| 1266 | queue_linker_work = false; | ||
| 1267 | is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline; | ||
| 1268 | is_func = decl.owns_tv; | ||
| 1269 | }, | ||
| 1270 | |||
| 1271 | else => {}, | ||
| 1272 | }, | ||
| 1273 | } | ||
| 1274 | 1257 | ||
| 1275 | decl.val = decl_val; | 1258 | if (nav_already_populated) { |
| 1276 | // Function linksection, align, and addrspace were already set by Sema | 1259 | // This is a function declaration. |
| 1277 | if (!is_func) { | 1260 | // Logic in `Sema.funcCommon` has already populated the `Nav` for us. |
| 1278 | decl.alignment = blk: { | 1261 | assert(ip.getNav(nav_index).status.resolved.val == decl_val.toIntern()); |
| 1279 | const align_body = decl_bodies.align_body orelse break :blk .none; | 1262 | } else { |
| 1280 | const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst); | 1263 | // Keep in sync with logic in `Sema.zirVarExtended`. |
| 1281 | break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref); | 1264 | const alignment: InternPool.Alignment = a: { |
| 1265 | const align_body = decl_bodies.align_body orelse break :a .none; | ||
| 1266 | const align_ref = try sema.resolveInlineBody(&block, align_body, inst_info.inst); | ||
| 1267 | break :a try sema.analyzeAsAlign(&block, align_src, align_ref); | ||
| 1282 | }; | 1268 | }; |
| 1283 | decl.@"linksection" = blk: { | 1269 | |
| 1284 | const linksection_body = decl_bodies.linksection_body orelse break :blk .none; | 1270 | const @"linksection": InternPool.OptionalNullTerminatedString = ls: { |
| 1285 | const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst); | 1271 | const linksection_body = decl_bodies.linksection_body orelse break :ls .none; |
| 1286 | const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{ | 1272 | const linksection_ref = try sema.resolveInlineBody(&block, linksection_body, inst_info.inst); |
| 1273 | const bytes = try sema.toConstString(&block, section_src, linksection_ref, .{ | ||
| 1287 | .needed_comptime_reason = "linksection must be comptime-known", | 1274 | .needed_comptime_reason = "linksection must be comptime-known", |
| 1288 | }); | 1275 | }); |
| 1289 | if (std.mem.indexOfScalar(u8, bytes, 0) != null) { | 1276 | if (std.mem.indexOfScalar(u8, bytes, 0) != null) { |
| 1290 | return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{}); | 1277 | return sema.fail(&block, section_src, "linksection cannot contain null bytes", .{}); |
| 1291 | } else if (bytes.len == 0) { | 1278 | } else if (bytes.len == 0) { |
| 1292 | return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{}); | 1279 | return sema.fail(&block, section_src, "linksection cannot be empty", .{}); |
| 1293 | } | 1280 | } |
| 1294 | break :blk try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls); | 1281 | break :ls try ip.getOrPutStringOpt(gpa, pt.tid, bytes, .no_embedded_nulls); |
| 1295 | }; | 1282 | }; |
| 1296 | decl.@"addrspace" = blk: { | 1283 | |
| 1284 | const @"addrspace": std.builtin.AddressSpace = as: { | ||
| 1297 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { | 1285 | const addrspace_ctx: Sema.AddressSpaceContext = switch (ip.indexToKey(decl_val.toIntern())) { |
| 1286 | .func => .function, | ||
| 1298 | .variable => .variable, | 1287 | .variable => .variable, |
| 1299 | .extern_func, .func => .function, | 1288 | .@"extern" => |e| if (ip.indexToKey(e.ty) == .func_type) |
| 1289 | .function | ||
| 1290 | else | ||
| 1291 | .variable, | ||
| 1300 | else => .constant, | 1292 | else => .constant, |
| 1301 | }; | 1293 | }; |
| 1302 | |||
| 1303 | const target = zcu.getTarget(); | 1294 | const target = zcu.getTarget(); |
| 1304 | 1295 | const addrspace_body = decl_bodies.addrspace_body orelse break :as switch (addrspace_ctx) { | |
| 1305 | const addrspace_body = decl_bodies.addrspace_body orelse break :blk switch (addrspace_ctx) { | ||
| 1306 | .function => target_util.defaultAddressSpace(target, .function), | 1296 | .function => target_util.defaultAddressSpace(target, .function), |
| 1307 | .variable => target_util.defaultAddressSpace(target, .global_mutable), | 1297 | .variable => target_util.defaultAddressSpace(target, .global_mutable), |
| 1308 | .constant => target_util.defaultAddressSpace(target, .global_constant), | 1298 | .constant => target_util.defaultAddressSpace(target, .global_constant), |
| 1309 | else => unreachable, | 1299 | else => unreachable, |
| 1310 | }; | 1300 | }; |
| 1311 | const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst); | 1301 | const addrspace_ref = try sema.resolveInlineBody(&block, addrspace_body, inst_info.inst); |
| 1312 | break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx); | 1302 | break :as try sema.analyzeAsAddressSpace(&block, addrspace_src, addrspace_ref, addrspace_ctx); |
| 1313 | }; | 1303 | }; |
| 1314 | } | ||
| 1315 | decl.has_tv = true; | ||
| 1316 | decl.analysis = .complete; | ||
| 1317 | |||
| 1318 | const result: Zcu.SemaDeclResult = if (old_has_tv) .{ | ||
| 1319 | .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or | ||
| 1320 | !decl.val.eql(old_val, decl_ty, zcu) or | ||
| 1321 | is_inline != old_is_inline, | ||
| 1322 | .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or | ||
| 1323 | decl.alignment != old_align or | ||
| 1324 | decl.@"linksection" != old_linksection or | ||
| 1325 | decl.@"addrspace" != old_addrspace or | ||
| 1326 | is_inline != old_is_inline, | ||
| 1327 | } else .{ | ||
| 1328 | .invalidate_decl_val = true, | ||
| 1329 | .invalidate_decl_ref = true, | ||
| 1330 | }; | ||
| 1331 | |||
| 1332 | const has_runtime_bits = queue_linker_work and (is_func or try sema.typeHasRuntimeBits(decl_ty)); | ||
| 1333 | if (has_runtime_bits) { | ||
| 1334 | // Needed for codegen_decl which will call updateDecl and then the | ||
| 1335 | // codegen backend wants full access to the Decl Type. | ||
| 1336 | try decl_ty.resolveFully(pt); | ||
| 1337 | |||
| 1338 | try zcu.comp.queueJob(.{ .codegen_decl = decl_index }); | ||
| 1339 | 1304 | ||
| 1340 | if (result.invalidate_decl_ref and zcu.emit_h != null) { | 1305 | ip.resolveNavValue(nav_index, .{ |
| 1341 | try zcu.comp.queueJob(.{ .emit_h_decl = decl_index }); | 1306 | .val = decl_val.toIntern(), |
| 1342 | } | 1307 | .alignment = alignment, |
| 1308 | .@"linksection" = @"linksection", | ||
| 1309 | .@"addrspace" = @"addrspace", | ||
| 1310 | }); | ||
| 1343 | } | 1311 | } |
| 1344 | 1312 | ||
| 1345 | if (decl.is_exported) { | 1313 | // Mark the `Cau` as completed before evaluating the export! |
| 1346 | const export_src = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) }); | 1314 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); |
| 1347 | if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{}); | 1315 | |
| 1348 | // The scope needs to have the decl in it. | 1316 | if (zir_decl.flags.is_export) { |
| 1349 | try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index); | 1317 | const export_src = block.src(.{ .token_offset = @intFromBool(zir_decl.flags.is_pub) }); |
| 1318 | const name_slice = zir.nullTerminatedString(zir_decl.name.toString(zir).?); | ||
| 1319 | const name_ip = try ip.getOrPutString(gpa, pt.tid, name_slice, .no_embedded_nulls); | ||
| 1320 | try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_index); | ||
| 1350 | } | 1321 | } |
| 1351 | 1322 | ||
| 1352 | try sema.flushExports(); | 1323 | try sema.flushExports(); |
| 1353 | 1324 | ||
| 1354 | return result; | 1325 | queue_codegen: { |
| 1355 | } | 1326 | 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 | 1327 | ||
| 1361 | assert(decl.has_tv); | 1328 | // Needed for codegen_nav which will call updateDecl and then the |
| 1362 | assert(decl.owns_tv); | 1329 | // codegen backend wants full access to the Decl Type. |
| 1330 | // We also need this for the `isFnOrHasRuntimeBits` check below. | ||
| 1331 | // TODO: we could make the language more lenient by deferring this work | ||
| 1332 | // to the `codegen_nav` job. | ||
| 1333 | try decl_ty.resolveFully(pt); | ||
| 1363 | 1334 | ||
| 1364 | log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)}); | 1335 | if (!decl_ty.isFnOrHasRuntimeBits(pt)) break :queue_codegen; |
| 1365 | 1336 | ||
| 1366 | switch (decl.typeOf(zcu).zigTypeTag(zcu)) { | 1337 | try zcu.comp.queueJob(.{ .codegen_nav = nav_index }); |
| 1367 | .Fn => @panic("TODO: update fn instance"), | ||
| 1368 | .Type => {}, | ||
| 1369 | else => unreachable, | ||
| 1370 | } | 1338 | } |
| 1371 | 1339 | ||
| 1372 | // We are the owner Decl of a type, and we were marked as outdated. That means the *structure* | 1340 | switch (old_nav_info.status) { |
| 1373 | // of this type changed; not just its namespace. Therefore, we need a new InternPool index. | 1341 | .unresolved => return .{ |
| 1374 | // | 1342 | .invalidate_decl_val = true, |
| 1375 | // However, as soon as we make that, the context that created us will require re-analysis anyway | 1343 | .invalidate_decl_ref = true, |
| 1376 | // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction | 1344 | }, |
| 1377 | // will be analyzed again. Since Sema already needs to be able to reconstruct types like this, | 1345 | .resolved => |old| { |
| 1378 | // why should we bother implementing it here too when the Sema logic will be hit right after? | 1346 | const new = ip.getNav(nav_index).status.resolved; |
| 1379 | // | 1347 | return .{ |
| 1380 | // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely | 1348 | .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 | 1349 | .invalidate_decl_ref = ip.typeOf(new.val) != ip.typeOf(old.val) or |
| 1382 | // with a new Decl. | 1350 | new.alignment != old.alignment or |
| 1383 | // | 1351 | new.@"linksection" != old.@"linksection" or |
| 1384 | // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime. | 1352 | new.@"addrspace" != old.@"addrspace", |
| 1385 | zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | 1353 | }; |
| 1386 | zcu.intern_pool.remove(pt.tid, decl.val.toIntern()); | 1354 | }, |
| 1387 | decl.analysis = .dependency_failure; | 1355 | } |
| 1388 | return .{ | ||
| 1389 | .invalidate_decl_val = true, | ||
| 1390 | .invalidate_decl_ref = true, | ||
| 1391 | }; | ||
| 1392 | } | 1356 | } |
| 1393 | 1357 | ||
| 1394 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | 1358 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { |
| ... | @@ -1426,7 +1390,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | ... | @@ -1426,7 +1390,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { |
| 1426 | const file_index = try ip.createFile(gpa, pt.tid, .{ | 1390 | const file_index = try ip.createFile(gpa, pt.tid, .{ |
| 1427 | .bin_digest = path_digest, | 1391 | .bin_digest = path_digest, |
| 1428 | .file = builtin_file, | 1392 | .file = builtin_file, |
| 1429 | .root_decl = .none, | 1393 | .root_type = .none, |
| 1430 | }); | 1394 | }); |
| 1431 | keep_resolved_path = true; // It's now owned by import_table. | 1395 | keep_resolved_path = true; // It's now owned by import_table. |
| 1432 | gop.value_ptr.* = file_index; | 1396 | gop.value_ptr.* = file_index; |
| ... | @@ -1453,7 +1417,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { | ... | @@ -1453,7 +1417,7 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult { |
| 1453 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ | 1417 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ |
| 1454 | .bin_digest = path_digest, | 1418 | .bin_digest = path_digest, |
| 1455 | .file = new_file, | 1419 | .file = new_file, |
| 1456 | .root_decl = .none, | 1420 | .root_type = .none, |
| 1457 | }); | 1421 | }); |
| 1458 | keep_resolved_path = true; // It's now owned by import_table. | 1422 | keep_resolved_path = true; // It's now owned by import_table. |
| 1459 | gop.value_ptr.* = new_file_index; | 1423 | gop.value_ptr.* = new_file_index; |
| ... | @@ -1563,7 +1527,7 @@ pub fn importFile( | ... | @@ -1563,7 +1527,7 @@ pub fn importFile( |
| 1563 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ | 1527 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ |
| 1564 | .bin_digest = path_digest, | 1528 | .bin_digest = path_digest, |
| 1565 | .file = new_file, | 1529 | .file = new_file, |
| 1566 | .root_decl = .none, | 1530 | .root_type = .none, |
| 1567 | }); | 1531 | }); |
| 1568 | keep_resolved_path = true; // It's now owned by import_table. | 1532 | keep_resolved_path = true; // It's now owned by import_table. |
| 1569 | gop.value_ptr.* = new_file_index; | 1533 | gop.value_ptr.* = new_file_index; |
| ... | @@ -1726,7 +1690,7 @@ fn newEmbedFile( | ... | @@ -1726,7 +1690,7 @@ fn newEmbedFile( |
| 1726 | })).toIntern(); | 1690 | })).toIntern(); |
| 1727 | const ptr_val = try pt.intern(.{ .ptr = .{ | 1691 | const ptr_val = try pt.intern(.{ .ptr = .{ |
| 1728 | .ty = ptr_ty, | 1692 | .ty = ptr_ty, |
| 1729 | .base_addr = .{ .anon_decl = .{ | 1693 | .base_addr = .{ .uav = .{ |
| 1730 | .val = array_val, | 1694 | .val = array_val, |
| 1731 | .orig_ty = ptr_ty, | 1695 | .orig_ty = ptr_ty, |
| 1732 | } }, | 1696 | } }, |
| ... | @@ -1748,39 +1712,70 @@ pub fn scanNamespace( | ... | @@ -1748,39 +1712,70 @@ pub fn scanNamespace( |
| 1748 | pt: Zcu.PerThread, | 1712 | pt: Zcu.PerThread, |
| 1749 | namespace_index: Zcu.Namespace.Index, | 1713 | namespace_index: Zcu.Namespace.Index, |
| 1750 | decls: []const Zir.Inst.Index, | 1714 | decls: []const Zir.Inst.Index, |
| 1751 | parent_decl: *Zcu.Decl, | ||
| 1752 | ) Allocator.Error!void { | 1715 | ) Allocator.Error!void { |
| 1753 | const tracy = trace(@src()); | 1716 | const tracy = trace(@src()); |
| 1754 | defer tracy.end(); | 1717 | defer tracy.end(); |
| 1755 | 1718 | ||
| 1756 | const zcu = pt.zcu; | 1719 | const zcu = pt.zcu; |
| 1720 | const ip = &zcu.intern_pool; | ||
| 1757 | const gpa = zcu.gpa; | 1721 | const gpa = zcu.gpa; |
| 1758 | const namespace = zcu.namespacePtr(namespace_index); | 1722 | const namespace = zcu.namespacePtr(namespace_index); |
| 1759 | 1723 | ||
| 1760 | // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather | 1724 | // For incremental updates, `scanDecl` wants to look up existing decls by their ZIR index rather |
| 1761 | // than their name. We'll build an efficient mapping now, then discard the current `decls`. | 1725 | // than their name. We'll build an efficient mapping now, then discard the current `decls`. |
| 1762 | var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index) = .{}; | 1726 | // We map to the `Cau`, since not every declaration has a `Nav`. |
| 1727 | var existing_by_inst: std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index) = .{}; | ||
| 1763 | defer existing_by_inst.deinit(gpa); | 1728 | defer existing_by_inst.deinit(gpa); |
| 1764 | 1729 | ||
| 1765 | try existing_by_inst.ensureTotalCapacity(gpa, @intCast(namespace.decls.count())); | 1730 | try existing_by_inst.ensureTotalCapacity(gpa, @intCast( |
| 1766 | 1731 | namespace.pub_decls.count() + namespace.priv_decls.count() + | |
| 1767 | for (namespace.decls.keys()) |decl_index| { | 1732 | namespace.pub_usingnamespace.items.len + namespace.priv_usingnamespace.items.len + |
| 1768 | const decl = zcu.declPtr(decl_index); | 1733 | namespace.other_decls.items.len, |
| 1769 | existing_by_inst.putAssumeCapacityNoClobber(decl.zir_decl_index.unwrap().?, decl_index); | 1734 | )); |
| 1735 | |||
| 1736 | for (namespace.pub_decls.keys()) |nav| { | ||
| 1737 | const cau_index = ip.getNav(nav).analysis_owner.unwrap().?; | ||
| 1738 | const zir_index = ip.getCau(cau_index).zir_index; | ||
| 1739 | existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index); | ||
| 1740 | } | ||
| 1741 | for (namespace.priv_decls.keys()) |nav| { | ||
| 1742 | const cau_index = ip.getNav(nav).analysis_owner.unwrap().?; | ||
| 1743 | const zir_index = ip.getCau(cau_index).zir_index; | ||
| 1744 | existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index); | ||
| 1745 | } | ||
| 1746 | for (namespace.pub_usingnamespace.items) |nav| { | ||
| 1747 | const cau_index = ip.getNav(nav).analysis_owner.unwrap().?; | ||
| 1748 | const zir_index = ip.getCau(cau_index).zir_index; | ||
| 1749 | existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index); | ||
| 1750 | } | ||
| 1751 | for (namespace.priv_usingnamespace.items) |nav| { | ||
| 1752 | const cau_index = ip.getNav(nav).analysis_owner.unwrap().?; | ||
| 1753 | const zir_index = ip.getCau(cau_index).zir_index; | ||
| 1754 | existing_by_inst.putAssumeCapacityNoClobber(zir_index, cau_index); | ||
| 1755 | } | ||
| 1756 | for (namespace.other_decls.items) |cau_index| { | ||
| 1757 | const cau = ip.getCau(cau_index); | ||
| 1758 | existing_by_inst.putAssumeCapacityNoClobber(cau.zir_index, cau_index); | ||
| 1759 | // If this is a test, it'll be re-added to `test_functions` later on | ||
| 1760 | // if still alive. Remove it for now. | ||
| 1761 | switch (cau.owner.unwrap()) { | ||
| 1762 | .none, .type => {}, | ||
| 1763 | .nav => |nav| _ = zcu.test_functions.swapRemove(nav), | ||
| 1764 | } | ||
| 1770 | } | 1765 | } |
| 1771 | 1766 | ||
| 1772 | var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{}; | 1767 | var seen_decls: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{}; |
| 1773 | defer seen_decls.deinit(gpa); | 1768 | defer seen_decls.deinit(gpa); |
| 1774 | 1769 | ||
| 1775 | namespace.decls.clearRetainingCapacity(); | 1770 | namespace.pub_decls.clearRetainingCapacity(); |
| 1776 | try namespace.decls.ensureTotalCapacity(gpa, decls.len); | 1771 | namespace.priv_decls.clearRetainingCapacity(); |
| 1777 | 1772 | namespace.pub_usingnamespace.clearRetainingCapacity(); | |
| 1778 | namespace.usingnamespace_set.clearRetainingCapacity(); | 1773 | namespace.priv_usingnamespace.clearRetainingCapacity(); |
| 1774 | namespace.other_decls.clearRetainingCapacity(); | ||
| 1779 | 1775 | ||
| 1780 | var scan_decl_iter: ScanDeclIter = .{ | 1776 | var scan_decl_iter: ScanDeclIter = .{ |
| 1781 | .pt = pt, | 1777 | .pt = pt, |
| 1782 | .namespace_index = namespace_index, | 1778 | .namespace_index = namespace_index, |
| 1783 | .parent_decl = parent_decl, | ||
| 1784 | .seen_decls = &seen_decls, | 1779 | .seen_decls = &seen_decls, |
| 1785 | .existing_by_inst = &existing_by_inst, | 1780 | .existing_by_inst = &existing_by_inst, |
| 1786 | .pass = .named, | 1781 | .pass = .named, |
| ... | @@ -1792,34 +1787,17 @@ pub fn scanNamespace( | ... | @@ -1792,34 +1787,17 @@ pub fn scanNamespace( |
| 1792 | for (decls) |decl_inst| { | 1787 | for (decls) |decl_inst| { |
| 1793 | try scan_decl_iter.scanDecl(decl_inst); | 1788 | try scan_decl_iter.scanDecl(decl_inst); |
| 1794 | } | 1789 | } |
| 1795 | |||
| 1796 | if (seen_decls.count() != namespace.decls.count()) { | ||
| 1797 | // Do a pass over the namespace contents and remove any decls from the last update | ||
| 1798 | // which were removed in this one. | ||
| 1799 | var i: usize = 0; | ||
| 1800 | while (i < namespace.decls.count()) { | ||
| 1801 | const decl_index = namespace.decls.keys()[i]; | ||
| 1802 | const decl = zcu.declPtr(decl_index); | ||
| 1803 | if (!seen_decls.contains(decl.name)) { | ||
| 1804 | // We must preserve namespace ordering for @typeInfo. | ||
| 1805 | namespace.decls.orderedRemoveAt(i); | ||
| 1806 | i -= 1; | ||
| 1807 | } | ||
| 1808 | } | ||
| 1809 | } | ||
| 1810 | } | 1790 | } |
| 1811 | 1791 | ||
| 1812 | const ScanDeclIter = struct { | 1792 | const ScanDeclIter = struct { |
| 1813 | pt: Zcu.PerThread, | 1793 | pt: Zcu.PerThread, |
| 1814 | namespace_index: Zcu.Namespace.Index, | 1794 | namespace_index: Zcu.Namespace.Index, |
| 1815 | parent_decl: *Zcu.Decl, | ||
| 1816 | seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void), | 1795 | seen_decls: *std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void), |
| 1817 | existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, Zcu.Decl.Index), | 1796 | existing_by_inst: *const std.AutoHashMapUnmanaged(InternPool.TrackedInst.Index, InternPool.Cau.Index), |
| 1818 | /// Decl scanning is run in two passes, so that we can detect when a generated | 1797 | /// Decl scanning is run in two passes, so that we can detect when a generated |
| 1819 | /// name would clash with an explicit name and use a different one. | 1798 | /// name would clash with an explicit name and use a different one. |
| 1820 | pass: enum { named, unnamed }, | 1799 | pass: enum { named, unnamed }, |
| 1821 | usingnamespace_index: usize = 0, | 1800 | usingnamespace_index: usize = 0, |
| 1822 | comptime_index: usize = 0, | ||
| 1823 | unnamed_test_index: usize = 0, | 1801 | unnamed_test_index: usize = 0, |
| 1824 | 1802 | ||
| 1825 | fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString { | 1803 | fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString { |
| ... | @@ -1843,37 +1821,35 @@ const ScanDeclIter = struct { | ... | @@ -1843,37 +1821,35 @@ const ScanDeclIter = struct { |
| 1843 | 1821 | ||
| 1844 | const pt = iter.pt; | 1822 | const pt = iter.pt; |
| 1845 | const zcu = pt.zcu; | 1823 | const zcu = pt.zcu; |
| 1824 | const comp = zcu.comp; | ||
| 1846 | const namespace_index = iter.namespace_index; | 1825 | const namespace_index = iter.namespace_index; |
| 1847 | const namespace = zcu.namespacePtr(namespace_index); | 1826 | const namespace = zcu.namespacePtr(namespace_index); |
| 1848 | const gpa = zcu.gpa; | 1827 | const gpa = zcu.gpa; |
| 1849 | const zir = namespace.fileScope(zcu).zir; | 1828 | const file = namespace.fileScope(zcu); |
| 1829 | const zir = file.zir; | ||
| 1850 | const ip = &zcu.intern_pool; | 1830 | const ip = &zcu.intern_pool; |
| 1851 | 1831 | ||
| 1852 | const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration; | 1832 | const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration; |
| 1853 | const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index); | 1833 | const extra = zir.extraData(Zir.Inst.Declaration, inst_data.payload_index); |
| 1854 | const declaration = extra.data; | 1834 | const declaration = extra.data; |
| 1855 | 1835 | ||
| 1856 | // Every Decl needs a name. | 1836 | const Kind = enum { @"comptime", @"usingnamespace", @"test", named }; |
| 1857 | const decl_name: InternPool.NullTerminatedString, const kind: Zcu.Decl.Kind, const is_named_test: bool = switch (declaration.name) { | 1837 | |
| 1838 | const maybe_name: InternPool.OptionalNullTerminatedString, const kind: Kind, const is_named_test: bool = switch (declaration.name) { | ||
| 1858 | .@"comptime" => info: { | 1839 | .@"comptime" => info: { |
| 1859 | if (iter.pass != .unnamed) return; | 1840 | if (iter.pass != .unnamed) return; |
| 1860 | const i = iter.comptime_index; | ||
| 1861 | iter.comptime_index += 1; | ||
| 1862 | break :info .{ | 1841 | break :info .{ |
| 1863 | try iter.avoidNameConflict("comptime_{d}", .{i}), | 1842 | .none, |
| 1864 | .@"comptime", | 1843 | .@"comptime", |
| 1865 | false, | 1844 | false, |
| 1866 | }; | 1845 | }; |
| 1867 | }, | 1846 | }, |
| 1868 | .@"usingnamespace" => info: { | 1847 | .@"usingnamespace" => info: { |
| 1869 | // TODO: this isn't right! These should be considered unnamed. Name conflicts can happen here. | 1848 | if (iter.pass != .unnamed) return; |
| 1870 | // The problem is, we need to preserve the decl ordering for `@typeInfo`. | ||
| 1871 | // I'm not bothering to fix this now, since some upcoming changes will change this code significantly anyway. | ||
| 1872 | if (iter.pass != .named) return; | ||
| 1873 | const i = iter.usingnamespace_index; | 1849 | const i = iter.usingnamespace_index; |
| 1874 | iter.usingnamespace_index += 1; | 1850 | iter.usingnamespace_index += 1; |
| 1875 | break :info .{ | 1851 | break :info .{ |
| 1876 | try iter.avoidNameConflict("usingnamespace_{d}", .{i}), | 1852 | (try iter.avoidNameConflict("usingnamespace_{d}", .{i})).toOptional(), |
| 1877 | .@"usingnamespace", | 1853 | .@"usingnamespace", |
| 1878 | false, | 1854 | false, |
| 1879 | }; | 1855 | }; |
| ... | @@ -1883,7 +1859,7 @@ const ScanDeclIter = struct { | ... | @@ -1883,7 +1859,7 @@ const ScanDeclIter = struct { |
| 1883 | const i = iter.unnamed_test_index; | 1859 | const i = iter.unnamed_test_index; |
| 1884 | iter.unnamed_test_index += 1; | 1860 | iter.unnamed_test_index += 1; |
| 1885 | break :info .{ | 1861 | break :info .{ |
| 1886 | try iter.avoidNameConflict("test_{d}", .{i}), | 1862 | (try iter.avoidNameConflict("test_{d}", .{i})).toOptional(), |
| 1887 | .@"test", | 1863 | .@"test", |
| 1888 | false, | 1864 | false, |
| 1889 | }; | 1865 | }; |
| ... | @@ -1894,7 +1870,7 @@ const ScanDeclIter = struct { | ... | @@ -1894,7 +1870,7 @@ const ScanDeclIter = struct { |
| 1894 | assert(declaration.flags.has_doc_comment); | 1870 | assert(declaration.flags.has_doc_comment); |
| 1895 | const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end])); | 1871 | const name = zir.nullTerminatedString(@enumFromInt(zir.extra[extra.end])); |
| 1896 | break :info .{ | 1872 | break :info .{ |
| 1897 | try iter.avoidNameConflict("decltest.{s}", .{name}), | 1873 | (try iter.avoidNameConflict("decltest.{s}", .{name})).toOptional(), |
| 1898 | .@"test", | 1874 | .@"test", |
| 1899 | true, | 1875 | true, |
| 1900 | }; | 1876 | }; |
| ... | @@ -1903,7 +1879,7 @@ const ScanDeclIter = struct { | ... | @@ -1903,7 +1879,7 @@ const ScanDeclIter = struct { |
| 1903 | // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary. | 1879 | // We consider these to be unnamed since the decl name can be adjusted to avoid conflicts if necessary. |
| 1904 | if (iter.pass != .unnamed) return; | 1880 | if (iter.pass != .unnamed) return; |
| 1905 | break :info .{ | 1881 | break :info .{ |
| 1906 | try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)}), | 1882 | (try iter.avoidNameConflict("test.{s}", .{zir.nullTerminatedString(declaration.name.toString(zir).?)})).toOptional(), |
| 1907 | .@"test", | 1883 | .@"test", |
| 1908 | true, | 1884 | true, |
| 1909 | }; | 1885 | }; |
| ... | @@ -1917,132 +1893,144 @@ const ScanDeclIter = struct { | ... | @@ -1917,132 +1893,144 @@ const ScanDeclIter = struct { |
| 1917 | ); | 1893 | ); |
| 1918 | try iter.seen_decls.putNoClobber(gpa, name, {}); | 1894 | try iter.seen_decls.putNoClobber(gpa, name, {}); |
| 1919 | break :info .{ | 1895 | break :info .{ |
| 1920 | name, | 1896 | name.toOptional(), |
| 1921 | .named, | 1897 | .named, |
| 1922 | false, | 1898 | false, |
| 1923 | }; | 1899 | }; |
| 1924 | }, | 1900 | }, |
| 1925 | }; | 1901 | }; |
| 1926 | 1902 | ||
| 1927 | switch (kind) { | ||
| 1928 | .@"usingnamespace" => try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1), | ||
| 1929 | .@"test" => try zcu.test_functions.ensureUnusedCapacity(gpa, 1), | ||
| 1930 | else => {}, | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu); | ||
| 1934 | const tracked_inst = try ip.trackZir(gpa, pt.tid, .{ | 1903 | const tracked_inst = try ip.trackZir(gpa, pt.tid, .{ |
| 1935 | .file = parent_file_scope_index, | 1904 | .file = namespace.file_scope, |
| 1936 | .inst = decl_inst, | 1905 | .inst = decl_inst, |
| 1937 | }); | 1906 | }); |
| 1938 | 1907 | ||
| 1939 | // We create a Decl for it regardless of analysis status. | 1908 | const existing_cau = iter.existing_by_inst.get(tracked_inst); |
| 1940 | 1909 | ||
| 1941 | const prev_exported, const decl_index = if (iter.existing_by_inst.get(tracked_inst)) |decl_index| decl_index: { | 1910 | const cau, const want_analysis = switch (kind) { |
| 1942 | // We need only update this existing Decl. | 1911 | .@"comptime" => cau: { |
| 1943 | const decl = zcu.declPtr(decl_index); | 1912 | const cau = existing_cau orelse try ip.createComptimeCau(gpa, pt.tid, tracked_inst, namespace_index); |
| 1944 | const was_exported = decl.is_exported; | 1913 | |
| 1945 | assert(decl.kind == kind); // ZIR tracking should preserve this | 1914 | // For a `comptime` declaration, whether to re-analyze is based solely on whether the |
| 1946 | decl.name = decl_name; | 1915 | // `Cau` is outdated. So, add this one to `outdated` and `outdated_ready` if not already. |
| 1947 | decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name); | 1916 | const unit = InternPool.AnalUnit.wrap(.{ .cau = cau }); |
| 1948 | decl.is_pub = declaration.flags.is_pub; | 1917 | if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| { |
| 1949 | decl.is_exported = declaration.flags.is_export; | 1918 | try zcu.outdated.ensureUnusedCapacity(gpa, 1); |
| 1950 | break :decl_index .{ was_exported, decl_index }; | 1919 | try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1); |
| 1951 | } else decl_index: { | 1920 | zcu.outdated.putAssumeCapacityNoClobber(unit, kv.value); |
| 1952 | // Create and set up a new Decl. | 1921 | if (kv.value == 0) { // no PO deps |
| 1953 | const new_decl_index = try pt.allocateNewDecl(namespace_index); | 1922 | zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {}); |
| 1954 | const new_decl = zcu.declPtr(new_decl_index); | 1923 | } |
| 1955 | new_decl.kind = kind; | 1924 | } else if (!zcu.outdated.contains(unit)) { |
| 1956 | new_decl.name = decl_name; | 1925 | try zcu.outdated.ensureUnusedCapacity(gpa, 1); |
| 1957 | new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name); | 1926 | try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1); |
| 1958 | new_decl.is_pub = declaration.flags.is_pub; | 1927 | zcu.outdated.putAssumeCapacityNoClobber(unit, 0); |
| 1959 | new_decl.is_exported = declaration.flags.is_export; | 1928 | zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {}); |
| 1960 | new_decl.zir_decl_index = tracked_inst.toOptional(); | 1929 | } |
| 1961 | break :decl_index .{ false, new_decl_index }; | ||
| 1962 | }; | ||
| 1963 | |||
| 1964 | const decl = zcu.declPtr(decl_index); | ||
| 1965 | |||
| 1966 | namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu }); | ||
| 1967 | 1930 | ||
| 1968 | const comp = zcu.comp; | 1931 | break :cau .{ cau, true }; |
| 1969 | const decl_mod = namespace.fileScope(zcu).mod; | ||
| 1970 | const want_analysis = declaration.flags.is_export or switch (kind) { | ||
| 1971 | .anon => unreachable, | ||
| 1972 | .@"comptime" => true, | ||
| 1973 | .@"usingnamespace" => a: { | ||
| 1974 | namespace.usingnamespace_set.putAssumeCapacityNoClobber(decl_index, declaration.flags.is_pub); | ||
| 1975 | break :a true; | ||
| 1976 | }, | 1932 | }, |
| 1977 | .named => false, | 1933 | else => cau: { |
| 1978 | .@"test" => a: { | 1934 | const name = maybe_name.unwrap().?; |
| 1979 | if (!comp.config.is_test) break :a false; | 1935 | const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name); |
| 1980 | if (decl_mod != zcu.main_mod) break :a false; | 1936 | const cau, const nav = if (existing_cau) |cau_index| cau_nav: { |
| 1981 | if (is_named_test and comp.test_filters.len > 0) { | 1937 | const nav_index = ip.getCau(cau_index).owner.unwrap().nav; |
| 1982 | const decl_fqn = decl.fqn.toSlice(ip); | 1938 | const nav = ip.getNav(nav_index); |
| 1983 | for (comp.test_filters) |test_filter| { | 1939 | assert(nav.name == name); |
| 1984 | if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break; | 1940 | assert(nav.fqn == fqn); |
| 1985 | } else break :a false; | 1941 | break :cau_nav .{ cau_index, nav_index }; |
| 1986 | } | 1942 | } else try ip.createPairedCauNav(gpa, pt.tid, name, fqn, tracked_inst, namespace_index, kind == .@"usingnamespace"); |
| 1987 | zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update | 1943 | const want_analysis = switch (kind) { |
| 1988 | break :a true; | 1944 | .@"comptime" => unreachable, |
| 1945 | .@"usingnamespace" => a: { | ||
| 1946 | if (declaration.flags.is_pub) { | ||
| 1947 | try namespace.pub_usingnamespace.append(gpa, nav); | ||
| 1948 | } else { | ||
| 1949 | try namespace.priv_usingnamespace.append(gpa, nav); | ||
| 1950 | } | ||
| 1951 | break :a true; | ||
| 1952 | }, | ||
| 1953 | .@"test" => a: { | ||
| 1954 | try namespace.other_decls.append(gpa, cau); | ||
| 1955 | // TODO: incremental compilation! | ||
| 1956 | // * remove from `test_functions` if no longer matching filter | ||
| 1957 | // * add to `test_functions` if newly passing filter | ||
| 1958 | // This logic is unaware of incremental: we'll end up with duplicates. | ||
| 1959 | // Perhaps we should add all test indiscriminately and filter at the end of the update. | ||
| 1960 | if (!comp.config.is_test) break :a false; | ||
| 1961 | if (file.mod != zcu.main_mod) break :a false; | ||
| 1962 | if (is_named_test and comp.test_filters.len > 0) { | ||
| 1963 | const fqn_slice = fqn.toSlice(ip); | ||
| 1964 | for (comp.test_filters) |test_filter| { | ||
| 1965 | if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break; | ||
| 1966 | } else break :a false; | ||
| 1967 | } | ||
| 1968 | try zcu.test_functions.put(gpa, nav, {}); | ||
| 1969 | break :a true; | ||
| 1970 | }, | ||
| 1971 | .named => a: { | ||
| 1972 | if (declaration.flags.is_pub) { | ||
| 1973 | try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu }); | ||
| 1974 | } else { | ||
| 1975 | try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu }); | ||
| 1976 | } | ||
| 1977 | break :a false; | ||
| 1978 | }, | ||
| 1979 | }; | ||
| 1980 | break :cau .{ cau, want_analysis }; | ||
| 1989 | }, | 1981 | }, |
| 1990 | }; | 1982 | }; |
| 1991 | 1983 | ||
| 1992 | if (want_analysis) { | 1984 | if (want_analysis or declaration.flags.is_export) { |
| 1993 | // We will not queue analysis if the decl has been analyzed on a previous update and | 1985 | log.debug( |
| 1994 | // `is_export` is unchanged. In this case, the incremental update mechanism will handle | 1986 | "scanDecl queue analyze_cau file='{s}' cau_index={d}", |
| 1995 | // re-analysis for us if necessary. | 1987 | .{ namespace.fileScope(zcu).sub_file_path, cau }, |
| 1996 | if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) { | 1988 | ); |
| 1997 | log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{ | 1989 | try comp.queueJob(.{ .analyze_cau = cau }); |
| 1998 | namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index, | ||
| 1999 | }); | ||
| 2000 | try comp.queueJob(.{ .analyze_decl = decl_index }); | ||
| 2001 | } | ||
| 2002 | } | 1990 | } |
| 2003 | 1991 | ||
| 2004 | if (decl.getOwnedFunction(zcu) != null) { | 1992 | // TODO: we used to do line number updates here, but this is an inappropriate place for this logic to live. |
| 2005 | // TODO this logic is insufficient; namespaces we don't re-scan may still require | ||
| 2006 | // updated line numbers. Look into this! | ||
| 2007 | // TODO Look into detecting when this would be unnecessary by storing enough state | ||
| 2008 | // in `Decl` to notice that the line number did not change. | ||
| 2009 | try comp.queueJob(.{ .update_line_number = decl_index }); | ||
| 2010 | } | ||
| 2011 | } | 1993 | } |
| 2012 | }; | 1994 | }; |
| 2013 | 1995 | ||
| 2014 | /// Cancel the creation of an anon decl and delete any references to it. | 1996 | 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()); | 1997 | const tracy = trace(@src()); |
| 2030 | defer tracy.end(); | 1998 | defer tracy.end(); |
| 2031 | 1999 | ||
| 2032 | const mod = pt.zcu; | 2000 | const zcu = pt.zcu; |
| 2033 | const gpa = mod.gpa; | 2001 | const gpa = zcu.gpa; |
| 2034 | const ip = &mod.intern_pool; | 2002 | const ip = &zcu.intern_pool; |
| 2035 | const func = mod.funcInfo(func_index); | 2003 | |
| 2036 | const decl_index = func.owner_decl; | 2004 | const anal_unit = InternPool.AnalUnit.wrap(.{ .func = func_index }); |
| 2037 | const decl = mod.declPtr(decl_index); | 2005 | const func = zcu.funcInfo(func_index); |
| 2006 | const inst_info = func.zir_body_inst.resolveFull(ip); | ||
| 2007 | const file = zcu.fileByIndex(inst_info.file); | ||
| 2008 | const zir = file.zir; | ||
| 2009 | |||
| 2010 | try zcu.analysis_in_progress.put(gpa, anal_unit, {}); | ||
| 2011 | errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit); | ||
| 2012 | |||
| 2013 | func.setAnalysisState(ip, .analyzed); | ||
| 2014 | |||
| 2015 | // This is the `Cau` corresponding to the `declaration` instruction which the function or its generic owner originates from. | ||
| 2016 | const decl_cau = ip.getCau(cau: { | ||
| 2017 | const orig_nav = if (func.generic_owner == .none) | ||
| 2018 | func.owner_nav | ||
| 2019 | else | ||
| 2020 | zcu.funcInfo(func.generic_owner).owner_nav; | ||
| 2021 | |||
| 2022 | break :cau ip.getNav(orig_nav).analysis_owner.unwrap().?; | ||
| 2023 | }); | ||
| 2038 | 2024 | ||
| 2039 | log.debug("func name '{}'", .{decl.fqn.fmt(ip)}); | 2025 | const func_nav = ip.getNav(func.owner_nav); |
| 2040 | defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)}); | ||
| 2041 | 2026 | ||
| 2042 | const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0); | 2027 | const decl_prog_node = zcu.sema_prog_node.start(func_nav.fqn.toSlice(ip), 0); |
| 2043 | defer decl_prog_node.end(); | 2028 | defer decl_prog_node.end(); |
| 2044 | 2029 | ||
| 2045 | mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index })); | 2030 | zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit); |
| 2031 | |||
| 2032 | var analysis_arena = std.heap.ArenaAllocator.init(gpa); | ||
| 2033 | defer analysis_arena.deinit(); | ||
| 2046 | 2034 | ||
| 2047 | var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa); | 2035 | var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa); |
| 2048 | defer comptime_err_ret_trace.deinit(); | 2036 | defer comptime_err_ret_trace.deinit(); |
| ... | @@ -2052,21 +2040,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2052,21 +2040,19 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2052 | // the runtime-known parameters only, not to be confused with the | 2040 | // the runtime-known parameters only, not to be confused with the |
| 2053 | // generic_owner function type, which potentially has more parameters, | 2041 | // generic_owner function type, which potentially has more parameters, |
| 2054 | // including comptime parameters. | 2042 | // including comptime parameters. |
| 2055 | const fn_ty = decl.typeOf(mod); | 2043 | const fn_ty = Type.fromInterned(func.ty); |
| 2056 | const fn_ty_info = mod.typeToFunc(fn_ty).?; | 2044 | const fn_ty_info = zcu.typeToFunc(fn_ty).?; |
| 2057 | 2045 | ||
| 2058 | var sema: Sema = .{ | 2046 | var sema: Sema = .{ |
| 2059 | .pt = pt, | 2047 | .pt = pt, |
| 2060 | .gpa = gpa, | 2048 | .gpa = gpa, |
| 2061 | .arena = arena, | 2049 | .arena = analysis_arena.allocator(), |
| 2062 | .code = decl.getFileScope(mod).zir, | 2050 | .code = zir, |
| 2063 | .owner_decl = decl, | 2051 | .owner = anal_unit, |
| 2064 | .owner_decl_index = decl_index, | ||
| 2065 | .func_index = func_index, | 2052 | .func_index = func_index, |
| 2066 | .func_is_naked = fn_ty_info.cc == .Naked, | 2053 | .func_is_naked = fn_ty_info.cc == .Naked, |
| 2067 | .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type), | 2054 | .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type), |
| 2068 | .fn_ret_ty_ies = null, | 2055 | .fn_ret_ty_ies = null, |
| 2069 | .owner_func_index = func_index, | ||
| 2070 | .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota), | 2056 | .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota), |
| 2071 | .comptime_err_ret_trace = &comptime_err_ret_trace, | 2057 | .comptime_err_ret_trace = &comptime_err_ret_trace, |
| 2072 | }; | 2058 | }; |
| ... | @@ -2074,11 +2060,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2074,11 +2060,11 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2074 | 2060 | ||
| 2075 | // Every runtime function has a dependency on the source of the Decl it originates from. | 2061 | // Every runtime function has a dependency on the source of the Decl it originates from. |
| 2076 | // It also depends on the value of its owner Decl. | 2062 | // It also depends on the value of its owner Decl. |
| 2077 | try sema.declareDependency(.{ .src_hash = decl.zir_decl_index.unwrap().? }); | 2063 | try sema.declareDependency(.{ .src_hash = decl_cau.zir_index }); |
| 2078 | try sema.declareDependency(.{ .decl_val = decl_index }); | 2064 | try sema.declareDependency(.{ .nav_val = func.owner_nav }); |
| 2079 | 2065 | ||
| 2080 | if (func.analysisUnordered(ip).inferred_error_set) { | 2066 | if (func.analysisUnordered(ip).inferred_error_set) { |
| 2081 | const ies = try arena.create(Sema.InferredErrorSet); | 2067 | const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet); |
| 2082 | ies.* = .{ .func = func_index }; | 2068 | ies.* = .{ .func = func_index }; |
| 2083 | sema.fn_ret_ty_ies = ies; | 2069 | sema.fn_ret_ty_ies = ies; |
| 2084 | } | 2070 | } |
| ... | @@ -2094,19 +2080,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2094,19 +2080,12 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2094 | var inner_block: Sema.Block = .{ | 2080 | var inner_block: Sema.Block = .{ |
| 2095 | .parent = null, | 2081 | .parent = null, |
| 2096 | .sema = &sema, | 2082 | .sema = &sema, |
| 2097 | .namespace = decl.src_namespace, | 2083 | .namespace = decl_cau.namespace, |
| 2098 | .instructions = .{}, | 2084 | .instructions = .{}, |
| 2099 | .inlining = null, | 2085 | .inlining = null, |
| 2100 | .is_comptime = false, | 2086 | .is_comptime = false, |
| 2101 | .src_base_inst = inst: { | 2087 | .src_base_inst = decl_cau.zir_index, |
| 2102 | const owner_info = if (func.generic_owner == .none) | 2088 | .type_name_ctx = func_nav.fqn, |
| 2103 | func | ||
| 2104 | else | ||
| 2105 | mod.funcInfo(func.generic_owner); | ||
| 2106 | const orig_decl = mod.declPtr(owner_info.owner_decl); | ||
| 2107 | break :inst orig_decl.zir_decl_index.unwrap().?; | ||
| 2108 | }, | ||
| 2109 | .type_name_ctx = decl.name, | ||
| 2110 | }; | 2089 | }; |
| 2111 | defer inner_block.instructions.deinit(gpa); | 2090 | defer inner_block.instructions.deinit(gpa); |
| 2112 | 2091 | ||
| ... | @@ -2144,10 +2123,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2144,10 +2123,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2144 | const gop = sema.inst_map.getOrPutAssumeCapacity(inst); | 2123 | const gop = sema.inst_map.getOrPutAssumeCapacity(inst); |
| 2145 | if (gop.found_existing) continue; // provided above by comptime arg | 2124 | if (gop.found_existing) continue; // provided above by comptime arg |
| 2146 | 2125 | ||
| 2147 | const inst_info = sema.code.instructions.get(@intFromEnum(inst)); | 2126 | const param_inst_info = sema.code.instructions.get(@intFromEnum(inst)); |
| 2148 | const param_name: Zir.NullTerminatedString = switch (inst_info.tag) { | 2127 | const param_name: Zir.NullTerminatedString = switch (param_inst_info.tag) { |
| 2149 | .param_anytype => inst_info.data.str_tok.start, | 2128 | .param_anytype => param_inst_info.data.str_tok.start, |
| 2150 | .param => sema.code.extraData(Zir.Inst.Param, inst_info.data.pl_tok.payload_index).data.name, | 2129 | .param => sema.code.extraData(Zir.Inst.Param, param_inst_info.data.pl_tok.payload_index).data.name, |
| 2151 | else => unreachable, | 2130 | else => unreachable, |
| 2152 | }; | 2131 | }; |
| 2153 | 2132 | ||
| ... | @@ -2179,8 +2158,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2179,8 +2158,6 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2179 | }); | 2158 | }); |
| 2180 | } | 2159 | } |
| 2181 | 2160 | ||
| 2182 | func.setAnalysisState(ip, .in_progress); | ||
| 2183 | |||
| 2184 | const last_arg_index = inner_block.instructions.items.len; | 2161 | const last_arg_index = inner_block.instructions.items.len; |
| 2185 | 2162 | ||
| 2186 | // Save the error trace as our first action in the function. | 2163 | // Save the error trace as our first action in the function. |
| ... | @@ -2190,9 +2167,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2190,9 +2167,8 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2190 | inner_block.error_return_trace_index = error_return_trace_index; | 2167 | inner_block.error_return_trace_index = error_return_trace_index; |
| 2191 | 2168 | ||
| 2192 | sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) { | 2169 | sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) { |
| 2193 | // TODO make these unreachable instead of @panic | 2170 | error.GenericPoison => unreachable, |
| 2194 | error.GenericPoison => @panic("zig compiler bug: GenericPoison"), | 2171 | error.ComptimeReturn => unreachable, |
| 2195 | error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"), | ||
| 2196 | else => |e| return e, | 2172 | else => |e| return e, |
| 2197 | }; | 2173 | }; |
| 2198 | 2174 | ||
| ... | @@ -2207,14 +2183,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2207,14 +2183,13 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2207 | 2183 | ||
| 2208 | // If we don't get an error return trace from a caller, create our own. | 2184 | // If we don't get an error return trace from a caller, create our own. |
| 2209 | if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and | 2185 | if (func.analysisUnordered(ip).calls_or_awaits_errorable_fn and |
| 2210 | mod.comp.config.any_error_tracing and | 2186 | zcu.comp.config.any_error_tracing and |
| 2211 | !sema.fn_ret_ty.isError(mod)) | 2187 | !sema.fn_ret_ty.isError(zcu)) |
| 2212 | { | 2188 | { |
| 2213 | sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) { | 2189 | sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) { |
| 2214 | // TODO make these unreachable instead of @panic | 2190 | error.GenericPoison => unreachable, |
| 2215 | error.GenericPoison => @panic("zig compiler bug: GenericPoison"), | 2191 | error.ComptimeReturn => unreachable, |
| 2216 | error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"), | 2192 | error.ComptimeBreak => unreachable, |
| 2217 | error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"), | ||
| 2218 | else => |e| return e, | 2193 | else => |e| return e, |
| 2219 | }; | 2194 | }; |
| 2220 | } | 2195 | } |
| ... | @@ -2239,35 +2214,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -2239,35 +2214,25 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 2239 | error.GenericPoison => unreachable, | 2214 | error.GenericPoison => unreachable, |
| 2240 | error.ComptimeReturn => unreachable, | 2215 | error.ComptimeReturn => unreachable, |
| 2241 | error.ComptimeBreak => unreachable, | 2216 | error.ComptimeBreak => unreachable, |
| 2242 | error.AnalysisFail => { | ||
| 2243 | // In this case our function depends on a type that had a compile error. | ||
| 2244 | // We should not try to lower this function. | ||
| 2245 | decl.analysis = .dependency_failure; | ||
| 2246 | return error.AnalysisFail; | ||
| 2247 | }, | ||
| 2248 | else => |e| return e, | 2217 | else => |e| return e, |
| 2249 | }; | 2218 | }; |
| 2250 | assert(ies.resolved != .none); | 2219 | assert(ies.resolved != .none); |
| 2251 | ip.funcSetIesResolved(func_index, ies.resolved); | 2220 | ip.funcSetIesResolved(func_index, ies.resolved); |
| 2252 | } | 2221 | } |
| 2253 | 2222 | ||
| 2254 | func.setAnalysisState(ip, .success); | 2223 | assert(zcu.analysis_in_progress.swapRemove(anal_unit)); |
| 2255 | 2224 | ||
| 2256 | // Finally we must resolve the return type and parameter types so that backends | 2225 | // Finally we must resolve the return type and parameter types so that backends |
| 2257 | // have full access to type information. | 2226 | // have full access to type information. |
| 2258 | // Crucially, this happens *after* we set the function state to success above, | 2227 | // Crucially, this happens *after* we set the function state to success above, |
| 2259 | // so that dependencies on the function body will now be satisfied rather than | 2228 | // so that dependencies on the function body will now be satisfied rather than |
| 2260 | // result in circular dependency errors. | 2229 | // result in circular dependency errors. |
| 2230 | // TODO: this can go away once we fix backends having to resolve `StackTrace`. | ||
| 2231 | // The codegen timing guarantees that the parameter types will be populated. | ||
| 2261 | sema.resolveFnTypes(fn_ty) catch |err| switch (err) { | 2232 | sema.resolveFnTypes(fn_ty) catch |err| switch (err) { |
| 2262 | error.GenericPoison => unreachable, | 2233 | error.GenericPoison => unreachable, |
| 2263 | error.ComptimeReturn => unreachable, | 2234 | error.ComptimeReturn => unreachable, |
| 2264 | error.ComptimeBreak => unreachable, | 2235 | error.ComptimeBreak => unreachable, |
| 2265 | error.AnalysisFail => { | ||
| 2266 | // In this case our function depends on a type that had a compile error. | ||
| 2267 | // We should not try to lower this function. | ||
| 2268 | decl.analysis = .dependency_failure; | ||
| 2269 | return error.AnalysisFail; | ||
| 2270 | }, | ||
| 2271 | else => |e| return e, | 2236 | else => |e| return e, |
| 2272 | }; | 2237 | }; |
| 2273 | 2238 | ||
| ... | @@ -2287,36 +2252,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index) | ... | @@ -2287,36 +2252,6 @@ pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index) |
| 2287 | return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index); | 2252 | return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index); |
| 2288 | } | 2253 | } |
| 2289 | 2254 | ||
| 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( | 2255 | pub fn getErrorValue( |
| 2321 | pt: Zcu.PerThread, | 2256 | pt: Zcu.PerThread, |
| 2322 | name: InternPool.NullTerminatedString, | 2257 | name: InternPool.NullTerminatedString, |
| ... | @@ -2328,25 +2263,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err | ... | @@ -2328,25 +2263,6 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err |
| 2328 | return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name)); | 2263 | return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name)); |
| 2329 | } | 2264 | } |
| 2330 | 2265 | ||
| 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 { | 2266 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 2351 | switch (file.status) { | 2267 | switch (file.status) { |
| 2352 | .success_zir, .retryable_failure => {}, | 2268 | .success_zir, .retryable_failure => {}, |
| ... | @@ -2367,35 +2283,35 @@ pub fn processExports(pt: Zcu.PerThread) !void { | ... | @@ -2367,35 +2283,35 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2367 | const zcu = pt.zcu; | 2283 | const zcu = pt.zcu; |
| 2368 | const gpa = zcu.gpa; | 2284 | const gpa = zcu.gpa; |
| 2369 | 2285 | ||
| 2370 | // First, construct a mapping of every exported value and Decl to the indices of all its different exports. | 2286 | // First, construct a mapping of every exported value and Nav to the indices of all its different exports. |
| 2371 | var decl_exports: std.AutoArrayHashMapUnmanaged(Zcu.Decl.Index, std.ArrayListUnmanaged(u32)) = .{}; | 2287 | var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .{}; |
| 2372 | var value_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{}; | 2288 | var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .{}; |
| 2373 | defer { | 2289 | defer { |
| 2374 | for (decl_exports.values()) |*exports| { | 2290 | for (nav_exports.values()) |*exports| { |
| 2375 | exports.deinit(gpa); | 2291 | exports.deinit(gpa); |
| 2376 | } | 2292 | } |
| 2377 | decl_exports.deinit(gpa); | 2293 | nav_exports.deinit(gpa); |
| 2378 | for (value_exports.values()) |*exports| { | 2294 | for (uav_exports.values()) |*exports| { |
| 2379 | exports.deinit(gpa); | 2295 | exports.deinit(gpa); |
| 2380 | } | 2296 | } |
| 2381 | value_exports.deinit(gpa); | 2297 | uav_exports.deinit(gpa); |
| 2382 | } | 2298 | } |
| 2383 | 2299 | ||
| 2384 | // We note as a heuristic: | 2300 | // We note as a heuristic: |
| 2385 | // * It is rare to export a value. | 2301 | // * It is rare to export a value. |
| 2386 | // * It is rare for one Decl to be exported multiple times. | 2302 | // * It is rare for one Nav to be exported multiple times. |
| 2387 | // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization. | 2303 | // So, this ensureTotalCapacity serves as a reasonable (albeit very approximate) optimization. |
| 2388 | try decl_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count()); | 2304 | try nav_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count()); |
| 2389 | 2305 | ||
| 2390 | for (zcu.single_exports.values()) |export_idx| { | 2306 | for (zcu.single_exports.values()) |export_idx| { |
| 2391 | const exp = zcu.all_exports.items[export_idx]; | 2307 | const exp = zcu.all_exports.items[export_idx]; |
| 2392 | const value_ptr, const found_existing = switch (exp.exported) { | 2308 | const value_ptr, const found_existing = switch (exp.exported) { |
| 2393 | .decl_index => |i| gop: { | 2309 | .nav => |nav| gop: { |
| 2394 | const gop = try decl_exports.getOrPut(gpa, i); | 2310 | const gop = try nav_exports.getOrPut(gpa, nav); |
| 2395 | break :gop .{ gop.value_ptr, gop.found_existing }; | 2311 | break :gop .{ gop.value_ptr, gop.found_existing }; |
| 2396 | }, | 2312 | }, |
| 2397 | .value => |i| gop: { | 2313 | .uav => |uav| gop: { |
| 2398 | const gop = try value_exports.getOrPut(gpa, i); | 2314 | const gop = try uav_exports.getOrPut(gpa, uav); |
| 2399 | break :gop .{ gop.value_ptr, gop.found_existing }; | 2315 | break :gop .{ gop.value_ptr, gop.found_existing }; |
| 2400 | }, | 2316 | }, |
| 2401 | }; | 2317 | }; |
| ... | @@ -2406,12 +2322,12 @@ pub fn processExports(pt: Zcu.PerThread) !void { | ... | @@ -2406,12 +2322,12 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2406 | for (zcu.multi_exports.values()) |info| { | 2322 | for (zcu.multi_exports.values()) |info| { |
| 2407 | for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| { | 2323 | for (zcu.all_exports.items[info.index..][0..info.len], info.index..) |exp, export_idx| { |
| 2408 | const value_ptr, const found_existing = switch (exp.exported) { | 2324 | const value_ptr, const found_existing = switch (exp.exported) { |
| 2409 | .decl_index => |i| gop: { | 2325 | .nav => |nav| gop: { |
| 2410 | const gop = try decl_exports.getOrPut(gpa, i); | 2326 | const gop = try nav_exports.getOrPut(gpa, nav); |
| 2411 | break :gop .{ gop.value_ptr, gop.found_existing }; | 2327 | break :gop .{ gop.value_ptr, gop.found_existing }; |
| 2412 | }, | 2328 | }, |
| 2413 | .value => |i| gop: { | 2329 | .uav => |uav| gop: { |
| 2414 | const gop = try value_exports.getOrPut(gpa, i); | 2330 | const gop = try uav_exports.getOrPut(gpa, uav); |
| 2415 | break :gop .{ gop.value_ptr, gop.found_existing }; | 2331 | break :gop .{ gop.value_ptr, gop.found_existing }; |
| 2416 | }, | 2332 | }, |
| 2417 | }; | 2333 | }; |
| ... | @@ -2424,13 +2340,13 @@ pub fn processExports(pt: Zcu.PerThread) !void { | ... | @@ -2424,13 +2340,13 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2424 | var symbol_exports: SymbolExports = .{}; | 2340 | var symbol_exports: SymbolExports = .{}; |
| 2425 | defer symbol_exports.deinit(gpa); | 2341 | defer symbol_exports.deinit(gpa); |
| 2426 | 2342 | ||
| 2427 | for (decl_exports.keys(), decl_exports.values()) |exported_decl, exports_list| { | 2343 | for (nav_exports.keys(), nav_exports.values()) |exported_nav, exports_list| { |
| 2428 | const exported: Zcu.Exported = .{ .decl_index = exported_decl }; | 2344 | const exported: Zcu.Exported = .{ .nav = exported_nav }; |
| 2429 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); | 2345 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); |
| 2430 | } | 2346 | } |
| 2431 | 2347 | ||
| 2432 | for (value_exports.keys(), value_exports.values()) |exported_value, exports_list| { | 2348 | for (uav_exports.keys(), uav_exports.values()) |exported_uav, exports_list| { |
| 2433 | const exported: Zcu.Exported = .{ .value = exported_value }; | 2349 | const exported: Zcu.Exported = .{ .uav = exported_uav }; |
| 2434 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); | 2350 | try pt.processExportsInner(&symbol_exports, exported, exports_list.items); |
| 2435 | } | 2351 | } |
| 2436 | } | 2352 | } |
| ... | @@ -2467,20 +2383,31 @@ fn processExportsInner( | ... | @@ -2467,20 +2383,31 @@ fn processExportsInner( |
| 2467 | } | 2383 | } |
| 2468 | 2384 | ||
| 2469 | switch (exported) { | 2385 | switch (exported) { |
| 2470 | .decl_index => |idx| if (failed: { | 2386 | .nav => |nav_index| if (failed: { |
| 2471 | const decl = zcu.declPtr(idx); | 2387 | const nav = ip.getNav(nav_index); |
| 2472 | if (decl.analysis != .complete) break :failed true; | 2388 | if (zcu.failed_codegen.contains(nav_index)) break :failed true; |
| 2473 | // Check if has owned function | 2389 | if (nav.analysis_owner.unwrap()) |cau| { |
| 2474 | if (!decl.owns_tv) break :failed false; | 2390 | const cau_unit = InternPool.AnalUnit.wrap(.{ .cau = cau }); |
| 2475 | if (decl.typeOf(zcu).zigTypeTag(zcu) != .Fn) break :failed false; | 2391 | if (zcu.failed_analysis.contains(cau_unit)) break :failed true; |
| 2476 | // Check if owned function failed | 2392 | if (zcu.transitive_failed_analysis.contains(cau_unit)) break :failed true; |
| 2477 | break :failed zcu.funcInfo(decl.val.toIntern()).analysisUnordered(ip).state != .success; | 2393 | } |
| 2394 | const val = switch (nav.status) { | ||
| 2395 | .unresolved => break :failed true, | ||
| 2396 | .resolved => |r| Value.fromInterned(r.val), | ||
| 2397 | }; | ||
| 2398 | // If the value is a function, we also need to check if that function succeeded analysis. | ||
| 2399 | if (val.typeOf(zcu).zigTypeTag(zcu) == .Fn) { | ||
| 2400 | const func_unit = InternPool.AnalUnit.wrap(.{ .func = val.toIntern() }); | ||
| 2401 | if (zcu.failed_analysis.contains(func_unit)) break :failed true; | ||
| 2402 | if (zcu.transitive_failed_analysis.contains(func_unit)) break :failed true; | ||
| 2403 | } | ||
| 2404 | break :failed false; | ||
| 2478 | }) { | 2405 | }) { |
| 2479 | // This `Decl` is failed, so was never sent to codegen. | 2406 | // This `Decl` is failed, so was never sent to codegen. |
| 2480 | // TODO: we should probably tell the backend to delete any old exports of this `Decl`? | 2407 | // TODO: we should probably tell the backend to delete any old exports of this `Decl`? |
| 2481 | return; | 2408 | return; |
| 2482 | }, | 2409 | }, |
| 2483 | .value => {}, | 2410 | .uav => {}, |
| 2484 | } | 2411 | } |
| 2485 | 2412 | ||
| 2486 | if (zcu.comp.bin_file) |lf| { | 2413 | if (zcu.comp.bin_file) |lf| { |
| ... | @@ -2499,46 +2426,49 @@ pub fn populateTestFunctions( | ... | @@ -2499,46 +2426,49 @@ pub fn populateTestFunctions( |
| 2499 | const ip = &zcu.intern_pool; | 2426 | const ip = &zcu.intern_pool; |
| 2500 | const builtin_mod = zcu.root_mod.getBuiltinDependency(); | 2427 | const builtin_mod = zcu.root_mod.getBuiltinDependency(); |
| 2501 | const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index; | 2428 | const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index; |
| 2502 | const root_decl_index = zcu.fileRootDecl(builtin_file_index); | 2429 | pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) { |
| 2503 | const root_decl = zcu.declPtr(root_decl_index.unwrap().?); | 2430 | error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt |
| 2504 | const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace); | 2431 | error.OutOfMemory => |e| return e, |
| 2505 | const test_functions_str = try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls); | 2432 | }; |
| 2506 | const decl_index = builtin_namespace.decls.getKeyAdapted( | 2433 | const builtin_root_type = Type.fromInterned(zcu.fileRootType(builtin_file_index)); |
| 2507 | test_functions_str, | 2434 | const builtin_namespace = builtin_root_type.getNamespace(zcu).unwrap().?; |
| 2508 | Zcu.DeclAdapter{ .zcu = zcu }, | 2435 | const nav_index = zcu.namespacePtr(builtin_namespace).pub_decls.getKeyAdapted( |
| 2436 | try ip.getOrPutString(gpa, pt.tid, "test_functions", .no_embedded_nulls), | ||
| 2437 | Zcu.Namespace.NameAdapter{ .zcu = zcu }, | ||
| 2509 | ).?; | 2438 | ).?; |
| 2510 | { | 2439 | { |
| 2511 | // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions` | 2440 | // We have to call `ensureCauAnalyzed` here in case `builtin.test_functions` |
| 2512 | // was not referenced by start code. | 2441 | // was not referenced by start code. |
| 2513 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | 2442 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); |
| 2514 | defer { | 2443 | defer { |
| 2515 | zcu.sema_prog_node.end(); | 2444 | zcu.sema_prog_node.end(); |
| 2516 | zcu.sema_prog_node = std.Progress.Node.none; | 2445 | zcu.sema_prog_node = std.Progress.Node.none; |
| 2517 | } | 2446 | } |
| 2518 | try pt.ensureDeclAnalyzed(decl_index); | 2447 | const cau_index = ip.getNav(nav_index).analysis_owner.unwrap().?; |
| 2448 | try pt.ensureCauAnalyzed(cau_index); | ||
| 2519 | } | 2449 | } |
| 2520 | 2450 | ||
| 2521 | const decl = zcu.declPtr(decl_index); | 2451 | const test_fns_val = zcu.navValue(nav_index); |
| 2522 | const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); | 2452 | const test_fn_ty = test_fns_val.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); |
| 2523 | 2453 | ||
| 2524 | const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: { | 2454 | const array_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = array: { |
| 2525 | // Add zcu.test_functions to an array decl then make the test_functions | 2455 | // Add zcu.test_functions to an array decl then make the test_functions |
| 2526 | // decl reference it as a slice. | 2456 | // decl reference it as a slice. |
| 2527 | const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count()); | 2457 | const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count()); |
| 2528 | defer gpa.free(test_fn_vals); | 2458 | defer gpa.free(test_fn_vals); |
| 2529 | 2459 | ||
| 2530 | for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| { | 2460 | for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_nav_index| { |
| 2531 | const test_decl = zcu.declPtr(test_decl_index); | 2461 | const test_nav = ip.getNav(test_nav_index); |
| 2532 | const test_decl_name = test_decl.fqn; | 2462 | const test_nav_name = test_nav.fqn; |
| 2533 | const test_decl_name_len = test_decl_name.length(ip); | 2463 | const test_nav_name_len = test_nav_name.length(ip); |
| 2534 | const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: { | 2464 | const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.Uav = n: { |
| 2535 | const test_name_ty = try pt.arrayType(.{ | 2465 | const test_name_ty = try pt.arrayType(.{ |
| 2536 | .len = test_decl_name_len, | 2466 | .len = test_nav_name_len, |
| 2537 | .child = .u8_type, | 2467 | .child = .u8_type, |
| 2538 | }); | 2468 | }); |
| 2539 | const test_name_val = try pt.intern(.{ .aggregate = .{ | 2469 | const test_name_val = try pt.intern(.{ .aggregate = .{ |
| 2540 | .ty = test_name_ty.toIntern(), | 2470 | .ty = test_name_ty.toIntern(), |
| 2541 | .storage = .{ .bytes = test_decl_name.toString() }, | 2471 | .storage = .{ .bytes = test_nav_name.toString() }, |
| 2542 | } }); | 2472 | } }); |
| 2543 | break :n .{ | 2473 | break :n .{ |
| 2544 | .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(), | 2474 | .orig_ty = (try pt.singleConstPtrType(test_name_ty)).toIntern(), |
| ... | @@ -2552,23 +2482,18 @@ pub fn populateTestFunctions( | ... | @@ -2552,23 +2482,18 @@ pub fn populateTestFunctions( |
| 2552 | .ty = .slice_const_u8_type, | 2482 | .ty = .slice_const_u8_type, |
| 2553 | .ptr = try pt.intern(.{ .ptr = .{ | 2483 | .ptr = try pt.intern(.{ .ptr = .{ |
| 2554 | .ty = .manyptr_const_u8_type, | 2484 | .ty = .manyptr_const_u8_type, |
| 2555 | .base_addr = .{ .anon_decl = test_name_anon_decl }, | 2485 | .base_addr = .{ .uav = test_name_anon_decl }, |
| 2556 | .byte_offset = 0, | 2486 | .byte_offset = 0, |
| 2557 | } }), | 2487 | } }), |
| 2558 | .len = try pt.intern(.{ .int = .{ | 2488 | .len = try pt.intern(.{ .int = .{ |
| 2559 | .ty = .usize_type, | 2489 | .ty = .usize_type, |
| 2560 | .storage = .{ .u64 = test_decl_name_len }, | 2490 | .storage = .{ .u64 = test_nav_name_len }, |
| 2561 | } }), | 2491 | } }), |
| 2562 | } }), | 2492 | } }), |
| 2563 | // func | 2493 | // func |
| 2564 | try pt.intern(.{ .ptr = .{ | 2494 | try pt.intern(.{ .ptr = .{ |
| 2565 | .ty = try pt.intern(.{ .ptr_type = .{ | 2495 | .ty = (try pt.navPtrType(test_nav_index)).toIntern(), |
| 2566 | .child = test_decl.typeOf(zcu).toIntern(), | 2496 | .base_addr = .{ .nav = test_nav_index }, |
| 2567 | .flags = .{ | ||
| 2568 | .is_const = true, | ||
| 2569 | }, | ||
| 2570 | } }), | ||
| 2571 | .base_addr = .{ .decl = test_decl_index }, | ||
| 2572 | .byte_offset = 0, | 2497 | .byte_offset = 0, |
| 2573 | } }), | 2498 | } }), |
| 2574 | }; | 2499 | }; |
| ... | @@ -2601,22 +2526,16 @@ pub fn populateTestFunctions( | ... | @@ -2601,22 +2526,16 @@ pub fn populateTestFunctions( |
| 2601 | .size = .Slice, | 2526 | .size = .Slice, |
| 2602 | }, | 2527 | }, |
| 2603 | }); | 2528 | }); |
| 2604 | const new_val = decl.val; | ||
| 2605 | const new_init = try pt.intern(.{ .slice = .{ | 2529 | const new_init = try pt.intern(.{ .slice = .{ |
| 2606 | .ty = new_ty.toIntern(), | 2530 | .ty = new_ty.toIntern(), |
| 2607 | .ptr = try pt.intern(.{ .ptr = .{ | 2531 | .ptr = try pt.intern(.{ .ptr = .{ |
| 2608 | .ty = new_ty.slicePtrFieldType(zcu).toIntern(), | 2532 | .ty = new_ty.slicePtrFieldType(zcu).toIntern(), |
| 2609 | .base_addr = .{ .anon_decl = array_anon_decl }, | 2533 | .base_addr = .{ .uav = array_anon_decl }, |
| 2610 | .byte_offset = 0, | 2534 | .byte_offset = 0, |
| 2611 | } }), | 2535 | } }), |
| 2612 | .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(), | 2536 | .len = (try pt.intValue(Type.usize, zcu.test_functions.count())).toIntern(), |
| 2613 | } }); | 2537 | } }); |
| 2614 | ip.mutateVarInit(decl.val.toIntern(), new_init); | 2538 | ip.mutateVarInit(test_fns_val.toIntern(), new_init); |
| 2615 | |||
| 2616 | // Since we are replacing the Decl's value we must perform cleanup on the | ||
| 2617 | // previous value. | ||
| 2618 | decl.val = new_val; | ||
| 2619 | decl.has_tv = true; | ||
| 2620 | } | 2539 | } |
| 2621 | { | 2540 | { |
| 2622 | zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); | 2541 | zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); |
| ... | @@ -2625,40 +2544,45 @@ pub fn populateTestFunctions( | ... | @@ -2625,40 +2544,45 @@ pub fn populateTestFunctions( |
| 2625 | zcu.codegen_prog_node = std.Progress.Node.none; | 2544 | zcu.codegen_prog_node = std.Progress.Node.none; |
| 2626 | } | 2545 | } |
| 2627 | 2546 | ||
| 2628 | try pt.linkerUpdateDecl(decl_index); | 2547 | try pt.linkerUpdateNav(nav_index); |
| 2629 | } | 2548 | } |
| 2630 | } | 2549 | } |
| 2631 | 2550 | ||
| 2632 | pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void { | 2551 | pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| 2633 | const zcu = pt.zcu; | 2552 | const zcu = pt.zcu; |
| 2634 | const comp = zcu.comp; | 2553 | const comp = zcu.comp; |
| 2635 | 2554 | ||
| 2636 | const decl = zcu.declPtr(decl_index); | 2555 | const nav = zcu.intern_pool.getNav(nav_index); |
| 2637 | 2556 | const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0); | |
| 2638 | const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(&zcu.intern_pool), 0); | ||
| 2639 | defer codegen_prog_node.end(); | 2557 | defer codegen_prog_node.end(); |
| 2640 | 2558 | ||
| 2641 | if (comp.bin_file) |lf| { | 2559 | if (comp.bin_file) |lf| { |
| 2642 | lf.updateDecl(pt, decl_index) catch |err| switch (err) { | 2560 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 2643 | error.OutOfMemory => return error.OutOfMemory, | 2561 | error.OutOfMemory => return error.OutOfMemory, |
| 2644 | error.AnalysisFail => { | 2562 | error.AnalysisFail => { |
| 2645 | decl.analysis = .codegen_failure; | 2563 | assert(zcu.failed_codegen.contains(nav_index)); |
| 2646 | }, | 2564 | }, |
| 2647 | else => { | 2565 | else => { |
| 2648 | const gpa = zcu.gpa; | 2566 | const gpa = zcu.gpa; |
| 2649 | try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); | 2567 | try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1); |
| 2650 | zcu.failed_analysis.putAssumeCapacityNoClobber(InternPool.AnalUnit.wrap(.{ .decl = decl_index }), try Zcu.ErrorMsg.create( | 2568 | zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, try Zcu.ErrorMsg.create( |
| 2651 | gpa, | 2569 | gpa, |
| 2652 | decl.navSrcLoc(zcu), | 2570 | zcu.navSrcLoc(nav_index), |
| 2653 | "unable to codegen: {s}", | 2571 | "unable to codegen: {s}", |
| 2654 | .{@errorName(err)}, | 2572 | .{@errorName(err)}, |
| 2655 | )); | 2573 | )); |
| 2656 | decl.analysis = .codegen_failure; | 2574 | if (nav.analysis_owner.unwrap()) |cau| { |
| 2657 | try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); | 2575 | try zcu.retryable_failures.append(zcu.gpa, InternPool.AnalUnit.wrap(.{ .cau = cau })); |
| 2576 | } else { | ||
| 2577 | // TODO: we don't have a way to indicate that this failure is retryable! | ||
| 2578 | // Since these are really rare, we could as a cop-out retry the whole build next update. | ||
| 2579 | // But perhaps we can do better... | ||
| 2580 | @panic("TODO: retryable failure codegenning non-declaration Nav"); | ||
| 2581 | } | ||
| 2658 | }, | 2582 | }, |
| 2659 | }; | 2583 | }; |
| 2660 | } else if (zcu.llvm_object) |llvm_object| { | 2584 | } else if (zcu.llvm_object) |llvm_object| { |
| 2661 | llvm_object.updateDecl(pt, decl_index) catch |err| switch (err) { | 2585 | llvm_object.updateNav(pt, nav_index) catch |err| switch (err) { |
| 2662 | error.OutOfMemory => return error.OutOfMemory, | 2586 | error.OutOfMemory => return error.OutOfMemory, |
| 2663 | }; | 2587 | }; |
| 2664 | } | 2588 | } |
| ... | @@ -2750,9 +2674,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool | ... | @@ -2750,9 +2674,30 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool |
| 2750 | return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key); | 2674 | return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key); |
| 2751 | } | 2675 | } |
| 2752 | 2676 | ||
| 2753 | /// Shortcut for calling `intern_pool.getCoerced`. | 2677 | /// Essentially a shortcut for calling `intern_pool.getCoerced`. |
| 2678 | /// However, this function also allows coercing `extern`s. The `InternPool` function can't do | ||
| 2679 | /// this because it requires potentially pushing to the job queue. | ||
| 2754 | pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value { | 2680 | 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())); | 2681 | const ip = &pt.zcu.intern_pool; |
| 2682 | switch (ip.indexToKey(val.toIntern())) { | ||
| 2683 | .@"extern" => |e| { | ||
| 2684 | const coerced = try pt.getExtern(.{ | ||
| 2685 | .name = e.name, | ||
| 2686 | .ty = new_ty.toIntern(), | ||
| 2687 | .lib_name = e.lib_name, | ||
| 2688 | .is_const = e.is_const, | ||
| 2689 | .is_threadlocal = e.is_threadlocal, | ||
| 2690 | .is_weak_linkage = e.is_weak_linkage, | ||
| 2691 | .alignment = e.alignment, | ||
| 2692 | .@"addrspace" = e.@"addrspace", | ||
| 2693 | .zir_index = e.zir_index, | ||
| 2694 | .owner_nav = undefined, // ignored by `getExtern`. | ||
| 2695 | }); | ||
| 2696 | return Value.fromInterned(coerced); | ||
| 2697 | }, | ||
| 2698 | else => {}, | ||
| 2699 | } | ||
| 2700 | return Value.fromInterned(try ip.getCoerced(pt.zcu.gpa, pt.tid, val.toIntern(), new_ty.toIntern())); | ||
| 2756 | } | 2701 | } |
| 2757 | 2702 | ||
| 2758 | pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type { | 2703 | pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type { |
| ... | @@ -3237,24 +3182,28 @@ pub fn structPackedFieldBitOffset( | ... | @@ -3237,24 +3182,28 @@ pub fn structPackedFieldBitOffset( |
| 3237 | } | 3182 | } |
| 3238 | 3183 | ||
| 3239 | pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref { | 3184 | pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref { |
| 3240 | const decl_index = try pt.getBuiltinDecl(name); | 3185 | const zcu = pt.zcu; |
| 3241 | pt.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt"); | 3186 | const ip = &zcu.intern_pool; |
| 3242 | return Air.internedToRef(pt.zcu.declPtr(decl_index).val.toIntern()); | 3187 | const nav = try pt.getBuiltinNav(name); |
| 3188 | pt.ensureCauAnalyzed(ip.getNav(nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt"); | ||
| 3189 | return Air.internedToRef(ip.getNav(nav).status.resolved.val); | ||
| 3243 | } | 3190 | } |
| 3244 | 3191 | ||
| 3245 | pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.DeclIndex { | 3192 | pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index { |
| 3246 | const zcu = pt.zcu; | 3193 | const zcu = pt.zcu; |
| 3247 | const gpa = zcu.gpa; | 3194 | const gpa = zcu.gpa; |
| 3248 | const ip = &zcu.intern_pool; | 3195 | const ip = &zcu.intern_pool; |
| 3249 | const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig"); | 3196 | const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig"); |
| 3250 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?; | 3197 | const std_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index)); |
| 3251 | const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?; | 3198 | const std_namespace = zcu.namespacePtr(std_type.getNamespace(zcu).unwrap().?); |
| 3252 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); | 3199 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); |
| 3253 | const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'"); | 3200 | const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse |
| 3254 | pt.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt"); | 3201 | @panic("lib/std.zig is corrupt and missing 'builtin'"); |
| 3255 | const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt"); | 3202 | pt.ensureCauAnalyzed(ip.getNav(builtin_nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt"); |
| 3203 | const builtin_type = Type.fromInterned(ip.getNav(builtin_nav).status.resolved.val); | ||
| 3204 | const builtin_namespace = zcu.namespacePtr(builtin_type.getNamespace(zcu).unwrap() orelse @panic("std.builtin is corrupt")); | ||
| 3256 | const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls); | 3205 | const name_str = try ip.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls); |
| 3257 | return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt"); | 3206 | return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt"); |
| 3258 | } | 3207 | } |
| 3259 | 3208 | ||
| 3260 | pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type { | 3209 | pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type { |
| ... | @@ -3264,6 +3213,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type | ... | @@ -3264,6 +3213,47 @@ pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type |
| 3264 | return ty; | 3213 | return ty; |
| 3265 | } | 3214 | } |
| 3266 | 3215 | ||
| 3216 | pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator.Error!Type { | ||
| 3217 | const zcu = pt.zcu; | ||
| 3218 | const ip = &zcu.intern_pool; | ||
| 3219 | const r = ip.getNav(nav_index).status.resolved; | ||
| 3220 | const ty = Value.fromInterned(r.val).typeOf(zcu); | ||
| 3221 | return pt.ptrType(.{ | ||
| 3222 | .child = ty.toIntern(), | ||
| 3223 | .flags = .{ | ||
| 3224 | .alignment = if (r.alignment == ty.abiAlignment(pt)) | ||
| 3225 | .none | ||
| 3226 | else | ||
| 3227 | r.alignment, | ||
| 3228 | .address_space = r.@"addrspace", | ||
| 3229 | .is_const = switch (ip.indexToKey(r.val)) { | ||
| 3230 | .variable => false, | ||
| 3231 | .@"extern" => |e| e.is_const, | ||
| 3232 | else => true, | ||
| 3233 | }, | ||
| 3234 | }, | ||
| 3235 | }); | ||
| 3236 | } | ||
| 3237 | |||
| 3238 | /// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary. | ||
| 3239 | /// If necessary, the new `Nav` is queued for codegen. | ||
| 3240 | /// `key.owner_nav` is ignored and may be `undefined`. | ||
| 3241 | pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!InternPool.Index { | ||
| 3242 | const result = try pt.zcu.intern_pool.getExtern(pt.zcu.gpa, pt.tid, key); | ||
| 3243 | if (result.new_nav.unwrap()) |nav| { | ||
| 3244 | try pt.zcu.comp.queueJob(.{ .codegen_nav = nav }); | ||
| 3245 | } | ||
| 3246 | return result.index; | ||
| 3247 | } | ||
| 3248 | |||
| 3249 | // TODO: this shouldn't need a `PerThread`! Fix the signature of `Type.abiAlignment`. | ||
| 3250 | pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPool.Alignment { | ||
| 3251 | const zcu = pt.zcu; | ||
| 3252 | const r = zcu.intern_pool.getNav(nav_index).status.resolved; | ||
| 3253 | if (r.alignment != .none) return r.alignment; | ||
| 3254 | return Value.fromInterned(r.val).typeOf(zcu).abiAlignment(pt); | ||
| 3255 | } | ||
| 3256 | |||
| 3267 | const Air = @import("../Air.zig"); | 3257 | const Air = @import("../Air.zig"); |
| 3268 | const Allocator = std.mem.Allocator; | 3258 | const Allocator = std.mem.Allocator; |
| 3269 | const assert = std.debug.assert; | 3259 | 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+410-440| ... | @@ -776,7 +776,7 @@ pub const Object = struct { | ... | @@ -776,7 +776,7 @@ pub const Object = struct { |
| 776 | debug_enums: std.ArrayListUnmanaged(Builder.Metadata), | 776 | debug_enums: std.ArrayListUnmanaged(Builder.Metadata), |
| 777 | debug_globals: std.ArrayListUnmanaged(Builder.Metadata), | 777 | debug_globals: std.ArrayListUnmanaged(Builder.Metadata), |
| 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)); |
| 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.namespacePtr(builtin_ty.getNamespaceIndex(zcu)); |
| 2807 | const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Zcu.DeclAdapter{ .zcu = zcu }).?; | 2807 | const stack_trace_nav = builtin_namespace.pub_decls.getKeyAdapted(stack_trace_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?; |
| 2808 | const stack_trace_decl = zcu.declPtr(stack_trace_decl_index); | ||
| 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 |