| ... | ... | @@ -283,7 +283,9 @@ pub const Decl = struct { |
| 283 | 283 | pub fn destroy(decl: *Decl, module: *Module) void { |
| 284 | 284 | const gpa = module.gpa; |
| 285 | 285 | log.debug("destroy {*} ({s})", .{ decl, decl.name }); |
| 286 | | decl.clearName(gpa); |
| 286 | if (decl.deletion_flag) { |
| 287 | module.deletion_set.swapRemoveAssertDiscard(decl); |
| 288 | } |
| 287 | 289 | if (decl.has_tv) { |
| 288 | 290 | if (decl.getInnerNamespace()) |namespace| { |
| 289 | 291 | namespace.clearDecls(module); |
| ... | ... | @@ -292,6 +294,7 @@ pub const Decl = struct { |
| 292 | 294 | } |
| 293 | 295 | decl.dependants.deinit(gpa); |
| 294 | 296 | decl.dependencies.deinit(gpa); |
| 297 | decl.clearName(gpa); |
| 295 | 298 | if (module.emit_h != null) { |
| 296 | 299 | const decl_plus_emit_h = @fieldParentPtr(DeclPlusEmitH, "decl", decl); |
| 297 | 300 | decl_plus_emit_h.emit_h.fwd_decl.deinit(gpa); |
| ... | ... | @@ -546,28 +549,6 @@ pub const Decl = struct { |
| 546 | 549 | fn removeDependency(decl: *Decl, other: *Decl) void { |
| 547 | 550 | decl.dependencies.removeAssertDiscard(other); |
| 548 | 551 | } |
| 549 | | |
| 550 | | fn hasLinkAllocation(decl: Decl) bool { |
| 551 | | return switch (decl.analysis) { |
| 552 | | .unreferenced, |
| 553 | | .in_progress, |
| 554 | | .dependency_failure, |
| 555 | | .file_failure, |
| 556 | | .sema_failure, |
| 557 | | .sema_failure_retryable, |
| 558 | | .codegen_failure, |
| 559 | | .codegen_failure_retryable, |
| 560 | | => false, |
| 561 | | |
| 562 | | .complete, |
| 563 | | .outdated, |
| 564 | | => { |
| 565 | | if (!decl.owns_tv) |
| 566 | | return false; |
| 567 | | return decl.ty.hasCodeGenBits(); |
| 568 | | }, |
| 569 | | }; |
| 570 | | } |
| 571 | 552 | }; |
| 572 | 553 | |
| 573 | 554 | /// This state is attached to every Decl when Module emit_h is non-null. |
| ... | ... | @@ -929,6 +910,32 @@ pub const Scope = struct { |
| 929 | 910 | anon_decls.deinit(gpa); |
| 930 | 911 | } |
| 931 | 912 | |
| 913 | pub fn deleteAllDecls( |
| 914 | ns: *Namespace, |
| 915 | mod: *Module, |
| 916 | outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), |
| 917 | ) !void { |
| 918 | const gpa = mod.gpa; |
| 919 | |
| 920 | log.debug("deleteAllDecls {*}", .{ns}); |
| 921 | |
| 922 | while (ns.decls.count() != 0) { |
| 923 | const last_entry = ns.decls.entries.items[ns.decls.entries.items.len - 1]; |
| 924 | const child_decl = last_entry.value; |
| 925 | try mod.deleteDecl(child_decl, outdated_decls); |
| 926 | } |
| 927 | ns.decls.deinit(gpa); |
| 928 | ns.decls = .{}; |
| 929 | |
| 930 | while (ns.anon_decls.count() != 0) { |
| 931 | const last_entry = ns.anon_decls.entries.items[ns.anon_decls.entries.items.len - 1]; |
| 932 | const child_decl = last_entry.key; |
| 933 | try mod.deleteDecl(child_decl, outdated_decls); |
| 934 | } |
| 935 | ns.anon_decls.deinit(gpa); |
| 936 | ns.anon_decls = .{}; |
| 937 | } |
| 938 | |
| 932 | 939 | pub fn removeDecl(ns: *Namespace, child: *Decl) void { |
| 933 | 940 | if (child.zir_decl_index == 0) { |
| 934 | 941 | _ = ns.anon_decls.swapRemove(child); |
| ... | ... | @@ -2646,7 +2653,7 @@ fn updateZirRefs(gpa: *Allocator, file: *Scope.File, old_zir: Zir) !void { |
| 2646 | 2653 | } |
| 2647 | 2654 | } |
| 2648 | 2655 | |
| 2649 | | if (!decl.has_tv) continue; |
| 2656 | if (!decl.owns_tv) continue; |
| 2650 | 2657 | |
| 2651 | 2658 | if (decl.getStruct()) |struct_obj| { |
| 2652 | 2659 | struct_obj.zir_index = inst_map.get(struct_obj.zir_index) orelse { |
| ... | ... | @@ -3401,17 +3408,19 @@ pub fn deleteDecl( |
| 3401 | 3408 | mod: *Module, |
| 3402 | 3409 | decl: *Decl, |
| 3403 | 3410 | outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), |
| 3404 | | ) !void { |
| 3411 | ) Allocator.Error!void { |
| 3405 | 3412 | const tracy = trace(@src()); |
| 3406 | 3413 | defer tracy.end(); |
| 3407 | 3414 | |
| 3408 | 3415 | log.debug("deleting {*} ({s})", .{ decl, decl.name }); |
| 3409 | 3416 | |
| 3417 | const gpa = mod.gpa; |
| 3418 | try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count()); |
| 3419 | |
| 3410 | 3420 | if (outdated_decls) |map| { |
| 3411 | 3421 | _ = map.swapRemove(decl); |
| 3412 | 3422 | try map.ensureUnusedCapacity(decl.dependants.count()); |
| 3413 | 3423 | } |
| 3414 | | try mod.deletion_set.ensureUnusedCapacity(mod.gpa, decl.dependencies.count()); |
| 3415 | 3424 | |
| 3416 | 3425 | // Remove from the namespace it resides in. |
| 3417 | 3426 | decl.namespace.removeDecl(decl); |
| ... | ... | @@ -3443,18 +3452,23 @@ pub fn deleteDecl( |
| 3443 | 3452 | } |
| 3444 | 3453 | } |
| 3445 | 3454 | if (mod.failed_decls.swapRemove(decl)) |entry| { |
| 3446 | | entry.value.destroy(mod.gpa); |
| 3455 | entry.value.destroy(gpa); |
| 3447 | 3456 | } |
| 3448 | 3457 | if (mod.emit_h) |emit_h| { |
| 3449 | 3458 | if (emit_h.failed_decls.swapRemove(decl)) |entry| { |
| 3450 | | entry.value.destroy(mod.gpa); |
| 3459 | entry.value.destroy(gpa); |
| 3451 | 3460 | } |
| 3452 | 3461 | emit_h.decl_table.removeAssertDiscard(decl); |
| 3453 | 3462 | } |
| 3454 | 3463 | _ = mod.compile_log_decls.swapRemove(decl); |
| 3455 | 3464 | mod.deleteDeclExports(decl); |
| 3456 | | if (decl.hasLinkAllocation()) { |
| 3457 | | mod.comp.bin_file.freeDecl(decl); |
| 3465 | mod.comp.bin_file.freeDecl(decl); |
| 3466 | |
| 3467 | if (decl.has_tv) { |
| 3468 | if (decl.getInnerNamespace()) |namespace| { |
| 3469 | try namespace.deleteAllDecls(mod, outdated_decls); |
| 3470 | } |
| 3471 | decl.clearValues(gpa); |
| 3458 | 3472 | } |
| 3459 | 3473 | |
| 3460 | 3474 | decl.destroy(mod); |
| ... | ... | @@ -3827,6 +3841,12 @@ pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, b |
| 3827 | 3841 | } |
| 3828 | 3842 | } |
| 3829 | 3843 | |
| 3844 | pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void { |
| 3845 | const scope_decl = scope.ownerDecl().?; |
| 3846 | scope_decl.namespace.anon_decls.swapRemoveAssertDiscard(decl); |
| 3847 | decl.destroy(mod); |
| 3848 | } |
| 3849 | |
| 3830 | 3850 | /// Takes ownership of `name` even if it returns an error. |
| 3831 | 3851 | pub fn createAnonymousDeclNamed( |
| 3832 | 3852 | mod: *Module, |
| ... | ... | @@ -4814,6 +4834,8 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { |
| 4814 | 4834 | for (file.outdated_decls.items) |decl| { |
| 4815 | 4835 | outdated_decls.putAssumeCapacity(decl, {}); |
| 4816 | 4836 | } |
| 4837 | file.outdated_decls.clearRetainingCapacity(); |
| 4838 | |
| 4817 | 4839 | // Handle explicitly deleted decls from the source code. This is one of two |
| 4818 | 4840 | // places that Decl deletions happen. The other is in `Compilation`, after |
| 4819 | 4841 | // `performAllTheWork`, where we iterate over `Module.deletion_set` and |
| ... | ... | @@ -4824,12 +4846,9 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { |
| 4824 | 4846 | // deletion set at this time. |
| 4825 | 4847 | for (file.deleted_decls.items) |decl| { |
| 4826 | 4848 | log.debug("deleted from source: {*} ({s})", .{ decl, decl.name }); |
| 4827 | | if (decl.deletion_flag) { |
| 4828 | | log.debug("{*} ({s}) redundantly in deletion set; removing", .{ decl, decl.name }); |
| 4829 | | mod.deletion_set.removeAssertDiscard(decl); |
| 4830 | | } |
| 4831 | 4849 | try mod.deleteDecl(decl, &outdated_decls); |
| 4832 | 4850 | } |
| 4851 | file.deleted_decls.clearRetainingCapacity(); |
| 4833 | 4852 | } |
| 4834 | 4853 | // Finally we can queue up re-analysis tasks after we have processed |
| 4835 | 4854 | // the deleted decls. |