mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #9882 from mattbork/astgen-cursor
astgen.zig: keep source cursor increasing monotonically as much as possible
This commit is contained in:
commit
2454459ef5
270
src/AstGen.zig
270
src/AstGen.zig
@ -1683,7 +1683,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
scope = defer_scope.parent;
|
||||
const expr_node = node_datas[defer_scope.defer_node].rhs;
|
||||
_ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
|
||||
try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node);
|
||||
},
|
||||
.defer_error => scope = scope.cast(Scope.Defer).?.parent,
|
||||
.top => unreachable,
|
||||
@ -1736,7 +1736,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
scope = defer_scope.parent;
|
||||
const expr_node = node_datas[defer_scope.defer_node].rhs;
|
||||
_ = try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
|
||||
try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node);
|
||||
},
|
||||
.defer_error => scope = scope.cast(Scope.Defer).?.parent,
|
||||
.namespace => break,
|
||||
@ -1922,8 +1922,8 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
||||
.simple_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.simpleVarDecl(statement)),
|
||||
.aligned_var_decl => scope = try varDecl(gz, scope, statement, &block_arena.allocator, tree.alignedVarDecl(statement)),
|
||||
|
||||
.@"defer" => scope = try makeDeferScope(scope, statement, &block_arena.allocator, .defer_normal),
|
||||
.@"errdefer" => scope = try makeDeferScope(scope, statement, &block_arena.allocator, .defer_error),
|
||||
.@"defer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_normal),
|
||||
.@"errdefer" => scope = try makeDeferScope(gz.astgen, scope, statement, &block_arena.allocator, .defer_error),
|
||||
|
||||
.assign => try assign(gz, scope, statement),
|
||||
|
||||
@ -1951,6 +1951,22 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
||||
try checkUsed(gz, parent_scope, scope);
|
||||
}
|
||||
|
||||
fn unusedResultDeferExpr(gz: *GenZir, defer_scope: *Scope.Defer, expr_scope: *Scope, expr_node: Ast.Node.Index) InnerError!void {
|
||||
const astgen = gz.astgen;
|
||||
const prev_offset = astgen.source_offset;
|
||||
const prev_line = astgen.source_line;
|
||||
const prev_column = astgen.source_column;
|
||||
defer {
|
||||
astgen.source_offset = prev_offset;
|
||||
astgen.source_line = prev_line;
|
||||
astgen.source_column = prev_column;
|
||||
}
|
||||
astgen.source_offset = defer_scope.source_offset;
|
||||
astgen.source_line = defer_scope.source_line;
|
||||
astgen.source_column = defer_scope.source_column;
|
||||
_ = try unusedResultExpr(gz, expr_scope, expr_node);
|
||||
}
|
||||
|
||||
/// Returns AST source node of the thing that is noreturn if the statement is definitely `noreturn`.
|
||||
/// Otherwise returns 0.
|
||||
fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) InnerError!Ast.Node.Index {
|
||||
@ -2333,7 +2349,7 @@ fn genDefers(
|
||||
const prev_in_defer = gz.in_defer;
|
||||
gz.in_defer = true;
|
||||
defer gz.in_defer = prev_in_defer;
|
||||
_ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
|
||||
try unusedResultDeferExpr(gz, defer_scope, defer_scope.parent, expr_node);
|
||||
},
|
||||
.defer_error => {
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
@ -2344,7 +2360,7 @@ fn genDefers(
|
||||
const prev_in_defer = gz.in_defer;
|
||||
gz.in_defer = true;
|
||||
defer gz.in_defer = prev_in_defer;
|
||||
_ = try unusedResultExpr(gz, defer_scope.parent, expr_node);
|
||||
try unusedResultDeferExpr(gz, defer_scope, defer_scope.parent, expr_node);
|
||||
},
|
||||
.both => |err_code| {
|
||||
const expr_node = node_datas[defer_scope.defer_node].rhs;
|
||||
@ -2365,7 +2381,7 @@ fn genDefers(
|
||||
};
|
||||
break :blk &local_val_scope.base;
|
||||
};
|
||||
_ = try unusedResultExpr(gz, sub_scope, expr_node);
|
||||
try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);
|
||||
},
|
||||
.normal_only => continue,
|
||||
}
|
||||
@ -2409,16 +2425,27 @@ fn checkUsed(
|
||||
}
|
||||
|
||||
fn makeDeferScope(
|
||||
astgen: *AstGen,
|
||||
scope: *Scope,
|
||||
node: Ast.Node.Index,
|
||||
block_arena: *Allocator,
|
||||
scope_tag: Scope.Tag,
|
||||
) InnerError!*Scope {
|
||||
const tree = astgen.tree;
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
const expr_node = node_datas[node].rhs;
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
const node_start = token_starts[tree.firstToken(expr_node)];
|
||||
const defer_scope = try block_arena.create(Scope.Defer);
|
||||
astgen.advanceSourceCursor(tree.source, node_start);
|
||||
|
||||
defer_scope.* = .{
|
||||
.base = .{ .tag = scope_tag },
|
||||
.parent = scope,
|
||||
.defer_node = node,
|
||||
.source_offset = astgen.source_offset,
|
||||
.source_line = astgen.source_line,
|
||||
.source_column = astgen.source_column,
|
||||
};
|
||||
return &defer_scope.base;
|
||||
}
|
||||
@ -3184,6 +3211,12 @@ fn fnDecl(
|
||||
astgen.fn_block = &fn_gz;
|
||||
defer astgen.fn_block = prev_fn_block;
|
||||
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
const lbrace_start = token_starts[tree.firstToken(body_node)];
|
||||
astgen.advanceSourceCursor(tree.source, lbrace_start);
|
||||
const lbrace_line = @intCast(u32, astgen.source_line);
|
||||
const lbrace_column = @intCast(u32, astgen.source_column);
|
||||
|
||||
_ = try expr(&fn_gz, params_scope, .none, body_node);
|
||||
try checkUsed(gz, &fn_gz.base, params_scope);
|
||||
|
||||
@ -3202,6 +3235,8 @@ fn fnDecl(
|
||||
|
||||
break :func try decl_gz.addFunc(.{
|
||||
.src_node = decl_node,
|
||||
.lbrace_line = lbrace_line,
|
||||
.lbrace_column = lbrace_column,
|
||||
.param_block = block_inst,
|
||||
.ret_ty = ret_gz.instructions.items,
|
||||
.ret_br = ret_br,
|
||||
@ -3544,6 +3579,12 @@ fn testDecl(
|
||||
astgen.fn_block = &fn_block;
|
||||
defer astgen.fn_block = prev_fn_block;
|
||||
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
const lbrace_start = token_starts[tree.firstToken(body_node)];
|
||||
astgen.advanceSourceCursor(tree.source, lbrace_start);
|
||||
const lbrace_line = @intCast(u32, astgen.source_line);
|
||||
const lbrace_column = @intCast(u32, astgen.source_column);
|
||||
|
||||
const block_result = try expr(&fn_block, &fn_block.base, .none, body_node);
|
||||
if (fn_block.instructions.items.len == 0 or !fn_block.refIsNoReturn(block_result)) {
|
||||
// Since we are adding the return instruction here, we must handle the coercion.
|
||||
@ -3553,6 +3594,8 @@ fn testDecl(
|
||||
|
||||
const func_inst = try decl_block.addFunc(.{
|
||||
.src_node = node,
|
||||
.lbrace_line = lbrace_line,
|
||||
.lbrace_column = lbrace_column,
|
||||
.param_block = block_inst,
|
||||
.ret_ty = &.{},
|
||||
.ret_br = 0,
|
||||
@ -5935,10 +5978,11 @@ fn switchExpr(
|
||||
const operand_ty_inst = try parent_gz.addUnNode(typeof_tag, operand, operand_node);
|
||||
const item_rl: ResultLoc = .{ .ty = operand_ty_inst };
|
||||
|
||||
// Contains the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti.
|
||||
// This is the header as well as the optional else prong body, as well as all the
|
||||
// scalar cases.
|
||||
// At the end we will memcpy this into place.
|
||||
// These contain the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti.
|
||||
// This is the optional else prong body.
|
||||
var special_case_payload = ArrayListUnmanaged(u32){};
|
||||
defer special_case_payload.deinit(gpa);
|
||||
// This is all the scalar cases.
|
||||
var scalar_cases_payload = ArrayListUnmanaged(u32){};
|
||||
defer scalar_cases_payload.deinit(gpa);
|
||||
// Same deal, but this is only the `extra` data for the multi cases.
|
||||
@ -5956,86 +6000,10 @@ fn switchExpr(
|
||||
var case_scope = parent_gz.makeSubBlock(&block_scope.base);
|
||||
defer case_scope.instructions.deinit(gpa);
|
||||
|
||||
// Do the else/`_` first because it goes first in the payload.
|
||||
var capture_val_scope: Scope.LocalVal = undefined;
|
||||
if (special_node != 0) {
|
||||
const case = switch (node_tags[special_node]) {
|
||||
.switch_case_one => tree.switchCaseOne(special_node),
|
||||
.switch_case => tree.switchCase(special_node),
|
||||
else => unreachable,
|
||||
};
|
||||
const sub_scope = blk: {
|
||||
const payload_token = case.payload_token orelse break :blk &case_scope.base;
|
||||
const ident = if (token_tags[payload_token] == .asterisk)
|
||||
payload_token + 1
|
||||
else
|
||||
payload_token;
|
||||
const is_ptr = ident != payload_token;
|
||||
if (mem.eql(u8, tree.tokenSlice(ident), "_")) {
|
||||
if (is_ptr) {
|
||||
return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
|
||||
}
|
||||
break :blk &case_scope.base;
|
||||
}
|
||||
const capture_tag: Zir.Inst.Tag = if (is_ptr)
|
||||
.switch_capture_else_ref
|
||||
else
|
||||
.switch_capture_else;
|
||||
const capture = try case_scope.add(.{
|
||||
.tag = capture_tag,
|
||||
.data = .{ .switch_capture = .{
|
||||
.switch_inst = switch_block,
|
||||
.prong_index = undefined,
|
||||
} },
|
||||
});
|
||||
const capture_name = try astgen.identAsString(payload_token);
|
||||
capture_val_scope = .{
|
||||
.parent = &case_scope.base,
|
||||
.gen_zir = &case_scope,
|
||||
.name = capture_name,
|
||||
.inst = capture,
|
||||
.token_src = payload_token,
|
||||
.id_cat = .@"capture",
|
||||
};
|
||||
break :blk &capture_val_scope.base;
|
||||
};
|
||||
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr);
|
||||
try checkUsed(parent_gz, &case_scope.base, sub_scope);
|
||||
if (!parent_gz.refIsNoReturn(case_result)) {
|
||||
block_scope.break_count += 1;
|
||||
_ = try case_scope.addBreak(.@"break", switch_block, case_result);
|
||||
}
|
||||
// Documentation for this: `Zir.Inst.SwitchBlock` and `Zir.Inst.SwitchBlockMulti`.
|
||||
try scalar_cases_payload.ensureUnusedCapacity(gpa, case_scope.instructions.items.len +
|
||||
3 + // operand, scalar_cases_len, else body len
|
||||
@boolToInt(multi_cases_len != 0));
|
||||
scalar_cases_payload.appendAssumeCapacity(@enumToInt(operand));
|
||||
scalar_cases_payload.appendAssumeCapacity(scalar_cases_len);
|
||||
if (multi_cases_len != 0) {
|
||||
scalar_cases_payload.appendAssumeCapacity(multi_cases_len);
|
||||
}
|
||||
scalar_cases_payload.appendAssumeCapacity(@intCast(u32, case_scope.instructions.items.len));
|
||||
scalar_cases_payload.appendSliceAssumeCapacity(case_scope.instructions.items);
|
||||
} else {
|
||||
// Documentation for this: `Zir.Inst.SwitchBlock` and `Zir.Inst.SwitchBlockMulti`.
|
||||
try scalar_cases_payload.ensureUnusedCapacity(
|
||||
gpa,
|
||||
@as(usize, 2) + // operand, scalar_cases_len
|
||||
@boolToInt(multi_cases_len != 0),
|
||||
);
|
||||
scalar_cases_payload.appendAssumeCapacity(@enumToInt(operand));
|
||||
scalar_cases_payload.appendAssumeCapacity(scalar_cases_len);
|
||||
if (multi_cases_len != 0) {
|
||||
scalar_cases_payload.appendAssumeCapacity(multi_cases_len);
|
||||
}
|
||||
}
|
||||
|
||||
// In this pass we generate all the item and prong expressions except the special case.
|
||||
// In this pass we generate all the item and prong expressions.
|
||||
var multi_case_index: u32 = 0;
|
||||
var scalar_case_index: u32 = 0;
|
||||
for (case_nodes) |case_node| {
|
||||
if (case_node == special_node)
|
||||
continue;
|
||||
const case = switch (node_tags[case_node]) {
|
||||
.switch_case_one => tree.switchCaseOne(case_node),
|
||||
.switch_case => tree.switchCase(case_node),
|
||||
@ -6045,9 +6013,10 @@ fn switchExpr(
|
||||
// Reset the scope.
|
||||
case_scope.instructions.shrinkRetainingCapacity(0);
|
||||
|
||||
const is_multi_case = case.ast.values.len != 1 or
|
||||
node_tags[case.ast.values[0]] == .switch_range;
|
||||
const is_multi_case = case.ast.values.len > 1 or
|
||||
(case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);
|
||||
|
||||
var capture_val_scope: Scope.LocalVal = undefined;
|
||||
const sub_scope = blk: {
|
||||
const payload_token = case.payload_token orelse break :blk &case_scope.base;
|
||||
const ident = if (token_tags[payload_token] == .asterisk)
|
||||
@ -6061,28 +6030,42 @@ fn switchExpr(
|
||||
}
|
||||
break :blk &case_scope.base;
|
||||
}
|
||||
const is_multi_case_bits: u2 = @boolToInt(is_multi_case);
|
||||
const is_ptr_bits: u2 = @boolToInt(is_ptr);
|
||||
const capture_tag: Zir.Inst.Tag = switch ((is_multi_case_bits << 1) | is_ptr_bits) {
|
||||
0b00 => .switch_capture,
|
||||
0b01 => .switch_capture_ref,
|
||||
0b10 => .switch_capture_multi,
|
||||
0b11 => .switch_capture_multi_ref,
|
||||
const capture = if (case_node == special_node) capture: {
|
||||
const capture_tag: Zir.Inst.Tag = if (is_ptr)
|
||||
.switch_capture_else_ref
|
||||
else
|
||||
.switch_capture_else;
|
||||
break :capture try case_scope.add(.{
|
||||
.tag = capture_tag,
|
||||
.data = .{ .switch_capture = .{
|
||||
.switch_inst = switch_block,
|
||||
.prong_index = undefined,
|
||||
} },
|
||||
});
|
||||
} else capture: {
|
||||
const is_multi_case_bits: u2 = @boolToInt(is_multi_case);
|
||||
const is_ptr_bits: u2 = @boolToInt(is_ptr);
|
||||
const capture_tag: Zir.Inst.Tag = switch ((is_multi_case_bits << 1) | is_ptr_bits) {
|
||||
0b00 => .switch_capture,
|
||||
0b01 => .switch_capture_ref,
|
||||
0b10 => .switch_capture_multi,
|
||||
0b11 => .switch_capture_multi_ref,
|
||||
};
|
||||
const capture_index = if (is_multi_case) ci: {
|
||||
multi_case_index += 1;
|
||||
break :ci multi_case_index - 1;
|
||||
} else ci: {
|
||||
scalar_case_index += 1;
|
||||
break :ci scalar_case_index - 1;
|
||||
};
|
||||
break :capture try case_scope.add(.{
|
||||
.tag = capture_tag,
|
||||
.data = .{ .switch_capture = .{
|
||||
.switch_inst = switch_block,
|
||||
.prong_index = capture_index,
|
||||
} },
|
||||
});
|
||||
};
|
||||
const capture_index = if (is_multi_case) ci: {
|
||||
multi_case_index += 1;
|
||||
break :ci multi_case_index - 1;
|
||||
} else ci: {
|
||||
scalar_case_index += 1;
|
||||
break :ci scalar_case_index - 1;
|
||||
};
|
||||
const capture = try case_scope.add(.{
|
||||
.tag = capture_tag,
|
||||
.data = .{ .switch_capture = .{
|
||||
.switch_inst = switch_block,
|
||||
.prong_index = capture_index,
|
||||
} },
|
||||
});
|
||||
const capture_name = try astgen.identAsString(ident);
|
||||
capture_val_scope = .{
|
||||
.parent = &case_scope.base,
|
||||
@ -6134,6 +6117,17 @@ fn switchExpr(
|
||||
multi_cases_payload.items[header_index + 1] = ranges_len;
|
||||
multi_cases_payload.items[header_index + 2] = @intCast(u32, case_scope.instructions.items.len);
|
||||
try multi_cases_payload.appendSlice(gpa, case_scope.instructions.items);
|
||||
} else if (case_node == special_node) {
|
||||
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr);
|
||||
try checkUsed(parent_gz, &case_scope.base, sub_scope);
|
||||
if (!parent_gz.refIsNoReturn(case_result)) {
|
||||
block_scope.break_count += 1;
|
||||
_ = try case_scope.addBreak(.@"break", switch_block, case_result);
|
||||
}
|
||||
try special_case_payload.ensureUnusedCapacity(gpa, 1 + // body_len
|
||||
case_scope.instructions.items.len);
|
||||
special_case_payload.appendAssumeCapacity(@intCast(u32, case_scope.instructions.items.len));
|
||||
special_case_payload.appendSliceAssumeCapacity(case_scope.instructions.items);
|
||||
} else {
|
||||
const item_node = case.ast.values[0];
|
||||
const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node);
|
||||
@ -6143,7 +6137,7 @@ fn switchExpr(
|
||||
block_scope.break_count += 1;
|
||||
_ = try case_scope.addBreak(.@"break", switch_block, case_result);
|
||||
}
|
||||
try scalar_cases_payload.ensureUnusedCapacity(gpa, 2 +
|
||||
try scalar_cases_payload.ensureUnusedCapacity(gpa, 2 + // item + body_len
|
||||
case_scope.instructions.items.len);
|
||||
scalar_cases_payload.appendAssumeCapacity(@enumToInt(item_inst));
|
||||
scalar_cases_payload.appendAssumeCapacity(@intCast(u32, case_scope.instructions.items.len));
|
||||
@ -6180,8 +6174,17 @@ fn switchExpr(
|
||||
const payload_index = astgen.extra.items.len;
|
||||
const zir_datas = astgen.instructions.items(.data);
|
||||
zir_datas[switch_block].pl_node.payload_index = @intCast(u32, payload_index);
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, scalar_cases_payload.items.len +
|
||||
// Documentation for this: `Zir.Inst.SwitchBlock` and `Zir.Inst.SwitchBlockMulti`.
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, @as(usize, 2) + // operand, scalar_cases_len
|
||||
@boolToInt(multi_cases_len != 0) +
|
||||
special_case_payload.items.len +
|
||||
scalar_cases_payload.items.len +
|
||||
multi_cases_payload.items.len);
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(operand));
|
||||
astgen.extra.appendAssumeCapacity(scalar_cases_len);
|
||||
if (multi_cases_len != 0) {
|
||||
astgen.extra.appendAssumeCapacity(multi_cases_len);
|
||||
}
|
||||
const strat = rl.strategy(&block_scope);
|
||||
switch (strat.tag) {
|
||||
.break_operand => {
|
||||
@ -6189,6 +6192,7 @@ fn switchExpr(
|
||||
// `elide_store_to_block_ptr_instructions` will either be true,
|
||||
// or all prongs are noreturn.
|
||||
if (!strat.elide_store_to_block_ptr_instructions) {
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items);
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items);
|
||||
astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items);
|
||||
return indexToRef(switch_block);
|
||||
@ -6204,32 +6208,30 @@ fn switchExpr(
|
||||
// it as the break operand.
|
||||
|
||||
var extra_index: usize = 0;
|
||||
extra_index += 2;
|
||||
extra_index += @boolToInt(multi_cases_len != 0);
|
||||
if (special_prong != .none) special_prong: {
|
||||
const body_len_index = extra_index;
|
||||
const body_len = scalar_cases_payload.items[extra_index];
|
||||
const body_len = special_case_payload.items[extra_index];
|
||||
extra_index += 1;
|
||||
if (body_len < 2) {
|
||||
extra_index += body_len;
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[0..extra_index]);
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]);
|
||||
break :special_prong;
|
||||
}
|
||||
extra_index += body_len - 2;
|
||||
const store_inst = scalar_cases_payload.items[extra_index];
|
||||
const store_inst = special_case_payload.items[extra_index];
|
||||
if (zir_tags[store_inst] != .store_to_block_ptr or
|
||||
zir_datas[store_inst].bin.lhs != block_scope.rl_ptr)
|
||||
{
|
||||
extra_index += 2;
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[0..extra_index]);
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]);
|
||||
break :special_prong;
|
||||
}
|
||||
assert(zir_datas[store_inst].bin.lhs == block_scope.rl_ptr);
|
||||
if (block_scope.rl_ty_inst != .none) {
|
||||
extra_index += 1;
|
||||
const break_inst = scalar_cases_payload.items[extra_index];
|
||||
const break_inst = special_case_payload.items[extra_index];
|
||||
extra_index += 1;
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[0..extra_index]);
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]);
|
||||
zir_tags[store_inst] = .as;
|
||||
zir_datas[store_inst].bin = .{
|
||||
.lhs = block_scope.rl_ty_inst,
|
||||
@ -6237,15 +6239,16 @@ fn switchExpr(
|
||||
};
|
||||
zir_datas[break_inst].@"break".operand = indexToRef(store_inst);
|
||||
} else {
|
||||
scalar_cases_payload.items[body_len_index] -= 1;
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[0..extra_index]);
|
||||
special_case_payload.items[body_len_index] -= 1;
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]);
|
||||
extra_index += 1;
|
||||
astgen.extra.appendAssumeCapacity(scalar_cases_payload.items[extra_index]);
|
||||
astgen.extra.appendAssumeCapacity(special_case_payload.items[extra_index]);
|
||||
extra_index += 1;
|
||||
}
|
||||
} else {
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[0..extra_index]);
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]);
|
||||
}
|
||||
extra_index = 0;
|
||||
var scalar_i: u32 = 0;
|
||||
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
|
||||
const start_index = extra_index;
|
||||
@ -6342,6 +6345,7 @@ fn switchExpr(
|
||||
},
|
||||
.break_void => {
|
||||
assert(!strat.elide_store_to_block_ptr_instructions);
|
||||
astgen.extra.appendSliceAssumeCapacity(special_case_payload.items);
|
||||
astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items);
|
||||
astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items);
|
||||
// Modify all the terminating instruction tags to become `break` variants.
|
||||
@ -9282,6 +9286,9 @@ const Scope = struct {
|
||||
/// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`, `Namespace`.
|
||||
parent: *Scope,
|
||||
defer_node: Ast.Node.Index,
|
||||
source_offset: u32,
|
||||
source_line: u32,
|
||||
source_column: u32,
|
||||
};
|
||||
|
||||
/// Represents a global scope that has any number of declarations in it.
|
||||
@ -9563,6 +9570,8 @@ const GenZir = struct {
|
||||
|
||||
fn addFunc(gz: *GenZir, args: struct {
|
||||
src_node: Ast.Node.Index,
|
||||
lbrace_line: u32 = 0,
|
||||
lbrace_column: u32 = 0,
|
||||
body: []const Zir.Inst.Index,
|
||||
param_block: Zir.Inst.Index,
|
||||
ret_ty: []const Zir.Inst.Index,
|
||||
@ -9592,19 +9601,13 @@ const GenZir = struct {
|
||||
const fn_decl = args.src_node;
|
||||
assert(node_tags[fn_decl] == .fn_decl or node_tags[fn_decl] == .test_decl);
|
||||
const block = node_datas[fn_decl].rhs;
|
||||
const lbrace_start = token_starts[tree.firstToken(block)];
|
||||
const rbrace_start = token_starts[tree.lastToken(block)];
|
||||
|
||||
astgen.advanceSourceCursor(tree.source, lbrace_start);
|
||||
const lbrace_line = @intCast(u32, astgen.source_line);
|
||||
const lbrace_column = @intCast(u32, astgen.source_column);
|
||||
|
||||
astgen.advanceSourceCursor(tree.source, rbrace_start);
|
||||
const rbrace_line = @intCast(u32, astgen.source_line);
|
||||
const rbrace_column = @intCast(u32, astgen.source_column);
|
||||
|
||||
const columns = lbrace_column | (rbrace_column << 16);
|
||||
src_locs_buffer[0] = lbrace_line;
|
||||
const columns = args.lbrace_column | (rbrace_column << 16);
|
||||
src_locs_buffer[0] = args.lbrace_line;
|
||||
src_locs_buffer[1] = rbrace_line;
|
||||
src_locs_buffer[2] = columns;
|
||||
src_locs = &src_locs_buffer;
|
||||
@ -10577,6 +10580,7 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {
|
||||
var i = astgen.source_offset;
|
||||
var line = astgen.source_line;
|
||||
var column = astgen.source_column;
|
||||
assert(i <= end);
|
||||
while (i < end) : (i += 1) {
|
||||
if (source[i] == '\n') {
|
||||
line += 1;
|
||||
|
||||
@ -1913,8 +1913,8 @@ const Writer = struct {
|
||||
try stream.writeAll(") ");
|
||||
if (body.len != 0) {
|
||||
try stream.print("(lbrace={d}:{d},rbrace={d}:{d}) ", .{
|
||||
src_locs.lbrace_line, @truncate(u16, src_locs.columns),
|
||||
src_locs.rbrace_line, @truncate(u16, src_locs.columns >> 16),
|
||||
src_locs.lbrace_line + 1, @truncate(u16, src_locs.columns) + 1,
|
||||
src_locs.rbrace_line + 1, @truncate(u16, src_locs.columns >> 16) + 1,
|
||||
});
|
||||
}
|
||||
try self.writeSrc(stream, src);
|
||||
@ -1928,7 +1928,7 @@ const Writer = struct {
|
||||
|
||||
fn writeDbgStmt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[inst].dbg_stmt;
|
||||
try stream.print("{d}, {d})", .{ inst_data.line, inst_data.column });
|
||||
try stream.print("{d}, {d})", .{ inst_data.line + 1, inst_data.column + 1 });
|
||||
}
|
||||
|
||||
fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user