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.

transMacro

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

File

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

Code

pub fn transMacro(mt: *MacroTranslator) ParseError!void {
    const scope = &mt.t.global_scope.base;

    // Check if the macro only uses other blank macros.
    while (true) {
        switch (mt.peek()) {
            .identifier, .extended_identifier => {
                if (mt.t.global_scope.blank_macros.contains(mt.tokSlice())) {
                    mt.i += 1;
                    continue;
                }
            },
            .eof, .nl => {
                try mt.t.global_scope.blank_macros.put(mt.t.gpa, mt.name, {});
                const init_node = try ZigTag.string_literal.create(mt.t.arena, "\"\"");
                const var_decl = try ZigTag.pub_var_simple.create(mt.t.arena, .{ .name = mt.name, .init = init_node });
                try mt.t.addTopLevelDecl(mt.name, var_decl);
                return;
            },
            else => {},
        }
        break;
    }

    const init_node = 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 node = node: {
        const var_decl = try ZigTag.pub_var_simple.create(mt.t.arena, .{ .name = mt.name, .init = init_node });

        if (mt.t.getFnProto(var_decl)) |proto_node| {
            // If a macro aliases a global variable which is a function pointer, we conclude that
            // the macro is intended to represent a function that assumes the function pointer
            // variable is non-null and calls it.
            break :node try mt.createMacroFn(mt.name, var_decl, proto_node);
        } else if (mt.refs_var_decl) {
            const return_type = try ZigTag.typeof.create(mt.t.arena, init_node);
            const return_expr = try ZigTag.@"return".create(mt.t.arena, init_node);
            const block = try ZigTag.block_single.create(mt.t.arena, return_expr);

            const loc_str = try mt.t.locStr(mt.macro.loc);
            const value = try std.fmt.allocPrint(mt.t.arena, "\n// {s}: warning: macro '{s}' contains a runtime value, translated to function", .{ loc_str, mt.name });
            try scope.appendNode(try ZigTag.warning.create(mt.t.arena, value));

            break :node try ZigTag.pub_inline_fn.create(mt.t.arena, .{
                .name = mt.name,
                .params = &.{},
                .return_type = return_type,
                .body = block,
            });
        }

        break :node var_decl;
    };

    try mt.t.addTopLevelDecl(mt.name, node);
}