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.

createFlexibleMemberFn

Build a getter function for a flexible array field in a C record e.g. T items[] or T items[0]. The generated function returns a [*c] pointer to the flexible array with the correct const and volatile qualifiers

Translator.createFlexibleMemberFn
fn createFlexibleMemberFn(
    t: *Translator,
    member_name: []const u8,
    field_name: []const u8,
) Error!ZigNode

File

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

Code

fn createFlexibleMemberFn(
    t: *Translator,
    member_name: []const u8,
    field_name: []const u8,
) Error!ZigNode {
    // Use `_self` instead of the conventional `self` to avoid the Zig error
    // "function parameter shadows declaration of 'self'".
    // `processContainerMemberFns` merges C functions matching a struct's name
    // prefix into the struct as `pub const` aliases (e.g. `foo_self()` becomes
    // `pub const self = __root.foo_self`). A parameter also named `self` would
    // then shadow that declaration, which Zig rejects.
    const self_param_name = "_self";
    const self_param = try ZigTag.identifier.create(t.arena, self_param_name);
    const self_type = try ZigTag.typeof.create(t.arena, self_param);

    const fn_params = try t.arena.alloc(ast.Payload.Param, 1);
    fn_params[0] = .{
        .name = self_param_name,
        .type = ZigTag.@"anytype".init(),
        .is_noalias = false,
    };

    // @typeInfo(@TypeOf(self.*.<field_name>)).pointer.child
    const dereffed = try ZigTag.deref.create(t.arena, self_param);
    const field_access = try ZigTag.field_access.create(t.arena, .{ .lhs = dereffed, .field_name = field_name });
    const type_of = try ZigTag.typeof.create(t.arena, field_access);
    const type_info = try ZigTag.typeinfo.create(t.arena, type_of);
    const array_info = try ZigTag.field_access.create(t.arena, .{ .lhs = type_info, .field_name = "array" });
    const child_info = try ZigTag.field_access.create(t.arena, .{ .lhs = array_info, .field_name = "child" });

    const return_type = try t.createHelperCallNode(.FlexibleArrayType, &.{ self_type, child_info });

    // return @ptrCast(&self.*.<field_name>);
    const address_of = try ZigTag.address_of.create(t.arena, field_access);
    const aligned = try ZigTag.align_cast.create(t.arena, address_of);
    const casted = try ZigTag.ptr_cast.create(t.arena, aligned);
    const return_stmt = try ZigTag.@"return".create(t.arena, casted);
    const body = try ZigTag.block_single.create(t.arena, return_stmt);

    return ZigTag.func.create(t.arena, .{
        .is_pub = true,
        .is_extern = false,
        .is_export = false,
        .is_inline = false,
        .is_var_args = false,
        .name = member_name,
        .linksection_string = null,
        .explicit_callconv = null,
        .params = fn_params,
        .return_type = return_type,
        .body = body,
        .alignment = null,
    });
}