| ... | @@ -690,6 +690,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { | ... | @@ -690,6 +690,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { |
| 690 | static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type, | 690 | static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type, |
| 691 | clang::QualType src_type, AstNode *expr) | 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 | if (qual_types_equal(dest_type, src_type)) { | 700 | if (qual_types_equal(dest_type, src_type)) { |
| 694 | return expr; | 701 | return expr; |
| 695 | } | 702 | } |
| ... | @@ -1225,6 +1232,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang:: | ... | @@ -1225,6 +1232,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang:: |
| 1225 | return child_scope_block->node; | 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 | static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) { | 1260 | static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) { |
| 1229 | const clang::Expr *value_expr = stmt->getRetValue(); | 1261 | const clang::Expr *value_expr = stmt->getRetValue(); |
| 1230 | if (value_expr == nullptr) { | 1262 | if (value_expr == nullptr) { |
| ... | @@ -1238,13 +1270,15 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re | ... | @@ -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 | llvm::APSInt result; | 1274 | llvm::APSInt result; |
| 1243 | if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) { | 1275 | if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) { |
| 1244 | emit_warning(c, stmt->getLocStart(), "invalid integer literal"); | 1276 | emit_warning(c, stmt->getLocStart(), "invalid integer literal"); |
| 1245 | return nullptr; | 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 | static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope, | 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,14 +1415,17 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1381 | case clang::BO_Cmp: | 1415 | case clang::BO_Cmp: |
| 1382 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_Cmp"); | 1416 | emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_Cmp"); |
| 1383 | return nullptr; | 1417 | return nullptr; |
| 1384 | case clang::BO_Mul: | 1418 | case clang::BO_Mul: { |
| 1385 | return trans_create_bin_op(c, scope, stmt->getLHS(), | 1419 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1386 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult, | 1420 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult, |
| 1387 | stmt->getRHS()); | 1421 | stmt->getRHS()); |
| | 1422 | return maybe_suppress_result(c, result_used, node); |
| | 1423 | } |
| 1388 | case clang::BO_Div: | 1424 | case clang::BO_Div: |
| 1389 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { | 1425 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { |
| 1390 | // unsigned/float division uses the operator | 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 | } else { | 1429 | } else { |
| 1393 | // signed integer division uses @divTrunc | 1430 | // signed integer division uses @divTrunc |
| 1394 | AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc"); | 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,12 +1435,13 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1398 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue); | 1435 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue); |
| 1399 | if (rhs == nullptr) return nullptr; | 1436 | if (rhs == nullptr) return nullptr; |
| 1400 | fn_call->data.fn_call_expr.params.append(rhs); | 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 | case clang::BO_Rem: | 1440 | case clang::BO_Rem: |
| 1404 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { | 1441 | if (qual_type_has_wrapping_overflow(c, stmt->getType())) { |
| 1405 | // unsigned/float division uses the operator | 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 | } else { | 1445 | } else { |
| 1408 | // signed integer division uses @rem | 1446 | // signed integer division uses @rem |
| 1409 | AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem"); | 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,42 +1451,72 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1413 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue); | 1451 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue); |
| 1414 | if (rhs == nullptr) return nullptr; | 1452 | if (rhs == nullptr) return nullptr; |
| 1415 | fn_call->data.fn_call_expr.params.append(rhs); | 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: | 1456 | case clang::BO_Add: { |
| 1419 | return trans_create_bin_op(c, scope, stmt->getLHS(), | 1457 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1420 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd, | 1458 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd, |
| 1421 | stmt->getRHS()); | 1459 | stmt->getRHS()); |
| 1422 | case clang::BO_Sub: | 1460 | return maybe_suppress_result(c, result_used, node); |
| 1423 | return trans_create_bin_op(c, scope, stmt->getLHS(), | 1461 | } |
| | 1462 | case clang::BO_Sub: { |
| | 1463 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), |
| 1424 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub, | 1464 | qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub, |
| 1425 | stmt->getRHS()); | 1465 | stmt->getRHS()); |
| 1426 | case clang::BO_Shl: | 1466 | return maybe_suppress_result(c, result_used, node); |
| 1427 | return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS()); | 1467 | } |
| 1428 | case clang::BO_Shr: | 1468 | case clang::BO_Shl: { |
| 1429 | return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS()); | 1469 | AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS()); |
| 1430 | case clang::BO_LT: | 1470 | return maybe_suppress_result(c, result_used, node); |
| 1431 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS()); | 1471 | } |
| 1432 | case clang::BO_GT: | 1472 | case clang::BO_Shr: { |
| 1433 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS()); | 1473 | AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS()); |
| 1434 | case clang::BO_LE: | 1474 | return maybe_suppress_result(c, result_used, node); |
| 1435 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS()); | 1475 | } |
| 1436 | case clang::BO_GE: | 1476 | case clang::BO_LT: { |
| 1437 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS()); | 1477 | AstNode *node =trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS()); |
| 1438 | case clang::BO_EQ: | 1478 | return maybe_suppress_result(c, result_used, node); |
| 1439 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS()); | 1479 | } |
| 1440 | case clang::BO_NE: | 1480 | case clang::BO_GT: { |
| 1441 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS()); | 1481 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS()); |
| 1442 | case clang::BO_And: | 1482 | return maybe_suppress_result(c, result_used, node); |
| 1443 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS()); | 1483 | } |
| 1444 | case clang::BO_Xor: | 1484 | case clang::BO_LE: { |
| 1445 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS()); | 1485 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS()); |
| 1446 | case clang::BO_Or: | 1486 | return maybe_suppress_result(c, result_used, node); |
| 1447 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS()); | 1487 | } |
| 1448 | case clang::BO_LAnd: | 1488 | case clang::BO_GE: { |
| 1449 | return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS()); | 1489 | AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS()); |
| 1450 | case clang::BO_LOr: | 1490 | return maybe_suppress_result(c, result_used, node); |
| 1451 | return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); | 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 | case clang::BO_Assign: | 1520 | case clang::BO_Assign: |
| 1453 | return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS()); | 1521 | return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS()); |
| 1454 | case clang::BO_Comma: | 1522 | case clang::BO_Comma: |
| ... | @@ -1460,13 +1528,15 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS | ... | @@ -1460,13 +1528,15 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1460 | AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue); | 1528 | AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue); |
| 1461 | if (lhs == nullptr) | 1529 | if (lhs == nullptr) |
| 1462 | return nullptr; | 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 | if (rhs == nullptr) | 1534 | if (rhs == nullptr) |
| 1467 | return nullptr; | 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))); | 1536 | |
| 1469 | return scope_block->node; | 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 | case clang::BO_MulAssign: | 1541 | case clang::BO_MulAssign: |
| 1472 | case clang::BO_DivAssign: | 1542 | case clang::BO_DivAssign: |
| ... | @@ -1692,7 +1762,7 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use | ... | @@ -1692,7 +1762,7 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use |
| 1692 | zig_unreachable(); | 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 | switch (stmt->getCastKind()) { | 1766 | switch (stmt->getCastKind()) { |
| 1697 | case clang::CK_LValueToRValue: | 1767 | case clang::CK_LValueToRValue: |
| 1698 | return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); | 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,8 +1771,9 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl |
| 1701 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); | 1771 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); |
| 1702 | if (target_node == nullptr) | 1772 | if (target_node == nullptr) |
| 1703 | return nullptr; | 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 | stmt->getSubExpr()->getType(), target_node); | 1775 | stmt->getSubExpr()->getType(), target_node); |
| | 1776 | return maybe_suppress_result(c, result_used, node); |
| 1706 | } | 1777 | } |
| 1707 | case clang::CK_FunctionToPointerDecay: | 1778 | case clang::CK_FunctionToPointerDecay: |
| 1708 | case clang::CK_ArrayToPointerDecay: | 1779 | case clang::CK_ArrayToPointerDecay: |
| ... | @@ -1710,7 +1781,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl | ... | @@ -1710,7 +1781,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl |
| 1710 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); | 1781 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue); |
| 1711 | if (target_node == nullptr) | 1782 | if (target_node == nullptr) |
| 1712 | return nullptr; | 1783 | return nullptr; |
| 1713 | return target_node; | 1784 | return maybe_suppress_result(c, result_used, target_node); |
| 1714 | } | 1785 | } |
| 1715 | case clang::CK_BitCast: | 1786 | case clang::CK_BitCast: |
| 1716 | { | 1787 | { |
| ... | @@ -1727,7 +1798,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl | ... | @@ -1727,7 +1798,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl |
| 1727 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); | 1798 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 1728 | node->data.fn_call_expr.params.append(dest_type_node); | 1799 | node->data.fn_call_expr.params.append(dest_type_node); |
| 1729 | node->data.fn_call_expr.params.append(target_node); | 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 | case clang::CK_NullToPointer: | 1803 | case clang::CK_NullToPointer: |
| 1733 | return trans_create_node_unsigned(c, 0); | 1804 | return trans_create_node_unsigned(c, 0); |
| ... | @@ -2103,8 +2174,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc | ... | @@ -2103,8 +2174,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc |
| 2103 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag"); | 2174 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag"); |
| 2104 | return nullptr; | 2175 | return nullptr; |
| 2105 | case clang::UO_Extension: | 2176 | case clang::UO_Extension: |
| 2106 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Extension"); | 2177 | return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue); |
| 2107 | return nullptr; | | |
| 2108 | case clang::UO_Coawait: | 2178 | case clang::UO_Coawait: |
| 2109 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait"); | 2179 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait"); |
| 2110 | return nullptr; | 2180 | return nullptr; |
| ... | @@ -2721,7 +2791,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * | ... | @@ -2721,7 +2791,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * |
| 2721 | return node; | 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 | AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue); | 2797 | AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue); |
| 2726 | if (container_node == nullptr) | 2798 | if (container_node == nullptr) |
| 2727 | return nullptr; | 2799 | return nullptr; |
| ... | @@ -2733,10 +2805,10 @@ static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::Me | ... | @@ -2733,10 +2805,10 @@ static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::Me |
| 2733 | const char *name = decl_name(stmt->getMemberDecl()); | 2805 | const char *name = decl_name(stmt->getMemberDecl()); |
| 2734 | | 2806 | |
| 2735 | AstNode *node = trans_create_node_field_access_str(c, container_node, name); | 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 | AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue); | 2812 | AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue); |
| 2741 | if (container_node == nullptr) | 2813 | if (container_node == nullptr) |
| 2742 | return nullptr; | 2814 | return nullptr; |
| ... | @@ -2749,21 +2821,25 @@ static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const | ... | @@ -2749,21 +2821,25 @@ static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const |
| 2749 | AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr); | 2821 | AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr); |
| 2750 | node->data.array_access_expr.array_ref_expr = container_node; | 2822 | node->data.array_access_expr.array_ref_expr = container_node; |
| 2751 | node->data.array_access_expr.subscript = idx_node; | 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 | static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, | 2827 | static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, |
| 2756 | const clang::CStyleCastExpr *stmt, TransLRValue lrvalue) | 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 | if (sub_expr_node == nullptr) | 2831 | if (sub_expr_node == nullptr) |
| 2760 | return nullptr; | 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, | 2841 | static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used, |
| 2766 | const clang::UnaryExprOrTypeTraitExpr *stmt) | 2842 | TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt) |
| 2767 | { | 2843 | { |
| 2768 | AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart()); | 2844 | AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart()); |
| 2769 | if (type_node == nullptr) | 2845 | if (type_node == nullptr) |
| ... | @@ -2771,7 +2847,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop | ... | @@ -2771,7 +2847,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop |
| 2771 | | 2847 | |
| 2772 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf"); | 2848 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf"); |
| 2773 | node->data.fn_call_expr.params.append(type_node); | 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 | static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang::DoStmt *stmt) { | 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,11 +3125,13 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const clan |
| 3049 | return ErrorNone; | 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 | switch (stmt->getKind()) { | 3129 | switch (stmt->getKind()) { |
| 3054 | case clang::StringLiteral::Ascii: | 3130 | case clang::StringLiteral::Ascii: |
| 3055 | case clang::StringLiteral::UTF8: | 3131 | case clang::StringLiteral::UTF8: { |
| 3056 | return trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString())); | 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 | case clang::StringLiteral::UTF16: | 3135 | case clang::StringLiteral::UTF16: |
| 3058 | emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals"); | 3136 | emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals"); |
| 3059 | return nullptr; | 3137 | return nullptr; |
| ... | @@ -3085,6 +3163,12 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang:: | ... | @@ -3085,6 +3163,12 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang:: |
| 3085 | return trans_create_node(c, NodeTypeContinue); | 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 | static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) { | 3172 | static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) { |
| 3089 | if (result_node == nullptr) | 3173 | if (result_node == nullptr) |
| 3090 | return ErrorUnexpected; | 3174 | return ErrorUnexpected; |
| ... | @@ -3109,7 +3193,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st | ... | @@ -3109,7 +3193,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3109 | trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope)); | 3193 | trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope)); |
| 3110 | case clang::Stmt::IntegerLiteralClass: | 3194 | case clang::Stmt::IntegerLiteralClass: |
| 3111 | return wrap_stmt(out_node, out_child_scope, scope, | 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 | case clang::Stmt::ConditionalOperatorClass: | 3197 | case clang::Stmt::ConditionalOperatorClass: |
| 3114 | return wrap_stmt(out_node, out_child_scope, scope, | 3198 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3115 | trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt)); | 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,7 +3205,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3121 | trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt)); | 3205 | trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt)); |
| 3122 | case clang::Stmt::ImplicitCastExprClass: | 3206 | case clang::Stmt::ImplicitCastExprClass: |
| 3123 | return wrap_stmt(out_node, out_child_scope, scope, | 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 | case clang::Stmt::DeclRefExprClass: | 3209 | case clang::Stmt::DeclRefExprClass: |
| 3126 | return wrap_stmt(out_node, out_child_scope, scope, | 3210 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3127 | trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue)); | 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,28 +3236,28 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3152 | return wrap_stmt(out_node, out_child_scope, scope, | 3236 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3153 | trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt)); | 3237 | trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt)); |
| 3154 | case clang::Stmt::NullStmtClass: | 3238 | case clang::Stmt::NullStmtClass: |
| 3155 | *out_node = nullptr; | 3239 | *out_node = trans_create_node(c, NodeTypeBlock); |
| 3156 | *out_child_scope = scope; | 3240 | *out_child_scope = scope; |
| 3157 | return ErrorNone; | 3241 | return ErrorNone; |
| 3158 | case clang::Stmt::MemberExprClass: | 3242 | case clang::Stmt::MemberExprClass: |
| 3159 | return wrap_stmt(out_node, out_child_scope, scope, | 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 | case clang::Stmt::ArraySubscriptExprClass: | 3245 | case clang::Stmt::ArraySubscriptExprClass: |
| 3162 | return wrap_stmt(out_node, out_child_scope, scope, | 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 | case clang::Stmt::CStyleCastExprClass: | 3248 | case clang::Stmt::CStyleCastExprClass: |
| 3165 | return wrap_stmt(out_node, out_child_scope, scope, | 3249 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3166 | trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue)); | 3250 | trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue)); |
| 3167 | case clang::Stmt::UnaryExprOrTypeTraitExprClass: | 3251 | case clang::Stmt::UnaryExprOrTypeTraitExprClass: |
| 3168 | return wrap_stmt(out_node, out_child_scope, scope, | 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 | case clang::Stmt::ForStmtClass: { | 3254 | case clang::Stmt::ForStmtClass: { |
| 3171 | AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt); | 3255 | AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt); |
| 3172 | return wrap_stmt(out_node, out_child_scope, scope, node); | 3256 | return wrap_stmt(out_node, out_child_scope, scope, node); |
| 3173 | } | 3257 | } |
| 3174 | case clang::Stmt::StringLiteralClass: | 3258 | case clang::Stmt::StringLiteralClass: |
| 3175 | return wrap_stmt(out_node, out_child_scope, scope, | 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 | case clang::Stmt::BreakStmtClass: | 3261 | case clang::Stmt::BreakStmtClass: |
| 3178 | return wrap_stmt(out_node, out_child_scope, scope, | 3262 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3179 | trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt)); | 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,8 +3563,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3479 | emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass"); | 3563 | emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass"); |
| 3480 | return ErrorUnexpected; | 3564 | return ErrorUnexpected; |
| 3481 | case clang::Stmt::PredefinedExprClass: | 3565 | case clang::Stmt::PredefinedExprClass: |
| 3482 | emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass"); | 3566 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3483 | return ErrorUnexpected; | 3567 | trans_predefined_expr(c, result_used, scope, (const clang::PredefinedExpr *)stmt)); |
| 3484 | case clang::Stmt::PseudoObjectExprClass: | 3568 | case clang::Stmt::PseudoObjectExprClass: |
| 3485 | emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass"); | 3569 | emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass"); |
| 3486 | return ErrorUnexpected; | 3570 | return ErrorUnexpected; |
| ... | @@ -3491,8 +3575,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st | ... | @@ -3491,8 +3575,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3491 | emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass"); | 3575 | emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass"); |
| 3492 | return ErrorUnexpected; | 3576 | return ErrorUnexpected; |
| 3493 | case clang::Stmt::StmtExprClass: | 3577 | case clang::Stmt::StmtExprClass: |
| 3494 | emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass"); | 3578 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3495 | return ErrorUnexpected; | 3579 | trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope)); |
| 3496 | case clang::Stmt::SubstNonTypeTemplateParmExprClass: | 3580 | case clang::Stmt::SubstNonTypeTemplateParmExprClass: |
| 3497 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); | 3581 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); |
| 3498 | return ErrorUnexpected; | 3582 | return ErrorUnexpected; |