| ... | @@ -61,7 +61,8 @@ const Scope = struct { | ... | @@ -61,7 +61,8 @@ const Scope = struct { |
| 61 | pending_block: Block, | 61 | pending_block: Block, |
| 62 | cases: []*ast.Node, | 62 | cases: []*ast.Node, |
| 63 | case_index: usize, | 63 | case_index: usize, |
| 64 | has_default: bool = false, | 64 | switch_label: ?[]const u8, |
| | 65 | default_label: ?[]const u8, |
| 65 | }; | 66 | }; |
| 66 | | 67 | |
| 67 | /// Used for the scope of condition expressions, for example `if (cond)`. | 68 | /// Used for the scope of condition expressions, for example `if (cond)`. |
| ... | @@ -73,7 +74,7 @@ const Scope = struct { | ... | @@ -73,7 +74,7 @@ const Scope = struct { |
| 73 | | 74 | |
| 74 | fn getBlockScope(self: *Condition, c: *Context) !*Block { | 75 | fn getBlockScope(self: *Condition, c: *Context) !*Block { |
| 75 | if (self.block) |*b| return b; | 76 | if (self.block) |*b| return b; |
| 76 | self.block = try Block.init(c, &self.base, "blk"); | 77 | self.block = try Block.init(c, &self.base, true); |
| 77 | return &self.block.?; | 78 | return &self.block.?; |
| 78 | } | 79 | } |
| 79 | | 80 | |
| ... | @@ -93,21 +94,22 @@ const Scope = struct { | ... | @@ -93,21 +94,22 @@ const Scope = struct { |
| 93 | mangle_count: u32 = 0, | 94 | mangle_count: u32 = 0, |
| 94 | lbrace: ast.TokenIndex, | 95 | lbrace: ast.TokenIndex, |
| 95 | | 96 | |
| 96 | fn init(c: *Context, parent: *Scope, label: ?[]const u8) !Block { | 97 | fn init(c: *Context, parent: *Scope, labeled: bool) !Block { |
| 97 | return Block{ | 98 | var blk = Block{ |
| 98 | .base = .{ | 99 | .base = .{ |
| 99 | .id = .Block, | 100 | .id = .Block, |
| 100 | .parent = parent, | 101 | .parent = parent, |
| 101 | }, | 102 | }, |
| 102 | .statements = std.ArrayList(*ast.Node).init(c.gpa), | 103 | .statements = std.ArrayList(*ast.Node).init(c.gpa), |
| 103 | .variables = AliasList.init(c.gpa), | 104 | .variables = AliasList.init(c.gpa), |
| 104 | .label = if (label) |l| blk: { | 105 | .label = null, |
| 105 | const ll = try appendIdentifier(c, l); | | |
| 106 | _ = try appendToken(c, .Colon, ":"); | | |
| 107 | break :blk ll; | | |
| 108 | } else null, | | |
| 109 | .lbrace = try appendToken(c, .LBrace, "{"), | 106 | .lbrace = try appendToken(c, .LBrace, "{"), |
| 110 | }; | 107 | }; |
| | 108 | if (labeled) { |
| | 109 | blk.label = try appendIdentifier(c, try blk.makeMangledName(c, "blk")); |
| | 110 | _ = try appendToken(c, .Colon, ":"); |
| | 111 | } |
| | 112 | return blk; |
| 111 | } | 113 | } |
| 112 | | 114 | |
| 113 | fn deinit(self: *Block) void { | 115 | fn deinit(self: *Block) void { |
| ... | @@ -577,7 +579,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { | ... | @@ -577,7 +579,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 577 | | 579 | |
| 578 | // actual function definition with body | 580 | // actual function definition with body |
| 579 | const body_stmt = ZigClangFunctionDecl_getBody(fn_decl); | 581 | const body_stmt = ZigClangFunctionDecl_getBody(fn_decl); |
| 580 | var block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null); | 582 | var block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, false); |
| 581 | defer block_scope.deinit(); | 583 | defer block_scope.deinit(); |
| 582 | var scope = &block_scope.base; | 584 | var scope = &block_scope.base; |
| 583 | | 585 | |
| ... | @@ -1307,7 +1309,7 @@ fn transBinaryOperator( | ... | @@ -1307,7 +1309,7 @@ fn transBinaryOperator( |
| 1307 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 1309 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 1308 | if (expr) { | 1310 | if (expr) { |
| 1309 | _ = try appendToken(rp.c, .Semicolon, ";"); | 1311 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 1310 | const break_node = try transCreateNodeBreakToken(rp.c, block_scope.label, rhs); | 1312 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label, rhs); |
| 1311 | try block_scope.statements.append(&break_node.base); | 1313 | try block_scope.statements.append(&break_node.base); |
| 1312 | const block_node = try block_scope.complete(rp.c); | 1314 | const block_node = try block_scope.complete(rp.c); |
| 1313 | const rparen = try appendToken(rp.c, .RParen, ")"); | 1315 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -1476,7 +1478,7 @@ fn transCompoundStmtInline( | ... | @@ -1476,7 +1478,7 @@ fn transCompoundStmtInline( |
| 1476 | } | 1478 | } |
| 1477 | | 1479 | |
| 1478 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { | 1480 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { |
| 1479 | var block_scope = try Scope.Block.init(rp.c, scope, null); | 1481 | var block_scope = try Scope.Block.init(rp.c, scope, false); |
| 1480 | defer block_scope.deinit(); | 1482 | defer block_scope.deinit(); |
| 1481 | try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope); | 1483 | try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope); |
| 1482 | const node = try block_scope.complete(rp.c); | 1484 | const node = try block_scope.complete(rp.c); |
| ... | @@ -2587,7 +2589,7 @@ fn transForLoop( | ... | @@ -2587,7 +2589,7 @@ fn transForLoop( |
| 2587 | defer if (block_scope) |*bs| bs.deinit(); | 2589 | defer if (block_scope) |*bs| bs.deinit(); |
| 2588 | | 2590 | |
| 2589 | if (ZigClangForStmt_getInit(stmt)) |init| { | 2591 | if (ZigClangForStmt_getInit(stmt)) |init| { |
| 2590 | block_scope = try Scope.Block.init(rp.c, scope, null); | 2592 | block_scope = try Scope.Block.init(rp.c, scope, false); |
| 2591 | loop_scope.parent = &block_scope.?.base; | 2593 | loop_scope.parent = &block_scope.?.base; |
| 2592 | const init_node = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value); | 2594 | const init_node = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value); |
| 2593 | try block_scope.?.statements.append(init_node); | 2595 | try block_scope.?.statements.append(init_node); |
| ... | @@ -2673,17 +2675,19 @@ fn transSwitch( | ... | @@ -2673,17 +2675,19 @@ fn transSwitch( |
| 2673 | .cases = switch_node.cases(), | 2675 | .cases = switch_node.cases(), |
| 2674 | .case_index = 0, | 2676 | .case_index = 0, |
| 2675 | .pending_block = undefined, | 2677 | .pending_block = undefined, |
| | 2678 | .default_label = null, |
| | 2679 | .switch_label = null, |
| 2676 | }; | 2680 | }; |
| 2677 | | 2681 | |
| 2678 | // tmp block that all statements will go before being picked up by a case or default | 2682 | // tmp block that all statements will go before being picked up by a case or default |
| 2679 | var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null); | 2683 | var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, false); |
| 2680 | defer block_scope.deinit(); | 2684 | defer block_scope.deinit(); |
| 2681 | | 2685 | |
| 2682 | // Note that we do not defer a deinit here; the switch_scope.pending_block field | 2686 | // Note that we do not defer a deinit here; the switch_scope.pending_block field |
| 2683 | // has its own memory management. This resource is freed inside `transCase` and | 2687 | // has its own memory management. This resource is freed inside `transCase` and |
| 2684 | // then the final pending_block is freed at the bottom of this function with | 2688 | // then the final pending_block is freed at the bottom of this function with |
| 2685 | // pending_block.deinit(). | 2689 | // pending_block.deinit(). |
| 2686 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null); | 2690 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, false); |
| 2687 | try switch_scope.pending_block.statements.append(&switch_node.base); | 2691 | try switch_scope.pending_block.statements.append(&switch_node.base); |
| 2688 | | 2692 | |
| 2689 | const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value); | 2693 | const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value); |
| ... | @@ -2698,11 +2702,19 @@ fn transSwitch( | ... | @@ -2698,11 +2702,19 @@ fn transSwitch( |
| 2698 | switch_scope.pending_block.statements.appendAssumeCapacity(n); | 2702 | switch_scope.pending_block.statements.appendAssumeCapacity(n); |
| 2699 | } | 2703 | } |
| 2700 | | 2704 | |
| 2701 | switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch"); | 2705 | if (switch_scope.default_label == null) { |
| 2702 | _ = try appendToken(rp.c, .Colon, ":"); | 2706 | switch_scope.switch_label = try block_scope.makeMangledName(rp.c, "switch"); |
| 2703 | if (!switch_scope.has_default) { | 2707 | } |
| | 2708 | if (switch_scope.switch_label) |l| { |
| | 2709 | switch_scope.pending_block.label = try appendIdentifier(rp.c, l); |
| | 2710 | _ = try appendToken(rp.c, .Colon, ":"); |
| | 2711 | } |
| | 2712 | if (switch_scope.default_label == null) { |
| 2704 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); | 2713 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); |
| 2705 | else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch", null)).base; | 2714 | else_prong.expr = blk: { |
| | 2715 | var br = try CtrlFlow.init(rp.c, .Break, switch_scope.switch_label.?); |
| | 2716 | break :blk &(try br.finish(null)).base; |
| | 2717 | }; |
| 2706 | _ = try appendToken(rp.c, .Comma, ","); | 2718 | _ = try appendToken(rp.c, .Comma, ","); |
| 2707 | | 2719 | |
| 2708 | if (switch_scope.case_index >= switch_scope.cases.len) | 2720 | if (switch_scope.case_index >= switch_scope.cases.len) |
| ... | @@ -2726,7 +2738,7 @@ fn transCase( | ... | @@ -2726,7 +2738,7 @@ fn transCase( |
| 2726 | ) TransError!*ast.Node { | 2738 | ) TransError!*ast.Node { |
| 2727 | const block_scope = scope.findBlockScope(rp.c) catch unreachable; | 2739 | const block_scope = scope.findBlockScope(rp.c) catch unreachable; |
| 2728 | const switch_scope = scope.getSwitch(); | 2740 | const switch_scope = scope.getSwitch(); |
| 2729 | const label = try std.fmt.allocPrint(rp.c.arena, "__case_{}", .{switch_scope.case_index - @boolToInt(switch_scope.has_default)}); | 2741 | const label = try block_scope.makeMangledName(rp.c, "case"); |
| 2730 | _ = try appendToken(rp.c, .Semicolon, ";"); | 2742 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2731 | | 2743 | |
| 2732 | const expr = if (ZigClangCaseStmt_getRHS(stmt)) |rhs| blk: { | 2744 | const expr = if (ZigClangCaseStmt_getRHS(stmt)) |rhs| blk: { |
| ... | @@ -2746,7 +2758,10 @@ fn transCase( | ... | @@ -2746,7 +2758,10 @@ fn transCase( |
| 2746 | try transExpr(rp, scope, ZigClangCaseStmt_getLHS(stmt), .used, .r_value); | 2758 | try transExpr(rp, scope, ZigClangCaseStmt_getLHS(stmt), .used, .r_value); |
| 2747 | | 2759 | |
| 2748 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); | 2760 | const switch_prong = try transCreateNodeSwitchCase(rp.c, expr); |
| 2749 | switch_prong.expr = &(try transCreateNodeBreak(rp.c, label, null)).base; | 2761 | switch_prong.expr = blk: { |
| | 2762 | var br = try CtrlFlow.init(rp.c, .Break, label); |
| | 2763 | break :blk &(try br.finish(null)).base; |
| | 2764 | }; |
| 2750 | _ = try appendToken(rp.c, .Comma, ","); | 2765 | _ = try appendToken(rp.c, .Comma, ","); |
| 2751 | | 2766 | |
| 2752 | if (switch_scope.case_index >= switch_scope.cases.len) | 2767 | if (switch_scope.case_index >= switch_scope.cases.len) |
| ... | @@ -2763,7 +2778,7 @@ fn transCase( | ... | @@ -2763,7 +2778,7 @@ fn transCase( |
| 2763 | | 2778 | |
| 2764 | const pending_node = try switch_scope.pending_block.complete(rp.c); | 2779 | const pending_node = try switch_scope.pending_block.complete(rp.c); |
| 2765 | switch_scope.pending_block.deinit(); | 2780 | switch_scope.pending_block.deinit(); |
| 2766 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null); | 2781 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, false); |
| 2767 | | 2782 | |
| 2768 | try switch_scope.pending_block.statements.append(&pending_node.base); | 2783 | try switch_scope.pending_block.statements.append(&pending_node.base); |
| 2769 | | 2784 | |
| ... | @@ -2777,12 +2792,14 @@ fn transDefault( | ... | @@ -2777,12 +2792,14 @@ fn transDefault( |
| 2777 | ) TransError!*ast.Node { | 2792 | ) TransError!*ast.Node { |
| 2778 | const block_scope = scope.findBlockScope(rp.c) catch unreachable; | 2793 | const block_scope = scope.findBlockScope(rp.c) catch unreachable; |
| 2779 | const switch_scope = scope.getSwitch(); | 2794 | const switch_scope = scope.getSwitch(); |
| 2780 | const label = "__default"; | 2795 | switch_scope.default_label = try block_scope.makeMangledName(rp.c, "default"); |
| 2781 | switch_scope.has_default = true; | | |
| 2782 | _ = try appendToken(rp.c, .Semicolon, ";"); | 2796 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 2783 | | 2797 | |
| 2784 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); | 2798 | const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c)); |
| 2785 | else_prong.expr = &(try transCreateNodeBreak(rp.c, label, null)).base; | 2799 | else_prong.expr = blk: { |
| | 2800 | var br = try CtrlFlow.init(rp.c, .Break, switch_scope.default_label.?); |
| | 2801 | break :blk &(try br.finish(null)).base; |
| | 2802 | }; |
| 2786 | _ = try appendToken(rp.c, .Comma, ","); | 2803 | _ = try appendToken(rp.c, .Comma, ","); |
| 2787 | | 2804 | |
| 2788 | if (switch_scope.case_index >= switch_scope.cases.len) | 2805 | if (switch_scope.case_index >= switch_scope.cases.len) |
| ... | @@ -2790,7 +2807,7 @@ fn transDefault( | ... | @@ -2790,7 +2807,7 @@ fn transDefault( |
| 2790 | switch_scope.cases[switch_scope.case_index] = &else_prong.base; | 2807 | switch_scope.cases[switch_scope.case_index] = &else_prong.base; |
| 2791 | switch_scope.case_index += 1; | 2808 | switch_scope.case_index += 1; |
| 2792 | | 2809 | |
| 2793 | switch_scope.pending_block.label = try appendIdentifier(rp.c, label); | 2810 | switch_scope.pending_block.label = try appendIdentifier(rp.c, switch_scope.default_label.?); |
| 2794 | _ = try appendToken(rp.c, .Colon, ":"); | 2811 | _ = try appendToken(rp.c, .Colon, ":"); |
| 2795 | | 2812 | |
| 2796 | // take all pending statements | 2813 | // take all pending statements |
| ... | @@ -2799,7 +2816,7 @@ fn transDefault( | ... | @@ -2799,7 +2816,7 @@ fn transDefault( |
| 2799 | | 2816 | |
| 2800 | const pending_node = try switch_scope.pending_block.complete(rp.c); | 2817 | const pending_node = try switch_scope.pending_block.complete(rp.c); |
| 2801 | switch_scope.pending_block.deinit(); | 2818 | switch_scope.pending_block.deinit(); |
| 2802 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null); | 2819 | switch_scope.pending_block = try Scope.Block.init(rp.c, scope, false); |
| 2803 | try switch_scope.pending_block.statements.append(&pending_node.base); | 2820 | try switch_scope.pending_block.statements.append(&pending_node.base); |
| 2804 | | 2821 | |
| 2805 | return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value); | 2822 | return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value); |
| ... | @@ -2894,7 +2911,7 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, | ... | @@ -2894,7 +2911,7 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, |
| 2894 | return transCompoundStmt(rp, scope, comp); | 2911 | return transCompoundStmt(rp, scope, comp); |
| 2895 | } | 2912 | } |
| 2896 | const lparen = try appendToken(rp.c, .LParen, "("); | 2913 | const lparen = try appendToken(rp.c, .LParen, "("); |
| 2897 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 2914 | var block_scope = try Scope.Block.init(rp.c, scope, true); |
| 2898 | defer block_scope.deinit(); | 2915 | defer block_scope.deinit(); |
| 2899 | | 2916 | |
| 2900 | var it = ZigClangCompoundStmt_body_begin(comp); | 2917 | var it = ZigClangCompoundStmt_body_begin(comp); |
| ... | @@ -3209,7 +3226,7 @@ fn transCreatePreCrement( | ... | @@ -3209,7 +3226,7 @@ fn transCreatePreCrement( |
| 3209 | // zig: _ref.* += 1; | 3226 | // zig: _ref.* += 1; |
| 3210 | // zig: break :blk _ref.* | 3227 | // zig: break :blk _ref.* |
| 3211 | // zig: }) | 3228 | // zig: }) |
| 3212 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3229 | var block_scope = try Scope.Block.init(rp.c, scope, true); |
| 3213 | defer block_scope.deinit(); | 3230 | defer block_scope.deinit(); |
| 3214 | const ref = try block_scope.makeMangledName(rp.c, "ref"); | 3231 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3215 | | 3232 | |
| ... | @@ -3239,7 +3256,7 @@ fn transCreatePreCrement( | ... | @@ -3239,7 +3256,7 @@ fn transCreatePreCrement( |
| 3239 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); | 3256 | const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false); |
| 3240 | try block_scope.statements.append(assign); | 3257 | try block_scope.statements.append(assign); |
| 3241 | | 3258 | |
| 3242 | const break_node = try transCreateNodeBreakToken(rp.c, block_scope.label, ref_node); | 3259 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label, ref_node); |
| 3243 | try block_scope.statements.append(&break_node.base); | 3260 | try block_scope.statements.append(&break_node.base); |
| 3244 | const block_node = try block_scope.complete(rp.c); | 3261 | const block_node = try block_scope.complete(rp.c); |
| 3245 | // semicolon must immediately follow rbrace because it is the last token in a block | 3262 | // semicolon must immediately follow rbrace because it is the last token in a block |
| ... | @@ -3283,7 +3300,7 @@ fn transCreatePostCrement( | ... | @@ -3283,7 +3300,7 @@ fn transCreatePostCrement( |
| 3283 | // zig: _ref.* += 1; | 3300 | // zig: _ref.* += 1; |
| 3284 | // zig: break :blk _tmp | 3301 | // zig: break :blk _tmp |
| 3285 | // zig: }) | 3302 | // zig: }) |
| 3286 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3303 | var block_scope = try Scope.Block.init(rp.c, scope, true); |
| 3287 | defer block_scope.deinit(); | 3304 | defer block_scope.deinit(); |
| 3288 | const ref = try block_scope.makeMangledName(rp.c, "ref"); | 3305 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3289 | | 3306 | |
| ... | @@ -3458,7 +3475,7 @@ fn transCreateCompoundAssign( | ... | @@ -3458,7 +3475,7 @@ fn transCreateCompoundAssign( |
| 3458 | // zig: _ref.* = _ref.* + rhs; | 3475 | // zig: _ref.* = _ref.* + rhs; |
| 3459 | // zig: break :blk _ref.* | 3476 | // zig: break :blk _ref.* |
| 3460 | // zig: }) | 3477 | // zig: }) |
| 3461 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3478 | var block_scope = try Scope.Block.init(rp.c, scope, true); |
| 3462 | defer block_scope.deinit(); | 3479 | defer block_scope.deinit(); |
| 3463 | const ref = try block_scope.makeMangledName(rp.c, "ref"); | 3480 | const ref = try block_scope.makeMangledName(rp.c, "ref"); |
| 3464 | | 3481 | |
| ... | @@ -3526,7 +3543,7 @@ fn transCreateCompoundAssign( | ... | @@ -3526,7 +3543,7 @@ fn transCreateCompoundAssign( |
| 3526 | try block_scope.statements.append(assign); | 3543 | try block_scope.statements.append(assign); |
| 3527 | } | 3544 | } |
| 3528 | | 3545 | |
| 3529 | const break_node = try transCreateNodeBreakToken(rp.c, block_scope.label, ref_node); | 3546 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label, ref_node); |
| 3530 | try block_scope.statements.append(&break_node.base); | 3547 | try block_scope.statements.append(&break_node.base); |
| 3531 | const block_node = try block_scope.complete(rp.c); | 3548 | const block_node = try block_scope.complete(rp.c); |
| 3532 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); | 3549 | const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression); |
| ... | @@ -3602,8 +3619,16 @@ fn transCPtrCast( | ... | @@ -3602,8 +3619,16 @@ fn transCPtrCast( |
| 3602 | | 3619 | |
| 3603 | fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node { | 3620 | fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node { |
| 3604 | const break_scope = scope.getBreakableScope(); | 3621 | const break_scope = scope.getBreakableScope(); |
| 3605 | const label_text: ?[]const u8 = if (break_scope.id == .Switch) "__switch" else null; | 3622 | const label_text: ?[]const u8 = if (break_scope.id == .Switch) blk: { |
| 3606 | const br = try transCreateNodeBreak(rp.c, label_text, null); | 3623 | const swtch = @fieldParentPtr(Scope.Switch, "base", break_scope); |
| | 3624 | const block_scope = try scope.findBlockScope(rp.c); |
| | 3625 | swtch.switch_label = try block_scope.makeMangledName(rp.c, "switch"); |
| | 3626 | break :blk swtch.switch_label; |
| | 3627 | } else |
| | 3628 | null; |
| | 3629 | |
| | 3630 | var cf = try CtrlFlow.init(rp.c, .Break, label_text); |
| | 3631 | const br = try cf.finish(null); |
| 3607 | _ = try appendToken(rp.c, .Semicolon, ";"); | 3632 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 3608 | return &br.base; | 3633 | return &br.base; |
| 3609 | } | 3634 | } |
| ... | @@ -3634,7 +3659,7 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const | ... | @@ -3634,7 +3659,7 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const |
| 3634 | // }) | 3659 | // }) |
| 3635 | const lparen = try appendToken(rp.c, .LParen, "("); | 3660 | const lparen = try appendToken(rp.c, .LParen, "("); |
| 3636 | | 3661 | |
| 3637 | var block_scope = try Scope.Block.init(rp.c, scope, "blk"); | 3662 | var block_scope = try Scope.Block.init(rp.c, scope, true); |
| 3638 | defer block_scope.deinit(); | 3663 | defer block_scope.deinit(); |
| 3639 | | 3664 | |
| 3640 | const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp"); | 3665 | const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp"); |
| ... | @@ -4082,8 +4107,7 @@ fn transCreateNodeAssign( | ... | @@ -4082,8 +4107,7 @@ fn transCreateNodeAssign( |
| 4082 | // zig: lhs = _tmp; | 4107 | // zig: lhs = _tmp; |
| 4083 | // zig: break :blk _tmp | 4108 | // zig: break :blk _tmp |
| 4084 | // zig: }) | 4109 | // zig: }) |
| 4085 | const label_name = "blk"; | 4110 | var block_scope = try Scope.Block.init(rp.c, scope, true); |
| 4086 | var block_scope = try Scope.Block.init(rp.c, scope, label_name); | | |
| 4087 | defer block_scope.deinit(); | 4111 | defer block_scope.deinit(); |
| 4088 | | 4112 | |
| 4089 | const tmp = try block_scope.makeMangledName(rp.c, "tmp"); | 4113 | const tmp = try block_scope.makeMangledName(rp.c, "tmp"); |
| ... | @@ -4118,7 +4142,7 @@ fn transCreateNodeAssign( | ... | @@ -4118,7 +4142,7 @@ fn transCreateNodeAssign( |
| 4118 | try block_scope.statements.append(assign); | 4142 | try block_scope.statements.append(assign); |
| 4119 | | 4143 | |
| 4120 | const break_node = blk: { | 4144 | const break_node = blk: { |
| 4121 | var tmp_ctrl_flow = try CtrlFlow.init(rp.c, .Break, label_name); | 4145 | var tmp_ctrl_flow = try CtrlFlow.init(rp.c, .Break, tokenSlice(rp.c, block_scope.label.?)); |
| 4122 | const rhs_expr = try transCreateNodeIdentifier(rp.c, tmp); | 4146 | const rhs_expr = try transCreateNodeIdentifier(rp.c, tmp); |
| 4123 | break :blk try tmp_ctrl_flow.finish(rhs_expr); | 4147 | break :blk try tmp_ctrl_flow.finish(rhs_expr); |
| 4124 | }; | 4148 | }; |
| ... | @@ -4495,23 +4519,12 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { | ... | @@ -4495,23 +4519,12 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else { |
| 4495 | return node; | 4519 | return node; |
| 4496 | } | 4520 | } |
| 4497 | | 4521 | |
| 4498 | fn transCreateNodeBreakToken( | | |
| 4499 | c: *Context, | | |
| 4500 | label: ?ast.TokenIndex, | | |
| 4501 | rhs: ?*ast.Node, | | |
| 4502 | ) !*ast.Node.ControlFlowExpression { | | |
| 4503 | const other_token = label orelse return transCreateNodeBreak(c, null, rhs); | | |
| 4504 | const loc = c.token_locs.items[other_token]; | | |
| 4505 | const label_name = c.source_buffer.items[loc.start..loc.end]; | | |
| 4506 | return transCreateNodeBreak(c, label_name, rhs); | | |
| 4507 | } | | |
| 4508 | | | |
| 4509 | fn transCreateNodeBreak( | 4522 | fn transCreateNodeBreak( |
| 4510 | c: *Context, | 4523 | c: *Context, |
| 4511 | label: ?[]const u8, | 4524 | label: ?ast.TokenIndex, |
| 4512 | rhs: ?*ast.Node, | 4525 | rhs: ?*ast.Node, |
| 4513 | ) !*ast.Node.ControlFlowExpression { | 4526 | ) !*ast.Node.ControlFlowExpression { |
| 4514 | var ctrl_flow = try CtrlFlow.init(c, .Break, label); | 4527 | var ctrl_flow = try CtrlFlow.init(c, .Break, if (label) |l| tokenSlice(c, l) else null); |
| 4515 | return ctrl_flow.finish(rhs); | 4528 | return ctrl_flow.finish(rhs); |
| 4516 | } | 4529 | } |
| 4517 | | 4530 | |
| ... | @@ -5362,7 +5375,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { | ... | @@ -5362,7 +5375,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5362 | } | 5375 | } |
| 5363 | | 5376 | |
| 5364 | fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { | 5377 | fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void { |
| 5365 | var block_scope = try Scope.Block.init(c, &c.global_scope.base, null); | 5378 | var block_scope = try Scope.Block.init(c, &c.global_scope.base, false); |
| 5366 | defer block_scope.deinit(); | 5379 | defer block_scope.deinit(); |
| 5367 | const scope = &block_scope.base; | 5380 | const scope = &block_scope.base; |
| 5368 | | 5381 | |
| ... | @@ -5475,8 +5488,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { | ... | @@ -5475,8 +5488,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { |
| 5475 | }, | 5488 | }, |
| 5476 | .Comma => { | 5489 | .Comma => { |
| 5477 | _ = try appendToken(c, .Semicolon, ";"); | 5490 | _ = try appendToken(c, .Semicolon, ";"); |
| 5478 | const label_name = "blk"; | 5491 | var block_scope = try Scope.Block.init(c, scope, true); |
| 5479 | var block_scope = try Scope.Block.init(c, scope, label_name); | | |
| 5480 | defer block_scope.deinit(); | 5492 | defer block_scope.deinit(); |
| 5481 | | 5493 | |
| 5482 | var last = node; | 5494 | var last = node; |
| ... | @@ -5501,7 +5513,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { | ... | @@ -5501,7 +5513,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.Node { |
| 5501 | } | 5513 | } |
| 5502 | } | 5514 | } |
| 5503 | | 5515 | |
| 5504 | const break_node = try transCreateNodeBreak(c, label_name, last); | 5516 | const break_node = try transCreateNodeBreak(c, block_scope.label, last); |
| 5505 | try block_scope.statements.append(&break_node.base); | 5517 | try block_scope.statements.append(&break_node.base); |
| 5506 | const block_node = try block_scope.complete(c); | 5518 | const block_node = try block_scope.complete(c); |
| 5507 | return &block_node.base; | 5519 | return &block_node.base; |