| ... | ... | @@ -159,6 +159,14 @@ static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpTyp |
| 159 | 159 | return node; |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | static AstNode *maybe_suppress_result(Context *c, bool result_used, AstNode *node) { |
| 163 | if (result_used) return node; |
| 164 | return trans_create_node_bin_op(c, |
| 165 | trans_create_node_symbol_str(c, "_"), |
| 166 | BinOpTypeAssign, |
| 167 | node); |
| 168 | } |
| 169 | |
| 162 | 170 | static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) { |
| 163 | 171 | AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr); |
| 164 | 172 | node->data.addr_of_expr.is_const = is_const; |
| ... | ... | @@ -433,11 +441,11 @@ static bool c_is_float(Context *c, QualType qt) { |
| 433 | 441 | } |
| 434 | 442 | } |
| 435 | 443 | |
| 436 | | static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt); |
| 444 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt); |
| 437 | 445 | static AstNode *const skip_add_to_block_node = (AstNode *) 0x2; |
| 438 | 446 | |
| 439 | | static AstNode *trans_expr(Context *c, AstNode *block, Expr *expr) { |
| 440 | | return trans_stmt(c, block, expr); |
| 447 | static AstNode *trans_expr(Context *c, bool result_used, AstNode *block, Expr *expr) { |
| 448 | return trans_stmt(c, result_used, block, expr); |
| 441 | 449 | } |
| 442 | 450 | |
| 443 | 451 | static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) { |
| ... | ... | @@ -781,7 +789,7 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s |
| 781 | 789 | static AstNode *trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) { |
| 782 | 790 | AstNode *child_block = trans_create_node(c, NodeTypeBlock); |
| 783 | 791 | for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { |
| 784 | | AstNode *child_node = trans_stmt(c, child_block, *it); |
| 792 | AstNode *child_node = trans_stmt(c, false, child_block, *it); |
| 785 | 793 | if (child_node == nullptr) |
| 786 | 794 | return nullptr; |
| 787 | 795 | if (child_node != skip_add_to_block_node) |
| ... | ... | @@ -797,7 +805,7 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) |
| 797 | 805 | return nullptr; |
| 798 | 806 | } else { |
| 799 | 807 | AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr); |
| 800 | | return_node->data.return_expr.expr = trans_expr(c, block, value_expr); |
| 808 | return_node->data.return_expr.expr = trans_expr(c, true, block, value_expr); |
| 801 | 809 | if (return_node->data.return_expr.expr == nullptr) |
| 802 | 810 | return nullptr; |
| 803 | 811 | return return_node; |
| ... | ... | @@ -813,44 +821,44 @@ static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) { |
| 813 | 821 | return trans_create_node_apint(c, result); |
| 814 | 822 | } |
| 815 | 823 | |
| 816 | | static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) { |
| 824 | static AstNode *trans_conditional_operator(Context *c, bool result_used, AstNode *block, ConditionalOperator *stmt) { |
| 817 | 825 | AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr); |
| 818 | 826 | |
| 819 | 827 | Expr *cond_expr = stmt->getCond(); |
| 820 | 828 | Expr *true_expr = stmt->getTrueExpr(); |
| 821 | 829 | Expr *false_expr = stmt->getFalseExpr(); |
| 822 | 830 | |
| 823 | | node->data.if_bool_expr.condition = trans_expr(c, block, cond_expr); |
| 831 | node->data.if_bool_expr.condition = trans_expr(c, true, block, cond_expr); |
| 824 | 832 | if (node->data.if_bool_expr.condition == nullptr) |
| 825 | 833 | return nullptr; |
| 826 | 834 | |
| 827 | | node->data.if_bool_expr.then_block = trans_expr(c, block, true_expr); |
| 835 | node->data.if_bool_expr.then_block = trans_expr(c, result_used, block, true_expr); |
| 828 | 836 | if (node->data.if_bool_expr.then_block == nullptr) |
| 829 | 837 | return nullptr; |
| 830 | 838 | |
| 831 | | node->data.if_bool_expr.else_node = trans_expr(c, block, false_expr); |
| 839 | node->data.if_bool_expr.else_node = trans_expr(c, result_used, block, false_expr); |
| 832 | 840 | if (node->data.if_bool_expr.else_node == nullptr) |
| 833 | 841 | return nullptr; |
| 834 | 842 | |
| 835 | | return node; |
| 843 | return maybe_suppress_result(c, result_used, node); |
| 836 | 844 | } |
| 837 | 845 | |
| 838 | 846 | static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOpType bin_op, Expr *rhs) { |
| 839 | 847 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| 840 | 848 | node->data.bin_op_expr.bin_op = bin_op; |
| 841 | 849 | |
| 842 | | node->data.bin_op_expr.op1 = trans_expr(c, block, lhs); |
| 850 | node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs); |
| 843 | 851 | if (node->data.bin_op_expr.op1 == nullptr) |
| 844 | 852 | return nullptr; |
| 845 | 853 | |
| 846 | | node->data.bin_op_expr.op2 = trans_expr(c, block, rhs); |
| 854 | node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs); |
| 847 | 855 | if (node->data.bin_op_expr.op2 == nullptr) |
| 848 | 856 | return nullptr; |
| 849 | 857 | |
| 850 | 858 | return node; |
| 851 | 859 | } |
| 852 | 860 | |
| 853 | | static AstNode *trans_binary_operator(Context *c, AstNode *block, BinaryOperator *stmt) { |
| 861 | static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *block, BinaryOperator *stmt) { |
| 854 | 862 | switch (stmt->getOpcode()) { |
| 855 | 863 | case BO_PtrMemD: |
| 856 | 864 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemD"); |
| ... | ... | @@ -909,6 +917,7 @@ static AstNode *trans_binary_operator(Context *c, AstNode *block, BinaryOperator |
| 909 | 917 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_LOr"); |
| 910 | 918 | return nullptr; |
| 911 | 919 | case BO_Assign: |
| 920 | (void)result_used; |
| 912 | 921 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Assign"); |
| 913 | 922 | return nullptr; |
| 914 | 923 | case BO_MulAssign: |
| ... | ... | @@ -949,7 +958,7 @@ static AstNode *trans_binary_operator(Context *c, AstNode *block, BinaryOperator |
| 949 | 958 | zig_unreachable(); |
| 950 | 959 | } |
| 951 | 960 | |
| 952 | | static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, CompoundAssignOperator *stmt) { |
| 961 | static AstNode *trans_compound_assign_operator(Context *c, bool result_used, AstNode *block, CompoundAssignOperator *stmt) { |
| 953 | 962 | switch (stmt->getOpcode()) { |
| 954 | 963 | case BO_MulAssign: |
| 955 | 964 | emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_MulAssign"); |
| ... | ... | @@ -983,7 +992,7 @@ static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, Compo |
| 983 | 992 | AstNode *child_block = trans_create_node(c, NodeTypeBlock); |
| 984 | 993 | |
| 985 | 994 | // const _ref = &lhs; |
| 986 | | AstNode *lhs = trans_expr(c, child_block, stmt->getLHS()); |
| 995 | AstNode *lhs = trans_expr(c, true, child_block, stmt->getLHS()); |
| 987 | 996 | if (lhs == nullptr) return nullptr; |
| 988 | 997 | AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs); |
| 989 | 998 | // TODO: avoid name collisions with generated variable names |
| ... | ... | @@ -993,7 +1002,7 @@ static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, Compo |
| 993 | 1002 | |
| 994 | 1003 | // *_ref = result_type(operation_type(*_ref) >> u5(rhs)); |
| 995 | 1004 | |
| 996 | | AstNode *rhs = trans_expr(c, child_block, stmt->getRHS()); |
| 1005 | AstNode *rhs = trans_expr(c, true, child_block, stmt->getRHS()); |
| 997 | 1006 | if (rhs == nullptr) return nullptr; |
| 998 | 1007 | const SourceLocation &rhs_location = stmt->getRHS()->getLocStart(); |
| 999 | 1008 | AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location); |
| ... | ... | @@ -1015,11 +1024,13 @@ static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, Compo |
| 1015 | 1024 | rhs)))); |
| 1016 | 1025 | child_block->data.block.statements.append(assign_statement); |
| 1017 | 1026 | |
| 1018 | | // *_ref |
| 1019 | | child_block->data.block.statements.append( |
| 1020 | | trans_create_node_prefix_op(c, PrefixOpDereference, |
| 1021 | | trans_create_node_symbol(c, tmp_var_name))); |
| 1022 | | child_block->data.block.last_statement_is_result_expression = true; |
| 1027 | if (result_used) { |
| 1028 | // *_ref |
| 1029 | child_block->data.block.statements.append( |
| 1030 | trans_create_node_prefix_op(c, PrefixOpDereference, |
| 1031 | trans_create_node_symbol(c, tmp_var_name))); |
| 1032 | child_block->data.block.last_statement_is_result_expression = true; |
| 1033 | } |
| 1023 | 1034 | |
| 1024 | 1035 | return child_block; |
| 1025 | 1036 | } |
| ... | ... | @@ -1063,10 +1074,10 @@ static AstNode *trans_compound_assign_operator(Context *c, AstNode *block, Compo |
| 1063 | 1074 | static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) { |
| 1064 | 1075 | switch (stmt->getCastKind()) { |
| 1065 | 1076 | case CK_LValueToRValue: |
| 1066 | | return trans_expr(c, block, stmt->getSubExpr()); |
| 1077 | return trans_expr(c, true, block, stmt->getSubExpr()); |
| 1067 | 1078 | case CK_IntegralCast: |
| 1068 | 1079 | { |
| 1069 | | AstNode *target_node = trans_expr(c, block, stmt->getSubExpr()); |
| 1080 | AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr()); |
| 1070 | 1081 | if (target_node == nullptr) |
| 1071 | 1082 | return nullptr; |
| 1072 | 1083 | return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node); |
| ... | ... | @@ -1279,7 +1290,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator * |
| 1279 | 1290 | AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); |
| 1280 | 1291 | node->data.prefix_op_expr.prefix_op = PrefixOpNegation; |
| 1281 | 1292 | |
| 1282 | | node->data.prefix_op_expr.primary_expr = trans_expr(c, block, op_expr); |
| 1293 | node->data.prefix_op_expr.primary_expr = trans_expr(c, true, block, op_expr); |
| 1283 | 1294 | if (node->data.prefix_op_expr.primary_expr == nullptr) |
| 1284 | 1295 | return nullptr; |
| 1285 | 1296 | |
| ... | ... | @@ -1289,7 +1300,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator * |
| 1289 | 1300 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| 1290 | 1301 | node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0); |
| 1291 | 1302 | |
| 1292 | | node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr); |
| 1303 | node->data.bin_op_expr.op2 = trans_expr(c, true, block, op_expr); |
| 1293 | 1304 | if (node->data.bin_op_expr.op2 == nullptr) |
| 1294 | 1305 | return nullptr; |
| 1295 | 1306 | |
| ... | ... | @@ -1331,7 +1342,7 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st |
| 1331 | 1342 | QualType qual_type = var_decl->getTypeSourceInfo()->getType(); |
| 1332 | 1343 | AstNode *init_node = nullptr; |
| 1333 | 1344 | if (var_decl->hasInit()) { |
| 1334 | | init_node = trans_expr(c, block, var_decl->getInit()); |
| 1345 | init_node = trans_expr(c, true, block, var_decl->getInit()); |
| 1335 | 1346 | if (init_node == nullptr) |
| 1336 | 1347 | return nullptr; |
| 1337 | 1348 | |
| ... | ... | @@ -1572,18 +1583,18 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st |
| 1572 | 1583 | static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) { |
| 1573 | 1584 | AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); |
| 1574 | 1585 | |
| 1575 | | while_node->data.while_expr.condition = trans_expr(c, block, stmt->getCond()); |
| 1586 | while_node->data.while_expr.condition = trans_expr(c, true, block, stmt->getCond()); |
| 1576 | 1587 | if (while_node->data.while_expr.condition == nullptr) |
| 1577 | 1588 | return nullptr; |
| 1578 | 1589 | |
| 1579 | | while_node->data.while_expr.body = trans_stmt(c, block, stmt->getBody()); |
| 1590 | while_node->data.while_expr.body = trans_stmt(c, false, block, stmt->getBody()); |
| 1580 | 1591 | if (while_node->data.while_expr.body == nullptr) |
| 1581 | 1592 | return nullptr; |
| 1582 | 1593 | |
| 1583 | 1594 | return while_node; |
| 1584 | 1595 | } |
| 1585 | 1596 | |
| 1586 | | static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) { |
| 1597 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt) { |
| 1587 | 1598 | Stmt::StmtClass sc = stmt->getStmtClass(); |
| 1588 | 1599 | switch (sc) { |
| 1589 | 1600 | case Stmt::ReturnStmtClass: |
| ... | ... | @@ -1593,11 +1604,11 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) { |
| 1593 | 1604 | case Stmt::IntegerLiteralClass: |
| 1594 | 1605 | return trans_integer_literal(c, (IntegerLiteral *)stmt); |
| 1595 | 1606 | case Stmt::ConditionalOperatorClass: |
| 1596 | | return trans_conditional_operator(c, block, (ConditionalOperator *)stmt); |
| 1607 | return trans_conditional_operator(c, result_used, block, (ConditionalOperator *)stmt); |
| 1597 | 1608 | case Stmt::BinaryOperatorClass: |
| 1598 | | return trans_binary_operator(c, block, (BinaryOperator *)stmt); |
| 1609 | return trans_binary_operator(c, result_used, block, (BinaryOperator *)stmt); |
| 1599 | 1610 | case Stmt::CompoundAssignOperatorClass: |
| 1600 | | return trans_compound_assign_operator(c, block, (CompoundAssignOperator *)stmt); |
| 1611 | return trans_compound_assign_operator(c, result_used, block, (CompoundAssignOperator *)stmt); |
| 1601 | 1612 | case Stmt::ImplicitCastExprClass: |
| 1602 | 1613 | return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt); |
| 1603 | 1614 | case Stmt::DeclRefExprClass: |
| ... | ... | @@ -1747,12 +1758,14 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) { |
| 1747 | 1758 | emit_warning(c, stmt->getLocStart(), "TODO handle C CXXUuidofExprClass"); |
| 1748 | 1759 | return nullptr; |
| 1749 | 1760 | case Stmt::CallExprClass: |
| 1761 | (void)result_used; |
| 1750 | 1762 | emit_warning(c, stmt->getLocStart(), "TODO handle C CallExprClass"); |
| 1751 | 1763 | return nullptr; |
| 1752 | 1764 | case Stmt::CUDAKernelCallExprClass: |
| 1753 | 1765 | emit_warning(c, stmt->getLocStart(), "TODO handle C CUDAKernelCallExprClass"); |
| 1754 | 1766 | return nullptr; |
| 1755 | 1767 | case Stmt::CXXMemberCallExprClass: |
| 1768 | (void)result_used; |
| 1756 | 1769 | emit_warning(c, stmt->getLocStart(), "TODO handle C CXXMemberCallExprClass"); |
| 1757 | 1770 | return nullptr; |
| 1758 | 1771 | case Stmt::CXXOperatorCallExprClass: |
| ... | ... | @@ -2219,7 +2232,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 2219 | 2232 | // actual function definition with body |
| 2220 | 2233 | |
| 2221 | 2234 | Stmt *body = fn_decl->getBody(); |
| 2222 | | AstNode *actual_body_node = trans_stmt(c, nullptr, body); |
| 2235 | AstNode *actual_body_node = trans_stmt(c, false, nullptr, body); |
| 2223 | 2236 | assert(actual_body_node != skip_add_to_block_node); |
| 2224 | 2237 | if (actual_body_node == nullptr) { |
| 2225 | 2238 | emit_warning(c, fn_decl->getLocation(), "unable to translate function"); |