| author | |
| committer | |
| log | a318aeed9b8ccec453e9f15415ea3fd20cb13c8d |
| tree | 12c7de4eb436130491aefa1a4e8ef517cd20491e |
| parent | 67665286575d406769000b3f3e80d4d03d2cab2b |
| parent | d56e3c988f0707e996be8eeb7a55f8a90c497a26 |
| signature |
stage2: add debug info for payload captures + inline function parameters16 files changed, 296 insertions(+), 74 deletions(-)
src/Air.zig+6| ... | ... | @@ -326,6 +326,10 @@ pub const Inst = struct { |
| 326 | 326 | /// Result type is always void. |
| 327 | 327 | /// Uses the `dbg_stmt` field. |
| 328 | 328 | dbg_stmt, |
| 329 | /// Marks the beginning of a semantic scope for debug info variables. | |
| 330 | dbg_block_begin, | |
| 331 | /// Marks the end of a semantic scope for debug info variables. | |
| 332 | dbg_block_end, | |
| 329 | 333 | /// Marks the start of an inline call. |
| 330 | 334 | /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values. |
| 331 | 335 | dbg_inline_begin, |
| ... | ... | @@ -990,6 +994,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 990 | 994 | .dbg_stmt, |
| 991 | 995 | .dbg_inline_begin, |
| 992 | 996 | .dbg_inline_end, |
| 997 | .dbg_block_begin, | |
| 998 | .dbg_block_end, | |
| 993 | 999 | .dbg_var_ptr, |
| 994 | 1000 | .dbg_var_val, |
| 995 | 1001 | .store, |
src/AstGen.zig+92-32| ... | ... | @@ -2052,6 +2052,10 @@ 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 | if (statements.len == 0) return; | |
| 2056 | ||
| 2057 | try gz.addDbgBlockBegin(); | |
| 2058 | ||
| 2055 | 2059 | var block_arena = std.heap.ArenaAllocator.init(gz.astgen.gpa); |
| 2056 | 2060 | defer block_arena.deinit(); |
| 2057 | 2061 | const block_arena_allocator = block_arena.allocator(); |
| ... | ... | @@ -2105,6 +2109,8 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2105 | 2109 | } |
| 2106 | 2110 | } |
| 2107 | 2111 | |
| 2112 | try gz.addDbgBlockEnd(); | |
| 2113 | ||
| 2108 | 2114 | try genDefers(gz, parent_scope, scope, .normal_only); |
| 2109 | 2115 | try checkUsed(gz, parent_scope, scope); |
| 2110 | 2116 | } |
| ... | ... | @@ -2527,6 +2533,7 @@ fn genDefers( |
| 2527 | 2533 | gz.in_defer = true; |
| 2528 | 2534 | defer gz.in_defer = prev_in_defer; |
| 2529 | 2535 | var local_val_scope: Scope.LocalVal = undefined; |
| 2536 | try gz.addDbgBlockBegin(); | |
| 2530 | 2537 | const sub_scope = if (payload_token == 0) defer_scope.parent else blk: { |
| 2531 | 2538 | const ident_name = try astgen.identAsString(payload_token); |
| 2532 | 2539 | local_val_scope = .{ |
| ... | ... | @@ -2537,9 +2544,11 @@ fn genDefers( |
| 2537 | 2544 | .token_src = payload_token, |
| 2538 | 2545 | .id_cat = .@"capture", |
| 2539 | 2546 | }; |
| 2547 | try gz.addDbgVar(.dbg_var_val, ident_name, err_code); | |
| 2540 | 2548 | break :blk &local_val_scope.base; |
| 2541 | 2549 | }; |
| 2542 | 2550 | try unusedResultDeferExpr(gz, defer_scope, sub_scope, expr_node); |
| 2551 | try gz.addDbgBlockEnd(); | |
| 2543 | 2552 | }, |
| 2544 | 2553 | .normal_only => continue, |
| 2545 | 2554 | } |
| ... | ... | @@ -2665,14 +2674,7 @@ fn varDecl( |
| 2665 | 2674 | } else .none; |
| 2666 | 2675 | const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node); |
| 2667 | 2676 | |
| 2668 | if (!gz.force_comptime) { | |
| 2669 | _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{ | |
| 2670 | .str_op = .{ | |
| 2671 | .str = ident_name, | |
| 2672 | .operand = init_inst, | |
| 2673 | }, | |
| 2674 | } }); | |
| 2675 | } | |
| 2677 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); | |
| 2676 | 2678 | |
| 2677 | 2679 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| 2678 | 2680 | sub_scope.* = .{ |
| ... | ... | @@ -2766,14 +2768,7 @@ fn varDecl( |
| 2766 | 2768 | else |
| 2767 | 2769 | init_inst; |
| 2768 | 2770 | |
| 2769 | if (!gz.force_comptime) { | |
| 2770 | _ = try gz.add(.{ .tag = .dbg_var_val, .data = .{ | |
| 2771 | .str_op = .{ | |
| 2772 | .str = ident_name, | |
| 2773 | .operand = coerced_init, | |
| 2774 | }, | |
| 2775 | } }); | |
| 2776 | } | |
| 2771 | try gz.addDbgVar(.dbg_var_val, ident_name, coerced_init); | |
| 2777 | 2772 | |
| 2778 | 2773 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| 2779 | 2774 | sub_scope.* = .{ |
| ... | ... | @@ -2810,14 +2805,7 @@ fn varDecl( |
| 2810 | 2805 | } |
| 2811 | 2806 | const const_ptr = try gz.addUnNode(.make_ptr_const, init_scope.rl_ptr, node); |
| 2812 | 2807 | |
| 2813 | if (!gz.force_comptime) { | |
| 2814 | _ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{ | |
| 2815 | .str_op = .{ | |
| 2816 | .str = ident_name, | |
| 2817 | .operand = const_ptr, | |
| 2818 | }, | |
| 2819 | } }); | |
| 2820 | } | |
| 2808 | try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr); | |
| 2821 | 2809 | |
| 2822 | 2810 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 2823 | 2811 | sub_scope.* = .{ |
| ... | ... | @@ -2883,14 +2871,7 @@ fn varDecl( |
| 2883 | 2871 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); |
| 2884 | 2872 | } |
| 2885 | 2873 | |
| 2886 | if (!gz.force_comptime) { | |
| 2887 | _ = try gz.add(.{ .tag = .dbg_var_ptr, .data = .{ | |
| 2888 | .str_op = .{ | |
| 2889 | .str = ident_name, | |
| 2890 | .operand = var_data.alloc, | |
| 2891 | }, | |
| 2892 | } }); | |
| 2893 | } | |
| 2874 | try gz.addDbgVar(.dbg_var_ptr, ident_name, var_data.alloc); | |
| 2894 | 2875 | |
| 2895 | 2876 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 2896 | 2877 | sub_scope.* = .{ |
| ... | ... | @@ -5187,6 +5168,7 @@ fn ifExpr( |
| 5187 | 5168 | |
| 5188 | 5169 | var payload_val_scope: Scope.LocalVal = undefined; |
| 5189 | 5170 | |
| 5171 | try then_scope.addDbgBlockBegin(); | |
| 5190 | 5172 | const then_sub_scope = s: { |
| 5191 | 5173 | if (if_full.error_token != null) { |
| 5192 | 5174 | if (if_full.payload_token) |payload_token| { |
| ... | ... | @@ -5209,6 +5191,7 @@ fn ifExpr( |
| 5209 | 5191 | .token_src = payload_token, |
| 5210 | 5192 | .id_cat = .@"capture", |
| 5211 | 5193 | }; |
| 5194 | try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst); | |
| 5212 | 5195 | break :s &payload_val_scope.base; |
| 5213 | 5196 | } else { |
| 5214 | 5197 | break :s &then_scope.base; |
| ... | ... | @@ -5233,6 +5216,7 @@ fn ifExpr( |
| 5233 | 5216 | .token_src = ident_token, |
| 5234 | 5217 | .id_cat = .@"capture", |
| 5235 | 5218 | }; |
| 5219 | try then_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst); | |
| 5236 | 5220 | break :s &payload_val_scope.base; |
| 5237 | 5221 | } else { |
| 5238 | 5222 | break :s &then_scope.base; |
| ... | ... | @@ -5244,6 +5228,7 @@ fn ifExpr( |
| 5244 | 5228 | block_scope.break_count += 1; |
| 5245 | 5229 | } |
| 5246 | 5230 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 5231 | try then_scope.addDbgBlockEnd(); | |
| 5247 | 5232 | // We hold off on the break instructions as well as copying the then/else |
| 5248 | 5233 | // instructions into place until we know whether to keep store_to_block_ptr |
| 5249 | 5234 | // instructions or not. |
| ... | ... | @@ -5256,6 +5241,7 @@ fn ifExpr( |
| 5256 | 5241 | src: Ast.Node.Index, |
| 5257 | 5242 | result: Zir.Inst.Ref, |
| 5258 | 5243 | } = if (else_node != 0) blk: { |
| 5244 | try else_scope.addDbgBlockBegin(); | |
| 5259 | 5245 | const sub_scope = s: { |
| 5260 | 5246 | if (if_full.error_token) |error_token| { |
| 5261 | 5247 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | ... | @@ -5276,6 +5262,7 @@ fn ifExpr( |
| 5276 | 5262 | .token_src = error_token, |
| 5277 | 5263 | .id_cat = .@"capture", |
| 5278 | 5264 | }; |
| 5265 | try else_scope.addDbgVar(.dbg_var_val, ident_name, payload_inst); | |
| 5279 | 5266 | break :s &payload_val_scope.base; |
| 5280 | 5267 | } else { |
| 5281 | 5268 | break :s &else_scope.base; |
| ... | ... | @@ -5286,6 +5273,7 @@ fn ifExpr( |
| 5286 | 5273 | block_scope.break_count += 1; |
| 5287 | 5274 | } |
| 5288 | 5275 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 5276 | try else_scope.addDbgBlockEnd(); | |
| 5289 | 5277 | break :blk .{ |
| 5290 | 5278 | .src = else_node, |
| 5291 | 5279 | .result = e, |
| ... | ... | @@ -5501,6 +5489,8 @@ fn whileExpr( |
| 5501 | 5489 | then_scope.instructions_top = GenZir.unstacked_top; |
| 5502 | 5490 | defer then_scope.unstack(); |
| 5503 | 5491 | |
| 5492 | var dbg_var_name: ?u32 = null; | |
| 5493 | var dbg_var_inst: Zir.Inst.Ref = undefined; | |
| 5504 | 5494 | var payload_inst: Zir.Inst.Index = 0; |
| 5505 | 5495 | var payload_val_scope: Scope.LocalVal = undefined; |
| 5506 | 5496 | const then_sub_scope = s: { |
| ... | ... | @@ -5527,6 +5517,8 @@ fn whileExpr( |
| 5527 | 5517 | .token_src = payload_token, |
| 5528 | 5518 | .id_cat = .@"capture", |
| 5529 | 5519 | }; |
| 5520 | dbg_var_name = ident_name; | |
| 5521 | dbg_var_inst = indexToRef(payload_inst); | |
| 5530 | 5522 | break :s &payload_val_scope.base; |
| 5531 | 5523 | } else { |
| 5532 | 5524 | break :s &then_scope.base; |
| ... | ... | @@ -5552,6 +5544,8 @@ fn whileExpr( |
| 5552 | 5544 | .token_src = ident_token, |
| 5553 | 5545 | .id_cat = .@"capture", |
| 5554 | 5546 | }; |
| 5547 | dbg_var_name = ident_name; | |
| 5548 | dbg_var_inst = indexToRef(payload_inst); | |
| 5555 | 5549 | break :s &payload_val_scope.base; |
| 5556 | 5550 | } else { |
| 5557 | 5551 | break :s &then_scope.base; |
| ... | ... | @@ -5562,9 +5556,14 @@ fn whileExpr( |
| 5562 | 5556 | // are no jumps to it. This happens when the last statement of a while body is noreturn |
| 5563 | 5557 | // and there are no `continue` statements. |
| 5564 | 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 | } | |
| 5565 | 5563 | if (while_full.ast.cont_expr != 0) { |
| 5566 | 5564 | _ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr); |
| 5567 | 5565 | } |
| 5566 | try then_scope.addDbgBlockEnd(); | |
| 5568 | 5567 | const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat; |
| 5569 | 5568 | _ = try loop_scope.addNode(repeat_tag, node); |
| 5570 | 5569 | |
| ... | ... | @@ -5580,9 +5579,15 @@ fn whileExpr( |
| 5580 | 5579 | |
| 5581 | 5580 | // done adding instructions to loop_scope, can now stack then_scope |
| 5582 | 5581 | then_scope.instructions_top = then_scope.instructions.items.len; |
| 5582 | ||
| 5583 | 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 | } | |
| 5584 | 5588 | const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, while_full.ast.then_expr); |
| 5585 | 5589 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 5590 | try then_scope.addDbgBlockEnd(); | |
| 5586 | 5591 | |
| 5587 | 5592 | var else_scope = parent_gz.makeSubBlock(&continue_scope.base); |
| 5588 | 5593 | defer else_scope.unstack(); |
| ... | ... | @@ -5592,6 +5597,7 @@ fn whileExpr( |
| 5592 | 5597 | src: Ast.Node.Index, |
| 5593 | 5598 | result: Zir.Inst.Ref, |
| 5594 | 5599 | } = if (else_node != 0) blk: { |
| 5600 | try else_scope.addDbgBlockBegin(); | |
| 5595 | 5601 | const sub_scope = s: { |
| 5596 | 5602 | if (while_full.error_token) |error_token| { |
| 5597 | 5603 | const tag: Zir.Inst.Tag = if (payload_is_ref) |
| ... | ... | @@ -5612,6 +5618,7 @@ fn whileExpr( |
| 5612 | 5618 | .token_src = error_token, |
| 5613 | 5619 | .id_cat = .@"capture", |
| 5614 | 5620 | }; |
| 5621 | try else_scope.addDbgVar(.dbg_var_val, ident_name, else_payload_inst); | |
| 5615 | 5622 | break :s &payload_val_scope.base; |
| 5616 | 5623 | } else { |
| 5617 | 5624 | break :s &else_scope.base; |
| ... | ... | @@ -5622,6 +5629,7 @@ fn whileExpr( |
| 5622 | 5629 | loop_scope.break_count += 1; |
| 5623 | 5630 | } |
| 5624 | 5631 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 5632 | try else_scope.addDbgBlockEnd(); | |
| 5625 | 5633 | break :blk .{ |
| 5626 | 5634 | .src = else_node, |
| 5627 | 5635 | .result = e, |
| ... | ... | @@ -5743,6 +5751,7 @@ fn forExpr( |
| 5743 | 5751 | then_scope.markAsLoopBody(loop_scope); |
| 5744 | 5752 | defer then_scope.unstack(); |
| 5745 | 5753 | |
| 5754 | try then_scope.addDbgBlockBegin(); | |
| 5746 | 5755 | var payload_val_scope: Scope.LocalVal = undefined; |
| 5747 | 5756 | var index_scope: Scope.LocalPtr = undefined; |
| 5748 | 5757 | const then_sub_scope = blk: { |
| ... | ... | @@ -5767,6 +5776,7 @@ fn forExpr( |
| 5767 | 5776 | .token_src = ident, |
| 5768 | 5777 | .id_cat = .@"capture", |
| 5769 | 5778 | }; |
| 5779 | try then_scope.addDbgVar(.dbg_var_val, name_str_index, payload_inst); | |
| 5770 | 5780 | payload_sub_scope = &payload_val_scope.base; |
| 5771 | 5781 | } else if (is_ptr) { |
| 5772 | 5782 | return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{}); |
| ... | ... | @@ -5793,11 +5803,13 @@ fn forExpr( |
| 5793 | 5803 | .maybe_comptime = is_inline, |
| 5794 | 5804 | .id_cat = .@"loop index capture", |
| 5795 | 5805 | }; |
| 5806 | try then_scope.addDbgVar(.dbg_var_val, index_name, index_ptr); | |
| 5796 | 5807 | break :blk &index_scope.base; |
| 5797 | 5808 | }; |
| 5798 | 5809 | |
| 5799 | 5810 | const then_result = try expr(&then_scope, then_sub_scope, loop_scope.break_result_loc, for_full.ast.then_expr); |
| 5800 | 5811 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 5812 | try then_scope.addDbgBlockEnd(); | |
| 5801 | 5813 | |
| 5802 | 5814 | var else_scope = parent_gz.makeSubBlock(&cond_scope.base); |
| 5803 | 5815 | defer else_scope.unstack(); |
| ... | ... | @@ -6016,6 +6028,8 @@ fn switchExpr( |
| 6016 | 6028 | const is_multi_case = case.ast.values.len > 1 or |
| 6017 | 6029 | (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); |
| 6018 | 6030 | |
| 6031 | var dbg_var_name: ?u32 = null; | |
| 6032 | var dbg_var_inst: Zir.Inst.Ref = undefined; | |
| 6019 | 6033 | var capture_inst: Zir.Inst.Index = 0; |
| 6020 | 6034 | var capture_val_scope: Scope.LocalVal = undefined; |
| 6021 | 6035 | const sub_scope = blk: { |
| ... | ... | @@ -6075,6 +6089,8 @@ fn switchExpr( |
| 6075 | 6089 | .token_src = payload_token, |
| 6076 | 6090 | .id_cat = .@"capture", |
| 6077 | 6091 | }; |
| 6092 | dbg_var_name = capture_name; | |
| 6093 | dbg_var_inst = indexToRef(capture_inst); | |
| 6078 | 6094 | break :blk &capture_val_scope.base; |
| 6079 | 6095 | }; |
| 6080 | 6096 | |
| ... | ... | @@ -6130,8 +6146,13 @@ fn switchExpr( |
| 6130 | 6146 | defer case_scope.unstack(); |
| 6131 | 6147 | |
| 6132 | 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 | } | |
| 6133 | 6153 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); |
| 6134 | 6154 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 6155 | try case_scope.addDbgBlockEnd(); | |
| 6135 | 6156 | if (!parent_gz.refIsNoReturn(case_result)) { |
| 6136 | 6157 | block_scope.break_count += 1; |
| 6137 | 6158 | _ = try case_scope.addBreak(.@"break", switch_block, case_result); |
| ... | ... | @@ -10829,6 +10850,45 @@ const GenZir = struct { |
| 10829 | 10850 | } |
| 10830 | 10851 | } |
| 10831 | 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 | const gpa = gz.astgen.gpa; | |
| 10875 | ||
| 10876 | const tags = gz.astgen.instructions.items(.tag); | |
| 10877 | const data = gz.astgen.instructions.items(.data); | |
| 10878 | const last_inst = gz.instructions.items[gz.instructions.items.len - 1]; | |
| 10879 | // remove dbg_block_begin immediately followed by dbg_block_end | |
| 10880 | if (tags[last_inst] == .extended and data[last_inst].extended.opcode == .dbg_block_begin) { | |
| 10881 | _ = gz.instructions.pop(); | |
| 10882 | return; | |
| 10883 | } | |
| 10884 | ||
| 10885 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); | |
| 10886 | try gz.astgen.instructions.append(gpa, .{ .tag = .extended, .data = .{ | |
| 10887 | .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined }, | |
| 10888 | } }); | |
| 10889 | try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index); | |
| 10890 | } | |
| 10891 | ||
| 10832 | 10892 | /// Control flow does not fall through the "then" block of a loop; it continues |
| 10833 | 10893 | /// back to the while condition. This prevents `rvalue` from |
| 10834 | 10894 | /// adding an invalid store to the result location of `then_scope`. |
src/Liveness.zig+2| ... | ... | @@ -316,6 +316,8 @@ fn analyzeInst( |
| 316 | 316 | .dbg_stmt, |
| 317 | 317 | .dbg_inline_begin, |
| 318 | 318 | .dbg_inline_end, |
| 319 | .dbg_block_begin, | |
| 320 | .dbg_block_end, | |
| 319 | 321 | .unreach, |
| 320 | 322 | .fence, |
| 321 | 323 | .ret_addr, |
src/Sema.zig+115-40| ... | ... | @@ -618,6 +618,8 @@ fn analyzeBodyInner( |
| 618 | 618 | crash_info.push(); |
| 619 | 619 | defer crash_info.pop(); |
| 620 | 620 | |
| 621 | var dbg_block_begins: u32 = 0; | |
| 622 | ||
| 621 | 623 | // We use a while(true) loop here to avoid a redundant way of breaking out of |
| 622 | 624 | // the loop. The only way to break out of the loop is with a `noreturn` |
| 623 | 625 | // instruction. |
| ... | ... | @@ -792,7 +794,6 @@ fn analyzeBodyInner( |
| 792 | 794 | .@"resume" => try sema.zirResume(block, inst), |
| 793 | 795 | .@"await" => try sema.zirAwait(block, inst, false), |
| 794 | 796 | .await_nosuspend => try sema.zirAwait(block, inst, true), |
| 795 | .extended => try sema.zirExtended(block, inst), | |
| 796 | 797 | .array_base_ptr => try sema.zirArrayBasePtr(block, inst), |
| 797 | 798 | .field_base_ptr => try sema.zirFieldBasePtr(block, inst), |
| 798 | 799 | |
| ... | ... | @@ -854,6 +855,55 @@ fn analyzeBodyInner( |
| 854 | 855 | .panic => break sema.zirPanic(block, inst), |
| 855 | 856 | // zig fmt: on |
| 856 | 857 | |
| 858 | .extended => ext: { | |
| 859 | const extended = datas[inst].extended; | |
| 860 | break :ext switch (extended.opcode) { | |
| 861 | // zig fmt: off | |
| 862 | .func => try sema.zirFuncExtended( block, extended, inst), | |
| 863 | .variable => try sema.zirVarExtended( block, extended), | |
| 864 | .struct_decl => try sema.zirStructDecl( block, extended, inst), | |
| 865 | .enum_decl => try sema.zirEnumDecl( block, extended), | |
| 866 | .union_decl => try sema.zirUnionDecl( block, extended, inst), | |
| 867 | .opaque_decl => try sema.zirOpaqueDecl( block, extended), | |
| 868 | .ret_ptr => try sema.zirRetPtr( block, extended), | |
| 869 | .ret_type => try sema.zirRetType( block, extended), | |
| 870 | .this => try sema.zirThis( block, extended), | |
| 871 | .ret_addr => try sema.zirRetAddr( block, extended), | |
| 872 | .builtin_src => try sema.zirBuiltinSrc( block, extended), | |
| 873 | .error_return_trace => try sema.zirErrorReturnTrace( block, extended), | |
| 874 | .frame => try sema.zirFrame( block, extended), | |
| 875 | .frame_address => try sema.zirFrameAddress( block, extended), | |
| 876 | .alloc => try sema.zirAllocExtended( block, extended), | |
| 877 | .builtin_extern => try sema.zirBuiltinExtern( block, extended), | |
| 878 | .@"asm" => try sema.zirAsm( block, extended), | |
| 879 | .typeof_peer => try sema.zirTypeofPeer( block, extended), | |
| 880 | .compile_log => try sema.zirCompileLog( block, extended), | |
| 881 | .add_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 882 | .sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 883 | .mul_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 884 | .shl_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 885 | .c_undef => try sema.zirCUndef( block, extended), | |
| 886 | .c_include => try sema.zirCInclude( block, extended), | |
| 887 | .c_define => try sema.zirCDefine( block, extended), | |
| 888 | .wasm_memory_size => try sema.zirWasmMemorySize( block, extended), | |
| 889 | .wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended), | |
| 890 | .prefetch => try sema.zirPrefetch( block, extended), | |
| 891 | // zig fmt: on | |
| 892 | .dbg_block_begin => { | |
| 893 | dbg_block_begins += 1; | |
| 894 | try sema.zirDbgBlockBegin(block); | |
| 895 | i += 1; | |
| 896 | continue; | |
| 897 | }, | |
| 898 | .dbg_block_end => { | |
| 899 | dbg_block_begins -= 1; | |
| 900 | try sema.zirDbgBlockEnd(block); | |
| 901 | i += 1; | |
| 902 | continue; | |
| 903 | }, | |
| 904 | }; | |
| 905 | }, | |
| 906 | ||
| 857 | 907 | // Instructions that we know can *never* be noreturn based solely on |
| 858 | 908 | // their tag. We avoid needlessly checking if they are noreturn and |
| 859 | 909 | // continue the loop. |
| ... | ... | @@ -1179,6 +1229,19 @@ fn analyzeBodyInner( |
| 1179 | 1229 | i += 1; |
| 1180 | 1230 | } else unreachable; |
| 1181 | 1231 | |
| 1232 | // balance out dbg_block_begins in case of early noreturn | |
| 1233 | const noreturn_inst = block.instructions.popOrNull(); | |
| 1234 | while (dbg_block_begins > 0) { | |
| 1235 | dbg_block_begins -= 1; | |
| 1236 | if (block.is_comptime or sema.mod.comp.bin_file.options.strip) continue; | |
| 1237 | ||
| 1238 | _ = try block.addInst(.{ | |
| 1239 | .tag = .dbg_block_end, | |
| 1240 | .data = undefined, | |
| 1241 | }); | |
| 1242 | } | |
| 1243 | if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some); | |
| 1244 | ||
| 1182 | 1245 | if (!wip_captures.finalized) { |
| 1183 | 1246 | try wip_captures.finalize(); |
| 1184 | 1247 | block.wip_capture_scope = parent_capture_scope; |
| ... | ... | @@ -1187,43 +1250,6 @@ fn analyzeBodyInner( |
| 1187 | 1250 | return result; |
| 1188 | 1251 | } |
| 1189 | 1252 | |
| 1190 | fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | |
| 1191 | const extended = sema.code.instructions.items(.data)[inst].extended; | |
| 1192 | switch (extended.opcode) { | |
| 1193 | // zig fmt: off | |
| 1194 | .func => return sema.zirFuncExtended( block, extended, inst), | |
| 1195 | .variable => return sema.zirVarExtended( block, extended), | |
| 1196 | .struct_decl => return sema.zirStructDecl( block, extended, inst), | |
| 1197 | .enum_decl => return sema.zirEnumDecl( block, extended), | |
| 1198 | .union_decl => return sema.zirUnionDecl( block, extended, inst), | |
| 1199 | .opaque_decl => return sema.zirOpaqueDecl( block, extended), | |
| 1200 | .ret_ptr => return sema.zirRetPtr( block, extended), | |
| 1201 | .ret_type => return sema.zirRetType( block, extended), | |
| 1202 | .this => return sema.zirThis( block, extended), | |
| 1203 | .ret_addr => return sema.zirRetAddr( block, extended), | |
| 1204 | .builtin_src => return sema.zirBuiltinSrc( block, extended), | |
| 1205 | .error_return_trace => return sema.zirErrorReturnTrace( block, extended), | |
| 1206 | .frame => return sema.zirFrame( block, extended), | |
| 1207 | .frame_address => return sema.zirFrameAddress( block, extended), | |
| 1208 | .alloc => return sema.zirAllocExtended( block, extended), | |
| 1209 | .builtin_extern => return sema.zirBuiltinExtern( block, extended), | |
| 1210 | .@"asm" => return sema.zirAsm( block, extended), | |
| 1211 | .typeof_peer => return sema.zirTypeofPeer( block, extended), | |
| 1212 | .compile_log => return sema.zirCompileLog( block, extended), | |
| 1213 | .add_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 1214 | .sub_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 1215 | .mul_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 1216 | .shl_with_overflow => return sema.zirOverflowArithmetic(block, extended, extended.opcode), | |
| 1217 | .c_undef => return sema.zirCUndef( block, extended), | |
| 1218 | .c_include => return sema.zirCInclude( block, extended), | |
| 1219 | .c_define => return sema.zirCDefine( block, extended), | |
| 1220 | .wasm_memory_size => return sema.zirWasmMemorySize( block, extended), | |
| 1221 | .wasm_memory_grow => return sema.zirWasmMemoryGrow( block, extended), | |
| 1222 | .prefetch => return sema.zirPrefetch( block, extended), | |
| 1223 | // zig fmt: on | |
| 1224 | } | |
| 1225 | } | |
| 1226 | ||
| 1227 | 1253 | pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref { |
| 1228 | 1254 | var i: usize = @enumToInt(zir_ref); |
| 1229 | 1255 | |
| ... | ... | @@ -4241,6 +4267,24 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi |
| 4241 | 4267 | }); |
| 4242 | 4268 | } |
| 4243 | 4269 | |
| 4270 | fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void { | |
| 4271 | if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return; | |
| 4272 | ||
| 4273 | _ = try block.addInst(.{ | |
| 4274 | .tag = .dbg_block_begin, | |
| 4275 | .data = undefined, | |
| 4276 | }); | |
| 4277 | } | |
| 4278 | ||
| 4279 | fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!void { | |
| 4280 | if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return; | |
| 4281 | ||
| 4282 | _ = try block.addInst(.{ | |
| 4283 | .tag = .dbg_block_end, | |
| 4284 | .data = undefined, | |
| 4285 | }); | |
| 4286 | } | |
| 4287 | ||
| 4244 | 4288 | fn zirDbgVar( |
| 4245 | 4289 | sema: *Sema, |
| 4246 | 4290 | block: *Block, |
| ... | ... | @@ -4251,6 +4295,17 @@ fn zirDbgVar( |
| 4251 | 4295 | |
| 4252 | 4296 | const str_op = sema.code.instructions.items(.data)[inst].str_op; |
| 4253 | 4297 | const operand = sema.resolveInst(str_op.operand); |
| 4298 | const name = str_op.getStr(sema.code); | |
| 4299 | try sema.addDbgVar(block, operand, air_tag, name); | |
| 4300 | } | |
| 4301 | ||
| 4302 | fn addDbgVar( | |
| 4303 | sema: *Sema, | |
| 4304 | block: *Block, | |
| 4305 | operand: Air.Inst.Ref, | |
| 4306 | air_tag: Air.Inst.Tag, | |
| 4307 | name: []const u8, | |
| 4308 | ) CompileError!void { | |
| 4254 | 4309 | const operand_ty = sema.typeOf(operand); |
| 4255 | 4310 | switch (air_tag) { |
| 4256 | 4311 | .dbg_var_ptr => { |
| ... | ... | @@ -4261,7 +4316,6 @@ fn zirDbgVar( |
| 4261 | 4316 | }, |
| 4262 | 4317 | else => unreachable, |
| 4263 | 4318 | } |
| 4264 | const name = str_op.getStr(sema.code); | |
| 4265 | 4319 | |
| 4266 | 4320 | // Add the name to the AIR. |
| 4267 | 4321 | const name_extra_index = @intCast(u32, sema.air_extra.items.len); |
| ... | ... | @@ -4817,6 +4871,25 @@ fn analyzeCall( |
| 4817 | 4871 | const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info); |
| 4818 | 4872 | if (!is_comptime_call) { |
| 4819 | 4873 | try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin); |
| 4874 | ||
| 4875 | for (fn_info.param_body) |param| switch (zir_tags[param]) { | |
| 4876 | .param, .param_comptime => { | |
| 4877 | const inst_data = sema.code.instructions.items(.data)[param].pl_tok; | |
| 4878 | const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index); | |
| 4879 | const param_name = sema.code.nullTerminatedString(extra.data.name); | |
| 4880 | const inst = sema.inst_map.get(param).?; | |
| 4881 | ||
| 4882 | try sema.addDbgVar(&child_block, inst, .dbg_var_val, param_name); | |
| 4883 | }, | |
| 4884 | .param_anytype, .param_anytype_comptime => { | |
| 4885 | const inst_data = sema.code.instructions.items(.data)[param].str_tok; | |
| 4886 | const param_name = inst_data.get(sema.code); | |
| 4887 | const inst = sema.inst_map.get(param).?; | |
| 4888 | ||
| 4889 | try sema.addDbgVar(&child_block, inst, .dbg_var_val, param_name); | |
| 4890 | }, | |
| 4891 | else => continue, | |
| 4892 | }; | |
| 4820 | 4893 | } |
| 4821 | 4894 | |
| 4822 | 4895 | const result = result: { |
| ... | ... | @@ -5250,7 +5323,9 @@ fn emitDbgInline( |
| 5250 | 5323 | new_func_ty: Type, |
| 5251 | 5324 | tag: Air.Inst.Tag, |
| 5252 | 5325 | ) CompileError!void { |
| 5253 | // No change of file; no dbg_inline needed. | |
| 5326 | if (sema.mod.comp.bin_file.options.strip) return; | |
| 5327 | ||
| 5328 | // Recursive inline call; no dbg_inline needed. | |
| 5254 | 5329 | if (old_func == new_func) return; |
| 5255 | 5330 | |
| 5256 | 5331 | try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func)); |
src/Zir.zig+4| ... | ... | @@ -1646,6 +1646,10 @@ pub const Inst = struct { |
| 1646 | 1646 | /// The `@prefetch` builtin. |
| 1647 | 1647 | /// `operand` is payload index to `BinNode`. |
| 1648 | 1648 | prefetch, |
| 1649 | /// Marks the beginning of a semantic scope for debug info variables. | |
| 1650 | dbg_block_begin, | |
| 1651 | /// Marks the end of a semantic scope for debug info variables. | |
| 1652 | dbg_block_end, | |
| 1649 | 1653 | |
| 1650 | 1654 | pub const InstData = struct { |
| 1651 | 1655 | opcode: Extended, |
src/arch/aarch64/CodeGen.zig+9| ... | ... | @@ -654,6 +654,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 654 | 654 | .dbg_inline_end, |
| 655 | 655 | => try self.airDbgInline(inst), |
| 656 | 656 | |
| 657 | .dbg_block_begin, | |
| 658 | .dbg_block_end, | |
| 659 | => try self.airDbgBlock(inst), | |
| 660 | ||
| 657 | 661 | .call => try self.airCall(inst, .auto), |
| 658 | 662 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 659 | 663 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -2731,6 +2735,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 2731 | 2735 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 2732 | 2736 | } |
| 2733 | 2737 | |
| 2738 | fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 2739 | // TODO emit debug info lexical block | |
| 2740 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 2741 | } | |
| 2742 | ||
| 2734 | 2743 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 2735 | 2744 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 2736 | 2745 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/arch/arm/CodeGen.zig+9| ... | ... | @@ -644,6 +644,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 644 | 644 | .dbg_inline_end, |
| 645 | 645 | => try self.airDbgInline(inst), |
| 646 | 646 | |
| 647 | .dbg_block_begin, | |
| 648 | .dbg_block_end, | |
| 649 | => try self.airDbgBlock(inst), | |
| 650 | ||
| 647 | 651 | .call => try self.airCall(inst, .auto), |
| 648 | 652 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 649 | 653 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -2948,6 +2952,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 2948 | 2952 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 2949 | 2953 | } |
| 2950 | 2954 | |
| 2955 | fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 2956 | // TODO emit debug info lexical block | |
| 2957 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 2958 | } | |
| 2959 | ||
| 2951 | 2960 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 2952 | 2961 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 2953 | 2962 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/arch/riscv64/CodeGen.zig+9| ... | ... | @@ -618,6 +618,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 618 | 618 | .dbg_inline_end, |
| 619 | 619 | => try self.airDbgInline(inst), |
| 620 | 620 | |
| 621 | .dbg_block_begin, | |
| 622 | .dbg_block_end, | |
| 623 | => try self.airDbgBlock(inst), | |
| 624 | ||
| 621 | 625 | .call => try self.airCall(inst, .auto), |
| 622 | 626 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 623 | 627 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -1653,6 +1657,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 1653 | 1657 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 1654 | 1658 | } |
| 1655 | 1659 | |
| 1660 | fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 1661 | // TODO emit debug info lexical block | |
| 1662 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 1663 | } | |
| 1664 | ||
| 1656 | 1665 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 1657 | 1666 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1658 | 1667 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/arch/wasm/CodeGen.zig+2| ... | ... | @@ -1330,6 +1330,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1330 | 1330 | .dbg_stmt, |
| 1331 | 1331 | .dbg_inline_begin, |
| 1332 | 1332 | .dbg_inline_end, |
| 1333 | .dbg_block_begin, | |
| 1334 | .dbg_block_end, | |
| 1333 | 1335 | .dbg_var_ptr, |
| 1334 | 1336 | .dbg_var_val, |
| 1335 | 1337 | => WValue.none, |
src/arch/x86_64/CodeGen.zig+9| ... | ... | @@ -735,6 +735,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 735 | 735 | .dbg_inline_end, |
| 736 | 736 | => try self.airDbgInline(inst), |
| 737 | 737 | |
| 738 | .dbg_block_begin, | |
| 739 | .dbg_block_end, | |
| 740 | => try self.airDbgBlock(inst), | |
| 741 | ||
| 738 | 742 | .call => try self.airCall(inst, .auto), |
| 739 | 743 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 740 | 744 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -3683,6 +3687,11 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 3683 | 3687 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); |
| 3684 | 3688 | } |
| 3685 | 3689 | |
| 3690 | fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void { | |
| 3691 | // TODO emit debug info lexical block | |
| 3692 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | |
| 3693 | } | |
| 3694 | ||
| 3686 | 3695 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 3687 | 3696 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 3688 | 3697 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/codegen/c.zig+4| ... | ... | @@ -1786,6 +1786,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1786 | 1786 | .dbg_inline_end, |
| 1787 | 1787 | => try airDbgInline(f, inst), |
| 1788 | 1788 | |
| 1789 | .dbg_block_begin, | |
| 1790 | .dbg_block_end, | |
| 1791 | => CValue{ .none = {} }, | |
| 1792 | ||
| 1789 | 1793 | .call => try airCall(f, inst, .auto), |
| 1790 | 1794 | .call_always_tail => try airCall(f, inst, .always_tail), |
| 1791 | 1795 | .call_never_tail => try airCall(f, inst, .never_tail), |
src/codegen/llvm.zig+22| ... | ... | @@ -3220,6 +3220,10 @@ pub const FuncGen = struct { |
| 3220 | 3220 | /// Stack of locations where a call was inlined. |
| 3221 | 3221 | dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{}, |
| 3222 | 3222 | |
| 3223 | /// Stack of `DILexicalBlock`s. dbg_block instructions cannot happend accross | |
| 3224 | /// dbg_inline instructions so no special handling there is required. | |
| 3225 | dbg_block_stack: std.ArrayListUnmanaged(*llvm.DIScope) = .{}, | |
| 3226 | ||
| 3223 | 3227 | /// This stores the LLVM values used in a function, such that they can be referred to |
| 3224 | 3228 | /// in other instructions. This table is cleared before every function is generated. |
| 3225 | 3229 | func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value), |
| ... | ... | @@ -3254,6 +3258,7 @@ pub const FuncGen = struct { |
| 3254 | 3258 | fn deinit(self: *FuncGen) void { |
| 3255 | 3259 | self.builder.dispose(); |
| 3256 | 3260 | self.dbg_inlined.deinit(self.gpa); |
| 3261 | self.dbg_block_stack.deinit(self.gpa); | |
| 3257 | 3262 | self.func_inst_table.deinit(self.gpa); |
| 3258 | 3263 | self.blocks.deinit(self.gpa); |
| 3259 | 3264 | } |
| ... | ... | @@ -3475,6 +3480,8 @@ pub const FuncGen = struct { |
| 3475 | 3480 | .dbg_stmt => self.airDbgStmt(inst), |
| 3476 | 3481 | .dbg_inline_begin => try self.airDbgInlineBegin(inst), |
| 3477 | 3482 | .dbg_inline_end => try self.airDbgInlineEnd(inst), |
| 3483 | .dbg_block_begin => try self.airDbgBlockBegin(), | |
| 3484 | .dbg_block_end => try self.airDbgBlockEnd(), | |
| 3478 | 3485 | .dbg_var_ptr => try self.airDbgVarPtr(inst), |
| 3479 | 3486 | .dbg_var_val => try self.airDbgVarVal(inst), |
| 3480 | 3487 | // zig fmt: on |
| ... | ... | @@ -4256,6 +4263,21 @@ pub const FuncGen = struct { |
| 4256 | 4263 | return null; |
| 4257 | 4264 | } |
| 4258 | 4265 | |
| 4266 | fn airDbgBlockBegin(self: *FuncGen) !?*const llvm.Value { | |
| 4267 | const dib = self.dg.object.di_builder orelse return null; | |
| 4268 | const old_scope = self.di_scope.?; | |
| 4269 | try self.dbg_block_stack.append(self.gpa, old_scope); | |
| 4270 | const lexical_block = dib.createLexicalBlock(old_scope, self.di_file.?, self.prev_dbg_line, self.prev_dbg_column); | |
| 4271 | self.di_scope = lexical_block.toScope(); | |
| 4272 | return null; | |
| 4273 | } | |
| 4274 | ||
| 4275 | fn airDbgBlockEnd(self: *FuncGen) !?*const llvm.Value { | |
| 4276 | if (self.dg.object.di_builder == null) return null; | |
| 4277 | self.di_scope = self.dbg_block_stack.pop(); | |
| 4278 | return null; | |
| 4279 | } | |
| 4280 | ||
| 4259 | 4281 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 4260 | 4282 | const dib = self.dg.object.di_builder orelse return null; |
| 4261 | 4283 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
src/print_air.zig+4-2| ... | ... | @@ -272,6 +272,8 @@ const Writer = struct { |
| 272 | 272 | .mul_with_overflow, |
| 273 | 273 | .shl_with_overflow, |
| 274 | 274 | => try w.writeOverflow(s, inst), |
| 275 | ||
| 276 | .dbg_block_begin, .dbg_block_end => {}, | |
| 275 | 277 | } |
| 276 | 278 | } |
| 277 | 279 | |
| ... | ... | @@ -384,8 +386,8 @@ const Writer = struct { |
| 384 | 386 | } |
| 385 | 387 | |
| 386 | 388 | fn writeShuffle(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 387 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; | |
| 388 | const extra = w.air.extraData(Air.Shuffle, pl_op.payload).data; | |
| 389 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; | |
| 390 | const extra = w.air.extraData(Air.Shuffle, ty_pl.payload).data; | |
| 389 | 391 | |
| 390 | 392 | try w.writeOperand(s, inst, 0, extra.a); |
| 391 | 393 | try s.writeAll(", "); |
src/print_zir.zig+4| ... | ... | @@ -463,6 +463,10 @@ const Writer = struct { |
| 463 | 463 | .builtin_src, |
| 464 | 464 | => try self.writeExtNode(stream, extended), |
| 465 | 465 | |
| 466 | .dbg_block_begin, | |
| 467 | .dbg_block_end, | |
| 468 | => try stream.writeAll("))"), | |
| 469 | ||
| 466 | 470 | .@"asm" => try self.writeAsm(stream, extended), |
| 467 | 471 | .func => try self.writeFuncExtended(stream, extended), |
| 468 | 472 | .variable => try self.writeVarExtended(stream, extended), |
test/behavior/struct.zig+2| ... | ... | @@ -427,6 +427,7 @@ test "packed struct 24bits" { |
| 427 | 427 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 428 | 428 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 429 | 429 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO |
| 430 | if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO | |
| 430 | 431 | |
| 431 | 432 | comptime { |
| 432 | 433 | try expect(@sizeOf(Foo24Bits) == 4); |
| ... | ... | @@ -979,6 +980,7 @@ test "tuple assigned to variable" { |
| 979 | 980 | |
| 980 | 981 | test "comptime struct field" { |
| 981 | 982 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 983 | if (builtin.stage2_arch == .arm) return error.SkipZigTest; // TODO | |
| 982 | 984 | |
| 983 | 985 | const T = struct { |
| 984 | 986 | a: i32, |
test/behavior/while.zig+3| ... | ... | @@ -173,6 +173,7 @@ test "while with optional as condition with else" { |
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | test "while with error union condition" { |
| 176 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 176 | 177 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 177 | 178 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 178 | 179 | |
| ... | ... | @@ -289,6 +290,7 @@ test "while bool 2 break statements and an else" { |
| 289 | 290 | } |
| 290 | 291 | |
| 291 | 292 | test "while optional 2 break statements and an else" { |
| 293 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 292 | 294 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 293 | 295 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 294 | 296 | |
| ... | ... | @@ -307,6 +309,7 @@ test "while optional 2 break statements and an else" { |
| 307 | 309 | } |
| 308 | 310 | |
| 309 | 311 | test "while error 2 break statements and an else" { |
| 312 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 310 | 313 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 311 | 314 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 312 | 315 |