authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2019-03-15 16:12:41+01:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2019-03-15 16:12:41+01:00
loga77b2a0810bd835aa1adcfc18d32bc66ba8f1914
tree5daae184b1dd50cd4674d9f84c665c3a22492524
parent761356209bd64ed655be96c0cf11869f2ff5f530

Implemented enough of translate-c to translate assert

This required the following * __extention__ * ({}) * Fixing if (0) ; else ;

2 files changed, 99 insertions(+), 49 deletions(-)

src/translate_c.cpp+43-8
...@@ -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) {
684static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,684static 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}
12211228
1229static 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
1222static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {1254static 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}
30813112
3113static AstNode *trans_predefined_expr(Context *c, TransScope *scope, const clang::PredefinedExpr *expr) {
3114 return trans_string_literal(c, scope, expr->getFunctionName());
3115}
3116
3082static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {3117static 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;
test/translate_c.zig+56-41
...@@ -59,6 +59,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -59,6 +59,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
59 );59 );
60 }60 }
6161
62 cases.add("for loop with var init but empty body",
63 \\void foo(void) {
64 \\ __func__;
65 \\ __FUNCTION__;
66 \\ __PRETTY_FUNCTION__;
67 \\}
68 ,
69 \\pub fn foo() void {
70 \\ c"foo";
71 \\ c"foo";
72 \\ c"void foo(void)";
73 \\}
74 );
75
62 cases.add("for loop with var init but empty body",76 cases.add("for loop with var init but empty body",
63 \\void foo(void) {77 \\void foo(void) {
64 \\ for (int x = 0; x < 10; x++);78 \\ for (int x = 0; x < 10; x++);
...@@ -79,6 +93,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -79,6 +93,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
79 , // TODO this should be if (1 != 0) break93 , // TODO this should be if (1 != 0) break
80 \\pub fn foo() void {94 \\pub fn foo() void {
81 \\ while (true) {95 \\ while (true) {
96 \\ {}
82 \\ if (!1) break;97 \\ if (!1) break;
83 \\ }98 \\ }
84 \\}99 \\}
...@@ -720,7 +735,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -720,7 +735,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
720 \\ ;;;;;735 \\ ;;;;;
721 \\}736 \\}
722 ,737 ,
723 \\pub export fn foo() void {}738 \\pub export fn foo() void {
739 \\ {}
740 \\ {}
741 \\ {}
742 \\ {}
743 \\ {}
744 \\}
724 );745 );
725746
726 cases.add("undefined array global",747 cases.add("undefined array global",
...@@ -795,6 +816,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -795,6 +816,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
795 \\}816 \\}
796 );817 );
797818
819 cases.addC("statement expression",
820 \\int foo(void) {
821 \\ return ({
822 \\ int a = 1;
823 \\ a;
824 \\ });
825 \\}
826 ,
827 \\pub export fn foo() c_int {
828 \\ return x: {
829 \\ var a: c_int = 1;
830 \\ break :x a;
831 \\ };
832 \\}
833 );
834
835 cases.addC("__extension__ cast",
836 \\int foo(void) {
837 \\ return __extension__ 1;
838 \\}
839 ,
840 \\pub export fn foo() c_int {
841 \\ return 1;
842 \\}
843 );
844
798 cases.addC("bitshift",845 cases.addC("bitshift",
799 \\int foo(void) {846 \\int foo(void) {
800 \\ return (1 << 2) >> 1;847 \\ return (1 << 2) >> 1;
...@@ -1425,53 +1472,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1425,53 +1472,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1425 \\pub export fn bar() void {}1472 \\pub export fn bar() void {}
1426 );1473 );
14271474
1428 cases.addC("u integer suffix after 0 (zero) in macro definition",1475 cases.addC("u integer suffix after 0 (zero) in macro definition", "#define ZERO 0U", "pub const ZERO = c_uint(0);");
1429 "#define ZERO 0U"
1430 ,
1431 "pub const ZERO = c_uint(0);"
1432 );
14331476
1434 cases.addC("l integer suffix after 0 (zero) in macro definition",1477 cases.addC("l integer suffix after 0 (zero) in macro definition", "#define ZERO 0L", "pub const ZERO = c_long(0);");
1435 "#define ZERO 0L"
1436 ,
1437 "pub const ZERO = c_long(0);"
1438 );
14391478
1440 cases.addC("ul integer suffix after 0 (zero) in macro definition",1479 cases.addC("ul integer suffix after 0 (zero) in macro definition", "#define ZERO 0UL", "pub const ZERO = c_ulong(0);");
1441 "#define ZERO 0UL"
1442 ,
1443 "pub const ZERO = c_ulong(0);"
1444 );
14451480
1446 cases.addC("lu integer suffix after 0 (zero) in macro definition",1481 cases.addC("lu integer suffix after 0 (zero) in macro definition", "#define ZERO 0LU", "pub const ZERO = c_ulong(0);");
1447 "#define ZERO 0LU"
1448 ,
1449 "pub const ZERO = c_ulong(0);"
1450 );
14511482
1452 cases.addC("ll integer suffix after 0 (zero) in macro definition",1483 cases.addC("ll integer suffix after 0 (zero) in macro definition", "#define ZERO 0LL", "pub const ZERO = c_longlong(0);");
1453 "#define ZERO 0LL"
1454 ,
1455 "pub const ZERO = c_longlong(0);"
1456 );
14571484
1458 cases.addC("ull integer suffix after 0 (zero) in macro definition",1485 cases.addC("ull integer suffix after 0 (zero) in macro definition", "#define ZERO 0ULL", "pub const ZERO = c_ulonglong(0);");
1459 "#define ZERO 0ULL"
1460 ,
1461 "pub const ZERO = c_ulonglong(0);"
1462 );
14631486
1464 cases.addC("llu integer suffix after 0 (zero) in macro definition",1487 cases.addC("llu integer suffix after 0 (zero) in macro definition", "#define ZERO 0LLU", "pub const ZERO = c_ulonglong(0);");
1465 "#define ZERO 0LLU"
1466 ,
1467 "pub const ZERO = c_ulonglong(0);"
1468 );
14691488
1470 cases.addC("bitwise not on u-suffixed 0 (zero) in macro definition",1489 cases.addC("bitwise not on u-suffixed 0 (zero) in macro definition", "#define NOT_ZERO (~0U)", "pub const NOT_ZERO = ~c_uint(0);");
1471 "#define NOT_ZERO (~0U)"
1472 ,
1473 "pub const NOT_ZERO = ~c_uint(0);"
1474 );
14751490
1476 // cases.add("empty array with initializer",1491 // cases.add("empty array with initializer",
1477 // "int a[4] = {};"1492 // "int a[4] = {};"