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.

transFnType

Translator.transFnType
fn transFnType(
    t: *Translator,
    scope: *Scope,
    func_qt: QualType,
    func_ty: aro.Type.Func,
    source_loc: TokenIndex,
    ctx: FnProtoContext,
) !ZigNode

File

lib/compiler/translate-c/Translator.zig:1439

Code

fn transFnType(
    t: *Translator,
    scope: *Scope,
    func_qt: QualType,
    func_ty: aro.Type.Func,
    source_loc: TokenIndex,
    ctx: FnProtoContext,
) !ZigNode {
    const param_count: usize = func_ty.params.len;
    const fn_params = try t.arena.alloc(ast.Payload.Param, param_count);

    for (func_ty.params, fn_params) |param_info, *param_node| {
        const param_qt = param_info.qt;
        const is_noalias = param_qt.restrict;

        const param_name: ?[]const u8 = if (param_info.name == .empty)
            null
        else
            param_info.name.lookup(t.comp);

        const type_node = try t.transType(scope, param_qt, param_info.name_tok);
        param_node.* = .{
            .is_noalias = is_noalias,
            .name = param_name,
            .type = type_node,
        };
    }

    const linksection_string = blk: {
        if (func_qt.getAttribute(t.comp, .section)) |section| {
            break :blk t.comp.interner.get(section.name.ref()).bytes;
        }
        break :blk null;
    };

    const alignment: ?c_uint = func_qt.requestedAlignment(t.comp) orelse null;

    const explicit_callconv = if ((ctx.is_always_inline or ctx.is_export or ctx.is_extern) and ctx.cc == .c) null else ctx.cc;

    const return_type_node = blk: {
        if (func_qt.getAttribute(t.comp, .noreturn) != null) {
            break :blk ZigTag.noreturn_type.init();
        } else {
            const return_qt = func_ty.return_type;
            if (return_qt.is(t.comp, .void)) {
                // convert primitive anyopaque to actual void (only for return type)
                break :blk ZigTag.void_type.init();
            } else {
                break :blk t.transType(scope, return_qt, source_loc) catch |err| switch (err) {
                    error.UnsupportedType => {
                        try t.warn(scope, source_loc, "unsupported function proto return type", .{});
                        return err;
                    },
                    error.OutOfMemory => |e| return e,
                };
            }
        }
    };

    // TODO actually set with @export/@extern
    const linkage = func_qt.linkage(t.comp);
    if (linkage != .strong) {
        try t.warn(scope, source_loc, "TODO {s} linkage ignored", .{@tagName(linkage)});
    }

    const payload = try t.arena.create(ast.Payload.Func);
    payload.* = .{
        .base = .{ .tag = .func },
        .data = .{
            .is_pub = ctx.is_pub,
            .is_extern = ctx.is_extern,
            .is_export = ctx.is_export and linkage == .strong,
            .is_inline = ctx.is_always_inline,
            .is_var_args = switch (func_ty.kind) {
                .normal => false,
                .variadic => true,
                .old_style => if (t.comp.target.cpu.arch.isWasm())
                    false
                else
                    !ctx.is_export and !ctx.is_always_inline and !ctx.has_body,
            },
            .name = ctx.fn_name,
            .linksection_string = linksection_string,
            .explicit_callconv = explicit_callconv,
            .params = fn_params,
            .return_type = return_type_node,
            .body = null,
            .alignment = alignment,
        },
    };
    return ZigNode.initPayload(&payload.base);
}