| ... | ... | @@ -690,6 +690,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { |
| 690 | 690 | static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type, |
| 691 | 691 | clang::QualType src_type, AstNode *expr) |
| 692 | 692 | { |
| 693 | // The only way void pointer casts are valid C code, is if |
| 694 | // the value of the expression is ignored. We therefore just |
| 695 | // return the expr, and let the system that ignores values |
| 696 | // translate this correctly. |
| 697 | if (qual_type_canon(dest_type)->isVoidType()) { |
| 698 | return expr; |
| 699 | } |
| 693 | 700 | if (qual_types_equal(dest_type, src_type)) { |
| 694 | 701 | return expr; |
| 695 | 702 | } |
| ... | ... | @@ -1225,6 +1232,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang:: |
| 1225 | 1232 | return child_scope_block->node; |
| 1226 | 1233 | } |
| 1227 | 1234 | |
| 1235 | static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *scope, |
| 1236 | const clang::StmtExpr *stmt, TransScope **out_node_scope) |
| 1237 | { |
| 1238 | AstNode *block = trans_compound_stmt(c, scope, stmt->getSubStmt(), out_node_scope); |
| 1239 | if (block == nullptr) |
| 1240 | return block; |
| 1241 | assert(block->type == NodeTypeBlock); |
| 1242 | if (block->data.block.statements.length == 0) |
| 1243 | return block; |
| 1244 | |
| 1245 | Buf *label = buf_create_from_str("x"); |
| 1246 | block->data.block.name = label; |
| 1247 | AstNode *return_expr = block->data.block.statements.pop(); |
| 1248 | if (return_expr->type == NodeTypeBinOpExpr && |
| 1249 | return_expr->data.bin_op_expr.bin_op == BinOpTypeAssign && |
| 1250 | return_expr->data.bin_op_expr.op1->type == NodeTypeSymbol) |
| 1251 | { |
| 1252 | Buf *symbol_buf = return_expr->data.bin_op_expr.op1->data.symbol_expr.symbol; |
| 1253 | if (strcmp("_", buf_ptr(symbol_buf)) == 0) |
| 1254 | return_expr = return_expr->data.bin_op_expr.op2; |
| 1255 | } |
| 1256 | block->data.block.statements.append(trans_create_node_break(c, label, return_expr)); |
| 1257 | return maybe_suppress_result(c, result_used, block); |
| 1258 | } |
| 1259 | |
| 1228 | 1260 | static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) { |
| 1229 | 1261 | const clang::Expr *value_expr = stmt->getRetValue(); |
| 1230 | 1262 | if (value_expr == nullptr) { |
| ... | ... | @@ -1238,13 +1270,15 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re |
| 1238 | 1270 | } |
| 1239 | 1271 | } |
| 1240 | 1272 | |
| 1241 | | static AstNode *trans_integer_literal(Context *c, const clang::IntegerLiteral *stmt) { |
| 1273 | static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const clang::IntegerLiteral *stmt) { |
| 1242 | 1274 | llvm::APSInt result; |
| 1243 | 1275 | if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) { |
| 1244 | 1276 | emit_warning(c, stmt->getLocStart(), "invalid integer literal"); |
| 1245 | 1277 | return nullptr; |
| 1246 | 1278 | } |
| 1247 | | return trans_create_node_apint(c, result); |
| 1279 | |
| 1280 | AstNode *node = trans_create_node_apint(c, result); |
| 1281 | return maybe_suppress_result(c, result_used, node); |
| 1248 | 1282 | } |
| 1249 | 1283 | |
| 1250 | 1284 | static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope, |
| ... | ... | @@ -1381,14 +1415,17 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1381 | 1415 | case clang::BO_Cmp: |
| 1382 | 1416 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_Cmp"); |
| 1383 | 1417 | return nullptr; |
| 1384 | | case clang::BO_Mul: |
| 1385 | | return trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1418 | case clang::BO_Mul: { |
| 1419 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1386 | 1420 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult, |
| 1387 | 1421 | stmt->getRHS()); |
| 1422 | return maybe_suppress_result(c, result_used, node); |
| 1423 | } |
| 1388 | 1424 | case clang::BO_Div: |
| 1389 | 1425 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { |
| 1390 | 1426 | // unsigned/float division uses the operator |
| 1391 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS()); |
| 1427 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS()); |
| 1428 | return maybe_suppress_result(c, result_used, node); |
| 1392 | 1429 | } else { |
| 1393 | 1430 | // signed integer division uses @divTrunc |
| 1394 | 1431 | AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc"); |
| ... | ... | @@ -1398,12 +1435,13 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1398 | 1435 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue); |
| 1399 | 1436 | if (rhs == nullptr) return nullptr; |
| 1400 | 1437 | fn_call->data.fn_call_expr.params.append(rhs); |
| 1401 | | return fn_call; |
| 1438 | return maybe_suppress_result(c, result_used, fn_call); |
| 1402 | 1439 | } |
| 1403 | 1440 | case clang::BO_Rem: |
| 1404 | 1441 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { |
| 1405 | 1442 | // unsigned/float division uses the operator |
| 1406 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS()); |
| 1443 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS()); |
| 1444 | return maybe_suppress_result(c, result_used, node); |
| 1407 | 1445 | } else { |
| 1408 | 1446 | // signed integer division uses @rem |
| 1409 | 1447 | AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem"); |
| ... | ... | @@ -1413,42 +1451,72 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1413 | 1451 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue); |
| 1414 | 1452 | if (rhs == nullptr) return nullptr; |
| 1415 | 1453 | fn_call->data.fn_call_expr.params.append(rhs); |
| 1416 | | return fn_call; |
| 1454 | return maybe_suppress_result(c, result_used, fn_call); |
| 1417 | 1455 | } |
| 1418 | | case clang::BO_Add: |
| 1419 | | return trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1456 | case clang::BO_Add: { |
| 1457 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1420 | 1458 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd, |
| 1421 | 1459 | stmt->getRHS()); |
| 1422 | | case clang::BO_Sub: |
| 1423 | | return trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1460 | return maybe_suppress_result(c, result_used, node); |
| 1461 | } |
| 1462 | case clang::BO_Sub: { |
| 1463 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1424 | 1464 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub, |
| 1425 | 1465 | stmt->getRHS()); |
| 1426 | | case clang::BO_Shl: |
| 1427 | | return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS()); |
| 1428 | | case clang::BO_Shr: |
| 1429 | | return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS()); |
| 1430 | | case clang::BO_LT: |
| 1431 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS()); |
| 1432 | | case clang::BO_GT: |
| 1433 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS()); |
| 1434 | | case clang::BO_LE: |
| 1435 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS()); |
| 1436 | | case clang::BO_GE: |
| 1437 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS()); |
| 1438 | | case clang::BO_EQ: |
| 1439 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS()); |
| 1440 | | case clang::BO_NE: |
| 1441 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS()); |
| 1442 | | case clang::BO_And: |
| 1443 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS()); |
| 1444 | | case clang::BO_Xor: |
| 1445 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS()); |
| 1446 | | case clang::BO_Or: |
| 1447 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS()); |
| 1448 | | case clang::BO_LAnd: |
| 1449 | | return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS()); |
| 1450 | | case clang::BO_LOr: |
| 1451 | | return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); |
| 1466 | return maybe_suppress_result(c, result_used, node); |
| 1467 | } |
| 1468 | case clang::BO_Shl: { |
| 1469 | AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS()); |
| 1470 | return maybe_suppress_result(c, result_used, node); |
| 1471 | } |
| 1472 | case clang::BO_Shr: { |
| 1473 | AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS()); |
| 1474 | return maybe_suppress_result(c, result_used, node); |
| 1475 | } |
| 1476 | case clang::BO_LT: { |
| 1477 | AstNode *node =trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS()); |
| 1478 | return maybe_suppress_result(c, result_used, node); |
| 1479 | } |
| 1480 | case clang::BO_GT: { |
| 1481 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS()); |
| 1482 | return maybe_suppress_result(c, result_used, node); |
| 1483 | } |
| 1484 | case clang::BO_LE: { |
| 1485 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS()); |
| 1486 | return maybe_suppress_result(c, result_used, node); |
| 1487 | } |
| 1488 | case clang::BO_GE: { |
| 1489 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS()); |
| 1490 | return maybe_suppress_result(c, result_used, node); |
| 1491 | } |
| 1492 | case clang::BO_EQ: { |
| 1493 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS()); |
| 1494 | return maybe_suppress_result(c, result_used, node); |
| 1495 | } |
| 1496 | case clang::BO_NE: { |
| 1497 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS()); |
| 1498 | return maybe_suppress_result(c, result_used, node); |
| 1499 | } |
| 1500 | case clang::BO_And: { |
| 1501 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS()); |
| 1502 | return maybe_suppress_result(c, result_used, node); |
| 1503 | } |
| 1504 | case clang::BO_Xor: { |
| 1505 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS()); |
| 1506 | return maybe_suppress_result(c, result_used, node); |
| 1507 | } |
| 1508 | case clang::BO_Or: { |
| 1509 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS()); |
| 1510 | return maybe_suppress_result(c, result_used, node); |
| 1511 | } |
| 1512 | case clang::BO_LAnd: { |
| 1513 | AstNode *node = trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS()); |
| 1514 | return maybe_suppress_result(c, result_used, node); |
| 1515 | } |
| 1516 | case clang::BO_LOr: { |
| 1517 | AstNode *node = trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); |
| 1518 | return maybe_suppress_result(c, result_used, node); |
| 1519 | } |
| 1452 | 1520 | case clang::BO_Assign: |
| 1453 | 1521 | return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS()); |
| 1454 | 1522 | case clang::BO_Comma: |
| ... | ... | @@ -1460,13 +1528,15 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1460 | 1528 | AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue); |
| 1461 | 1529 | if (lhs == nullptr) |
| 1462 | 1530 | return nullptr; |
| 1463 | | scope_block->node->data.block.statements.append(maybe_suppress_result(c, ResultUsedNo, lhs)); |
| 1531 | scope_block->node->data.block.statements.append(lhs); |
| 1464 | 1532 | |
| 1465 | | AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue); |
| 1533 | AstNode *rhs = trans_expr(c, ResultUsedYes, &scope_block->base, stmt->getRHS(), TransRValue); |
| 1466 | 1534 | if (rhs == nullptr) |
| 1467 | 1535 | return nullptr; |
| 1468 | | scope_block->node->data.block.statements.append(trans_create_node_break(c, label_name, maybe_suppress_result(c, result_used, rhs))); |
| 1469 | | return scope_block->node; |
| 1536 | |
| 1537 | rhs = trans_create_node_break(c, label_name, rhs); |
| 1538 | scope_block->node->data.block.statements.append(rhs); |
| 1539 | return maybe_suppress_result(c, result_used, scope_block->node); |
| 1470 | 1540 | } |
| 1471 | 1541 | case clang::BO_MulAssign: |
| 1472 | 1542 | case clang::BO_DivAssign: |
| ... | ... | @@ -1692,7 +1762,7 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use |
| 1692 | 1762 | zig_unreachable(); |
| 1693 | 1763 | } |
| 1694 | 1764 | |
| 1695 | | static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const clang::ImplicitCastExpr *stmt) { |
| 1765 | static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ImplicitCastExpr *stmt) { |
| 1696 | 1766 | switch (stmt->getCastKind()) { |
| 1697 | 1767 | case clang::CK_LValueToRValue: |
| 1698 | 1768 | return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); |
| ... | ... | @@ -1701,8 +1771,9 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl |
| 1701 | 1771 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); |
| 1702 | 1772 | if (target_node == nullptr) |
| 1703 | 1773 | return nullptr; |
| 1704 | | return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), |
| 1774 | AstNode *node = trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), |
| 1705 | 1775 | stmt->getSubExpr()->getType(), target_node); |
| 1776 | return maybe_suppress_result(c, result_used, node); |
| 1706 | 1777 | } |
| 1707 | 1778 | case clang::CK_FunctionToPointerDecay: |
| 1708 | 1779 | case clang::CK_ArrayToPointerDecay: |
| ... | ... | @@ -1710,7 +1781,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl |
| 1710 | 1781 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); |
| 1711 | 1782 | if (target_node == nullptr) |
| 1712 | 1783 | return nullptr; |
| 1713 | | return target_node; |
| 1784 | return maybe_suppress_result(c, result_used, target_node); |
| 1714 | 1785 | } |
| 1715 | 1786 | case clang::CK_BitCast: |
| 1716 | 1787 | { |
| ... | ... | @@ -1727,7 +1798,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl |
| 1727 | 1798 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 1728 | 1799 | node->data.fn_call_expr.params.append(dest_type_node); |
| 1729 | 1800 | node->data.fn_call_expr.params.append(target_node); |
| 1730 | | return node; |
| 1801 | return maybe_suppress_result(c, result_used, node); |
| 1731 | 1802 | } |
| 1732 | 1803 | case clang::CK_NullToPointer: |
| 1733 | 1804 | return trans_create_node_unsigned(c, 0); |
| ... | ... | @@ -2103,8 +2174,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc |
| 2103 | 2174 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag"); |
| 2104 | 2175 | return nullptr; |
| 2105 | 2176 | case clang::UO_Extension: |
| 2106 | | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Extension"); |
| 2107 | | return nullptr; |
| 2177 | return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue); |
| 2108 | 2178 | case clang::UO_Coawait: |
| 2109 | 2179 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait"); |
| 2110 | 2180 | return nullptr; |
| ... | ... | @@ -2721,7 +2791,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * |
| 2721 | 2791 | return node; |
| 2722 | 2792 | } |
| 2723 | 2793 | |
| 2724 | | static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::MemberExpr *stmt) { |
| 2794 | static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope *scope, |
| 2795 | const clang::MemberExpr *stmt) |
| 2796 | { |
| 2725 | 2797 | AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue); |
| 2726 | 2798 | if (container_node == nullptr) |
| 2727 | 2799 | return nullptr; |
| ... | ... | @@ -2733,10 +2805,10 @@ static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::Me |
| 2733 | 2805 | const char *name = decl_name(stmt->getMemberDecl()); |
| 2734 | 2806 | |
| 2735 | 2807 | AstNode *node = trans_create_node_field_access_str(c, container_node, name); |
| 2736 | | return node; |
| 2808 | return maybe_suppress_result(c, result_used, node); |
| 2737 | 2809 | } |
| 2738 | 2810 | |
| 2739 | | static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const clang::ArraySubscriptExpr *stmt) { |
| 2811 | static AstNode *trans_array_subscript_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ArraySubscriptExpr *stmt) { |
| 2740 | 2812 | AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue); |
| 2741 | 2813 | if (container_node == nullptr) |
| 2742 | 2814 | return nullptr; |
| ... | ... | @@ -2749,21 +2821,25 @@ static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const |
| 2749 | 2821 | AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr); |
| 2750 | 2822 | node->data.array_access_expr.array_ref_expr = container_node; |
| 2751 | 2823 | node->data.array_access_expr.subscript = idx_node; |
| 2752 | | return node; |
| 2824 | return maybe_suppress_result(c, result_used, node); |
| 2753 | 2825 | } |
| 2754 | 2826 | |
| 2755 | 2827 | static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, |
| 2756 | 2828 | const clang::CStyleCastExpr *stmt, TransLRValue lrvalue) |
| 2757 | 2829 | { |
| 2758 | | AstNode *sub_expr_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), lrvalue); |
| 2830 | AstNode *sub_expr_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), lrvalue); |
| 2759 | 2831 | if (sub_expr_node == nullptr) |
| 2760 | 2832 | return nullptr; |
| 2761 | 2833 | |
| 2762 | | return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node); |
| 2834 | AstNode *cast = trans_c_cast(c, stmt->getLocStart(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node); |
| 2835 | if (cast == nullptr) |
| 2836 | return nullptr; |
| 2837 | |
| 2838 | return maybe_suppress_result(c, result_used, cast); |
| 2763 | 2839 | } |
| 2764 | 2840 | |
| 2765 | | static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scope, |
| 2766 | | const clang::UnaryExprOrTypeTraitExpr *stmt) |
| 2841 | static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used, |
| 2842 | TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt) |
| 2767 | 2843 | { |
| 2768 | 2844 | AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart()); |
| 2769 | 2845 | if (type_node == nullptr) |
| ... | ... | @@ -2771,7 +2847,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop |
| 2771 | 2847 | |
| 2772 | 2848 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf"); |
| 2773 | 2849 | node->data.fn_call_expr.params.append(type_node); |
| 2774 | | return node; |
| 2850 | return maybe_suppress_result(c, result_used, node); |
| 2775 | 2851 | } |
| 2776 | 2852 | |
| 2777 | 2853 | static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang::DoStmt *stmt) { |
| ... | ... | @@ -3049,11 +3125,13 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const clan |
| 3049 | 3125 | return ErrorNone; |
| 3050 | 3126 | } |
| 3051 | 3127 | |
| 3052 | | static AstNode *trans_string_literal(Context *c, TransScope *scope, const clang::StringLiteral *stmt) { |
| 3128 | static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransScope *scope, const clang::StringLiteral *stmt) { |
| 3053 | 3129 | switch (stmt->getKind()) { |
| 3054 | 3130 | case clang::StringLiteral::Ascii: |
| 3055 | | case clang::StringLiteral::UTF8: |
| 3056 | | return trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString())); |
| 3131 | case clang::StringLiteral::UTF8: { |
| 3132 | AstNode *node = trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString())); |
| 3133 | return maybe_suppress_result(c, result_used, node); |
| 3134 | } |
| 3057 | 3135 | case clang::StringLiteral::UTF16: |
| 3058 | 3136 | emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals"); |
| 3059 | 3137 | return nullptr; |
| ... | ... | @@ -3085,6 +3163,12 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang:: |
| 3085 | 3163 | return trans_create_node(c, NodeTypeContinue); |
| 3086 | 3164 | } |
| 3087 | 3165 | |
| 3166 | static AstNode *trans_predefined_expr(Context *c, ResultUsed result_used, TransScope *scope, |
| 3167 | const clang::PredefinedExpr *expr) |
| 3168 | { |
| 3169 | return trans_string_literal(c, result_used, scope, expr->getFunctionName()); |
| 3170 | } |
| 3171 | |
| 3088 | 3172 | static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) { |
| 3089 | 3173 | if (result_node == nullptr) |
| 3090 | 3174 | return ErrorUnexpected; |
| ... | ... | @@ -3109,7 +3193,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3109 | 3193 | trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope)); |
| 3110 | 3194 | case clang::Stmt::IntegerLiteralClass: |
| 3111 | 3195 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3112 | | trans_integer_literal(c, (const clang::IntegerLiteral *)stmt)); |
| 3196 | trans_integer_literal(c, result_used, (const clang::IntegerLiteral *)stmt)); |
| 3113 | 3197 | case clang::Stmt::ConditionalOperatorClass: |
| 3114 | 3198 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3115 | 3199 | trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt)); |
| ... | ... | @@ -3121,7 +3205,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3121 | 3205 | trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt)); |
| 3122 | 3206 | case clang::Stmt::ImplicitCastExprClass: |
| 3123 | 3207 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3124 | | trans_implicit_cast_expr(c, scope, (const clang::ImplicitCastExpr *)stmt)); |
| 3208 | trans_implicit_cast_expr(c, result_used, scope, (const clang::ImplicitCastExpr *)stmt)); |
| 3125 | 3209 | case clang::Stmt::DeclRefExprClass: |
| 3126 | 3210 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3127 | 3211 | trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue)); |
| ... | ... | @@ -3152,28 +3236,28 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3152 | 3236 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3153 | 3237 | trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt)); |
| 3154 | 3238 | case clang::Stmt::NullStmtClass: |
| 3155 | | *out_node = nullptr; |
| 3239 | *out_node = trans_create_node(c, NodeTypeBlock); |
| 3156 | 3240 | *out_child_scope = scope; |
| 3157 | 3241 | return ErrorNone; |
| 3158 | 3242 | case clang::Stmt::MemberExprClass: |
| 3159 | 3243 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3160 | | trans_member_expr(c, scope, (const clang::MemberExpr *)stmt)); |
| 3244 | trans_member_expr(c, result_used, scope, (const clang::MemberExpr *)stmt)); |
| 3161 | 3245 | case clang::Stmt::ArraySubscriptExprClass: |
| 3162 | 3246 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3163 | | trans_array_subscript_expr(c, scope, (const clang::ArraySubscriptExpr *)stmt)); |
| 3247 | trans_array_subscript_expr(c, result_used, scope, (const clang::ArraySubscriptExpr *)stmt)); |
| 3164 | 3248 | case clang::Stmt::CStyleCastExprClass: |
| 3165 | 3249 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3166 | 3250 | trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue)); |
| 3167 | 3251 | case clang::Stmt::UnaryExprOrTypeTraitExprClass: |
| 3168 | 3252 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3169 | | trans_unary_expr_or_type_trait_expr(c, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt)); |
| 3253 | trans_unary_expr_or_type_trait_expr(c, result_used, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt)); |
| 3170 | 3254 | case clang::Stmt::ForStmtClass: { |
| 3171 | 3255 | AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt); |
| 3172 | 3256 | return wrap_stmt(out_node, out_child_scope, scope, node); |
| 3173 | 3257 | } |
| 3174 | 3258 | case clang::Stmt::StringLiteralClass: |
| 3175 | 3259 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3176 | | trans_string_literal(c, scope, (const clang::StringLiteral *)stmt)); |
| 3260 | trans_string_literal(c, result_used, scope, (const clang::StringLiteral *)stmt)); |
| 3177 | 3261 | case clang::Stmt::BreakStmtClass: |
| 3178 | 3262 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3179 | 3263 | trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt)); |
| ... | ... | @@ -3479,8 +3563,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3479 | 3563 | emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass"); |
| 3480 | 3564 | return ErrorUnexpected; |
| 3481 | 3565 | case clang::Stmt::PredefinedExprClass: |
| 3482 | | emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass"); |
| 3483 | | return ErrorUnexpected; |
| 3566 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3567 | trans_predefined_expr(c, result_used, scope, (const clang::PredefinedExpr *)stmt)); |
| 3484 | 3568 | case clang::Stmt::PseudoObjectExprClass: |
| 3485 | 3569 | emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass"); |
| 3486 | 3570 | return ErrorUnexpected; |
| ... | ... | @@ -3491,8 +3575,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3491 | 3575 | emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass"); |
| 3492 | 3576 | return ErrorUnexpected; |
| 3493 | 3577 | case clang::Stmt::StmtExprClass: |
| 3494 | | emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass"); |
| 3495 | | return ErrorUnexpected; |
| 3578 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3579 | trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope)); |
| 3496 | 3580 | case clang::Stmt::SubstNonTypeTemplateParmExprClass: |
| 3497 | 3581 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); |
| 3498 | 3582 | return ErrorUnexpected; |