| ... | ... | @@ -291,7 +291,7 @@ pub const Decl = struct { |
| 291 | 291 | } |
| 292 | 292 | if (decl.has_tv) { |
| 293 | 293 | if (decl.getInnerNamespace()) |namespace| { |
| 294 | | namespace.clearDecls(module); |
| 294 | namespace.destroyDecls(module); |
| 295 | 295 | } |
| 296 | 296 | decl.clearValues(gpa); |
| 297 | 297 | } |
| ... | ... | @@ -880,14 +880,14 @@ pub const Scope = struct { |
| 880 | 880 | anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, |
| 881 | 881 | |
| 882 | 882 | pub fn deinit(ns: *Namespace, mod: *Module) void { |
| 883 | | ns.clearDecls(mod); |
| 883 | ns.destroyDecls(mod); |
| 884 | 884 | ns.* = undefined; |
| 885 | 885 | } |
| 886 | 886 | |
| 887 | | pub fn clearDecls(ns: *Namespace, mod: *Module) void { |
| 887 | pub fn destroyDecls(ns: *Namespace, mod: *Module) void { |
| 888 | 888 | const gpa = mod.gpa; |
| 889 | 889 | |
| 890 | | log.debug("clearDecls {*}", .{ns}); |
| 890 | log.debug("destroyDecls {*}", .{ns}); |
| 891 | 891 | |
| 892 | 892 | var decls = ns.decls; |
| 893 | 893 | ns.decls = .{}; |
| ... | ... | @@ -915,30 +915,28 @@ pub const Scope = struct { |
| 915 | 915 | |
| 916 | 916 | log.debug("deleteAllDecls {*}", .{ns}); |
| 917 | 917 | |
| 918 | | while (ns.decls.count() != 0) { |
| 919 | | const last_entry = ns.decls.entries.items[ns.decls.entries.items.len - 1]; |
| 920 | | const child_decl = last_entry.value; |
| 921 | | try mod.deleteDecl(child_decl, outdated_decls); |
| 922 | | } |
| 923 | | ns.decls.deinit(gpa); |
| 918 | var decls = ns.decls; |
| 924 | 919 | ns.decls = .{}; |
| 925 | 920 | |
| 926 | | while (ns.anon_decls.count() != 0) { |
| 927 | | const last_entry = ns.anon_decls.entries.items[ns.anon_decls.entries.items.len - 1]; |
| 928 | | const child_decl = last_entry.key; |
| 929 | | try mod.deleteDecl(child_decl, outdated_decls); |
| 930 | | } |
| 931 | | ns.anon_decls.deinit(gpa); |
| 921 | var anon_decls = ns.anon_decls; |
| 932 | 922 | ns.anon_decls = .{}; |
| 933 | | } |
| 934 | 923 | |
| 935 | | pub fn removeDecl(ns: *Namespace, child: *Decl) void { |
| 936 | | if (child.zir_decl_index == 0) { |
| 937 | | _ = ns.anon_decls.swapRemove(child); |
| 938 | | } else { |
| 939 | | // Preserve declaration order. |
| 940 | | _ = ns.decls.orderedRemove(mem.spanZ(child.name)); |
| 924 | // TODO rework this code to not panic on OOM. |
| 925 | // (might want to coordinate with the clearDecl function) |
| 926 | |
| 927 | for (decls.items()) |entry| { |
| 928 | const child_decl = entry.value; |
| 929 | mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); |
| 930 | child_decl.destroy(mod); |
| 931 | } |
| 932 | decls.deinit(gpa); |
| 933 | |
| 934 | for (anon_decls.items()) |entry| { |
| 935 | const child_decl = entry.key; |
| 936 | mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); |
| 937 | child_decl.destroy(mod); |
| 941 | 938 | } |
| 939 | anon_decls.deinit(gpa); |
| 942 | 940 | } |
| 943 | 941 | |
| 944 | 942 | // This renders e.g. "std.fs.Dir.OpenOptions" |
| ... | ... | @@ -2122,6 +2120,14 @@ pub const InnerError = error{ OutOfMemory, AnalysisFail }; |
| 2122 | 2120 | pub fn deinit(mod: *Module) void { |
| 2123 | 2121 | const gpa = mod.gpa; |
| 2124 | 2122 | |
| 2123 | for (mod.import_table.items()) |entry| { |
| 2124 | gpa.free(entry.key); |
| 2125 | entry.value.destroy(mod); |
| 2126 | } |
| 2127 | mod.import_table.deinit(gpa); |
| 2128 | |
| 2129 | mod.deletion_set.deinit(gpa); |
| 2130 | |
| 2125 | 2131 | // The callsite of `Compilation.create` owns the `root_pkg`, however |
| 2126 | 2132 | // Module owns the builtin and std packages that it adds. |
| 2127 | 2133 | if (mod.root_pkg.table.remove("builtin")) |entry| { |
| ... | ... | @@ -2142,8 +2148,6 @@ pub fn deinit(mod: *Module) void { |
| 2142 | 2148 | mod.local_zir_cache.handle.close(); |
| 2143 | 2149 | mod.global_zir_cache.handle.close(); |
| 2144 | 2150 | |
| 2145 | | mod.deletion_set.deinit(gpa); |
| 2146 | | |
| 2147 | 2151 | for (mod.failed_decls.items()) |entry| { |
| 2148 | 2152 | entry.value.destroy(gpa); |
| 2149 | 2153 | } |
| ... | ... | @@ -2188,12 +2192,6 @@ pub fn deinit(mod: *Module) void { |
| 2188 | 2192 | mod.global_error_set.deinit(gpa); |
| 2189 | 2193 | |
| 2190 | 2194 | mod.error_name_list.deinit(gpa); |
| 2191 | | |
| 2192 | | for (mod.import_table.items()) |entry| { |
| 2193 | | gpa.free(entry.key); |
| 2194 | | entry.value.destroy(mod); |
| 2195 | | } |
| 2196 | | mod.import_table.deinit(gpa); |
| 2197 | 2195 | } |
| 2198 | 2196 | |
| 2199 | 2197 | fn freeExportList(gpa: *Allocator, export_list: []*Export) void { |
| ... | ... | @@ -3420,7 +3418,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo |
| 3420 | 3418 | } |
| 3421 | 3419 | } |
| 3422 | 3420 | |
| 3423 | | pub fn deleteDecl( |
| 3421 | /// Make it as if the semantic analysis for this Decl never happened. |
| 3422 | pub fn clearDecl( |
| 3424 | 3423 | mod: *Module, |
| 3425 | 3424 | decl: *Decl, |
| 3426 | 3425 | outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), |
| ... | ... | @@ -3428,7 +3427,7 @@ pub fn deleteDecl( |
| 3428 | 3427 | const tracy = trace(@src()); |
| 3429 | 3428 | defer tracy.end(); |
| 3430 | 3429 | |
| 3431 | | log.debug("deleting {*} ({s})", .{ decl, decl.name }); |
| 3430 | log.debug("clearing {*} ({s})", .{ decl, decl.name }); |
| 3432 | 3431 | |
| 3433 | 3432 | const gpa = mod.gpa; |
| 3434 | 3433 | try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count()); |
| ... | ... | @@ -3438,10 +3437,7 @@ pub fn deleteDecl( |
| 3438 | 3437 | try map.ensureUnusedCapacity(decl.dependants.count()); |
| 3439 | 3438 | } |
| 3440 | 3439 | |
| 3441 | | // Remove from the namespace it resides in. |
| 3442 | | decl.namespace.removeDecl(decl); |
| 3443 | | |
| 3444 | | // Remove itself from its dependencies, because we are about to destroy the decl pointer. |
| 3440 | // Remove itself from its dependencies. |
| 3445 | 3441 | for (decl.dependencies.items()) |entry| { |
| 3446 | 3442 | const dep = entry.key; |
| 3447 | 3443 | dep.removeDependant(decl); |
| ... | ... | @@ -3452,6 +3448,8 @@ pub fn deleteDecl( |
| 3452 | 3448 | mod.deletion_set.putAssumeCapacity(dep, {}); |
| 3453 | 3449 | } |
| 3454 | 3450 | } |
| 3451 | decl.dependencies.clearRetainingCapacity(); |
| 3452 | |
| 3455 | 3453 | // Anything that depends on this deleted decl needs to be re-analyzed. |
| 3456 | 3454 | for (decl.dependants.items()) |entry| { |
| 3457 | 3455 | const dep = entry.key; |
| ... | ... | @@ -3467,6 +3465,8 @@ pub fn deleteDecl( |
| 3467 | 3465 | assert(mod.deletion_set.contains(dep)); |
| 3468 | 3466 | } |
| 3469 | 3467 | } |
| 3468 | decl.dependants.clearRetainingCapacity(); |
| 3469 | |
| 3470 | 3470 | if (mod.failed_decls.swapRemove(decl)) |entry| { |
| 3471 | 3471 | entry.value.destroy(gpa); |
| 3472 | 3472 | } |
| ... | ... | @@ -3482,6 +3482,25 @@ pub fn deleteDecl( |
| 3482 | 3482 | if (decl.has_tv) { |
| 3483 | 3483 | if (decl.ty.hasCodeGenBits()) { |
| 3484 | 3484 | mod.comp.bin_file.freeDecl(decl); |
| 3485 | |
| 3486 | // TODO instead of a union, put this memory trailing Decl objects, |
| 3487 | // and allow it to be variably sized. |
| 3488 | decl.link = switch (mod.comp.bin_file.tag) { |
| 3489 | .coff => .{ .coff = link.File.Coff.TextBlock.empty }, |
| 3490 | .elf => .{ .elf = link.File.Elf.TextBlock.empty }, |
| 3491 | .macho => .{ .macho = link.File.MachO.TextBlock.empty }, |
| 3492 | .c => .{ .c = link.File.C.DeclBlock.empty }, |
| 3493 | .wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty }, |
| 3494 | .spirv => .{ .spirv = {} }, |
| 3495 | }; |
| 3496 | decl.fn_link = switch (mod.comp.bin_file.tag) { |
| 3497 | .coff => .{ .coff = {} }, |
| 3498 | .elf => .{ .elf = link.File.Elf.SrcFn.empty }, |
| 3499 | .macho => .{ .macho = link.File.MachO.SrcFn.empty }, |
| 3500 | .c => .{ .c = link.File.C.FnBlock.empty }, |
| 3501 | .wasm => .{ .wasm = link.File.Wasm.FnData.empty }, |
| 3502 | .spirv => .{ .spirv = .{} }, |
| 3503 | }; |
| 3485 | 3504 | } |
| 3486 | 3505 | if (decl.getInnerNamespace()) |namespace| { |
| 3487 | 3506 | try namespace.deleteAllDecls(mod, outdated_decls); |
| ... | ... | @@ -3489,7 +3508,12 @@ pub fn deleteDecl( |
| 3489 | 3508 | decl.clearValues(gpa); |
| 3490 | 3509 | } |
| 3491 | 3510 | |
| 3492 | | decl.destroy(mod); |
| 3511 | if (decl.deletion_flag) { |
| 3512 | decl.deletion_flag = false; |
| 3513 | mod.deletion_set.swapRemoveAssertDiscard(decl); |
| 3514 | } |
| 3515 | |
| 3516 | decl.analysis = .unreferenced; |
| 3493 | 3517 | } |
| 3494 | 3518 | |
| 3495 | 3519 | /// Delete all the Export objects that are caused by this Decl. Re-analysis of |
| ... | ... | @@ -4836,7 +4860,13 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { |
| 4836 | 4860 | // deletion set at this time. |
| 4837 | 4861 | for (file.deleted_decls.items) |decl| { |
| 4838 | 4862 | log.debug("deleted from source: {*} ({s})", .{ decl, decl.name }); |
| 4839 | | try mod.deleteDecl(decl, &outdated_decls); |
| 4863 | |
| 4864 | // Remove from the namespace it resides in, preserving declaration order. |
| 4865 | assert(decl.zir_decl_index != 0); |
| 4866 | _ = decl.namespace.decls.orderedRemove(mem.spanZ(decl.name)); |
| 4867 | |
| 4868 | try mod.clearDecl(decl, &outdated_decls); |
| 4869 | decl.destroy(mod); |
| 4840 | 4870 | } |
| 4841 | 4871 | file.deleted_decls.clearRetainingCapacity(); |
| 4842 | 4872 | } |