authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 15:27:29+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 15:27:29+03:00
logc5368ba20c79b62d658c71033df9aeb7aa6e4581
treed3497333bb4df3e52a473627a5a8b7666c6239df
parent373488157751dbaa22415ce842c4f5616fc845ff
signature Commit is signed but in an unrecognized format.

translate-c: ensure generated labels are unique


2 files changed, 81 insertions(+), 69 deletions(-)

src-self-hosted/translate_c.zig+68-56
...@@ -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 };
6667
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 {
7374
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 }
7980
...@@ -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,
9596
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 }
112114
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 {
577579
578 // actual function definition with body580 // 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;
583585
...@@ -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}
14771479
1478fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {1480fn 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();
25882590
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 };
26772681
2678 // tmp block that all statements will go before being picked up by a case or default2682 // 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();
26812685
2682 // Note that we do not defer a deinit here; the switch_scope.pending_block field2686 // 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` and2687 // 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 with2688 // 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);
26882692
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 }
27002704
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, ",");
27072719
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, ";");
27312743
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);
27472759
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, ",");
27512766
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(
27632778
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);
27672782
2768 try switch_scope.pending_block.statements.append(&pending_node.base);2783 try switch_scope.pending_block.statements.append(&pending_node.base);
27692784
...@@ -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, ";");
27832797
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, ",");
27872804
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;
27922809
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, ":");
27952812
2796 // take all pending statements2813 // take all pending statements
...@@ -2799,7 +2816,7 @@ fn transDefault(...@@ -2799,7 +2816,7 @@ fn transDefault(
27992816
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);
28042821
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();
28992916
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");
32153232
...@@ -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);
32413258
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 block3262 // 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 _tmp3301 // 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");
32893306
...@@ -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");
34643481
...@@ -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 }
35283545
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(
36023619
3603fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node {3620fn 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, "(");
36363661
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();
36393664
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 _tmp4108 // 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();
40884112
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);
41194143
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}
44974521
4498fn 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
4509fn transCreateNodeBreak(4522fn 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}
45174530
...@@ -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}
53635376
5364fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {5377fn 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;
53685381
...@@ -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();
54815493
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 }
55035515
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;
test/translate_c.zig+13-13
...@@ -1730,16 +1730,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1730,16 +1730,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1730 \\pub export fn switch_fn(arg_i: c_int) c_int {1730 \\pub export fn switch_fn(arg_i: c_int) c_int {
1731 \\ var i = arg_i;1731 \\ var i = arg_i;
1732 \\ var res: c_int = 0;1732 \\ var res: c_int = 0;
1733 \\ __switch: {1733 \\ @"switch": {
1734 \\ __case_2: {1734 \\ case_2: {
1735 \\ __default: {1735 \\ default: {
1736 \\ __case_1: {1736 \\ case_1: {
1737 \\ __case_0: {1737 \\ case: {
1738 \\ switch (i) {1738 \\ switch (i) {
1739 \\ @as(c_int, 0) => break :__case_0,1739 \\ @as(c_int, 0) => break :case,
1740 \\ @as(c_int, 1)...@as(c_int, 3) => break :__case_1,1740 \\ @as(c_int, 1)...@as(c_int, 3) => break :case_1,
1741 \\ else => break :__default,1741 \\ else => break :default,
1742 \\ @as(c_int, 4) => break :__case_2,1742 \\ @as(c_int, 4) => break :case_2,
1743 \\ }1743 \\ }
1744 \\ }1744 \\ }
1745 \\ res = 1;1745 \\ res = 1;
...@@ -1747,7 +1747,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1747,7 +1747,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1747 \\ res = 2;1747 \\ res = 2;
1748 \\ }1748 \\ }
1749 \\ res = (@as(c_int, 3) * i);1749 \\ res = (@as(c_int, 3) * i);
1750 \\ break :__switch;1750 \\ break :@"switch";
1751 \\ }1751 \\ }
1752 \\ res = 5;1752 \\ res = 5;
1753 \\ }1753 \\ }
...@@ -2782,11 +2782,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2782,11 +2782,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2782 \\ var x = arg_x;2782 \\ var x = arg_x;
2783 \\ return blk: {2783 \\ return blk: {
2784 \\ const tmp = x;2784 \\ const tmp = x;
2785 \\ (blk: {2785 \\ (blk_1: {
2786 \\ const ref = &p;2786 \\ const ref = &p;
2787 \\ const tmp_1 = ref.*;2787 \\ const tmp_2 = ref.*;
2788 \\ ref.* += 1;2788 \\ ref.* += 1;
2789 \\ break :blk tmp_1;2789 \\ break :blk_1 tmp_2;
2790 \\ }).?.* = tmp;2790 \\ }).?.* = tmp;
2791 \\ break :blk tmp;2791 \\ break :blk tmp;
2792 \\ };2792 \\ };