mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 11:13:08 +00:00
stage2: add debug info for payload captures
This commit is contained in:
parent
a8520fbd0f
commit
739734170e
128
src/AstGen.zig
128
src/AstGen.zig
@ -2052,11 +2052,9 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
|||||||
const tree = astgen.tree;
|
const tree = astgen.tree;
|
||||||
const node_tags = tree.nodes.items(.tag);
|
const node_tags = tree.nodes.items(.tag);
|
||||||
|
|
||||||
_ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{
|
if (statements.len == 0) return;
|
||||||
.opcode = .dbg_block_begin,
|
|
||||||
.small = undefined,
|
try gz.addDbgBlockBegin();
|
||||||
.operand = undefined
|
|
||||||
} } });
|
|
||||||
|
|
||||||
var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
|
var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
|
||||||
defer block_arena.deinit();
|
defer block_arena.deinit();
|
||||||
@ -2111,11 +2109,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{
|
try gz.addDbgBlockEnd();
|
||||||
.opcode = .dbg_block_end,
|
|
||||||
.small = undefined,
|
|
||||||
.operand = undefined
|
|
||||||
} } });
|
|
||||||
|
|
||||||
try genDefers(gz, parent_scope, scope, .normal_only);
|
try genDefers(gz, parent_scope, scope, .normal_only);
|
||||||
try checkUsed(gz, parent_scope, scope);
|
try checkUsed(gz, parent_scope, scope);
|
||||||
@ -2539,6 +2533,7 @@ fn genDefers(
|
|||||||
gz.in_defer = true;
|
gz.in_defer = true;
|
||||||
defer gz.in_defer = prev_in_defer;
|
defer gz.in_defer = prev_in_defer;
|
||||||
var local_val_scope: Scope.LocalVal = undefined;
|
var local_val_scope: Scope.LocalVal = undefined;
|
||||||
|
try gz.addDbgBlockBegin();
|
||||||
const sub_scope = if (payload_token == 0) defer_scope.parent else blk: {
|
const sub_scope = if (payload_token == 0) defer_scope.parent else blk: {
|
||||||
const ident_name = try astgen.identAsString(payload_token);
|
const ident_name = try astgen.identAsString(payload_token);
|
||||||
local_val_scope = .{
|
local_val_scope = .{
|
||||||
@ -2549,9 +2544,11 @@ fn genDefers(
|
|||||||
.token_src = payload_token,
|
.token_src = payload_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
try gz.addDbgVar(.dbg_var_val, ident_name, err_code);
|
||||||
break :blk &local_val_scope.base;
|
break :blk &local_val_scope.base;
|
||||||
};
|
};
|
||||||
try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);
|
try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);
|
||||||
|
try gz.addDbgBlockEnd();
|
||||||
},
|
},
|
||||||
.normal_only => continue,
|
.normal_only => continue,
|
||||||
}
|
}
|
||||||
@ -2677,14 +2674,7 @@ fn varDecl(
|
|||||||
} else .none;
|
} else .none;
|
||||||
const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);
|
const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);
|
||||||
|
|
||||||
if (!gz.force_comptime) {
|
try gz.addDbgVar(.dbg_var_val, ident_name, init_inst);
|
||||||
_ = try gz.add(.{ .tag = .dbg_var_val, .data = .{
|
|
||||||
.str_op = .{
|
|
||||||
.str = ident_name,
|
|
||||||
.operand = init_inst,
|
|
||||||
},
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
|
|
||||||
const sub_scope = try block_arena.create(Scope.LocalVal);
|
const sub_scope = try block_arena.create(Scope.LocalVal);
|
||||||
sub_scope.* = .{
|
sub_scope.* = .{
|
||||||
@ -2778,14 +2768,7 @@ fn varDecl(
|
|||||||
else
|
else
|
||||||
init_inst;
|
init_inst;
|
||||||
|
|
||||||
if (!gz.force_comptime) {
|
try gz.addDbgVar(.dbg_var_val, ident_name, coerced_init);
|
||||||
_ = try gz.add(.{ .tag = .dbg_var_val, .data = .{
|
|
||||||
.str_op = .{
|
|
||||||
.str = ident_name,
|
|
||||||
.operand = coerced_init,
|
|
||||||
},
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
|
|
||||||
const sub_scope = try block_arena.create(Scope.LocalVal);
|
const sub_scope = try block_arena.create(Scope.LocalVal);
|
||||||
sub_scope.* = .{
|
sub_scope.* = .{
|
||||||
@ -2822,14 +2805,7 @@ fn varDecl(
|
|||||||
}
|
}
|
||||||
const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node);
|
const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node);
|
||||||
|
|
||||||
if (!gz.force_comptime) {
|
try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr);
|
||||||
_ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{
|
|
||||||
.str_op = .{
|
|
||||||
.str = ident_name,
|
|
||||||
.operand = const_ptr,
|
|
||||||
},
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
|
|
||||||
const sub_scope = try block_arena.create(Scope.LocalPtr);
|
const sub_scope = try block_arena.create(Scope.LocalPtr);
|
||||||
sub_scope.* = .{
|
sub_scope.* = .{
|
||||||
@ -2895,14 +2871,7 @@ fn varDecl(
|
|||||||
_ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
|
_ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gz.force_comptime) {
|
try gz.addDbgVar(.dbg_var_ptr, ident_name, var_data.alloc);
|
||||||
_ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{
|
|
||||||
.str_op = .{
|
|
||||||
.str = ident_name,
|
|
||||||
.operand = var_data.alloc,
|
|
||||||
},
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
|
|
||||||
const sub_scope = try block_arena.create(Scope.LocalPtr);
|
const sub_scope = try block_arena.create(Scope.LocalPtr);
|
||||||
sub_scope.* = .{
|
sub_scope.* = .{
|
||||||
@ -5199,6 +5168,7 @@ fn ifExpr(
|
|||||||
|
|
||||||
var payload_val_scope: Scope.LocalVal = undefined;
|
var payload_val_scope: Scope.LocalVal = undefined;
|
||||||
|
|
||||||
|
try then_scope.addDbgBlockBegin();
|
||||||
const then_sub_scope = s: {
|
const then_sub_scope = s: {
|
||||||
if (if_full.error_token != null) {
|
if (if_full.error_token != null) {
|
||||||
if (if_full.payload_token) |payload_token| {
|
if (if_full.payload_token) |payload_token| {
|
||||||
@ -5221,6 +5191,7 @@ fn ifExpr(
|
|||||||
.token_src = payload_token,
|
.token_src = payload_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst);
|
||||||
break :s &payload_val_scope.base;
|
break :s &payload_val_scope.base;
|
||||||
} else {
|
} else {
|
||||||
break :s &then_scope.base;
|
break :s &then_scope.base;
|
||||||
@ -5245,6 +5216,7 @@ fn ifExpr(
|
|||||||
.token_src = ident_token,
|
.token_src = ident_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst);
|
||||||
break :s &payload_val_scope.base;
|
break :s &payload_val_scope.base;
|
||||||
} else {
|
} else {
|
||||||
break :s &then_scope.base;
|
break :s &then_scope.base;
|
||||||
@ -5256,6 +5228,7 @@ fn ifExpr(
|
|||||||
block_scope.break_count += 1;
|
block_scope.break_count += 1;
|
||||||
}
|
}
|
||||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||||
|
try then_scope.addDbgBlockEnd();
|
||||||
// We hold off on the break instructions as well as copying the then/else
|
// We hold off on the break instructions as well as copying the then/else
|
||||||
// instructions into place until we know whether to keep store_to_block_ptr
|
// instructions into place until we know whether to keep store_to_block_ptr
|
||||||
// instructions or not.
|
// instructions or not.
|
||||||
@ -5268,6 +5241,7 @@ fn ifExpr(
|
|||||||
src: Ast.Node.Index,
|
src: Ast.Node.Index,
|
||||||
result: Zir.Inst.Ref,
|
result: Zir.Inst.Ref,
|
||||||
} = if (else_node != 0) blk: {
|
} = if (else_node != 0) blk: {
|
||||||
|
try else_scope.addDbgBlockBegin();
|
||||||
const sub_scope = s: {
|
const sub_scope = s: {
|
||||||
if (if_full.error_token) |error_token| {
|
if (if_full.error_token) |error_token| {
|
||||||
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
||||||
@ -5288,6 +5262,7 @@ fn ifExpr(
|
|||||||
.token_src = error_token,
|
.token_src = error_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
try else_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst);
|
||||||
break :s &payload_val_scope.base;
|
break :s &payload_val_scope.base;
|
||||||
} else {
|
} else {
|
||||||
break :s &else_scope.base;
|
break :s &else_scope.base;
|
||||||
@ -5298,6 +5273,7 @@ fn ifExpr(
|
|||||||
block_scope.break_count += 1;
|
block_scope.break_count += 1;
|
||||||
}
|
}
|
||||||
try checkUsed(parent_gz, &else_scope.base, sub_scope);
|
try checkUsed(parent_gz, &else_scope.base, sub_scope);
|
||||||
|
try else_scope.addDbgBlockEnd();
|
||||||
break :blk .{
|
break :blk .{
|
||||||
.src = else_node,
|
.src = else_node,
|
||||||
.result = e,
|
.result = e,
|
||||||
@ -5513,6 +5489,8 @@ fn whileExpr(
|
|||||||
then_scope.instructions_top = GenZir.unstacked_top;
|
then_scope.instructions_top = GenZir.unstacked_top;
|
||||||
defer then_scope.unstack();
|
defer then_scope.unstack();
|
||||||
|
|
||||||
|
var dbg_var_name: ?u32 = null;
|
||||||
|
var dbg_var_inst: Zir.Inst.Ref = undefined;
|
||||||
var payload_inst: Zir.Inst.Index = 0;
|
var payload_inst: Zir.Inst.Index = 0;
|
||||||
var payload_val_scope: Scope.LocalVal = undefined;
|
var payload_val_scope: Scope.LocalVal = undefined;
|
||||||
const then_sub_scope = s: {
|
const then_sub_scope = s: {
|
||||||
@ -5539,6 +5517,8 @@ fn whileExpr(
|
|||||||
.token_src = payload_token,
|
.token_src = payload_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
dbg_var_name = ident_name;
|
||||||
|
dbg_var_inst = indexToRef(payload_inst);
|
||||||
break :s &payload_val_scope.base;
|
break :s &payload_val_scope.base;
|
||||||
} else {
|
} else {
|
||||||
break :s &then_scope.base;
|
break :s &then_scope.base;
|
||||||
@ -5564,6 +5544,8 @@ fn whileExpr(
|
|||||||
.token_src = ident_token,
|
.token_src = ident_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
dbg_var_name = ident_name;
|
||||||
|
dbg_var_inst = indexToRef(payload_inst);
|
||||||
break :s &payload_val_scope.base;
|
break :s &payload_val_scope.base;
|
||||||
} else {
|
} else {
|
||||||
break :s &then_scope.base;
|
break :s &then_scope.base;
|
||||||
@ -5574,9 +5556,14 @@ fn whileExpr(
|
|||||||
// are no jumps to it. This happens when the last statement of a while body is noreturn
|
// are no jumps to it. This happens when the last statement of a while body is noreturn
|
||||||
// and there are no `continue` statements.
|
// and there are no `continue` statements.
|
||||||
// Tracking issue: https://github.com/ziglang/zig/issues/9185
|
// Tracking issue: https://github.com/ziglang/zig/issues/9185
|
||||||
|
try then_scope.addDbgBlockBegin();
|
||||||
|
if (dbg_var_name) |some| {
|
||||||
|
try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
|
||||||
|
}
|
||||||
if (while_full.ast.cont_expr != 0) {
|
if (while_full.ast.cont_expr != 0) {
|
||||||
_ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr);
|
_ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr);
|
||||||
}
|
}
|
||||||
|
try then_scope.addDbgBlockEnd();
|
||||||
const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;
|
const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;
|
||||||
_ = try loop_scope.addNode(repeat_tag, node);
|
_ = try loop_scope.addNode(repeat_tag, node);
|
||||||
|
|
||||||
@ -5592,9 +5579,15 @@ fn whileExpr(
|
|||||||
|
|
||||||
// done adding instructions to loop_scope, can now stack then_scope
|
// done adding instructions to loop_scope, can now stack then_scope
|
||||||
then_scope.instructions_top = then_scope.instructions.items.len;
|
then_scope.instructions_top = then_scope.instructions.items.len;
|
||||||
|
|
||||||
if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);
|
if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);
|
||||||
|
try then_scope.addDbgBlockBegin();
|
||||||
|
if (dbg_var_name) |some| {
|
||||||
|
try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
|
||||||
|
}
|
||||||
const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);
|
const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);
|
||||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||||
|
try then_scope.addDbgBlockEnd();
|
||||||
|
|
||||||
var else_scope = parent_gz.makeSubBlock(&continue_scope.base);
|
var else_scope = parent_gz.makeSubBlock(&continue_scope.base);
|
||||||
defer else_scope.unstack();
|
defer else_scope.unstack();
|
||||||
@ -5604,6 +5597,7 @@ fn whileExpr(
|
|||||||
src: Ast.Node.Index,
|
src: Ast.Node.Index,
|
||||||
result: Zir.Inst.Ref,
|
result: Zir.Inst.Ref,
|
||||||
} = if (else_node != 0) blk: {
|
} = if (else_node != 0) blk: {
|
||||||
|
try else_scope.addDbgBlockBegin();
|
||||||
const sub_scope = s: {
|
const sub_scope = s: {
|
||||||
if (while_full.error_token) |error_token| {
|
if (while_full.error_token) |error_token| {
|
||||||
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
const tag: Zir.Inst.Tag = if (payload_is_ref)
|
||||||
@ -5624,6 +5618,7 @@ fn whileExpr(
|
|||||||
.token_src = error_token,
|
.token_src = error_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
try else_scope.addDbgVar(.dbg_var_val, ident_name, else_payload_inst);
|
||||||
break :s &payload_val_scope.base;
|
break :s &payload_val_scope.base;
|
||||||
} else {
|
} else {
|
||||||
break :s &else_scope.base;
|
break :s &else_scope.base;
|
||||||
@ -5634,6 +5629,7 @@ fn whileExpr(
|
|||||||
loop_scope.break_count += 1;
|
loop_scope.break_count += 1;
|
||||||
}
|
}
|
||||||
try checkUsed(parent_gz, &else_scope.base, sub_scope);
|
try checkUsed(parent_gz, &else_scope.base, sub_scope);
|
||||||
|
try else_scope.addDbgBlockEnd();
|
||||||
break :blk .{
|
break :blk .{
|
||||||
.src = else_node,
|
.src = else_node,
|
||||||
.result = e,
|
.result = e,
|
||||||
@ -5755,6 +5751,7 @@ fn forExpr(
|
|||||||
then_scope.markAsLoopBody(loop_scope);
|
then_scope.markAsLoopBody(loop_scope);
|
||||||
defer then_scope.unstack();
|
defer then_scope.unstack();
|
||||||
|
|
||||||
|
try then_scope.addDbgBlockBegin();
|
||||||
var payload_val_scope: Scope.LocalVal = undefined;
|
var payload_val_scope: Scope.LocalVal = undefined;
|
||||||
var index_scope: Scope.LocalPtr = undefined;
|
var index_scope: Scope.LocalPtr = undefined;
|
||||||
const then_sub_scope = blk: {
|
const then_sub_scope = blk: {
|
||||||
@ -5779,6 +5776,7 @@ fn forExpr(
|
|||||||
.token_src = ident,
|
.token_src = ident,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
try then_scope.addDbgVar(.dbg_var_val, name_str_index, payload_inst);
|
||||||
payload_sub_scope = &payload_val_scope.base;
|
payload_sub_scope = &payload_val_scope.base;
|
||||||
} else if (is_ptr) {
|
} else if (is_ptr) {
|
||||||
return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
|
return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
|
||||||
@ -5805,11 +5803,13 @@ fn forExpr(
|
|||||||
.maybe_comptime = is_inline,
|
.maybe_comptime = is_inline,
|
||||||
.id_cat = .@"loop index capture",
|
.id_cat = .@"loop index capture",
|
||||||
};
|
};
|
||||||
|
try then_scope.addDbgVar(.dbg_var_val, index_name, index_ptr);
|
||||||
break :blk &index_scope.base;
|
break :blk &index_scope.base;
|
||||||
};
|
};
|
||||||
|
|
||||||
const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr);
|
const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr);
|
||||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||||
|
try then_scope.addDbgBlockEnd();
|
||||||
|
|
||||||
var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
||||||
defer else_scope.unstack();
|
defer else_scope.unstack();
|
||||||
@ -6028,6 +6028,8 @@ fn switchExpr(
|
|||||||
const is_multi_case = case.ast.values.len > 1 or
|
const is_multi_case = case.ast.values.len > 1 or
|
||||||
(case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);
|
(case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);
|
||||||
|
|
||||||
|
var dbg_var_name: ?u32 = null;
|
||||||
|
var dbg_var_inst: Zir.Inst.Ref = undefined;
|
||||||
var capture_inst: Zir.Inst.Index = 0;
|
var capture_inst: Zir.Inst.Index = 0;
|
||||||
var capture_val_scope: Scope.LocalVal = undefined;
|
var capture_val_scope: Scope.LocalVal = undefined;
|
||||||
const sub_scope = blk: {
|
const sub_scope = blk: {
|
||||||
@ -6087,6 +6089,8 @@ fn switchExpr(
|
|||||||
.token_src = payload_token,
|
.token_src = payload_token,
|
||||||
.id_cat = .@"capture",
|
.id_cat = .@"capture",
|
||||||
};
|
};
|
||||||
|
dbg_var_name = capture_name;
|
||||||
|
dbg_var_inst = indexToRef(capture_inst);
|
||||||
break :blk &capture_val_scope.base;
|
break :blk &capture_val_scope.base;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -6142,12 +6146,17 @@ fn switchExpr(
|
|||||||
defer case_scope.unstack();
|
defer case_scope.unstack();
|
||||||
|
|
||||||
if (capture_inst != 0) try case_scope.instructions.append(gpa, capture_inst);
|
if (capture_inst != 0) try case_scope.instructions.append(gpa, capture_inst);
|
||||||
|
try case_scope.addDbgBlockBegin();
|
||||||
|
if (dbg_var_name) |some| {
|
||||||
|
try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
|
||||||
|
}
|
||||||
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr);
|
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);
|
try checkUsed(parent_gz, &case_scope.base, sub_scope);
|
||||||
if (!parent_gz.refIsNoReturn(case_result)) {
|
if (!parent_gz.refIsNoReturn(case_result)) {
|
||||||
block_scope.break_count += 1;
|
block_scope.break_count += 1;
|
||||||
_ = try case_scope.addBreak(.@"break", switch_block, case_result);
|
_ = try case_scope.addBreak(.@"break", switch_block, case_result);
|
||||||
}
|
}
|
||||||
|
try case_scope.addDbgBlockEnd();
|
||||||
|
|
||||||
const case_slice = case_scope.instructionsSlice();
|
const case_slice = case_scope.instructionsSlice();
|
||||||
payloads.items[body_len_index] = @intCast(u32, case_slice.len);
|
payloads.items[body_len_index] = @intCast(u32, case_slice.len);
|
||||||
@ -10841,6 +10850,41 @@ const GenZir = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void {
|
||||||
|
if (gz.force_comptime) return;
|
||||||
|
|
||||||
|
_ = try gz.add(.{ .tag = tag, .data = .{
|
||||||
|
.str_op = .{
|
||||||
|
.str = name,
|
||||||
|
.operand = inst,
|
||||||
|
},
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addDbgBlockBegin(gz: *GenZir) !void {
|
||||||
|
if (gz.force_comptime) return;
|
||||||
|
|
||||||
|
_ = try gz.add(.{ .tag = .extended, .data = .{
|
||||||
|
.extended = .{ .opcode = .dbg_block_begin, .small = undefined, .operand = undefined },
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn addDbgBlockEnd(gz: *GenZir) !void {
|
||||||
|
if (gz.force_comptime) return;
|
||||||
|
|
||||||
|
if (gz.endsWithNoReturn()) {
|
||||||
|
const last = gz.instructions.pop();
|
||||||
|
_ = try gz.add(.{ .tag = .extended, .data = .{
|
||||||
|
.extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
|
||||||
|
} });
|
||||||
|
try gz.instructions.append(gz.astgen.gpa, last);
|
||||||
|
} else {
|
||||||
|
_ = try gz.add(.{ .tag = .extended, .data = .{
|
||||||
|
.extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Control flow does not fall through the "then" block of a loop; it continues
|
/// Control flow does not fall through the "then" block of a loop; it continues
|
||||||
/// back to the while condition. This prevents `rvalue` from
|
/// back to the while condition. This prevents `rvalue` from
|
||||||
/// adding an invalid store to the result location of `then_scope`.
|
/// adding an invalid store to the result location of `then_scope`.
|
||||||
|
|||||||
97
src/Sema.zig
97
src/Sema.zig
@ -788,7 +788,6 @@ fn analyzeBodyInner(
|
|||||||
.@"resume" => try sema.zirResume(block, inst),
|
.@"resume" => try sema.zirResume(block, inst),
|
||||||
.@"await" => try sema.zirAwait(block, inst, false),
|
.@"await" => try sema.zirAwait(block, inst, false),
|
||||||
.await_nosuspend => try sema.zirAwait(block, inst, true),
|
.await_nosuspend => try sema.zirAwait(block, inst, true),
|
||||||
.extended => try sema.zirExtended(block, inst),
|
|
||||||
.array_base_ptr => try sema.zirArrayBasePtr(block, inst),
|
.array_base_ptr => try sema.zirArrayBasePtr(block, inst),
|
||||||
.field_base_ptr => try sema.zirFieldBasePtr(block, inst),
|
.field_base_ptr => try sema.zirFieldBasePtr(block, inst),
|
||||||
|
|
||||||
@ -850,6 +849,53 @@ fn analyzeBodyInner(
|
|||||||
.panic => break sema.zirPanic(block, inst),
|
.panic => break sema.zirPanic(block, inst),
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
|
|
||||||
|
.extended => ext: {
|
||||||
|
const extended = datas[inst].extended;
|
||||||
|
break :ext switch (extended.opcode) {
|
||||||
|
// zig fmt: off
|
||||||
|
.func => try sema.zirFuncExtended( block, extended, inst),
|
||||||
|
.variable => try sema.zirVarExtended( block, extended),
|
||||||
|
.struct_decl => try sema.zirStructDecl( block, extended, inst),
|
||||||
|
.enum_decl => try sema.zirEnumDecl( block, extended),
|
||||||
|
.union_decl => try sema.zirUnionDecl( block, extended, inst),
|
||||||
|
.opaque_decl => try sema.zirOpaqueDecl( block, extended),
|
||||||
|
.ret_ptr => try sema.zirRetPtr( block, extended),
|
||||||
|
.ret_type => try sema.zirRetType( block, extended),
|
||||||
|
.this => try sema.zirThis( block, extended),
|
||||||
|
.ret_addr => try sema.zirRetAddr( block, extended),
|
||||||
|
.builtin_src => try sema.zirBuiltinSrc( block, extended),
|
||||||
|
.error_return_trace => try sema.zirErrorReturnTrace( block, extended),
|
||||||
|
.frame => try sema.zirFrame( block, extended),
|
||||||
|
.frame_address => try sema.zirFrameAddress( block, extended),
|
||||||
|
.alloc => try sema.zirAllocExtended( block, extended),
|
||||||
|
.builtin_extern => try sema.zirBuiltinExtern( block, extended),
|
||||||
|
.@"asm" => try sema.zirAsm( block, extended),
|
||||||
|
.typeof_peer => try sema.zirTypeofPeer( block, extended),
|
||||||
|
.compile_log => try sema.zirCompileLog( block, extended),
|
||||||
|
.add_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||||
|
.sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||||
|
.mul_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||||
|
.shl_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
||||||
|
.c_undef => try sema.zirCUndef( block, extended),
|
||||||
|
.c_include => try sema.zirCInclude( block, extended),
|
||||||
|
.c_define => try sema.zirCDefine( block, extended),
|
||||||
|
.wasm_memory_size => try sema.zirWasmMemorySize( block, extended),
|
||||||
|
.wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
|
||||||
|
.prefetch => try sema.zirPrefetch( block, extended),
|
||||||
|
// zig fmt: on
|
||||||
|
.dbg_block_begin => {
|
||||||
|
try sema.zirDbgBlockBegin(block);
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
.dbg_block_end => {
|
||||||
|
try sema.zirDbgBlockEnd(block);
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
// Instructions that we know can *never* be noreturn based solely on
|
// Instructions that we know can *never* be noreturn based solely on
|
||||||
// their tag. We avoid needlessly checking if they are noreturn and
|
// their tag. We avoid needlessly checking if they are noreturn and
|
||||||
// continue the loop.
|
// continue the loop.
|
||||||
@ -1183,45 +1229,6 @@ fn analyzeBodyInner(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
|
||||||
const extended = sema.code.instructions.items(.data)[inst].extended;
|
|
||||||
switch (extended.opcode) {
|
|
||||||
// zig fmt: off
|
|
||||||
.func => return sema.zirFuncExtended( block, extended, inst),
|
|
||||||
.variable => return sema.zirVarExtended( block, extended),
|
|
||||||
.struct_decl => return sema.zirStructDecl( block, extended, inst),
|
|
||||||
.enum_decl => return sema.zirEnumDecl( block, extended),
|
|
||||||
.union_decl => return sema.zirUnionDecl( block, extended, inst),
|
|
||||||
.opaque_decl => return sema.zirOpaqueDecl( block, extended),
|
|
||||||
.ret_ptr => return sema.zirRetPtr( block, extended),
|
|
||||||
.ret_type => return sema.zirRetType( block, extended),
|
|
||||||
.this => return sema.zirThis( block, extended),
|
|
||||||
.ret_addr => return sema.zirRetAddr( block, extended),
|
|
||||||
.builtin_src => return sema.zirBuiltinSrc( block, extended),
|
|
||||||
.error_return_trace => return sema.zirErrorReturnTrace( block, extended),
|
|
||||||
.frame => return sema.zirFrame( block, extended),
|
|
||||||
.frame_address => return sema.zirFrameAddress( block, extended),
|
|
||||||
.alloc => return sema.zirAllocExtended( block, extended),
|
|
||||||
.builtin_extern => return sema.zirBuiltinExtern( block, extended),
|
|
||||||
.@"asm" => return sema.zirAsm( block, extended),
|
|
||||||
.typeof_peer => return sema.zirTypeofPeer( block, extended),
|
|
||||||
.compile_log => return sema.zirCompileLog( block, extended),
|
|
||||||
.add_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
|
||||||
.sub_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
|
||||||
.mul_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
|
||||||
.shl_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
|
|
||||||
.c_undef => return sema.zirCUndef( block, extended),
|
|
||||||
.c_include => return sema.zirCInclude( block, extended),
|
|
||||||
.c_define => return sema.zirCDefine( block, extended),
|
|
||||||
.wasm_memory_size => return sema.zirWasmMemorySize( block, extended),
|
|
||||||
.wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),
|
|
||||||
.prefetch => return sema.zirPrefetch( block, extended),
|
|
||||||
.dbg_block_begin => return sema.zirDbgBlockBegin( block),
|
|
||||||
.dbg_block_end => return sema.zirDbgBlockEnd( block),
|
|
||||||
// zig fmt: on
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref {
|
pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref {
|
||||||
var i: usize = @enumToInt(zir_ref);
|
var i: usize = @enumToInt(zir_ref);
|
||||||
|
|
||||||
@ -4217,24 +4224,22 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
|
fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void {
|
||||||
if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return .void_value;
|
if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
|
||||||
|
|
||||||
_ = try block.addInst(.{
|
_ = try block.addInst(.{
|
||||||
.tag = .dbg_block_begin,
|
.tag = .dbg_block_begin,
|
||||||
.data = undefined,
|
.data = undefined,
|
||||||
});
|
});
|
||||||
return .void_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
|
fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!void {
|
||||||
if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return .void_value;
|
if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
|
||||||
|
|
||||||
_ = try block.addInst(.{
|
_ = try block.addInst(.{
|
||||||
.tag = .dbg_block_end,
|
.tag = .dbg_block_end,
|
||||||
.data = undefined,
|
.data = undefined,
|
||||||
});
|
});
|
||||||
return .void_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zirDbgVar(
|
fn zirDbgVar(
|
||||||
|
|||||||
@ -173,6 +173,7 @@ test "while with optional as condition with else" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "while with error union condition" {
|
test "while with error union condition" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
|
||||||
@ -289,6 +290,7 @@ test "while bool 2 break statements and an else" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "while optional 2 break statements and an else" {
|
test "while optional 2 break statements and an else" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
@ -307,6 +309,7 @@ test "while optional 2 break statements and an else" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "while error 2 break statements and an else" {
|
test "while error 2 break statements and an else" {
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user