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.

transType

Translator.transType
fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex) TypeError!ZigNode

File

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

Code

fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex) TypeError!ZigNode {
    loop: switch (qt.type(t.comp)) {
        .atomic => {
            const type_name = try t.getTypeStr(qt);
            return t.fail(error.UnsupportedType, source_loc, "TODO support atomic type: '{s}'", .{type_name});
        },
        .void => return ZigTag.type.create(t.arena, "anyopaque"),
        .bool => return ZigTag.type.create(t.arena, "bool"),
        .int => |int_ty| switch (int_ty) {
            //.char => return ZigTag.type.create(t.arena, "c_char"), // TODO: this is the preferred translation
            .char => return ZigTag.type.create(t.arena, "u8"),
            .schar => return ZigTag.type.create(t.arena, "i8"),
            .uchar => return ZigTag.type.create(t.arena, "u8"),
            .short => return ZigTag.type.create(t.arena, "c_short"),
            .ushort => return ZigTag.type.create(t.arena, "c_ushort"),
            .int => return ZigTag.type.create(t.arena, "c_int"),
            .uint => return ZigTag.type.create(t.arena, "c_uint"),
            .long => return ZigTag.type.create(t.arena, "c_long"),
            .ulong => return ZigTag.type.create(t.arena, "c_ulong"),
            .long_long => return ZigTag.type.create(t.arena, "c_longlong"),
            .ulong_long => return ZigTag.type.create(t.arena, "c_ulonglong"),
            .int128 => return ZigTag.type.create(t.arena, "i128"),
            .uint128 => return ZigTag.type.create(t.arena, "u128"),
        },
        .float => |float_ty| switch (float_ty) {
            .fp16, .float16 => return ZigTag.type.create(t.arena, "f16"),
            .float, .float32 => return ZigTag.type.create(t.arena, "f32"),
            .double, .float64, .float32x => return ZigTag.type.create(t.arena, "f64"),
            .long_double, .float64x => return ZigTag.type.create(t.arena, "c_longdouble"),
            .float128 => return ZigTag.type.create(t.arena, "f128"),
            .bf16 => return t.fail(error.UnsupportedType, source_loc, "TODO support bfloat16", .{}),
            .dfloat32,
            .dfloat64,
            .dfloat128,
            .dfloat64x,
            => return t.fail(error.UnsupportedType, source_loc, "TODO support decimal float type: '{s}'", .{try t.getTypeStr(qt)}),
            .float128x => unreachable, // Unsupported on all targets
        },
        .pointer => |pointer_ty| {
            const child_qt = pointer_ty.child;

            const is_fn_proto = child_qt.is(t.comp, .func);
            const is_const = is_fn_proto or child_qt.@"const";
            const is_volatile = child_qt.@"volatile";
            const elem_type = try t.transType(scope, child_qt, source_loc);
            const ptr_info: @FieldType(ast.Payload.Pointer, "data") = .{
                .is_const = is_const,
                .is_volatile = is_volatile,
                .elem_type = elem_type,
                .is_allowzero = false,
            };
            if (is_fn_proto or
                t.typeIsOpaque(child_qt) or
                t.typeWasDemotedToOpaque(child_qt))
            {
                const ptr = try ZigTag.single_pointer.create(t.arena, ptr_info);
                return ZigTag.optional_type.create(t.arena, ptr);
            }

            return ZigTag.c_pointer.create(t.arena, ptr_info);
        },
        .array => |array_ty| {
            const elem_qt = array_ty.elem;
            switch (array_ty.len) {
                .incomplete, .unspecified_variable => {
                    const elem_type = try t.transType(scope, elem_qt, source_loc);
                    return ZigTag.c_pointer.create(t.arena, .{
                        .is_const = elem_qt.@"const",
                        .is_volatile = elem_qt.@"volatile",
                        .is_allowzero = false,
                        .elem_type = elem_type,
                    });
                },
                .fixed, .static => |len| {
                    const elem_type = try t.transType(scope, elem_qt, source_loc);
                    return ZigTag.array_type.create(t.arena, .{ .len = len, .elem_type = elem_type });
                },
                .variable => return t.fail(error.UnsupportedType, source_loc, "VLA unsupported '{s}'", .{try t.getTypeStr(qt)}),
            }
        },
        .func => |func_ty| return t.transFnType(scope, qt, func_ty, source_loc, .{}),
        .@"struct", .@"union" => |record_ty| {
            var trans_scope = scope;
            if (!record_ty.isAnonymous(t.comp)) {
                if (t.weak_global_names.contains(record_ty.name.lookup(t.comp))) trans_scope = &t.global_scope.base;
            }
            try t.transRecordDecl(trans_scope, qt);
            const name = t.type_decls.get(record_ty.decl_node).?;
            return ZigTag.identifier.create(t.arena, name);
        },
        .@"enum" => |enum_ty| {
            var trans_scope = scope;
            const is_anonymous = enum_ty.isAnonymous(t.comp);
            if (!is_anonymous) {
                if (t.weak_global_names.contains(enum_ty.name.lookup(t.comp))) trans_scope = &t.global_scope.base;
            }
            try t.transEnumDecl(trans_scope, qt);
            const name = t.type_decls.get(enum_ty.decl_node).?;
            return ZigTag.identifier.create(t.arena, name);
        },
        .typedef => |typedef_ty| {
            var trans_scope = scope;
            const typedef_name = typedef_ty.name.lookup(t.comp);
            if (builtin_typedef_map.get(typedef_name)) |builtin| return ZigTag.type.create(t.arena, builtin);
            if (t.global_names.contains(typedef_name)) trans_scope = &t.global_scope.base;

            try t.transTypeDef(trans_scope, typedef_ty.decl_node);
            const name = t.type_decls.get(typedef_ty.decl_node).?;
            return ZigTag.identifier.create(t.arena, name);
        },
        .attributed => |attributed_ty| continue :loop attributed_ty.base.type(t.comp),
        .typeof => |typeof_ty| {
            if (typeof_ty.expr) |expr| {
                if (t.transExpr(scope, expr, .used)) |node| {
                    return ZigTag.typeof.create(t.arena, node);
                } else |err| switch (err) {
                    error.SelfReferential => {},
                    error.UnsupportedTranslation => {},
                    error.UnsupportedType => {},
                    error.OutOfMemory => |e| return e,
                }
            }
            continue :loop typeof_ty.base.type(t.comp);
        },
        .vector => |vector_ty| {
            const len = try t.createNumberNode(vector_ty.len);
            const elem_type = try t.transType(scope, vector_ty.elem, source_loc);
            return ZigTag.vector.create(t.arena, .{ .lhs = len, .rhs = elem_type });
        },
        else => return t.fail(error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{try t.getTypeStr(qt)}),
    }
}