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.

transEnumDecl

Translator.transEnumDecl
fn transEnumDecl(t: *Translator, scope: *Scope, enum_qt: QualType) Error!void

File

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

Code

fn transEnumDecl(t: *Translator, scope: *Scope, enum_qt: QualType) Error!void {
    const base = enum_qt.base(t.comp);
    const enum_ty = base.type.@"enum";

    if (t.type_decls.get(enum_ty.decl_node)) |_|
        return; // Avoid processing this decl twice

    const toplevel = scope.id == .root;
    const bs: *Scope.Block = if (!toplevel) try scope.findBlockScope(t) else undefined;

    var bare_name = enum_ty.name.lookup(t.comp);
    var is_unnamed = false;
    var name = bare_name;
    if (t.unnamed_typedefs.get(base.qt)) |typedef_name| {
        bare_name = typedef_name;
        name = typedef_name;
    } else {
        if (enum_ty.isAnonymous(t.comp)) {
            bare_name = try std.fmt.allocPrint(t.arena, "unnamed_{d}", .{t.getMangle()});
            is_unnamed = true;
        }
        name = try std.fmt.allocPrint(t.arena, "enum_{s}", .{bare_name});
    }
    if (!toplevel) name = try bs.makeMangledName(name);
    try t.type_decls.putNoClobber(t.gpa, enum_ty.decl_node, name);

    const enum_type_node = if (!base.qt.hasIncompleteSize(t.comp)) blk: {
        const enum_decl = enum_ty.decl_node.get(t.tree).enum_decl;
        for (enum_ty.fields, enum_decl.fields) |field, field_node| {
            var enum_val_name = field.name.lookup(t.comp);
            if (!toplevel) {
                enum_val_name = try bs.makeMangledName(enum_val_name);
            }

            const enum_const_type_node: ?ZigNode = t.transType(scope, field.qt, field.name_tok) catch |err| switch (err) {
                error.UnsupportedType => null,
                else => |e| return e,
            };

            const val = t.tree.value_map.get(field_node).?;
            const enum_const_def = try ZigTag.enum_constant.create(t.arena, .{
                .name = enum_val_name,
                .is_public = toplevel,
                .type = enum_const_type_node,
                .value = try t.createIntNode(val),
            });
            if (toplevel)
                try t.addTopLevelDecl(enum_val_name, enum_const_def)
            else {
                try scope.appendNode(enum_const_def);
                try bs.discardVariable(enum_val_name);
            }
        }

        break :blk t.transType(scope, enum_ty.tag.?, enum_decl.name_or_kind_tok) catch |err| switch (err) {
            error.UnsupportedType => {
                return t.failDecl(scope, enum_decl.name_or_kind_tok, name, "unable to translate enum integer type", .{});
            },
            else => |e| return e,
        };
    } else blk: {
        try t.opaque_demotes.put(t.gpa, base.qt, {});
        break :blk ZigTag.opaque_literal.init();
    };

    const is_pub = toplevel and !is_unnamed;
    const payload = try t.arena.create(ast.Payload.SimpleVarDecl);
    payload.* = .{
        .base = .{ .tag = if (is_pub) .pub_var_simple else .var_simple },
        .data = .{
            .init = enum_type_node,
            .name = name,
        },
    };
    const node = ZigNode.initPayload(&payload.base);
    if (toplevel) {
        try t.addTopLevelDecl(name, node);
        if (!is_unnamed)
            try t.alias_list.append(t.gpa, .{ .alias = bare_name, .name = name });
    } else {
        try scope.appendNode(node);
        try bs.discardVariable(name);
    }
}