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.

transFnMacro

MacroTranslator.transFnMacro
pub fn transFnMacro(mt: *MacroTranslator) ParseError!void

File

lib/compiler/translate-c/MacroTranslator.zig:66

Code

pub fn transFnMacro(mt: *MacroTranslator) ParseError!void {
    var block_scope = try Scope.Block.init(mt.t, &mt.t.global_scope.base, false);
    defer block_scope.deinit();
    const scope = &block_scope.base;

    const fn_params = try mt.t.arena.alloc(ast.Payload.Param, mt.macro.params.len);
    for (fn_params, mt.macro.params) |*param, param_name| {
        const mangled_name = try block_scope.makeMangledName(param_name);
        param.* = .{
            .is_noalias = false,
            .name = mangled_name,
            .type = ZigTag.@"anytype".init(),
        };
        try block_scope.discardVariable(mangled_name);
    }

    // #define FOO(x)
    if (mt.peek() == .eof) {
        try block_scope.statements.append(mt.t.gpa, ZigTag.return_void.init());

        const fn_decl = try ZigTag.pub_inline_fn.create(mt.t.arena, .{
            .name = mt.name,
            .params = fn_params,
            .return_type = ZigTag.void_type.init(),
            .body = try block_scope.complete(),
        });
        try mt.t.addTopLevelDecl(mt.name, fn_decl);
        return;
    }

    const expr = try mt.parseCExpr(scope);
    const last = mt.peek();
    if (last != .eof)
        return mt.fail("unable to translate C expr: unexpected token '{s}'", .{last.symbol()});

    const typeof_arg = if (expr.castTag(.block)) |some| blk: {
        const stmts = some.data.stmts;
        const blk_last = stmts[stmts.len - 1];
        const br = blk_last.castTag(.break_val).?;
        break :blk br.data.val;
    } else expr;

    const return_type = ret: {
        if (typeof_arg.castTag(.helper_call)) |some| {
            if (std.mem.eql(u8, some.data.name, "cast")) {
                break :ret some.data.args[0];
            }
        }
        if (typeof_arg.castTag(.std_mem_zeroinit)) |some| break :ret some.data.lhs;
        if (typeof_arg.castTag(.std_mem_zeroes)) |some| break :ret some.data;
        break :ret try ZigTag.typeof.create(mt.t.arena, typeof_arg);
    };

    const return_expr = try ZigTag.@"return".create(mt.t.arena, expr);
    try block_scope.statements.append(mt.t.gpa, return_expr);

    const fn_decl = try ZigTag.pub_inline_fn.create(mt.t.arena, .{
        .name = mt.name,
        .params = fn_params,
        .return_type = return_type,
        .body = try block_scope.complete(),
    });
    try mt.t.addTopLevelDecl(mt.name, fn_decl);
}