authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-18 13:22:44+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-19 11:20:38+02:00
log739734170e788f20a5c1d1f9f74cc7abf6efebf6
tree323bc30abd43dd4c7651d38ea17824765b6db3ea
parenta8520fbd0f73c57d133c28c44d97e1173c6fe381

stage2: add debug info for payload captures


3 files changed, 140 insertions(+), 88 deletions(-)

src/AstGen.zig+86-42
...@@ -2052,11 +2052,9 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod...@@ -2052,11 +2052,9 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
2052 const tree = astgen.tree;2052 const tree = astgen.tree;
2053 const node_tags = tree.nodes.items(.tag);2053 const node_tags = tree.nodes.items(.tag);
20542054
2055 _ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{2055 if (statements.len == 0) return;
2056 .opcode = .dbg_block_begin,2056
2057 .small = undefined,2057 try gz.addDbgBlockBegin();
2058 .operand = undefined
2059 } } });
20602058
2061 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);2059 var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa);
2062 defer block_arena.deinit();2060 defer block_arena.deinit();
...@@ -2111,11 +2109,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod...@@ -2111,11 +2109,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
2111 }2109 }
2112 }2110 }
21132111
2114 _ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{2112 try gz.addDbgBlockEnd();
2115 .opcode = .dbg_block_end,
2116 .small = undefined,
2117 .operand = undefined
2118 } } });
21192113
2120 try genDefers(gz, parent_scope, scope, .normal_only);2114 try genDefers(gz, parent_scope, scope, .normal_only);
2121 try checkUsed(gz, parent_scope, scope);2115 try checkUsed(gz, parent_scope, scope);
...@@ -2539,6 +2533,7 @@ fn genDefers(...@@ -2539,6 +2533,7 @@ fn genDefers(
2539 gz.in_defer = true;2533 gz.in_defer = true;
2540 defer gz.in_defer = prev_in_defer;2534 defer gz.in_defer = prev_in_defer;
2541 var local_val_scope: Scope.LocalVal = undefined;2535 var local_val_scope: Scope.LocalVal = undefined;
2536 try gz.addDbgBlockBegin();
2542 const sub_scope = if (payload_token == 0) defer_scope.parent else blk: {2537 const sub_scope = if (payload_token == 0) defer_scope.parent else blk: {
2543 const ident_name = try astgen.identAsString(payload_token);2538 const ident_name = try astgen.identAsString(payload_token);
2544 local_val_scope = .{2539 local_val_scope = .{
...@@ -2549,9 +2544,11 @@ fn genDefers(...@@ -2549,9 +2544,11 @@ fn genDefers(
2549 .token_src = payload_token,2544 .token_src = payload_token,
2550 .id_cat = .@"capture",2545 .id_cat = .@"capture",
2551 };2546 };
2547 try gz.addDbgVar(.dbg_var_val, ident_name, err_code);
2552 break :blk &local_val_scope.base;2548 break :blk &local_val_scope.base;
2553 };2549 };
2554 try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);2550 try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node);
2551 try gz.addDbgBlockEnd();
2555 },2552 },
2556 .normal_only => continue,2553 .normal_only => continue,
2557 }2554 }
...@@ -2677,14 +2674,7 @@ fn varDecl(...@@ -2677,14 +2674,7 @@ fn varDecl(
2677 } else .none;2674 } else .none;
2678 const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);2675 const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node);
26792676
2680 if (!gz.force_comptime) {2677 try gz.addDbgVar(.dbg_var_val, ident_name, init_inst);
2681 _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{
2682 .str_op = .{
2683 .str = ident_name,
2684 .operand = init_inst,
2685 },
2686 } });
2687 }
26882678
2689 const sub_scope = try block_arena.create(Scope.LocalVal);2679 const sub_scope = try block_arena.create(Scope.LocalVal);
2690 sub_scope.* = .{2680 sub_scope.* = .{
...@@ -2778,14 +2768,7 @@ fn varDecl(...@@ -2778,14 +2768,7 @@ fn varDecl(
2778 else2768 else
2779 init_inst;2769 init_inst;
27802770
2781 if (!gz.force_comptime) {2771 try gz.addDbgVar(.dbg_var_val, ident_name, coerced_init);
2782 _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{
2783 .str_op = .{
2784 .str = ident_name,
2785 .operand = coerced_init,
2786 },
2787 } });
2788 }
27892772
2790 const sub_scope = try block_arena.create(Scope.LocalVal);2773 const sub_scope = try block_arena.create(Scope.LocalVal);
2791 sub_scope.* = .{2774 sub_scope.* = .{
...@@ -2822,14 +2805,7 @@ fn varDecl(...@@ -2822,14 +2805,7 @@ fn varDecl(
2822 }2805 }
2823 const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node);2806 const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node);
28242807
2825 if (!gz.force_comptime) {2808 try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr);
2826 _ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{
2827 .str_op = .{
2828 .str = ident_name,
2829 .operand = const_ptr,
2830 },
2831 } });
2832 }
28332809
2834 const sub_scope = try block_arena.create(Scope.LocalPtr);2810 const sub_scope = try block_arena.create(Scope.LocalPtr);
2835 sub_scope.* = .{2811 sub_scope.* = .{
...@@ -2895,14 +2871,7 @@ fn varDecl(...@@ -2895,14 +2871,7 @@ fn varDecl(
2895 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);2871 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
2896 }2872 }
28972873
2898 if (!gz.force_comptime) {2874 try gz.addDbgVar(.dbg_var_ptr, ident_name, var_data.alloc);
2899 _ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{
2900 .str_op = .{
2901 .str = ident_name,
2902 .operand = var_data.alloc,
2903 },
2904 } });
2905 }
29062875
2907 const sub_scope = try block_arena.create(Scope.LocalPtr);2876 const sub_scope = try block_arena.create(Scope.LocalPtr);
2908 sub_scope.* = .{2877 sub_scope.* = .{
...@@ -5199,6 +5168,7 @@ fn ifExpr(...@@ -5199,6 +5168,7 @@ fn ifExpr(
51995168
5200 var payload_val_scope: Scope.LocalVal = undefined;5169 var payload_val_scope: Scope.LocalVal = undefined;
52015170
5171 try then_scope.addDbgBlockBegin();
5202 const then_sub_scope = s: {5172 const then_sub_scope = s: {
5203 if (if_full.error_token != null) {5173 if (if_full.error_token != null) {
5204 if (if_full.payload_token) |payload_token| {5174 if (if_full.payload_token) |payload_token| {
...@@ -5221,6 +5191,7 @@ fn ifExpr(...@@ -5221,6 +5191,7 @@ fn ifExpr(
5221 .token_src = payload_token,5191 .token_src = payload_token,
5222 .id_cat = .@"capture",5192 .id_cat = .@"capture",
5223 };5193 };
5194 try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst);
5224 break :s &payload_val_scope.base;5195 break :s &payload_val_scope.base;
5225 } else {5196 } else {
5226 break :s &then_scope.base;5197 break :s &then_scope.base;
...@@ -5245,6 +5216,7 @@ fn ifExpr(...@@ -5245,6 +5216,7 @@ fn ifExpr(
5245 .token_src = ident_token,5216 .token_src = ident_token,
5246 .id_cat = .@"capture",5217 .id_cat = .@"capture",
5247 };5218 };
5219 try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst);
5248 break :s &payload_val_scope.base;5220 break :s &payload_val_scope.base;
5249 } else {5221 } else {
5250 break :s &then_scope.base;5222 break :s &then_scope.base;
...@@ -5256,6 +5228,7 @@ fn ifExpr(...@@ -5256,6 +5228,7 @@ fn ifExpr(
5256 block_scope.break_count += 1;5228 block_scope.break_count += 1;
5257 }5229 }
5258 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);5230 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
5231 try then_scope.addDbgBlockEnd();
5259 // We hold off on the break instructions as well as copying the then/else5232 // We hold off on the break instructions as well as copying the then/else
5260 // instructions into place until we know whether to keep store_to_block_ptr5233 // instructions into place until we know whether to keep store_to_block_ptr
5261 // instructions or not.5234 // instructions or not.
...@@ -5268,6 +5241,7 @@ fn ifExpr(...@@ -5268,6 +5241,7 @@ fn ifExpr(
5268 src: Ast.Node.Index,5241 src: Ast.Node.Index,
5269 result: Zir.Inst.Ref,5242 result: Zir.Inst.Ref,
5270 } = if (else_node != 0) blk: {5243 } = if (else_node != 0) blk: {
5244 try else_scope.addDbgBlockBegin();
5271 const sub_scope = s: {5245 const sub_scope = s: {
5272 if (if_full.error_token) |error_token| {5246 if (if_full.error_token) |error_token| {
5273 const tag: Zir.Inst.Tag = if (payload_is_ref)5247 const tag: Zir.Inst.Tag = if (payload_is_ref)
...@@ -5288,6 +5262,7 @@ fn ifExpr(...@@ -5288,6 +5262,7 @@ fn ifExpr(
5288 .token_src = error_token,5262 .token_src = error_token,
5289 .id_cat = .@"capture",5263 .id_cat = .@"capture",
5290 };5264 };
5265 try else_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst);
5291 break :s &payload_val_scope.base;5266 break :s &payload_val_scope.base;
5292 } else {5267 } else {
5293 break :s &else_scope.base;5268 break :s &else_scope.base;
...@@ -5298,6 +5273,7 @@ fn ifExpr(...@@ -5298,6 +5273,7 @@ fn ifExpr(
5298 block_scope.break_count += 1;5273 block_scope.break_count += 1;
5299 }5274 }
5300 try checkUsed(parent_gz, &else_scope.base, sub_scope);5275 try checkUsed(parent_gz, &else_scope.base, sub_scope);
5276 try else_scope.addDbgBlockEnd();
5301 break :blk .{5277 break :blk .{
5302 .src = else_node,5278 .src = else_node,
5303 .result = e,5279 .result = e,
...@@ -5513,6 +5489,8 @@ fn whileExpr(...@@ -5513,6 +5489,8 @@ fn whileExpr(
5513 then_scope.instructions_top = GenZir.unstacked_top;5489 then_scope.instructions_top = GenZir.unstacked_top;
5514 defer then_scope.unstack();5490 defer then_scope.unstack();
55155491
5492 var dbg_var_name: ?u32 = null;
5493 var dbg_var_inst: Zir.Inst.Ref = undefined;
5516 var payload_inst: Zir.Inst.Index = 0;5494 var payload_inst: Zir.Inst.Index = 0;
5517 var payload_val_scope: Scope.LocalVal = undefined;5495 var payload_val_scope: Scope.LocalVal = undefined;
5518 const then_sub_scope = s: {5496 const then_sub_scope = s: {
...@@ -5539,6 +5517,8 @@ fn whileExpr(...@@ -5539,6 +5517,8 @@ fn whileExpr(
5539 .token_src = payload_token,5517 .token_src = payload_token,
5540 .id_cat = .@"capture",5518 .id_cat = .@"capture",
5541 };5519 };
5520 dbg_var_name = ident_name;
5521 dbg_var_inst = indexToRef(payload_inst);
5542 break :s &payload_val_scope.base;5522 break :s &payload_val_scope.base;
5543 } else {5523 } else {
5544 break :s &then_scope.base;5524 break :s &then_scope.base;
...@@ -5564,6 +5544,8 @@ fn whileExpr(...@@ -5564,6 +5544,8 @@ fn whileExpr(
5564 .token_src = ident_token,5544 .token_src = ident_token,
5565 .id_cat = .@"capture",5545 .id_cat = .@"capture",
5566 };5546 };
5547 dbg_var_name = ident_name;
5548 dbg_var_inst = indexToRef(payload_inst);
5567 break :s &payload_val_scope.base;5549 break :s &payload_val_scope.base;
5568 } else {5550 } else {
5569 break :s &then_scope.base;5551 break :s &then_scope.base;
...@@ -5574,9 +5556,14 @@ fn whileExpr(...@@ -5574,9 +5556,14 @@ fn whileExpr(
5574 // are no jumps to it. This happens when the last statement of a while body is noreturn5556 // are no jumps to it. This happens when the last statement of a while body is noreturn
5575 // and there are no `continue` statements.5557 // and there are no `continue` statements.
5576 // Tracking issue: https://github.com/ziglang/zig/issues/91855558 // Tracking issue: https://github.com/ziglang/zig/issues/9185
5559 try then_scope.addDbgBlockBegin();
5560 if (dbg_var_name) |some| {
5561 try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
5562 }
5577 if (while_full.ast.cont_expr != 0) {5563 if (while_full.ast.cont_expr != 0) {
5578 _ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr);5564 _ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr);
5579 }5565 }
5566 try then_scope.addDbgBlockEnd();
5580 const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;5567 const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;
5581 _ = try loop_scope.addNode(repeat_tag, node);5568 _ = try loop_scope.addNode(repeat_tag, node);
55825569
...@@ -5592,9 +5579,15 @@ fn whileExpr(...@@ -5592,9 +5579,15 @@ fn whileExpr(
55925579
5593 // done adding instructions to loop_scope, can now stack then_scope5580 // done adding instructions to loop_scope, can now stack then_scope
5594 then_scope.instructions_top = then_scope.instructions.items.len;5581 then_scope.instructions_top = then_scope.instructions.items.len;
5582
5595 if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);5583 if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);
5584 try then_scope.addDbgBlockBegin();
5585 if (dbg_var_name) |some| {
5586 try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
5587 }
5596 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);5588 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr);
5597 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);5589 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
5590 try then_scope.addDbgBlockEnd();
55985591
5599 var else_scope = parent_gz.makeSubBlock(&continue_scope.base);5592 var else_scope = parent_gz.makeSubBlock(&continue_scope.base);
5600 defer else_scope.unstack();5593 defer else_scope.unstack();
...@@ -5604,6 +5597,7 @@ fn whileExpr(...@@ -5604,6 +5597,7 @@ fn whileExpr(
5604 src: Ast.Node.Index,5597 src: Ast.Node.Index,
5605 result: Zir.Inst.Ref,5598 result: Zir.Inst.Ref,
5606 } = if (else_node != 0) blk: {5599 } = if (else_node != 0) blk: {
5600 try else_scope.addDbgBlockBegin();
5607 const sub_scope = s: {5601 const sub_scope = s: {
5608 if (while_full.error_token) |error_token| {5602 if (while_full.error_token) |error_token| {
5609 const tag: Zir.Inst.Tag = if (payload_is_ref)5603 const tag: Zir.Inst.Tag = if (payload_is_ref)
...@@ -5624,6 +5618,7 @@ fn whileExpr(...@@ -5624,6 +5618,7 @@ fn whileExpr(
5624 .token_src = error_token,5618 .token_src = error_token,
5625 .id_cat = .@"capture",5619 .id_cat = .@"capture",
5626 };5620 };
5621 try else_scope.addDbgVar(.dbg_var_val, ident_name, else_payload_inst);
5627 break :s &payload_val_scope.base;5622 break :s &payload_val_scope.base;
5628 } else {5623 } else {
5629 break :s &else_scope.base;5624 break :s &else_scope.base;
...@@ -5634,6 +5629,7 @@ fn whileExpr(...@@ -5634,6 +5629,7 @@ fn whileExpr(
5634 loop_scope.break_count += 1;5629 loop_scope.break_count += 1;
5635 }5630 }
5636 try checkUsed(parent_gz, &else_scope.base, sub_scope);5631 try checkUsed(parent_gz, &else_scope.base, sub_scope);
5632 try else_scope.addDbgBlockEnd();
5637 break :blk .{5633 break :blk .{
5638 .src = else_node,5634 .src = else_node,
5639 .result = e,5635 .result = e,
...@@ -5755,6 +5751,7 @@ fn forExpr(...@@ -5755,6 +5751,7 @@ fn forExpr(
5755 then_scope.markAsLoopBody(loop_scope);5751 then_scope.markAsLoopBody(loop_scope);
5756 defer then_scope.unstack();5752 defer then_scope.unstack();
57575753
5754 try then_scope.addDbgBlockBegin();
5758 var payload_val_scope: Scope.LocalVal = undefined;5755 var payload_val_scope: Scope.LocalVal = undefined;
5759 var index_scope: Scope.LocalPtr = undefined;5756 var index_scope: Scope.LocalPtr = undefined;
5760 const then_sub_scope = blk: {5757 const then_sub_scope = blk: {
...@@ -5779,6 +5776,7 @@ fn forExpr(...@@ -5779,6 +5776,7 @@ fn forExpr(
5779 .token_src = ident,5776 .token_src = ident,
5780 .id_cat = .@"capture",5777 .id_cat = .@"capture",
5781 };5778 };
5779 try then_scope.addDbgVar(.dbg_var_val, name_str_index, payload_inst);
5782 payload_sub_scope = &payload_val_scope.base;5780 payload_sub_scope = &payload_val_scope.base;
5783 } else if (is_ptr) {5781 } else if (is_ptr) {
5784 return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});5782 return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
...@@ -5805,11 +5803,13 @@ fn forExpr(...@@ -5805,11 +5803,13 @@ fn forExpr(
5805 .maybe_comptime = is_inline,5803 .maybe_comptime = is_inline,
5806 .id_cat = .@"loop index capture",5804 .id_cat = .@"loop index capture",
5807 };5805 };
5806 try then_scope.addDbgVar(.dbg_var_val, index_name, index_ptr);
5808 break :blk &index_scope.base;5807 break :blk &index_scope.base;
5809 };5808 };
58105809
5811 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr);5810 const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr);
5812 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);5811 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
5812 try then_scope.addDbgBlockEnd();
58135813
5814 var else_scope = parent_gz.makeSubBlock(&cond_scope.base);5814 var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
5815 defer else_scope.unstack();5815 defer else_scope.unstack();
...@@ -6028,6 +6028,8 @@ fn switchExpr(...@@ -6028,6 +6028,8 @@ fn switchExpr(
6028 const is_multi_case = case.ast.values.len > 1 or6028 const is_multi_case = case.ast.values.len > 1 or
6029 (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);6029 (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);
60306030
6031 var dbg_var_name: ?u32 = null;
6032 var dbg_var_inst: Zir.Inst.Ref = undefined;
6031 var capture_inst: Zir.Inst.Index = 0;6033 var capture_inst: Zir.Inst.Index = 0;
6032 var capture_val_scope: Scope.LocalVal = undefined;6034 var capture_val_scope: Scope.LocalVal = undefined;
6033 const sub_scope = blk: {6035 const sub_scope = blk: {
...@@ -6087,6 +6089,8 @@ fn switchExpr(...@@ -6087,6 +6089,8 @@ fn switchExpr(
6087 .token_src = payload_token,6089 .token_src = payload_token,
6088 .id_cat = .@"capture",6090 .id_cat = .@"capture",
6089 };6091 };
6092 dbg_var_name = capture_name;
6093 dbg_var_inst = indexToRef(capture_inst);
6090 break :blk &capture_val_scope.base;6094 break :blk &capture_val_scope.base;
6091 };6095 };
60926096
...@@ -6142,12 +6146,17 @@ fn switchExpr(...@@ -6142,12 +6146,17 @@ fn switchExpr(
6142 defer case_scope.unstack();6146 defer case_scope.unstack();
61436147
6144 if (capture_inst != 0) try case_scope.instructions.append(gpa, capture_inst);6148 if (capture_inst != 0) try case_scope.instructions.append(gpa, capture_inst);
6149 try case_scope.addDbgBlockBegin();
6150 if (dbg_var_name) |some| {
6151 try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
6152 }
6145 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr);6153 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr);
6146 try checkUsed(parent_gz, &case_scope.base, sub_scope);6154 try checkUsed(parent_gz, &case_scope.base, sub_scope);
6147 if (!parent_gz.refIsNoReturn(case_result)) {6155 if (!parent_gz.refIsNoReturn(case_result)) {
6148 block_scope.break_count += 1;6156 block_scope.break_count += 1;
6149 _ = try case_scope.addBreak(.@"break", switch_block, case_result);6157 _ = try case_scope.addBreak(.@"break", switch_block, case_result);
6150 }6158 }
6159 try case_scope.addDbgBlockEnd();
61516160
6152 const case_slice = case_scope.instructionsSlice();6161 const case_slice = case_scope.instructionsSlice();
6153 payloads.items[body_len_index] = @intCast(u32, case_slice.len);6162 payloads.items[body_len_index] = @intCast(u32, case_slice.len);
...@@ -10841,6 +10850,41 @@ const GenZir = struct {...@@ -10841,6 +10850,41 @@ const GenZir = struct {
10841 }10850 }
10842 }10851 }
1084310852
10853 fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void {
10854 if (gz.force_comptime) return;
10855
10856 _ = try gz.add(.{ .tag = tag, .data = .{
10857 .str_op = .{
10858 .str = name,
10859 .operand = inst,
10860 },
10861 } });
10862 }
10863
10864 fn addDbgBlockBegin(gz: *GenZir) !void {
10865 if (gz.force_comptime) return;
10866
10867 _ = try gz.add(.{ .tag = .extended, .data = .{
10868 .extended = .{ .opcode = .dbg_block_begin, .small = undefined, .operand = undefined },
10869 } });
10870 }
10871
10872 fn addDbgBlockEnd(gz: *GenZir) !void {
10873 if (gz.force_comptime) return;
10874
10875 if (gz.endsWithNoReturn()) {
10876 const last = gz.instructions.pop();
10877 _ = try gz.add(.{ .tag = .extended, .data = .{
10878 .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
10879 } });
10880 try gz.instructions.append(gz.astgen.gpa, last);
10881 } else {
10882 _ = try gz.add(.{ .tag = .extended, .data = .{
10883 .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
10884 } });
10885 }
10886 }
10887
10844 /// Control flow does not fall through the "then" block of a loop; it continues10888 /// Control flow does not fall through the "then" block of a loop; it continues
10845 /// back to the while condition. This prevents `rvalue` from10889 /// back to the while condition. This prevents `rvalue` from
10846 /// adding an invalid store to the result location of `then_scope`.10890 /// adding an invalid store to the result location of `then_scope`.
src/Sema.zig+51-46
...@@ -788,7 +788,6 @@ fn analyzeBodyInner(...@@ -788,7 +788,6 @@ fn analyzeBodyInner(
788 .@"resume" => try sema.zirResume(block, inst),788 .@"resume" => try sema.zirResume(block, inst),
789 .@"await" => try sema.zirAwait(block, inst, false),789 .@"await" => try sema.zirAwait(block, inst, false),
790 .await_nosuspend => try sema.zirAwait(block, inst, true),790 .await_nosuspend => try sema.zirAwait(block, inst, true),
791 .extended => try sema.zirExtended(block, inst),
792 .array_base_ptr => try sema.zirArrayBasePtr(block, inst),791 .array_base_ptr => try sema.zirArrayBasePtr(block, inst),
793 .field_base_ptr => try sema.zirFieldBasePtr(block, inst),792 .field_base_ptr => try sema.zirFieldBasePtr(block, inst),
794793
...@@ -850,6 +849,53 @@ fn analyzeBodyInner(...@@ -850,6 +849,53 @@ fn analyzeBodyInner(
850 .panic => break sema.zirPanic(block, inst),849 .panic => break sema.zirPanic(block, inst),
851 // zig fmt: on850 // zig fmt: on
852851
852 .extended => ext: {
853 const extended = datas[inst].extended;
854 break :ext switch (extended.opcode) {
855 // zig fmt: off
856 .func => try sema.zirFuncExtended( block, extended, inst),
857 .variable => try sema.zirVarExtended( block, extended),
858 .struct_decl => try sema.zirStructDecl( block, extended, inst),
859 .enum_decl => try sema.zirEnumDecl( block, extended),
860 .union_decl => try sema.zirUnionDecl( block, extended, inst),
861 .opaque_decl => try sema.zirOpaqueDecl( block, extended),
862 .ret_ptr => try sema.zirRetPtr( block, extended),
863 .ret_type => try sema.zirRetType( block, extended),
864 .this => try sema.zirThis( block, extended),
865 .ret_addr => try sema.zirRetAddr( block, extended),
866 .builtin_src => try sema.zirBuiltinSrc( block, extended),
867 .error_return_trace => try sema.zirErrorReturnTrace( block, extended),
868 .frame => try sema.zirFrame( block, extended),
869 .frame_address => try sema.zirFrameAddress( block, extended),
870 .alloc => try sema.zirAllocExtended( block, extended),
871 .builtin_extern => try sema.zirBuiltinExtern( block, extended),
872 .@"asm" => try sema.zirAsm( block, extended),
873 .typeof_peer => try sema.zirTypeofPeer( block, extended),
874 .compile_log => try sema.zirCompileLog( block, extended),
875 .add_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
876 .sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
877 .mul_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
878 .shl_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
879 .c_undef => try sema.zirCUndef( block, extended),
880 .c_include => try sema.zirCInclude( block, extended),
881 .c_define => try sema.zirCDefine( block, extended),
882 .wasm_memory_size => try sema.zirWasmMemorySize( block, extended),
883 .wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
884 .prefetch => try sema.zirPrefetch( block, extended),
885 // zig fmt: on
886 .dbg_block_begin => {
887 try sema.zirDbgBlockBegin(block);
888 i += 1;
889 continue;
890 },
891 .dbg_block_end => {
892 try sema.zirDbgBlockEnd(block);
893 i += 1;
894 continue;
895 },
896 };
897 },
898
853 // Instructions that we know can *never* be noreturn based solely on899 // Instructions that we know can *never* be noreturn based solely on
854 // their tag. We avoid needlessly checking if they are noreturn and900 // their tag. We avoid needlessly checking if they are noreturn and
855 // continue the loop.901 // continue the loop.
...@@ -1183,45 +1229,6 @@ fn analyzeBodyInner(...@@ -1183,45 +1229,6 @@ fn analyzeBodyInner(
1183 return result;1229 return result;
1184}1230}
11851231
1186fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1187 const extended = sema.code.instructions.items(.data)[inst].extended;
1188 switch (extended.opcode) {
1189 // zig fmt: off
1190 .func => return sema.zirFuncExtended( block, extended, inst),
1191 .variable => return sema.zirVarExtended( block, extended),
1192 .struct_decl => return sema.zirStructDecl( block, extended, inst),
1193 .enum_decl => return sema.zirEnumDecl( block, extended),
1194 .union_decl => return sema.zirUnionDecl( block, extended, inst),
1195 .opaque_decl => return sema.zirOpaqueDecl( block, extended),
1196 .ret_ptr => return sema.zirRetPtr( block, extended),
1197 .ret_type => return sema.zirRetType( block, extended),
1198 .this => return sema.zirThis( block, extended),
1199 .ret_addr => return sema.zirRetAddr( block, extended),
1200 .builtin_src => return sema.zirBuiltinSrc( block, extended),
1201 .error_return_trace => return sema.zirErrorReturnTrace( block, extended),
1202 .frame => return sema.zirFrame( block, extended),
1203 .frame_address => return sema.zirFrameAddress( block, extended),
1204 .alloc => return sema.zirAllocExtended( block, extended),
1205 .builtin_extern => return sema.zirBuiltinExtern( block, extended),
1206 .@"asm" => return sema.zirAsm( block, extended),
1207 .typeof_peer => return sema.zirTypeofPeer( block, extended),
1208 .compile_log => return sema.zirCompileLog( block, extended),
1209 .add_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
1210 .sub_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
1211 .mul_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
1212 .shl_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode),
1213 .c_undef => return sema.zirCUndef( block, extended),
1214 .c_include => return sema.zirCInclude( block, extended),
1215 .c_define => return sema.zirCDefine( block, extended),
1216 .wasm_memory_size => return sema.zirWasmMemorySize( block, extended),
1217 .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended),
1218 .prefetch => return sema.zirPrefetch( block, extended),
1219 .dbg_block_begin => return sema.zirDbgBlockBegin( block),
1220 .dbg_block_end => return sema.zirDbgBlockEnd( block),
1221 // zig fmt: on
1222 }
1223}
1224
1225pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref {1232pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref {
1226 var i: usize = @enumToInt(zir_ref);1233 var i: usize = @enumToInt(zir_ref);
12271234
...@@ -4217,24 +4224,22 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi...@@ -4217,24 +4224,22 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
4217 });4224 });
4218}4225}
42194226
4220fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {4227fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void {
4221 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return .void_value;4228 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
42224229
4223 _ = try block.addInst(.{4230 _ = try block.addInst(.{
4224 .tag = .dbg_block_begin,4231 .tag = .dbg_block_begin,
4225 .data = undefined,4232 .data = undefined,
4226 });4233 });
4227 return .void_value;
4228}4234}
42294235
4230fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {4236fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!void {
4231 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return .void_value;4237 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
42324238
4233 _ = try block.addInst(.{4239 _ = try block.addInst(.{
4234 .tag = .dbg_block_end,4240 .tag = .dbg_block_end,
4235 .data = undefined,4241 .data = undefined,
4236 });4242 });
4237 return .void_value;
4238}4243}
42394244
4240fn zirDbgVar(4245fn zirDbgVar(
test/behavior/while.zig+3
...@@ -173,6 +173,7 @@ test "while with optional as condition with else" {...@@ -173,6 +173,7 @@ test "while with optional as condition with else" {
173}173}
174174
175test "while with error union condition" {175test "while with error union condition" {
176 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
176 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;177 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
177 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;178 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
178179
...@@ -289,6 +290,7 @@ test "while bool 2 break statements and an else" {...@@ -289,6 +290,7 @@ test "while bool 2 break statements and an else" {
289}290}
290291
291test "while optional 2 break statements and an else" {292test "while optional 2 break statements and an else" {
293 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
292 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO294 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
293 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO295 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
294296
...@@ -307,6 +309,7 @@ test "while optional 2 break statements and an else" {...@@ -307,6 +309,7 @@ test "while optional 2 break statements and an else" {
307}309}
308310
309test "while error 2 break statements and an else" {311test "while error 2 break statements and an else" {
312 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
310 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO313 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
311 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
312315