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.

transCompoundAssign

Translator.transCompoundAssign
fn transCompoundAssign(
    t: *Translator,
    scope: *Scope,
    assign: Node.Binary,
    used: ResultUsed,
) !ZigNode

File

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

Code

fn transCompoundAssign(
    t: *Translator,
    scope: *Scope,
    assign: Node.Binary,
    used: ResultUsed,
) !ZigNode {
    // If the result is unused we can try using the equivalent Zig operator
    // without a block
    if (used == .unused) {
        if (try t.transCompoundAssignSimple(scope, null, assign)) |some| {
            return some;
        }
    }

    // Otherwise we need to wrap the the compound assignment in a block.
    var block_scope = try Scope.Block.init(t, scope, used == .used);
    defer block_scope.deinit();
    const ref = try block_scope.reserveMangledName("ref");

    const lhs_expr = try t.transExpr(&block_scope.base, assign.lhs, .used);
    const addr_of = try ZigTag.address_of.create(t.arena, lhs_expr);
    const ref_decl = try ZigTag.var_simple.create(t.arena, .{ .name = ref, .init = addr_of });
    try block_scope.statements.append(t.gpa, ref_decl);

    const lhs_node = try ZigTag.identifier.create(t.arena, ref);
    const ref_node = try ZigTag.deref.create(t.arena, lhs_node);

    // Use the equivalent Zig operator if possible.
    if (try t.transCompoundAssignSimple(scope, ref_node, assign)) |some| {
        try block_scope.statements.append(t.gpa, some);
    } else {
        const old_dummy = t.compound_assign_dummy;
        defer t.compound_assign_dummy = old_dummy;
        t.compound_assign_dummy = ref_node;

        // Otherwise do the operation and assignment separately.
        const rhs_node = try t.transExprCoercing(&block_scope.base, assign.rhs, .used);
        const assign_node = try t.createBinOpNode(.assign, ref_node, rhs_node);
        try block_scope.statements.append(t.gpa, assign_node);
    }

    if (used == .used) {
        const break_node = try ZigTag.break_val.create(t.arena, .{
            .label = block_scope.label,
            .val = ref_node,
        });
        try block_scope.statements.append(t.gpa, break_node);
    }
    return block_scope.complete();
}