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