astgen: fix call instruction append and port shiftOp

Fix call instruction not being appended to gz's instruction list due
to a debug range check left in callExpr. This caused emitDbgStmt's
dedup logic to not see call instructions, resulting in 10 missing
dbg_stmt instructions in the build.zig corpus test.

Also port shiftOp from upstream (AstGen.zig:9978) for shl/shr operators,
which need typeof_log2_int_type for RHS coercion and their own emitDbgStmt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 08:47:39 +00:00
parent 3134312e34
commit 421c76dead
2 changed files with 30 additions and 7 deletions

View File

@@ -1699,6 +1699,8 @@ static uint32_t exprRl(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node);
static void assignStmt(GenZir* gz, Scope* scope, uint32_t infix_node);
static void assignOp(
GenZir* gz, Scope* scope, uint32_t infix_node, ZirInstTag op_tag);
static uint32_t shiftOp(
GenZir* gz, Scope* scope, uint32_t node, ZirInstTag tag);
static void emitDbgStmt(GenZir* gz, uint32_t line, uint32_t column);
static void genDefers(
GenZir* gz, const Scope* outer_scope, Scope* inner_scope, int which);
@@ -2621,6 +2623,30 @@ static uint32_t simpleBinOp(
return addPlNodeBin(gz, op_tag, node, lhs, rhs);
}
// --- shiftOp (AstGen.zig:9978) ---
static uint32_t shiftOp(
GenZir* gz, Scope* scope, uint32_t node, ZirInstTag tag) {
AstGenCtx* ag = gz->astgen;
AstData nd = ag->tree->nodes.datas[node];
uint32_t lhs = exprRl(gz, scope, RL_NONE_VAL, nd.lhs);
advanceSourceCursorToMainToken(ag, node);
uint32_t saved_line = ag->source_line - gz->decl_line;
uint32_t saved_col = ag->source_column;
uint32_t log2_int_type
= addUnNode(gz, ZIR_INST_TYPEOF_LOG2_INT_TYPE, lhs, nd.lhs);
ResultLoc rhs_rl;
rhs_rl.tag = RL_TY;
rhs_rl.data = log2_int_type;
uint32_t rhs = exprRl(gz, scope, rhs_rl, nd.rhs);
emitDbgStmt(gz, saved_line, saved_col);
return addPlNodeBin(gz, tag, node, lhs, rhs);
}
// --- multilineStringLiteral (AstGen.zig:8645) ---
// Port of strLitNodeAsString for multiline strings.
static uint32_t multilineStringLiteral(
@@ -2894,8 +2920,7 @@ static uint32_t callExpr(
memset(&ag->inst_datas[call_index], 0, sizeof(ZirInstData));
ag->inst_tags[call_index] = (ZirInstTag)0;
ag->inst_len++;
if (call_index >= 925 && call_index <= 935)
gzAppendInstruction(gz, call_index);
gzAppendInstruction(gz, call_index);
// Process arguments in sub-blocks (AstGen.zig:10100-10115).
// Simplified: we collect arg body lengths into extra.
@@ -3467,11 +3492,9 @@ static uint32_t exprRl(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node) {
return rvalue(
gz, rl, simpleBinOp(gz, scope, node, ZIR_INST_XOR), node);
case AST_NODE_SHL:
return rvalue(
gz, rl, simpleBinOp(gz, scope, node, ZIR_INST_SHL), node);
return rvalue(gz, rl, shiftOp(gz, scope, node, ZIR_INST_SHL), node);
case AST_NODE_SHR:
return rvalue(
gz, rl, simpleBinOp(gz, scope, node, ZIR_INST_SHR), node);
return rvalue(gz, rl, shiftOp(gz, scope, node, ZIR_INST_SHR), node);
// Boolean operators (AstGen.zig:728-731) — special: boolBinOp.
case AST_NODE_BOOL_AND:
return rvalue(

View File

@@ -990,7 +990,7 @@ test "astgen: corpus test_all.zig" {
}
test "astgen: corpus build.zig" {
if (true) return error.SkipZigTest; // TODO: 11 inst diffs (10 dbg_stmt, 1 ref)
if (true) return error.SkipZigTest; // TODO: 1 inst diff (1 ref) - slice LHS needs .ref rl
const gpa = std.testing.allocator;
try corpusCheck(gpa, "build.zig", @embedFile("build.zig"));
}