findTrackable does not recurse into field expressions in a type. Instead, this function will
scan specifically field expressions in a given type declaration for trackable ZIR instructions.
pub fn findTrackableFields(
zir: *const Zir,
gpa: Allocator,
contents: *DeclContents,
type_decl_inst: Zir.Inst.Index,
) Allocator.Error!void
pub fn findTrackableFields(
zir: *const Zir,
gpa: Allocator,
contents: *DeclContents,
type_decl_inst: Zir.Inst.Index,
) Allocator.Error!void {
contents.clear();
var found_defers: std.AutoHashMapUnmanaged(u32, void) = .empty;
defer found_defers.deinit(gpa);
assert(zir.instructions.items(.tag)[@backingInt(type_decl_inst)] == .extended);
switch (zir.instructions.items(.data)[@backingInt(type_decl_inst)].extended.opcode) {
.struct_decl => {
const struct_decl = zir.getStructDecl(type_decl_inst);
var it = struct_decl.iterateFields();
while (it.next()) |field| {
try zir.findTrackableBody(gpa, contents, &found_defers, field.type_body);
if (field.align_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b);
if (field.default_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b);
}
},
.union_decl => {
const union_decl = zir.getUnionDecl(type_decl_inst);
var it = union_decl.iterateFields();
while (it.next()) |field| {
if (field.type_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b);
if (field.align_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b);
if (field.value_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b);
}
},
.enum_decl => {
const enum_decl = zir.getEnumDecl(type_decl_inst);
var it = enum_decl.iterateFields();
while (it.next()) |field| {
if (field.value_body) |b| try zir.findTrackableBody(gpa, contents, &found_defers, b);
}
},
.opaque_decl => {},
else => unreachable,
}
}