| ... | ... | @@ -3615,145 +3615,155 @@ pub const DeclIterator = struct { |
| 3615 | 3615 | }; |
| 3616 | 3616 | |
| 3617 | 3617 | pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator { |
| 3618 | | const tags = zir.instructions.items(.tag); |
| 3619 | | const datas = zir.instructions.items(.data); |
| 3620 | | switch (tags[@intFromEnum(decl_inst)]) { |
| 3621 | | // Functions are allowed and yield no iterations. |
| 3622 | | // This is because they are returned by `findDecls`. |
| 3623 | | .func, .func_inferred, .func_fancy => return .{ |
| 3624 | | .extra_index = undefined, |
| 3625 | | .decls_remaining = 0, |
| 3626 | | .zir = zir, |
| 3627 | | }, |
| 3628 | | |
| 3629 | | .extended => { |
| 3630 | | const extended = datas[@intFromEnum(decl_inst)].extended; |
| 3631 | | switch (extended.opcode) { |
| 3632 | | // Reifications are allowed and yield no iterations. |
| 3633 | | // This is because they are returned by `findDecls`. |
| 3634 | | .reify => return .{ |
| 3635 | | .extra_index = undefined, |
| 3636 | | .decls_remaining = 0, |
| 3637 | | .zir = zir, |
| 3638 | | }, |
| 3639 | | .struct_decl => { |
| 3640 | | const small: Inst.StructDecl.Small = @bitCast(extended.small); |
| 3641 | | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.StructDecl).@"struct".fields.len); |
| 3642 | | const captures_len = if (small.has_captures_len) captures_len: { |
| 3643 | | const captures_len = zir.extra[extra_index]; |
| 3644 | | extra_index += 1; |
| 3645 | | break :captures_len captures_len; |
| 3646 | | } else 0; |
| 3647 | | extra_index += @intFromBool(small.has_fields_len); |
| 3648 | | const decls_len = if (small.has_decls_len) decls_len: { |
| 3649 | | const decls_len = zir.extra[extra_index]; |
| 3650 | | extra_index += 1; |
| 3651 | | break :decls_len decls_len; |
| 3652 | | } else 0; |
| 3653 | | |
| 3654 | | extra_index += captures_len; |
| 3655 | | |
| 3656 | | if (small.has_backing_int) { |
| 3657 | | const backing_int_body_len = zir.extra[extra_index]; |
| 3658 | | extra_index += 1; // backing_int_body_len |
| 3659 | | if (backing_int_body_len == 0) { |
| 3660 | | extra_index += 1; // backing_int_ref |
| 3661 | | } else { |
| 3662 | | extra_index += backing_int_body_len; // backing_int_body_inst |
| 3663 | | } |
| 3664 | | } |
| 3618 | const inst = zir.instructions.get(@intFromEnum(decl_inst)); |
| 3619 | assert(inst.tag == .extended); |
| 3620 | const extended = inst.data.extended; |
| 3621 | switch (extended.opcode) { |
| 3622 | .struct_decl => { |
| 3623 | const small: Inst.StructDecl.Small = @bitCast(extended.small); |
| 3624 | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.StructDecl).@"struct".fields.len); |
| 3625 | const captures_len = if (small.has_captures_len) captures_len: { |
| 3626 | const captures_len = zir.extra[extra_index]; |
| 3627 | extra_index += 1; |
| 3628 | break :captures_len captures_len; |
| 3629 | } else 0; |
| 3630 | extra_index += @intFromBool(small.has_fields_len); |
| 3631 | const decls_len = if (small.has_decls_len) decls_len: { |
| 3632 | const decls_len = zir.extra[extra_index]; |
| 3633 | extra_index += 1; |
| 3634 | break :decls_len decls_len; |
| 3635 | } else 0; |
| 3636 | |
| 3637 | extra_index += captures_len; |
| 3638 | |
| 3639 | if (small.has_backing_int) { |
| 3640 | const backing_int_body_len = zir.extra[extra_index]; |
| 3641 | extra_index += 1; // backing_int_body_len |
| 3642 | if (backing_int_body_len == 0) { |
| 3643 | extra_index += 1; // backing_int_ref |
| 3644 | } else { |
| 3645 | extra_index += backing_int_body_len; // backing_int_body_inst |
| 3646 | } |
| 3647 | } |
| 3665 | 3648 | |
| 3666 | | return .{ |
| 3667 | | .extra_index = extra_index, |
| 3668 | | .decls_remaining = decls_len, |
| 3669 | | .zir = zir, |
| 3670 | | }; |
| 3671 | | }, |
| 3672 | | .enum_decl => { |
| 3673 | | const small: Inst.EnumDecl.Small = @bitCast(extended.small); |
| 3674 | | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.EnumDecl).@"struct".fields.len); |
| 3675 | | extra_index += @intFromBool(small.has_tag_type); |
| 3676 | | const captures_len = if (small.has_captures_len) captures_len: { |
| 3677 | | const captures_len = zir.extra[extra_index]; |
| 3678 | | extra_index += 1; |
| 3679 | | break :captures_len captures_len; |
| 3680 | | } else 0; |
| 3681 | | extra_index += @intFromBool(small.has_body_len); |
| 3682 | | extra_index += @intFromBool(small.has_fields_len); |
| 3683 | | const decls_len = if (small.has_decls_len) decls_len: { |
| 3684 | | const decls_len = zir.extra[extra_index]; |
| 3685 | | extra_index += 1; |
| 3686 | | break :decls_len decls_len; |
| 3687 | | } else 0; |
| 3649 | return .{ |
| 3650 | .extra_index = extra_index, |
| 3651 | .decls_remaining = decls_len, |
| 3652 | .zir = zir, |
| 3653 | }; |
| 3654 | }, |
| 3655 | .enum_decl => { |
| 3656 | const small: Inst.EnumDecl.Small = @bitCast(extended.small); |
| 3657 | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.EnumDecl).@"struct".fields.len); |
| 3658 | extra_index += @intFromBool(small.has_tag_type); |
| 3659 | const captures_len = if (small.has_captures_len) captures_len: { |
| 3660 | const captures_len = zir.extra[extra_index]; |
| 3661 | extra_index += 1; |
| 3662 | break :captures_len captures_len; |
| 3663 | } else 0; |
| 3664 | extra_index += @intFromBool(small.has_body_len); |
| 3665 | extra_index += @intFromBool(small.has_fields_len); |
| 3666 | const decls_len = if (small.has_decls_len) decls_len: { |
| 3667 | const decls_len = zir.extra[extra_index]; |
| 3668 | extra_index += 1; |
| 3669 | break :decls_len decls_len; |
| 3670 | } else 0; |
| 3688 | 3671 | |
| 3689 | | extra_index += captures_len; |
| 3672 | extra_index += captures_len; |
| 3690 | 3673 | |
| 3691 | | return .{ |
| 3692 | | .extra_index = extra_index, |
| 3693 | | .decls_remaining = decls_len, |
| 3694 | | .zir = zir, |
| 3695 | | }; |
| 3696 | | }, |
| 3697 | | .union_decl => { |
| 3698 | | const small: Inst.UnionDecl.Small = @bitCast(extended.small); |
| 3699 | | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.UnionDecl).@"struct".fields.len); |
| 3700 | | extra_index += @intFromBool(small.has_tag_type); |
| 3701 | | const captures_len = if (small.has_captures_len) captures_len: { |
| 3702 | | const captures_len = zir.extra[extra_index]; |
| 3703 | | extra_index += 1; |
| 3704 | | break :captures_len captures_len; |
| 3705 | | } else 0; |
| 3706 | | extra_index += @intFromBool(small.has_body_len); |
| 3707 | | extra_index += @intFromBool(small.has_fields_len); |
| 3708 | | const decls_len = if (small.has_decls_len) decls_len: { |
| 3709 | | const decls_len = zir.extra[extra_index]; |
| 3710 | | extra_index += 1; |
| 3711 | | break :decls_len decls_len; |
| 3712 | | } else 0; |
| 3674 | return .{ |
| 3675 | .extra_index = extra_index, |
| 3676 | .decls_remaining = decls_len, |
| 3677 | .zir = zir, |
| 3678 | }; |
| 3679 | }, |
| 3680 | .union_decl => { |
| 3681 | const small: Inst.UnionDecl.Small = @bitCast(extended.small); |
| 3682 | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.UnionDecl).@"struct".fields.len); |
| 3683 | extra_index += @intFromBool(small.has_tag_type); |
| 3684 | const captures_len = if (small.has_captures_len) captures_len: { |
| 3685 | const captures_len = zir.extra[extra_index]; |
| 3686 | extra_index += 1; |
| 3687 | break :captures_len captures_len; |
| 3688 | } else 0; |
| 3689 | extra_index += @intFromBool(small.has_body_len); |
| 3690 | extra_index += @intFromBool(small.has_fields_len); |
| 3691 | const decls_len = if (small.has_decls_len) decls_len: { |
| 3692 | const decls_len = zir.extra[extra_index]; |
| 3693 | extra_index += 1; |
| 3694 | break :decls_len decls_len; |
| 3695 | } else 0; |
| 3713 | 3696 | |
| 3714 | | extra_index += captures_len; |
| 3697 | extra_index += captures_len; |
| 3715 | 3698 | |
| 3716 | | return .{ |
| 3717 | | .extra_index = extra_index, |
| 3718 | | .decls_remaining = decls_len, |
| 3719 | | .zir = zir, |
| 3720 | | }; |
| 3721 | | }, |
| 3722 | | .opaque_decl => { |
| 3723 | | const small: Inst.OpaqueDecl.Small = @bitCast(extended.small); |
| 3724 | | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.OpaqueDecl).@"struct".fields.len); |
| 3725 | | const decls_len = if (small.has_decls_len) decls_len: { |
| 3726 | | const decls_len = zir.extra[extra_index]; |
| 3727 | | extra_index += 1; |
| 3728 | | break :decls_len decls_len; |
| 3729 | | } else 0; |
| 3730 | | const captures_len = if (small.has_captures_len) captures_len: { |
| 3731 | | const captures_len = zir.extra[extra_index]; |
| 3732 | | extra_index += 1; |
| 3733 | | break :captures_len captures_len; |
| 3734 | | } else 0; |
| 3699 | return .{ |
| 3700 | .extra_index = extra_index, |
| 3701 | .decls_remaining = decls_len, |
| 3702 | .zir = zir, |
| 3703 | }; |
| 3704 | }, |
| 3705 | .opaque_decl => { |
| 3706 | const small: Inst.OpaqueDecl.Small = @bitCast(extended.small); |
| 3707 | var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.OpaqueDecl).@"struct".fields.len); |
| 3708 | const decls_len = if (small.has_decls_len) decls_len: { |
| 3709 | const decls_len = zir.extra[extra_index]; |
| 3710 | extra_index += 1; |
| 3711 | break :decls_len decls_len; |
| 3712 | } else 0; |
| 3713 | const captures_len = if (small.has_captures_len) captures_len: { |
| 3714 | const captures_len = zir.extra[extra_index]; |
| 3715 | extra_index += 1; |
| 3716 | break :captures_len captures_len; |
| 3717 | } else 0; |
| 3735 | 3718 | |
| 3736 | | extra_index += captures_len; |
| 3719 | extra_index += captures_len; |
| 3737 | 3720 | |
| 3738 | | return .{ |
| 3739 | | .extra_index = extra_index, |
| 3740 | | .decls_remaining = decls_len, |
| 3741 | | .zir = zir, |
| 3742 | | }; |
| 3743 | | }, |
| 3744 | | else => unreachable, |
| 3745 | | } |
| 3721 | return .{ |
| 3722 | .extra_index = extra_index, |
| 3723 | .decls_remaining = decls_len, |
| 3724 | .zir = zir, |
| 3725 | }; |
| 3746 | 3726 | }, |
| 3747 | 3727 | else => unreachable, |
| 3748 | 3728 | } |
| 3749 | 3729 | } |
| 3750 | 3730 | |
| 3751 | | /// Find all type declarations, recursively, within a `declaration` instruction. Does not recurse through |
| 3752 | | /// said type declarations' declarations; to find all declarations, call this function on the declarations |
| 3753 | | /// of the discovered types recursively. |
| 3754 | | /// The iterator would have to allocate memory anyway to iterate, so an `ArrayList` is populated as the result. |
| 3755 | | pub fn findDecls(zir: Zir, gpa: Allocator, list: *std.ArrayListUnmanaged(Inst.Index), decl_inst: Zir.Inst.Index) !void { |
| 3756 | | list.clearRetainingCapacity(); |
| 3731 | /// `DeclContents` contains all "interesting" instructions found within a declaration by `findTrackable`. |
| 3732 | /// These instructions are partitioned into a few different sets, since this makes ZIR instruction mapping |
| 3733 | /// more effective. |
| 3734 | pub const DeclContents = struct { |
| 3735 | /// This is a simple optional because ZIR guarantees that a `func`/`func_inferred`/`func_fancy` instruction |
| 3736 | /// can only occur once per `declaration`. |
| 3737 | func_decl: ?Inst.Index, |
| 3738 | explicit_types: std.ArrayListUnmanaged(Inst.Index), |
| 3739 | other: std.ArrayListUnmanaged(Inst.Index), |
| 3740 | |
| 3741 | pub const init: DeclContents = .{ |
| 3742 | .func_decl = null, |
| 3743 | .explicit_types = .empty, |
| 3744 | .other = .empty, |
| 3745 | }; |
| 3746 | |
| 3747 | pub fn clear(contents: *DeclContents) void { |
| 3748 | contents.func_decl = null; |
| 3749 | contents.explicit_types.clearRetainingCapacity(); |
| 3750 | contents.other.clearRetainingCapacity(); |
| 3751 | } |
| 3752 | |
| 3753 | pub fn deinit(contents: *DeclContents, gpa: Allocator) void { |
| 3754 | contents.explicit_types.deinit(gpa); |
| 3755 | contents.other.deinit(gpa); |
| 3756 | } |
| 3757 | }; |
| 3758 | |
| 3759 | /// Find all tracked ZIR instructions, recursively, within a `declaration` instruction. Does not recurse through |
| 3760 | /// nested declarations; to find all declarations, call this function recursively on the type declarations discovered |
| 3761 | /// in `contents.explicit_types`. |
| 3762 | /// |
| 3763 | /// This populates an `ArrayListUnmanaged` because an iterator would need to allocate memory anyway. |
| 3764 | pub fn findTrackable(zir: Zir, gpa: Allocator, contents: *DeclContents, decl_inst: Zir.Inst.Index) !void { |
| 3765 | contents.clear(); |
| 3766 | |
| 3757 | 3767 | const declaration, const extra_end = zir.getDeclaration(decl_inst); |
| 3758 | 3768 | const bodies = declaration.getBodies(extra_end, zir); |
| 3759 | 3769 | |
| ... | ... | @@ -3762,27 +3772,27 @@ pub fn findDecls(zir: Zir, gpa: Allocator, list: *std.ArrayListUnmanaged(Inst.In |
| 3762 | 3772 | var found_defers: std.AutoHashMapUnmanaged(u32, void) = .empty; |
| 3763 | 3773 | defer found_defers.deinit(gpa); |
| 3764 | 3774 | |
| 3765 | | try zir.findDeclsBody(gpa, list, &found_defers, bodies.value_body); |
| 3766 | | if (bodies.align_body) |b| try zir.findDeclsBody(gpa, list, &found_defers, b); |
| 3767 | | if (bodies.linksection_body) |b| try zir.findDeclsBody(gpa, list, &found_defers, b); |
| 3768 | | if (bodies.addrspace_body) |b| try zir.findDeclsBody(gpa, list, &found_defers, b); |
| 3775 | try zir.findTrackableBody(gpa, contents, &found_defers, bodies.value_body); |
| 3776 | if (bodies.align_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b); |
| 3777 | if (bodies.linksection_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b); |
| 3778 | if (bodies.addrspace_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b); |
| 3769 | 3779 | } |
| 3770 | 3780 | |
| 3771 | | /// Like `findDecls`, but only considers the `main_struct_inst` instruction. This may return more than |
| 3781 | /// Like `findTrackable`, but only considers the `main_struct_inst` instruction. This may return more than |
| 3772 | 3782 | /// just that instruction because it will also traverse fields. |
| 3773 | | pub fn findDeclsRoot(zir: Zir, gpa: Allocator, list: *std.ArrayListUnmanaged(Inst.Index)) !void { |
| 3774 | | list.clearRetainingCapacity(); |
| 3783 | pub fn findTrackableRoot(zir: Zir, gpa: Allocator, contents: *DeclContents) !void { |
| 3784 | contents.clear(); |
| 3775 | 3785 | |
| 3776 | 3786 | var found_defers: std.AutoHashMapUnmanaged(u32, void) = .empty; |
| 3777 | 3787 | defer found_defers.deinit(gpa); |
| 3778 | 3788 | |
| 3779 | | try zir.findDeclsInner(gpa, list, &found_defers, .main_struct_inst); |
| 3789 | try zir.findTrackableInner(gpa, contents, &found_defers, .main_struct_inst); |
| 3780 | 3790 | } |
| 3781 | 3791 | |
| 3782 | | fn findDeclsInner( |
| 3792 | fn findTrackableInner( |
| 3783 | 3793 | zir: Zir, |
| 3784 | 3794 | gpa: Allocator, |
| 3785 | | list: *std.ArrayListUnmanaged(Inst.Index), |
| 3795 | contents: *DeclContents, |
| 3786 | 3796 | defers: *std.AutoHashMapUnmanaged(u32, void), |
| 3787 | 3797 | inst: Inst.Index, |
| 3788 | 3798 | ) Allocator.Error!void { |
| ... | ... | @@ -4026,7 +4036,7 @@ fn findDeclsInner( |
| 4026 | 4036 | .struct_init, |
| 4027 | 4037 | .struct_init_ref, |
| 4028 | 4038 | .struct_init_anon, |
| 4029 | | => return list.append(gpa, inst), |
| 4039 | => return contents.other.append(gpa, inst), |
| 4030 | 4040 | |
| 4031 | 4041 | .extended => { |
| 4032 | 4042 | const extended = datas[@intFromEnum(inst)].extended; |
| ... | ... | @@ -4093,15 +4103,15 @@ fn findDeclsInner( |
| 4093 | 4103 | .typeof_peer => { |
| 4094 | 4104 | const extra = zir.extraData(Zir.Inst.TypeOfPeer, extended.operand); |
| 4095 | 4105 | const body = zir.bodySlice(extra.data.body_index, extra.data.body_len); |
| 4096 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4106 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4097 | 4107 | }, |
| 4098 | 4108 | |
| 4099 | 4109 | // Reifications and opaque declarations need tracking, but have no body. |
| 4100 | | .reify, .opaque_decl => return list.append(gpa, inst), |
| 4110 | .reify, .opaque_decl => return contents.other.append(gpa, inst), |
| 4101 | 4111 | |
| 4102 | 4112 | // Struct declarations need tracking and have bodies. |
| 4103 | 4113 | .struct_decl => { |
| 4104 | | try list.append(gpa, inst); |
| 4114 | try contents.explicit_types.append(gpa, inst); |
| 4105 | 4115 | |
| 4106 | 4116 | const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); |
| 4107 | 4117 | const extra = zir.extraData(Zir.Inst.StructDecl, extended.operand); |
| ... | ... | @@ -4130,7 +4140,7 @@ fn findDeclsInner( |
| 4130 | 4140 | } else { |
| 4131 | 4141 | const body = zir.bodySlice(extra_index, backing_int_body_len); |
| 4132 | 4142 | extra_index += backing_int_body_len; |
| 4133 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4143 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4134 | 4144 | } |
| 4135 | 4145 | } |
| 4136 | 4146 | extra_index += decls_len; |
| ... | ... | @@ -4186,12 +4196,12 @@ fn findDeclsInner( |
| 4186 | 4196 | |
| 4187 | 4197 | // Now, `fields_extra_index` points to `bodies`. Let's treat this as one big body. |
| 4188 | 4198 | const merged_bodies = zir.bodySlice(fields_extra_index, total_bodies_len); |
| 4189 | | try zir.findDeclsBody(gpa, list, defers, merged_bodies); |
| 4199 | try zir.findTrackableBody(gpa, contents, defers, merged_bodies); |
| 4190 | 4200 | }, |
| 4191 | 4201 | |
| 4192 | 4202 | // Union declarations need tracking and have a body. |
| 4193 | 4203 | .union_decl => { |
| 4194 | | try list.append(gpa, inst); |
| 4204 | try contents.explicit_types.append(gpa, inst); |
| 4195 | 4205 | |
| 4196 | 4206 | const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small); |
| 4197 | 4207 | const extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand); |
| ... | ... | @@ -4216,12 +4226,12 @@ fn findDeclsInner( |
| 4216 | 4226 | extra_index += captures_len; |
| 4217 | 4227 | extra_index += decls_len; |
| 4218 | 4228 | const body = zir.bodySlice(extra_index, body_len); |
| 4219 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4229 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4220 | 4230 | }, |
| 4221 | 4231 | |
| 4222 | 4232 | // Enum declarations need tracking and have a body. |
| 4223 | 4233 | .enum_decl => { |
| 4224 | | try list.append(gpa, inst); |
| 4234 | try contents.explicit_types.append(gpa, inst); |
| 4225 | 4235 | |
| 4226 | 4236 | const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small); |
| 4227 | 4237 | const extra = zir.extraData(Zir.Inst.EnumDecl, extended.operand); |
| ... | ... | @@ -4246,7 +4256,7 @@ fn findDeclsInner( |
| 4246 | 4256 | extra_index += captures_len; |
| 4247 | 4257 | extra_index += decls_len; |
| 4248 | 4258 | const body = zir.bodySlice(extra_index, body_len); |
| 4249 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4259 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4250 | 4260 | }, |
| 4251 | 4261 | } |
| 4252 | 4262 | }, |
| ... | ... | @@ -4255,7 +4265,8 @@ fn findDeclsInner( |
| 4255 | 4265 | .func, |
| 4256 | 4266 | .func_inferred, |
| 4257 | 4267 | => { |
| 4258 | | try list.append(gpa, inst); |
| 4268 | assert(contents.func_decl == null); |
| 4269 | contents.func_decl = inst; |
| 4259 | 4270 | |
| 4260 | 4271 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 4261 | 4272 | const extra = zir.extraData(Inst.Func, inst_data.payload_index); |
| ... | ... | @@ -4266,14 +4277,15 @@ fn findDeclsInner( |
| 4266 | 4277 | else => { |
| 4267 | 4278 | const body = zir.bodySlice(extra_index, extra.data.ret_body_len); |
| 4268 | 4279 | extra_index += body.len; |
| 4269 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4280 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4270 | 4281 | }, |
| 4271 | 4282 | } |
| 4272 | 4283 | const body = zir.bodySlice(extra_index, extra.data.body_len); |
| 4273 | | return zir.findDeclsBody(gpa, list, defers, body); |
| 4284 | return zir.findTrackableBody(gpa, contents, defers, body); |
| 4274 | 4285 | }, |
| 4275 | 4286 | .func_fancy => { |
| 4276 | | try list.append(gpa, inst); |
| 4287 | assert(contents.func_decl == null); |
| 4288 | contents.func_decl = inst; |
| 4277 | 4289 | |
| 4278 | 4290 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 4279 | 4291 | const extra = zir.extraData(Inst.FuncFancy, inst_data.payload_index); |
| ... | ... | @@ -4284,7 +4296,7 @@ fn findDeclsInner( |
| 4284 | 4296 | const body_len = zir.extra[extra_index]; |
| 4285 | 4297 | extra_index += 1; |
| 4286 | 4298 | const body = zir.bodySlice(extra_index, body_len); |
| 4287 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4299 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4288 | 4300 | extra_index += body.len; |
| 4289 | 4301 | } else if (extra.data.bits.has_align_ref) { |
| 4290 | 4302 | extra_index += 1; |
| ... | ... | @@ -4294,7 +4306,7 @@ fn findDeclsInner( |
| 4294 | 4306 | const body_len = zir.extra[extra_index]; |
| 4295 | 4307 | extra_index += 1; |
| 4296 | 4308 | const body = zir.bodySlice(extra_index, body_len); |
| 4297 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4309 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4298 | 4310 | extra_index += body.len; |
| 4299 | 4311 | } else if (extra.data.bits.has_addrspace_ref) { |
| 4300 | 4312 | extra_index += 1; |
| ... | ... | @@ -4304,7 +4316,7 @@ fn findDeclsInner( |
| 4304 | 4316 | const body_len = zir.extra[extra_index]; |
| 4305 | 4317 | extra_index += 1; |
| 4306 | 4318 | const body = zir.bodySlice(extra_index, body_len); |
| 4307 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4319 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4308 | 4320 | extra_index += body.len; |
| 4309 | 4321 | } else if (extra.data.bits.has_section_ref) { |
| 4310 | 4322 | extra_index += 1; |
| ... | ... | @@ -4314,7 +4326,7 @@ fn findDeclsInner( |
| 4314 | 4326 | const body_len = zir.extra[extra_index]; |
| 4315 | 4327 | extra_index += 1; |
| 4316 | 4328 | const body = zir.bodySlice(extra_index, body_len); |
| 4317 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4329 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4318 | 4330 | extra_index += body.len; |
| 4319 | 4331 | } else if (extra.data.bits.has_cc_ref) { |
| 4320 | 4332 | extra_index += 1; |
| ... | ... | @@ -4324,7 +4336,7 @@ fn findDeclsInner( |
| 4324 | 4336 | const body_len = zir.extra[extra_index]; |
| 4325 | 4337 | extra_index += 1; |
| 4326 | 4338 | const body = zir.bodySlice(extra_index, body_len); |
| 4327 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4339 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4328 | 4340 | extra_index += body.len; |
| 4329 | 4341 | } else if (extra.data.bits.has_ret_ty_ref) { |
| 4330 | 4342 | extra_index += 1; |
| ... | ... | @@ -4333,7 +4345,7 @@ fn findDeclsInner( |
| 4333 | 4345 | extra_index += @intFromBool(extra.data.bits.has_any_noalias); |
| 4334 | 4346 | |
| 4335 | 4347 | const body = zir.bodySlice(extra_index, extra.data.body_len); |
| 4336 | | return zir.findDeclsBody(gpa, list, defers, body); |
| 4348 | return zir.findTrackableBody(gpa, contents, defers, body); |
| 4337 | 4349 | }, |
| 4338 | 4350 | |
| 4339 | 4351 | // Block instructions, recurse over the bodies. |
| ... | ... | @@ -4348,24 +4360,24 @@ fn findDeclsInner( |
| 4348 | 4360 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 4349 | 4361 | const extra = zir.extraData(Inst.Block, inst_data.payload_index); |
| 4350 | 4362 | const body = zir.bodySlice(extra.end, extra.data.body_len); |
| 4351 | | return zir.findDeclsBody(gpa, list, defers, body); |
| 4363 | return zir.findTrackableBody(gpa, contents, defers, body); |
| 4352 | 4364 | }, |
| 4353 | 4365 | .condbr, .condbr_inline => { |
| 4354 | 4366 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 4355 | 4367 | const extra = zir.extraData(Inst.CondBr, inst_data.payload_index); |
| 4356 | 4368 | const then_body = zir.bodySlice(extra.end, extra.data.then_body_len); |
| 4357 | 4369 | const else_body = zir.bodySlice(extra.end + then_body.len, extra.data.else_body_len); |
| 4358 | | try zir.findDeclsBody(gpa, list, defers, then_body); |
| 4359 | | try zir.findDeclsBody(gpa, list, defers, else_body); |
| 4370 | try zir.findTrackableBody(gpa, contents, defers, then_body); |
| 4371 | try zir.findTrackableBody(gpa, contents, defers, else_body); |
| 4360 | 4372 | }, |
| 4361 | 4373 | .@"try", .try_ptr => { |
| 4362 | 4374 | const inst_data = datas[@intFromEnum(inst)].pl_node; |
| 4363 | 4375 | const extra = zir.extraData(Inst.Try, inst_data.payload_index); |
| 4364 | 4376 | const body = zir.bodySlice(extra.end, extra.data.body_len); |
| 4365 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4377 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4366 | 4378 | }, |
| 4367 | | .switch_block, .switch_block_ref => return zir.findDeclsSwitch(gpa, list, defers, inst, .normal), |
| 4368 | | .switch_block_err_union => return zir.findDeclsSwitch(gpa, list, defers, inst, .err_union), |
| 4379 | .switch_block, .switch_block_ref => return zir.findTrackableSwitch(gpa, contents, defers, inst, .normal), |
| 4380 | .switch_block_err_union => return zir.findTrackableSwitch(gpa, contents, defers, inst, .err_union), |
| 4369 | 4381 | |
| 4370 | 4382 | .suspend_block => @panic("TODO iterate suspend block"), |
| 4371 | 4383 | |
| ... | ... | @@ -4373,7 +4385,7 @@ fn findDeclsInner( |
| 4373 | 4385 | const inst_data = datas[@intFromEnum(inst)].pl_tok; |
| 4374 | 4386 | const extra = zir.extraData(Inst.Param, inst_data.payload_index); |
| 4375 | 4387 | const body = zir.bodySlice(extra.end, extra.data.body_len); |
| 4376 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4388 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4377 | 4389 | }, |
| 4378 | 4390 | |
| 4379 | 4391 | inline .call, .field_call => |tag| { |
| ... | ... | @@ -4389,7 +4401,7 @@ fn findDeclsInner( |
| 4389 | 4401 | const first_arg_start_off = args_len; |
| 4390 | 4402 | const final_arg_end_off = zir.extra[extra.end + args_len - 1]; |
| 4391 | 4403 | const args_body = zir.bodySlice(extra.end + first_arg_start_off, final_arg_end_off - first_arg_start_off); |
| 4392 | | try zir.findDeclsBody(gpa, list, defers, args_body); |
| 4404 | try zir.findTrackableBody(gpa, contents, defers, args_body); |
| 4393 | 4405 | } |
| 4394 | 4406 | }, |
| 4395 | 4407 | .@"defer" => { |
| ... | ... | @@ -4397,7 +4409,7 @@ fn findDeclsInner( |
| 4397 | 4409 | const gop = try defers.getOrPut(gpa, inst_data.index); |
| 4398 | 4410 | if (!gop.found_existing) { |
| 4399 | 4411 | const body = zir.bodySlice(inst_data.index, inst_data.len); |
| 4400 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4412 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4401 | 4413 | } |
| 4402 | 4414 | }, |
| 4403 | 4415 | .defer_err_code => { |
| ... | ... | @@ -4406,16 +4418,16 @@ fn findDeclsInner( |
| 4406 | 4418 | const gop = try defers.getOrPut(gpa, extra.index); |
| 4407 | 4419 | if (!gop.found_existing) { |
| 4408 | 4420 | const body = zir.bodySlice(extra.index, extra.len); |
| 4409 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4421 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4410 | 4422 | } |
| 4411 | 4423 | }, |
| 4412 | 4424 | } |
| 4413 | 4425 | } |
| 4414 | 4426 | |
| 4415 | | fn findDeclsSwitch( |
| 4427 | fn findTrackableSwitch( |
| 4416 | 4428 | zir: Zir, |
| 4417 | 4429 | gpa: Allocator, |
| 4418 | | list: *std.ArrayListUnmanaged(Inst.Index), |
| 4430 | contents: *DeclContents, |
| 4419 | 4431 | defers: *std.AutoHashMapUnmanaged(u32, void), |
| 4420 | 4432 | inst: Inst.Index, |
| 4421 | 4433 | /// Distinguishes between `switch_block[_ref]` and `switch_block_err_union`. |
| ... | ... | @@ -4451,7 +4463,7 @@ fn findDeclsSwitch( |
| 4451 | 4463 | const body = zir.bodySlice(extra_index, prong_info.body_len); |
| 4452 | 4464 | extra_index += body.len; |
| 4453 | 4465 | |
| 4454 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4466 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4455 | 4467 | |
| 4456 | 4468 | break :has_special extra.data.bits.has_else; |
| 4457 | 4469 | }, |
| ... | ... | @@ -4463,7 +4475,7 @@ fn findDeclsSwitch( |
| 4463 | 4475 | const body = zir.bodySlice(extra_index, prong_info.body_len); |
| 4464 | 4476 | extra_index += body.len; |
| 4465 | 4477 | |
| 4466 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4478 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4467 | 4479 | } |
| 4468 | 4480 | |
| 4469 | 4481 | { |
| ... | ... | @@ -4475,7 +4487,7 @@ fn findDeclsSwitch( |
| 4475 | 4487 | const body = zir.bodySlice(extra_index, prong_info.body_len); |
| 4476 | 4488 | extra_index += body.len; |
| 4477 | 4489 | |
| 4478 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4490 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4479 | 4491 | } |
| 4480 | 4492 | } |
| 4481 | 4493 | { |
| ... | ... | @@ -4492,20 +4504,20 @@ fn findDeclsSwitch( |
| 4492 | 4504 | const body = zir.bodySlice(extra_index, prong_info.body_len); |
| 4493 | 4505 | extra_index += body.len; |
| 4494 | 4506 | |
| 4495 | | try zir.findDeclsBody(gpa, list, defers, body); |
| 4507 | try zir.findTrackableBody(gpa, contents, defers, body); |
| 4496 | 4508 | } |
| 4497 | 4509 | } |
| 4498 | 4510 | } |
| 4499 | 4511 | |
| 4500 | | fn findDeclsBody( |
| 4512 | fn findTrackableBody( |
| 4501 | 4513 | zir: Zir, |
| 4502 | 4514 | gpa: Allocator, |
| 4503 | | list: *std.ArrayListUnmanaged(Inst.Index), |
| 4515 | contents: *DeclContents, |
| 4504 | 4516 | defers: *std.AutoHashMapUnmanaged(u32, void), |
| 4505 | 4517 | body: []const Inst.Index, |
| 4506 | 4518 | ) Allocator.Error!void { |
| 4507 | 4519 | for (body) |member| { |
| 4508 | | try zir.findDeclsInner(gpa, list, defers, member); |
| 4520 | try zir.findTrackableInner(gpa, contents, defers, member); |
| 4509 | 4521 | } |
| 4510 | 4522 | } |
| 4511 | 4523 | |