| ... | ... | @@ -2052,11 +2052,9 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2052 | 2052 | const tree = astgen.tree; |
| 2053 | 2053 | const node_tags = tree.nodes.items(.tag); |
| 2054 | 2054 | |
| 2055 | | _ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{ |
| 2056 | | .opcode = .dbg_block_begin, |
| 2057 | | .small = undefined, |
| 2058 | | .operand = undefined |
| 2059 | | } } }); |
| 2055 | if (statements.len == 0) return; |
| 2056 | |
| 2057 | try gz.addDbgBlockBegin(); |
| 2060 | 2058 | |
| 2061 | 2059 | var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa); |
| 2062 | 2060 | defer block_arena.deinit(); |
| ... | ... | @@ -2111,11 +2109,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2111 | 2109 | } |
| 2112 | 2110 | } |
| 2113 | 2111 | |
| 2114 | | _ = try gz.add(.{ .tag = .extended, .data = .{ .extended = .{ |
| 2115 | | .opcode = .dbg_block_end, |
| 2116 | | .small = undefined, |
| 2117 | | .operand = undefined |
| 2118 | | } } }); |
| 2112 | try gz.addDbgBlockEnd(); |
| 2119 | 2113 | |
| 2120 | 2114 | try genDefers(gz, parent_scope, scope, .normal_only); |
| 2121 | 2115 | try checkUsed(gz, parent_scope, scope); |
| ... | ... | @@ -2539,6 +2533,7 @@ fn genDefers( |
| 2539 | 2533 | gz.in_defer = true; |
| 2540 | 2534 | defer gz.in_defer = prev_in_defer; |
| 2541 | 2535 | var local_val_scope: Scope.LocalVal = undefined; |
| 2536 | try gz.addDbgBlockBegin(); |
| 2542 | 2537 | const sub_scope = if (payload_token == 0) defer_scope.parent else blk: { |
| 2543 | 2538 | const ident_name = try astgen.identAsString(payload_token); |
| 2544 | 2539 | local_val_scope = .{ |
| ... | ... | @@ -2549,9 +2544,11 @@ fn genDefers( |
| 2549 | 2544 | .token_src = payload_token, |
| 2550 | 2545 | .id_cat = .@"capture", |
| 2551 | 2546 | }; |
| 2547 | try gz.addDbgVar(.dbg_var_val, ident_name, err_code); |
| 2552 | 2548 | break :blk &local_val_scope.base; |
| 2553 | 2549 | }; |
| 2554 | 2550 | try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node); |
| 2551 | try gz.addDbgBlockEnd(); |
| 2555 | 2552 | }, |
| 2556 | 2553 | .normal_only => continue, |
| 2557 | 2554 | } |
| ... | ... | @@ -2677,14 +2674,7 @@ fn varDecl( |
| 2677 | 2674 | } else .none; |
| 2678 | 2675 | const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node); |
| 2679 | 2676 | |
| 2680 | | if (!gz.force_comptime) { |
| 2681 | | _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{ |
| 2682 | | .str_op = .{ |
| 2683 | | .str = ident_name, |
| 2684 | | .operand = init_inst, |
| 2685 | | }, |
| 2686 | | } }); |
| 2687 | | } |
| 2677 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); |
| 2688 | 2678 | |
| 2689 | 2679 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| 2690 | 2680 | sub_scope.* = .{ |
| ... | ... | @@ -2778,14 +2768,7 @@ fn varDecl( |
| 2778 | 2768 | else |
| 2779 | 2769 | init_inst; |
| 2780 | 2770 | |
| 2781 | | if (!gz.force_comptime) { |
| 2782 | | _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{ |
| 2783 | | .str_op = .{ |
| 2784 | | .str = ident_name, |
| 2785 | | .operand = coerced_init, |
| 2786 | | }, |
| 2787 | | } }); |
| 2788 | | } |
| 2771 | try gz.addDbgVar(.dbg_var_val, ident_name, coerced_init); |
| 2789 | 2772 | |
| 2790 | 2773 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| 2791 | 2774 | sub_scope.* = .{ |
| ... | ... | @@ -2822,14 +2805,7 @@ fn varDecl( |
| 2822 | 2805 | } |
| 2823 | 2806 | const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node); |
| 2824 | 2807 | |
| 2825 | | if (!gz.force_comptime) { |
| 2826 | | _ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{ |
| 2827 | | .str_op = .{ |
| 2828 | | .str = ident_name, |
| 2829 | | .operand = const_ptr, |
| 2830 | | }, |
| 2831 | | } }); |
| 2832 | | } |
| 2808 | try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr); |
| 2833 | 2809 | |
| 2834 | 2810 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 2835 | 2811 | sub_scope.* = .{ |
| ... | ... | @@ -2895,14 +2871,7 @@ fn varDecl( |
| 2895 | 2871 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); |
| 2896 | 2872 | } |
| 2897 | 2873 | |
| 2898 | | if (!gz.force_comptime) { |
| 2899 | | _ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{ |
| 2900 | | .str_op = .{ |
| 2901 | | .str = ident_name, |
| 2902 | | .operand = var_data.alloc, |
| 2903 | | }, |
| 2904 | | } }); |
| 2905 | | } |
| 2874 | try gz.addDbgVar(.dbg_var_ptr, ident_name, var_data.alloc); |
| 2906 | 2875 | |
| 2907 | 2876 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 2908 | 2877 | sub_scope.* = .{ |
| ... | ... | @@ -5199,6 +5168,7 @@ fn ifExpr( |
| 5199 | 5168 | |
| 5200 | 5169 | var payload_val_scope: Scope.LocalVal = undefined; |
| 5201 | 5170 | |
| 5171 | try then_scope.addDbgBlockBegin(); |
| 5202 | 5172 | const then_sub_scope = s: { |
| 5203 | 5173 | if (if_full.error_token != null) { |
| 5204 | 5174 | if (if_full.payload_token) |payload_token| { |
| ... | ... | @@ -5221,6 +5191,7 @@ fn ifExpr( |
| 5221 | 5191 | .token_src = payload_token, |
| 5222 | 5192 | .id_cat = .@"capture", |
| 5223 | 5193 | }; |
| 5194 | try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst); |
| 5224 | 5195 | break :s &payload_val_scope.base; |
| 5225 | 5196 | } else { |
| 5226 | 5197 | break :s &then_scope.base; |
| ... | ... | @@ -5245,6 +5216,7 @@ fn ifExpr( |
| 5245 | 5216 | .token_src = ident_token, |
| 5246 | 5217 | .id_cat = .@"capture", |
| 5247 | 5218 | }; |
| 5219 | try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst); |
| 5248 | 5220 | break :s &payload_val_scope.base; |
| 5249 | 5221 | } else { |
| 5250 | 5222 | break :s &then_scope.base; |
| ... | ... | @@ -5256,6 +5228,7 @@ fn ifExpr( |
| 5256 | 5228 | block_scope.break_count += 1; |
| 5257 | 5229 | } |
| 5258 | 5230 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 5231 | try then_scope.addDbgBlockEnd(); |
| 5259 | 5232 | // We hold off on the break instructions as well as copying the then/else |
| 5260 | 5233 | // instructions into place until we know whether to keep store_to_block_ptr |
| 5261 | 5234 | // instructions or not. |
| ... | ... | @@ -5268,6 +5241,7 @@ fn ifExpr( |
| 5268 | 5241 | src: Ast.Node.Index, |
| 5269 | 5242 | result: Zir.Inst.Ref, |
| 5270 | 5243 | } = if (else_node != 0) blk: { |
| 5244 | try else_scope.addDbgBlockBegin(); |
| 5271 | 5245 | const sub_scope = s: { |
| 5272 | 5246 | if (if_full.error_token) |error_token| { |
| 5273 | 5247 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | ... | @@ -5288,6 +5262,7 @@ fn ifExpr( |
| 5288 | 5262 | .token_src = error_token, |
| 5289 | 5263 | .id_cat = .@"capture", |
| 5290 | 5264 | }; |
| 5265 | try else_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst); |
| 5291 | 5266 | break :s &payload_val_scope.base; |
| 5292 | 5267 | } else { |
| 5293 | 5268 | break :s &else_scope.base; |
| ... | ... | @@ -5298,6 +5273,7 @@ fn ifExpr( |
| 5298 | 5273 | block_scope.break_count += 1; |
| 5299 | 5274 | } |
| 5300 | 5275 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 5276 | try else_scope.addDbgBlockEnd(); |
| 5301 | 5277 | break :blk .{ |
| 5302 | 5278 | .src = else_node, |
| 5303 | 5279 | .result = e, |
| ... | ... | @@ -5513,6 +5489,8 @@ fn whileExpr( |
| 5513 | 5489 | then_scope.instructions_top = GenZir.unstacked_top; |
| 5514 | 5490 | defer then_scope.unstack(); |
| 5515 | 5491 | |
| 5492 | var dbg_var_name: ?u32 = null; |
| 5493 | var dbg_var_inst: Zir.Inst.Ref = undefined; |
| 5516 | 5494 | var payload_inst: Zir.Inst.Index = 0; |
| 5517 | 5495 | var payload_val_scope: Scope.LocalVal = undefined; |
| 5518 | 5496 | const then_sub_scope = s: { |
| ... | ... | @@ -5539,6 +5517,8 @@ fn whileExpr( |
| 5539 | 5517 | .token_src = payload_token, |
| 5540 | 5518 | .id_cat = .@"capture", |
| 5541 | 5519 | }; |
| 5520 | dbg_var_name = ident_name; |
| 5521 | dbg_var_inst = indexToRef(payload_inst); |
| 5542 | 5522 | break :s &payload_val_scope.base; |
| 5543 | 5523 | } else { |
| 5544 | 5524 | break :s &then_scope.base; |
| ... | ... | @@ -5564,6 +5544,8 @@ fn whileExpr( |
| 5564 | 5544 | .token_src = ident_token, |
| 5565 | 5545 | .id_cat = .@"capture", |
| 5566 | 5546 | }; |
| 5547 | dbg_var_name = ident_name; |
| 5548 | dbg_var_inst = indexToRef(payload_inst); |
| 5567 | 5549 | break :s &payload_val_scope.base; |
| 5568 | 5550 | } else { |
| 5569 | 5551 | break :s &then_scope.base; |
| ... | ... | @@ -5574,9 +5556,14 @@ fn whileExpr( |
| 5574 | 5556 | // are no jumps to it. This happens when the last statement of a while body is noreturn |
| 5575 | 5557 | // and there are no `continue` statements. |
| 5576 | 5558 | // 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 | 5563 | if (while_full.ast.cont_expr != 0) { |
| 5578 | 5564 | _ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr); |
| 5579 | 5565 | } |
| 5566 | try then_scope.addDbgBlockEnd(); |
| 5580 | 5567 | const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat; |
| 5581 | 5568 | _ = try loop_scope.addNode(repeat_tag, node); |
| 5582 | 5569 | |
| ... | ... | @@ -5592,9 +5579,15 @@ fn whileExpr( |
| 5592 | 5579 | |
| 5593 | 5580 | // done adding instructions to loop_scope, can now stack then_scope |
| 5594 | 5581 | then_scope.instructions_top = then_scope.instructions.items.len; |
| 5582 | |
| 5595 | 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 | 5588 | const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr); |
| 5597 | 5589 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 5590 | try then_scope.addDbgBlockEnd(); |
| 5598 | 5591 | |
| 5599 | 5592 | var else_scope = parent_gz.makeSubBlock(&continue_scope.base); |
| 5600 | 5593 | defer else_scope.unstack(); |
| ... | ... | @@ -5604,6 +5597,7 @@ fn whileExpr( |
| 5604 | 5597 | src: Ast.Node.Index, |
| 5605 | 5598 | result: Zir.Inst.Ref, |
| 5606 | 5599 | } = if (else_node != 0) blk: { |
| 5600 | try else_scope.addDbgBlockBegin(); |
| 5607 | 5601 | const sub_scope = s: { |
| 5608 | 5602 | if (while_full.error_token) |error_token| { |
| 5609 | 5603 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | ... | @@ -5624,6 +5618,7 @@ fn whileExpr( |
| 5624 | 5618 | .token_src = error_token, |
| 5625 | 5619 | .id_cat = .@"capture", |
| 5626 | 5620 | }; |
| 5621 | try else_scope.addDbgVar(.dbg_var_val, ident_name, else_payload_inst); |
| 5627 | 5622 | break :s &payload_val_scope.base; |
| 5628 | 5623 | } else { |
| 5629 | 5624 | break :s &else_scope.base; |
| ... | ... | @@ -5634,6 +5629,7 @@ fn whileExpr( |
| 5634 | 5629 | loop_scope.break_count += 1; |
| 5635 | 5630 | } |
| 5636 | 5631 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 5632 | try else_scope.addDbgBlockEnd(); |
| 5637 | 5633 | break :blk .{ |
| 5638 | 5634 | .src = else_node, |
| 5639 | 5635 | .result = e, |
| ... | ... | @@ -5755,6 +5751,7 @@ fn forExpr( |
| 5755 | 5751 | then_scope.markAsLoopBody(loop_scope); |
| 5756 | 5752 | defer then_scope.unstack(); |
| 5757 | 5753 | |
| 5754 | try then_scope.addDbgBlockBegin(); |
| 5758 | 5755 | var payload_val_scope: Scope.LocalVal = undefined; |
| 5759 | 5756 | var index_scope: Scope.LocalPtr = undefined; |
| 5760 | 5757 | const then_sub_scope = blk: { |
| ... | ... | @@ -5779,6 +5776,7 @@ fn forExpr( |
| 5779 | 5776 | .token_src = ident, |
| 5780 | 5777 | .id_cat = .@"capture", |
| 5781 | 5778 | }; |
| 5779 | try then_scope.addDbgVar(.dbg_var_val, name_str_index, payload_inst); |
| 5782 | 5780 | payload_sub_scope = &payload_val_scope.base; |
| 5783 | 5781 | } else if (is_ptr) { |
| 5784 | 5782 | return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); |
| ... | ... | @@ -5805,11 +5803,13 @@ fn forExpr( |
| 5805 | 5803 | .maybe_comptime = is_inline, |
| 5806 | 5804 | .id_cat = .@"loop index capture", |
| 5807 | 5805 | }; |
| 5806 | try then_scope.addDbgVar(.dbg_var_val, index_name, index_ptr); |
| 5808 | 5807 | break :blk &index_scope.base; |
| 5809 | 5808 | }; |
| 5810 | 5809 | |
| 5811 | 5810 | const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr); |
| 5812 | 5811 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 5812 | try then_scope.addDbgBlockEnd(); |
| 5813 | 5813 | |
| 5814 | 5814 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 5815 | 5815 | defer else_scope.unstack(); |
| ... | ... | @@ -6028,6 +6028,8 @@ fn switchExpr( |
| 6028 | 6028 | const is_multi_case = case.ast.values.len > 1 or |
| 6029 | 6029 | (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); |
| 6030 | 6030 | |
| 6031 | var dbg_var_name: ?u32 = null; |
| 6032 | var dbg_var_inst: Zir.Inst.Ref = undefined; |
| 6031 | 6033 | var capture_inst: Zir.Inst.Index = 0; |
| 6032 | 6034 | var capture_val_scope: Scope.LocalVal = undefined; |
| 6033 | 6035 | const sub_scope = blk: { |
| ... | ... | @@ -6087,6 +6089,8 @@ fn switchExpr( |
| 6087 | 6089 | .token_src = payload_token, |
| 6088 | 6090 | .id_cat = .@"capture", |
| 6089 | 6091 | }; |
| 6092 | dbg_var_name = capture_name; |
| 6093 | dbg_var_inst = indexToRef(capture_inst); |
| 6090 | 6094 | break :blk &capture_val_scope.base; |
| 6091 | 6095 | }; |
| 6092 | 6096 | |
| ... | ... | @@ -6142,12 +6146,17 @@ fn switchExpr( |
| 6142 | 6146 | defer case_scope.unstack(); |
| 6143 | 6147 | |
| 6144 | 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 | 6153 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); |
| 6146 | 6154 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 6147 | 6155 | if (!parent_gz.refIsNoReturn(case_result)) { |
| 6148 | 6156 | block_scope.break_count += 1; |
| 6149 | 6157 | _ = try case_scope.addBreak(.@"break", switch_block, case_result); |
| 6150 | 6158 | } |
| 6159 | try case_scope.addDbgBlockEnd(); |
| 6151 | 6160 | |
| 6152 | 6161 | const case_slice = case_scope.instructionsSlice(); |
| 6153 | 6162 | payloads.items[body_len_index] = @intCast(u32, case_slice.len); |
| ... | ... | @@ -10841,6 +10850,41 @@ const GenZir = struct { |
| 10841 | 10850 | } |
| 10842 | 10851 | } |
| 10843 | 10852 | |
| 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 | 10888 | /// Control flow does not fall through the "then" block of a loop; it continues |
| 10845 | 10889 | /// back to the while condition. This prevents `rvalue` from |
| 10846 | 10890 | /// adding an invalid store to the result location of `then_scope`. |