| ... | @@ -684,6 +684,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { | ... | @@ -684,6 +684,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) { |
| 684 | static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type, | 684 | static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type, |
| 685 | clang::QualType src_type, AstNode *expr) | 685 | clang::QualType src_type, AstNode *expr) |
| 686 | { | 686 | { |
| | 687 | // The only way void pointer casts are valid C code, is if |
| | 688 | // the value of the expression is ignored. We therefore just |
| | 689 | // return the expr, and let the system that ignores values |
| | 690 | // translate this correctly. |
| | 691 | if (qual_type_canon(dest_type)->isVoidType()) { |
| | 692 | return expr; |
| | 693 | } |
| 687 | if (qual_types_equal(dest_type, src_type)) { | 694 | if (qual_types_equal(dest_type, src_type)) { |
| 688 | return expr; | 695 | return expr; |
| 689 | } | 696 | } |
| ... | @@ -1219,6 +1226,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang:: | ... | @@ -1219,6 +1226,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang:: |
| 1219 | return child_scope_block->node; | 1226 | return child_scope_block->node; |
| 1220 | } | 1227 | } |
| 1221 | | 1228 | |
| | 1229 | static AstNode *trans_stmt_expr(Context *c, TransScope *scope, const clang::StmtExpr *stmt, |
| | 1230 | TransScope **out_node_scope) |
| | 1231 | { |
| | 1232 | AstNode *block = trans_compound_stmt(c, scope, stmt->getSubStmt(), out_node_scope); |
| | 1233 | if (block == nullptr) |
| | 1234 | return block; |
| | 1235 | assert(block->type == NodeTypeBlock); |
| | 1236 | if (block->data.block.statements.length == 0) |
| | 1237 | return block; |
| | 1238 | |
| | 1239 | Buf *label = buf_create_from_str("x"); |
| | 1240 | block->data.block.name = label; |
| | 1241 | AstNode *return_expr = block->data.block.statements.pop(); |
| | 1242 | if (return_expr->type == NodeTypeBinOpExpr && |
| | 1243 | return_expr->data.bin_op_expr.bin_op == BinOpTypeAssign && |
| | 1244 | return_expr->data.bin_op_expr.op1->type == NodeTypeSymbol) |
| | 1245 | { |
| | 1246 | Buf *symbol_buf = return_expr->data.bin_op_expr.op1->data.symbol_expr.symbol; |
| | 1247 | if (strcmp("_", buf_ptr(symbol_buf)) == 0) |
| | 1248 | return_expr = return_expr->data.bin_op_expr.op2; |
| | 1249 | } |
| | 1250 | block->data.block.statements.append(trans_create_node_break(c, label, return_expr)); |
| | 1251 | return block; |
| | 1252 | } |
| | 1253 | |
| 1222 | static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) { | 1254 | static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) { |
| 1223 | const clang::Expr *value_expr = stmt->getRetValue(); | 1255 | const clang::Expr *value_expr = stmt->getRetValue(); |
| 1224 | if (value_expr == nullptr) { | 1256 | if (value_expr == nullptr) { |
| ... | @@ -1459,7 +1491,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS | ... | @@ -1459,7 +1491,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1459 | AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue); | 1491 | AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue); |
| 1460 | if (rhs == nullptr) | 1492 | if (rhs == nullptr) |
| 1461 | return nullptr; | 1493 | return nullptr; |
| 1462 | scope_block->node->data.block.statements.append(trans_create_node_break(c, label_name, maybe_suppress_result(c, result_used, rhs))); | 1494 | scope_block->node->data.block.statements.append(trans_create_node_break(c, label_name, rhs)); |
| 1463 | return scope_block->node; | 1495 | return scope_block->node; |
| 1464 | } | 1496 | } |
| 1465 | case clang::BO_MulAssign: | 1497 | case clang::BO_MulAssign: |
| ... | @@ -2097,8 +2129,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc | ... | @@ -2097,8 +2129,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc |
| 2097 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag"); | 2129 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag"); |
| 2098 | return nullptr; | 2130 | return nullptr; |
| 2099 | case clang::UO_Extension: | 2131 | case clang::UO_Extension: |
| 2100 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Extension"); | 2132 | return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue); |
| 2101 | return nullptr; | | |
| 2102 | case clang::UO_Coawait: | 2133 | case clang::UO_Coawait: |
| 2103 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait"); | 2134 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait"); |
| 2104 | return nullptr; | 2135 | return nullptr; |
| ... | @@ -3079,6 +3110,10 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang:: | ... | @@ -3079,6 +3110,10 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang:: |
| 3079 | return trans_create_node(c, NodeTypeContinue); | 3110 | return trans_create_node(c, NodeTypeContinue); |
| 3080 | } | 3111 | } |
| 3081 | | 3112 | |
| | 3113 | static AstNode *trans_predefined_expr(Context *c, TransScope *scope, const clang::PredefinedExpr *expr) { |
| | 3114 | return trans_string_literal(c, scope, expr->getFunctionName()); |
| | 3115 | } |
| | 3116 | |
| 3082 | static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) { | 3117 | static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) { |
| 3083 | if (result_node == nullptr) | 3118 | if (result_node == nullptr) |
| 3084 | return ErrorUnexpected; | 3119 | return ErrorUnexpected; |
| ... | @@ -3146,7 +3181,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st | ... | @@ -3146,7 +3181,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3146 | return wrap_stmt(out_node, out_child_scope, scope, | 3181 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3147 | trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt)); | 3182 | trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt)); |
| 3148 | case clang::Stmt::NullStmtClass: | 3183 | case clang::Stmt::NullStmtClass: |
| 3149 | *out_node = nullptr; | 3184 | *out_node = trans_create_node(c, NodeTypeBlock); |
| 3150 | *out_child_scope = scope; | 3185 | *out_child_scope = scope; |
| 3151 | return ErrorNone; | 3186 | return ErrorNone; |
| 3152 | case clang::Stmt::MemberExprClass: | 3187 | case clang::Stmt::MemberExprClass: |
| ... | @@ -3473,8 +3508,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st | ... | @@ -3473,8 +3508,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3473 | emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass"); | 3508 | emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass"); |
| 3474 | return ErrorUnexpected; | 3509 | return ErrorUnexpected; |
| 3475 | case clang::Stmt::PredefinedExprClass: | 3510 | case clang::Stmt::PredefinedExprClass: |
| 3476 | emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass"); | 3511 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3477 | return ErrorUnexpected; | 3512 | trans_predefined_expr(c, scope, (const clang::PredefinedExpr *)stmt)); |
| 3478 | case clang::Stmt::PseudoObjectExprClass: | 3513 | case clang::Stmt::PseudoObjectExprClass: |
| 3479 | emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass"); | 3514 | emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass"); |
| 3480 | return ErrorUnexpected; | 3515 | return ErrorUnexpected; |
| ... | @@ -3485,8 +3520,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st | ... | @@ -3485,8 +3520,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st |
| 3485 | emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass"); | 3520 | emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass"); |
| 3486 | return ErrorUnexpected; | 3521 | return ErrorUnexpected; |
| 3487 | case clang::Stmt::StmtExprClass: | 3522 | case clang::Stmt::StmtExprClass: |
| 3488 | emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass"); | 3523 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3489 | return ErrorUnexpected; | 3524 | trans_stmt_expr(c, scope, (const clang::StmtExpr *)stmt, out_node_scope)); |
| 3490 | case clang::Stmt::SubstNonTypeTemplateParmExprClass: | 3525 | case clang::Stmt::SubstNonTypeTemplateParmExprClass: |
| 3491 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); | 3526 | emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass"); |
| 3492 | return ErrorUnexpected; | 3527 | return ErrorUnexpected; |