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.

setDeclaration

Sets all extra data for a declaration instruction. Unstacks type_gz, align_gz, linksection_gz, addrspace_gz, and value_gz.

AstGen.setDeclaration
fn setDeclaration(
    decl_inst: Zir.Inst.Index,
    args: struct

File

lib/std/zig/AstGen.zig:13393

Code

fn setDeclaration(
    decl_inst: Zir.Inst.Index,
    args: struct {
        src_hash: std.zig.SrcHash,
        src_line: u32,
        src_column: u32,

        kind: Zir.Inst.Declaration.Unwrapped.Kind,
        name: Zir.NullTerminatedString,
        is_pub: bool,
        is_threadlocal: bool,
        linkage: Zir.Inst.Declaration.Unwrapped.Linkage,
        lib_name: Zir.NullTerminatedString = .empty,

        type_gz: *GenZir,
        /// Must be stacked on `type_gz`.
        align_gz: *GenZir,
        /// Must be stacked on `align_gz`.
        linksection_gz: *GenZir,
        /// Must be stacked on `linksection_gz`.
        addrspace_gz: *GenZir,
        /// Must be stacked on `addrspace_gz` and have nothing stacked on top of it.
        value_gz: *GenZir,
    },
) !void {
    const astgen = args.value_gz.astgen;
    const gpa = astgen.gpa;

    const type_body = args.type_gz.instructionsSliceUpto(args.align_gz);
    const align_body = args.align_gz.instructionsSliceUpto(args.linksection_gz);
    const linksection_body = args.linksection_gz.instructionsSliceUpto(args.addrspace_gz);
    const addrspace_body = args.addrspace_gz.instructionsSliceUpto(args.value_gz);
    const value_body = args.value_gz.instructionsSlice();

    const has_name = args.name != .empty;
    const has_lib_name = args.lib_name != .empty;
    const has_type_body = type_body.len != 0;
    const has_special_body = align_body.len != 0 or linksection_body.len != 0 or addrspace_body.len != 0;
    const has_value_body = value_body.len != 0;

    const id: Zir.Inst.Declaration.Flags.Id = switch (args.kind) {
        .unnamed_test => .unnamed_test,
        .@"test" => .@"test",
        .decltest => .decltest,
        .@"comptime" => .@"comptime",
        .@"const" => switch (args.linkage) {
            .normal => if (args.is_pub) id: {
                if (has_special_body) break :id .pub_const;
                if (has_type_body) break :id .pub_const_typed;
                break :id .pub_const_simple;
            } else id: {
                if (has_special_body) break :id .@"const";
                if (has_type_body) break :id .const_typed;
                break :id .const_simple;
            },
            .@"extern" => if (args.is_pub) id: {
                if (has_lib_name) break :id .pub_extern_const;
                if (has_special_body) break :id .pub_extern_const;
                break :id .pub_extern_const_simple;
            } else id: {
                if (has_lib_name) break :id .extern_const;
                if (has_special_body) break :id .extern_const;
                break :id .extern_const_simple;
            },
            .@"export" => if (args.is_pub) .pub_export_const else .export_const,
        },
        .@"var" => switch (args.linkage) {
            .normal => if (args.is_pub) id: {
                if (args.is_threadlocal) break :id .pub_var_threadlocal;
                if (has_special_body) break :id .pub_var;
                if (has_type_body) break :id .pub_var;
                break :id .pub_var_simple;
            } else id: {
                if (args.is_threadlocal) break :id .var_threadlocal;
                if (has_special_body) break :id .@"var";
                if (has_type_body) break :id .@"var";
                break :id .var_simple;
            },
            .@"extern" => if (args.is_pub) id: {
                if (args.is_threadlocal) break :id .pub_extern_var_threadlocal;
                break :id .pub_extern_var;
            } else id: {
                if (args.is_threadlocal) break :id .extern_var_threadlocal;
                break :id .extern_var;
            },
            .@"export" => if (args.is_pub) id: {
                if (args.is_threadlocal) break :id .pub_export_var_threadlocal;
                break :id .pub_export_var;
            } else id: {
                if (args.is_threadlocal) break :id .export_var_threadlocal;
                break :id .export_var;
            },
        },
    };

    assert(id.hasTypeBody() or !has_type_body);
    assert(id.hasSpecialBodies() or !has_special_body);
    assert(id.hasValueBody() == has_value_body);
    assert(id.linkage() == args.linkage);
    assert(id.hasName() == has_name);
    assert(id.hasLibName() or !has_lib_name);
    assert(id.isPub() == args.is_pub);
    assert(id.isThreadlocal() == args.is_threadlocal);

    const type_len = astgen.countBodyLenAfterFixups(type_body);
    const align_len = astgen.countBodyLenAfterFixups(align_body);
    const linksection_len = astgen.countBodyLenAfterFixups(linksection_body);
    const addrspace_len = astgen.countBodyLenAfterFixups(addrspace_body);
    const value_len = astgen.countBodyLenAfterFixups(value_body);

    const src_hash_arr: [4]u32 = @bitCast(args.src_hash);
    const flags: Zir.Inst.Declaration.Flags = .{
        .src_line = @intCast(args.src_line),
        .src_column = @intCast(args.src_column),
        .id = id,
    };
    const flags_arr: [2]u32 = @bitCast(flags);

    const need_extra: usize =
        @typeInfo(Zir.Inst.Declaration).@"struct".field_names.len +
        @as(usize, @intFromBool(id.hasName())) +
        @as(usize, @intFromBool(id.hasLibName())) +
        @as(usize, @intFromBool(id.hasTypeBody())) +
        3 * @as(usize, @intFromBool(id.hasSpecialBodies())) +
        @as(usize, @intFromBool(id.hasValueBody())) +
        type_len + align_len + linksection_len + addrspace_len + value_len;

    try astgen.extra.ensureUnusedCapacity(gpa, need_extra);

    const extra: Zir.Inst.Declaration = .{
        .src_hash_0 = src_hash_arr[0],
        .src_hash_1 = src_hash_arr[1],
        .src_hash_2 = src_hash_arr[2],
        .src_hash_3 = src_hash_arr[3],
        .flags_0 = flags_arr[0],
        .flags_1 = flags_arr[1],
    };
    astgen.instructions.items(.data)[@backingInt(decl_inst)].declaration.payload_index =
        astgen.addExtraAssumeCapacity(extra);

    if (id.hasName()) {
        astgen.extra.appendAssumeCapacity(@backingInt(args.name));
    }
    if (id.hasLibName()) {
        astgen.extra.appendAssumeCapacity(@backingInt(args.lib_name));
    }
    if (id.hasTypeBody()) {
        astgen.extra.appendAssumeCapacity(type_len);
    }
    if (id.hasSpecialBodies()) {
        astgen.extra.appendSliceAssumeCapacity(&.{
            align_len,
            linksection_len,
            addrspace_len,
        });
    }
    if (id.hasValueBody()) {
        astgen.extra.appendAssumeCapacity(value_len);
    }

    astgen.appendBodyWithFixups(type_body);
    astgen.appendBodyWithFixups(align_body);
    astgen.appendBodyWithFixups(linksection_body);
    astgen.appendBodyWithFixups(addrspace_body);
    astgen.appendBodyWithFixups(value_body);

    args.value_gz.unstack();
    args.addrspace_gz.unstack();
    args.linksection_gz.unstack();
    args.align_gz.unstack();
    args.type_gz.unstack();
}