| ... | @@ -67,18 +67,17 @@ const Scope = struct { | ... | @@ -67,18 +67,17 @@ const Scope = struct { |
| 67 | variables: AliasList, | 67 | variables: AliasList, |
| 68 | label: ?[]const u8, | 68 | label: ?[]const u8, |
| 69 | | 69 | |
| 70 | /// Don't forget to set rbrace token later | 70 | /// Don't forget to set rbrace token and block_node later |
| 71 | fn init(c: *Context, parent: *Scope, want_label: bool) !*Block { | 71 | fn init(c: *Context, parent: *Scope, want_label: bool) !*Block { |
| 72 | // TODO removing `?[]const u8` here causes LLVM error | 72 | // TODO removing `?[]const u8` here causes LLVM error |
| 73 | const label: ?[]const u8 = if (want_label) try std.fmt.allocPrint(c.a(), "blk_{}", .{c.getMangle()}) else null; | 73 | const label: ?[]const u8 = if (want_label) try std.fmt.allocPrint(c.a(), "blk_{}", .{c.getMangle()}) else null; |
| 74 | const block_node = try transCreateNodeBlock(c, label); | | |
| 75 | const block = try c.a().create(Block); | 74 | const block = try c.a().create(Block); |
| 76 | block.* = .{ | 75 | block.* = .{ |
| 77 | .base = .{ | 76 | .base = .{ |
| 78 | .id = .Block, | 77 | .id = .Block, |
| 79 | .parent = parent, | 78 | .parent = parent, |
| 80 | }, | 79 | }, |
| 81 | .block_node = block_node, | 80 | .block_node = undefined, |
| 82 | .variables = AliasList.init(c.a()), | 81 | .variables = AliasList.init(c.a()), |
| 83 | .label = label, | 82 | .label = label, |
| 84 | }; | 83 | }; |
| ... | @@ -126,7 +125,6 @@ const Scope = struct { | ... | @@ -126,7 +125,6 @@ const Scope = struct { |
| 126 | }; | 125 | }; |
| 127 | | 126 | |
| 128 | const Condition = struct { | 127 | const Condition = struct { |
| 129 | expr: *ast.Node, | | |
| 130 | base: Scope, | 128 | base: Scope, |
| 131 | }; | 129 | }; |
| 132 | | 130 | |
| ... | @@ -612,6 +610,7 @@ fn transStmt( | ... | @@ -612,6 +610,7 @@ fn transStmt( |
| 612 | .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue), | 610 | .ParenExprClass => return transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), result_used, lrvalue), |
| 613 | .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used), | 611 | .InitListExprClass => return transInitListExpr(rp, scope, @ptrCast(*const ZigClangInitListExpr, stmt), result_used), |
| 614 | .ImplicitValueInitExprClass => return transImplicitValueInitExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used), | 612 | .ImplicitValueInitExprClass => return transImplicitValueInitExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used), |
| | 613 | .IfStmtClass => return transIfStmt(rp, scope, @ptrCast(*const ZigClangIfStmt, stmt), result_used), |
| 615 | else => { | 614 | else => { |
| 616 | return revertAndWarn( | 615 | return revertAndWarn( |
| 617 | rp, | 616 | rp, |
| ... | @@ -718,18 +717,31 @@ fn transBinaryOperator( | ... | @@ -718,18 +717,31 @@ fn transBinaryOperator( |
| 718 | ), | 717 | ), |
| 719 | .Comma => { | 718 | .Comma => { |
| 720 | const block_scope = try scope.findBlockScope(rp.c); | 719 | const block_scope = try scope.findBlockScope(rp.c); |
| | 720 | const expr = block_scope.base.parent == scope; |
| | 721 | const lparen = if (expr) blk: { |
| | 722 | const l = try appendToken(rp.c, .LParen, "("); |
| | 723 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| | 724 | break :blk l; |
| | 725 | } else undefined; |
| 721 | | 726 | |
| 722 | const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value); | 727 | const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value); |
| 723 | try block_scope.block_node.statements.push(lhs); | 728 | try block_scope.block_node.statements.push(lhs); |
| 724 | | 729 | |
| 725 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); | 730 | const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value); |
| 726 | if (block_scope.base.parent == scope) { | 731 | if (expr) { |
| | 732 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| 727 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | 733 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); |
| 728 | break_node.rhs = rhs; | 734 | break_node.rhs = rhs; |
| 729 | _ = try appendToken(rp.c, .Semicolon, ";"); | | |
| 730 | try block_scope.block_node.statements.push(&break_node.base); | 735 | try block_scope.block_node.statements.push(&break_node.base); |
| 731 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 736 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 732 | return maybeSuppressResult(rp, scope, result_used, &block_scope.block_node.base); | 737 | const rparen = try appendToken(rp.c, .RParen, ")"); |
| | 738 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); |
| | 739 | grouped_expr.* = .{ |
| | 740 | .lparen = lparen, |
| | 741 | .expr = &block_scope.block_node.base, |
| | 742 | .rparen = rparen, |
| | 743 | }; |
| | 744 | return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base); |
| 733 | } else { | 745 | } else { |
| 734 | return maybeSuppressResult(rp, scope, result_used, rhs); | 746 | return maybeSuppressResult(rp, scope, result_used, rhs); |
| 735 | } | 747 | } |
| ... | @@ -766,6 +778,7 @@ fn transCompoundStmtInline( | ... | @@ -766,6 +778,7 @@ fn transCompoundStmtInline( |
| 766 | | 778 | |
| 767 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { | 779 | fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node { |
| 768 | const block_scope = try Scope.Block.init(rp.c, scope, false); | 780 | const block_scope = try Scope.Block.init(rp.c, scope, false); |
| | 781 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| 769 | try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node); | 782 | try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node); |
| 770 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | 783 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| 771 | return &block_scope.block_node.base; | 784 | return &block_scope.block_node.base; |
| ... | @@ -792,7 +805,7 @@ fn transCStyleCastExprClass( | ... | @@ -792,7 +805,7 @@ fn transCStyleCastExprClass( |
| 792 | | 805 | |
| 793 | fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!*ast.Node { | 806 | fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!*ast.Node { |
| 794 | const c = rp.c; | 807 | const c = rp.c; |
| 795 | const block_scope = try scope.findBlockScope(c); | 808 | const block_scope = scope.findBlockScope(c) catch unreachable; |
| 796 | | 809 | |
| 797 | var it = ZigClangDeclStmt_decl_begin(stmt); | 810 | var it = ZigClangDeclStmt_decl_begin(stmt); |
| 798 | const end_it = ZigClangDeclStmt_decl_end(stmt); | 811 | const end_it = ZigClangDeclStmt_decl_end(stmt); |
| ... | @@ -1167,6 +1180,35 @@ fn transImplicitValueInitExpr( | ... | @@ -1167,6 +1180,35 @@ fn transImplicitValueInitExpr( |
| 1167 | }; | 1180 | }; |
| 1168 | } | 1181 | } |
| 1169 | | 1182 | |
| | 1183 | fn transIfStmt( |
| | 1184 | rp: RestorePoint, |
| | 1185 | scope: *Scope, |
| | 1186 | stmt: *const ZigClangIfStmt, |
| | 1187 | used: ResultUsed, |
| | 1188 | ) TransError!*ast.Node { |
| | 1189 | // if (c) t |
| | 1190 | // if (c) t else e |
| | 1191 | const if_node = try transCreateNodeIf(rp.c); |
| | 1192 | |
| | 1193 | var cond_scope = Scope.Condition{ |
| | 1194 | .base = .{ |
| | 1195 | .parent = scope, |
| | 1196 | .id = .Condition, |
| | 1197 | }, |
| | 1198 | }; |
| | 1199 | if_node.condition = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value); |
| | 1200 | _ = try appendToken(rp.c, .RParen, ")"); |
| | 1201 | |
| | 1202 | if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .used, .r_value); |
| | 1203 | |
| | 1204 | if (ZigClangIfStmt_getElse(stmt)) |expr| { |
| | 1205 | if_node.@"else" = try transCreateNodeElse(rp.c); |
| | 1206 | if_node.@"else".?.body = try transStmt(rp, scope, expr, .used, .r_value); |
| | 1207 | } |
| | 1208 | _ = try appendToken(rp.c, .Semicolon, ";"); |
| | 1209 | return &if_node.base; |
| | 1210 | } |
| | 1211 | |
| 1170 | fn transCPtrCast( | 1212 | fn transCPtrCast( |
| 1171 | rp: RestorePoint, | 1213 | rp: RestorePoint, |
| 1172 | loc: ZigClangSourceLocation, | 1214 | loc: ZigClangSourceLocation, |
| ... | @@ -1602,6 +1644,7 @@ fn transCreateNodeAssign( | ... | @@ -1602,6 +1644,7 @@ fn transCreateNodeAssign( |
| 1602 | // zig: }) | 1644 | // zig: }) |
| 1603 | _ = try appendToken(rp.c, .LParen, "("); | 1645 | _ = try appendToken(rp.c, .LParen, "("); |
| 1604 | const block_scope = try Scope.Block.init(rp.c, scope, true); | 1646 | const block_scope = try Scope.Block.init(rp.c, scope, true); |
| | 1647 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); |
| 1605 | const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()}); | 1648 | const tmp = try std.fmt.allocPrint(rp.c.a(), "_tmp_{}", .{rp.c.getMangle()}); |
| 1606 | | 1649 | |
| 1607 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); | 1650 | const node = try transCreateNodeVarDecl(rp.c, false, true, tmp); |