Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

getSwitchBlock

Zir.getSwitchBlock
pub fn getSwitchBlock(zir: *const Zir, switch_inst: Inst.Index) UnwrappedSwitchBlock

File

lib/std/zig/Zir.zig:4972

Code

pub fn getSwitchBlock(zir: *const Zir, switch_inst: Inst.Index) UnwrappedSwitchBlock {
    const has_non_err = switch (zir.instructions.items(.tag)[@backingInt(switch_inst)]) {
        .switch_block, .switch_block_ref => false,
        .switch_block_err_union => true,
        else => unreachable,
    };
    const inst_data = zir.instructions.items(.data)[@backingInt(switch_inst)].pl_node;
    const extra = zir.extraData(Inst.SwitchBlock, inst_data.payload_index);
    const bits = extra.data.bits;
    var extra_index = extra.end;
    const multi_cases_len = if (bits.has_multi_cases) len: {
        const multi_cases_len = zir.extra[extra_index];
        extra_index += 1;
        break :len multi_cases_len;
    } else 0;
    const payload_capture_placeholder: Inst.OptionalIndex = if (bits.payload_capture_inst_is_placeholder) inst: {
        const inst: Inst.Index = @fromBackingInt(@intCast(zir.extra[extra_index]));
        extra_index += 1;
        break :inst inst.toOptional();
    } else .none;
    const tag_capture_placeholder: Inst.OptionalIndex = if (bits.tag_capture_inst_is_placeholder) inst: {
        const inst: Inst.Index = @fromBackingInt(@intCast(zir.extra[extra_index]));
        extra_index += 1;
        break :inst inst.toOptional();
    } else .none;
    const catch_or_if_src_node_offset: Ast.Node.OptionalOffset = if (has_non_err) node_offset: {
        const node_offset: Ast.Node.Offset = @fromBackingInt(@intCast(@as(i32, @bitCast(zir.extra[extra_index]))));
        extra_index += 1;
        break :node_offset node_offset.toOptional();
    } else .none;
    const non_err_info: Inst.SwitchBlock.ProngInfo.NonErr = if (has_non_err) non_err_info: {
        const non_err_info: Inst.SwitchBlock.ProngInfo.NonErr = @bitCast(zir.extra[extra_index]);
        extra_index += 1;
        break :non_err_info non_err_info;
    } else undefined;
    const else_info: Inst.SwitchBlock.ProngInfo.Else = if (bits.has_else) else_info: {
        const else_info: Inst.SwitchBlock.ProngInfo.Else = @bitCast(zir.extra[extra_index]);
        extra_index += 1;
        break :else_info else_info;
    } else undefined;
    const scalar_cases_len: u32 = bits.scalar_cases_len;
    const prong_infos: []const Inst.SwitchBlock.ProngInfo =
        @ptrCast(zir.extra[extra_index..][0 .. scalar_cases_len + multi_cases_len]);
    extra_index += prong_infos.len;
    const multi_case_items_lens = zir.extra[extra_index..][0..multi_cases_len];
    extra_index += multi_case_items_lens.len;
    const multi_case_ranges_lens: ?[]const u32 = if (bits.any_ranges) lens: {
        const multi_case_ranges_lens = zir.extra[extra_index..][0..multi_cases_len];
        extra_index += multi_case_ranges_lens.len;
        break :lens multi_case_ranges_lens;
    } else null;
    var total_items_len: usize = scalar_cases_len;
    for (multi_case_items_lens) |items_len| {
        total_items_len += items_len;
    }
    if (multi_case_ranges_lens) |ranges_lens| for (ranges_lens) |ranges_len| {
        total_items_len += 2 * ranges_len;
    };
    const item_infos: []const Inst.SwitchBlock.ItemInfo =
        @ptrCast(zir.extra[extra_index..][0..total_items_len]);
    extra_index += item_infos.len;
    const non_err_case: ?UnwrappedSwitchBlock.Case.NonErr = if (has_non_err) non_err_case: {
        const body = zir.bodySlice(extra_index, non_err_info.body_len);
        extra_index += body.len;
        break :non_err_case .{
            .body = body,
            .capture = non_err_info.capture,
            .operand_is_ref = non_err_info.operand_is_ref,
        };
    } else null;
    const else_case: ?UnwrappedSwitchBlock.Case.Else = if (bits.has_else) else_case: {
        const body = zir.bodySlice(extra_index, else_info.body_len);
        extra_index += body.len;
        break :else_case .{
            .index = .@"else",
            .body = body,
            .capture = else_info.capture,
            .is_inline = else_info.is_inline,
            .has_tag_capture = else_info.has_tag_capture,
            .is_simple_noreturn = else_info.is_simple_noreturn,
        };
    } else null;
    return .{
        .main_operand = extra.data.raw_operand,
        .switch_src_node_offset = inst_data.src_node,
        .catch_or_if_src_node_offset = catch_or_if_src_node_offset,
        .payload_capture_placeholder = payload_capture_placeholder,
        .tag_capture_placeholder = tag_capture_placeholder,
        .has_continue = bits.has_continue,
        .any_maybe_runtime_capture = bits.any_maybe_runtime_capture,
        .non_err_case = non_err_case,
        .else_case = else_case,
        .has_under = bits.has_under,
        .prong_infos = prong_infos,
        .multi_case_items_lens = multi_case_items_lens,
        .multi_case_ranges_lens = multi_case_ranges_lens,
        .item_infos = item_infos,
        .end = extra_index,
    };
}