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) {
684684static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,
685685 clang::QualType src_type, AstNode *expr)
686686{
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 }
687694 if (qual_types_equal(dest_type, src_type)) {
688695 return expr;
689696 }
......@@ -1219,6 +1226,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::
12191226 return child_scope_block->node;
12201227}
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
12221254static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {
12231255 const clang::Expr *value_expr = stmt->getRetValue();
12241256 if (value_expr == nullptr) {
......@@ -1459,7 +1491,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
14591491 AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue);
14601492 if (rhs == nullptr)
14611493 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));
14631495 return scope_block->node;
14641496 }
14651497 case clang::BO_MulAssign:
......@@ -2097,8 +2129,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
20972129 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag");
20982130 return nullptr;
20992131 case clang::UO_Extension:
2100 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Extension");
2101 return nullptr;
2132 return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
21022133 case clang::UO_Coawait:
21032134 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait");
21042135 return nullptr;
......@@ -3079,6 +3110,10 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang::
30793110 return trans_create_node(c, NodeTypeContinue);
30803111}
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
30823117static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {
30833118 if (result_node == nullptr)
30843119 return ErrorUnexpected;
......@@ -3146,7 +3181,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
31463181 return wrap_stmt(out_node, out_child_scope, scope,
31473182 trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt));
31483183 case clang::Stmt::NullStmtClass:
3149 *out_node = nullptr;
3184 *out_node = trans_create_node(c, NodeTypeBlock);
31503185 *out_child_scope = scope;
31513186 return ErrorNone;
31523187 case clang::Stmt::MemberExprClass:
......@@ -3473,8 +3508,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
34733508 emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");
34743509 return ErrorUnexpected;
34753510 case clang::Stmt::PredefinedExprClass:
3476 emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass");
3477 return ErrorUnexpected;
3511 return wrap_stmt(out_node, out_child_scope, scope,
3512 trans_predefined_expr(c, scope, (const clang::PredefinedExpr *)stmt));
34783513 case clang::Stmt::PseudoObjectExprClass:
34793514 emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass");
34803515 return ErrorUnexpected;
......@@ -3485,8 +3520,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
34853520 emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass");
34863521 return ErrorUnexpected;
34873522 case clang::Stmt::StmtExprClass:
3488 emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass");
3489 return ErrorUnexpected;
3523 return wrap_stmt(out_node, out_child_scope, scope,
3524 trans_stmt_expr(c, scope, (const clang::StmtExpr *)stmt, out_node_scope));
34903525 case clang::Stmt::SubstNonTypeTemplateParmExprClass:
34913526 emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass");
34923527 return ErrorUnexpected;
test/translate_c.zig+56-41
......@@ -59,6 +59,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
5959 );
6060 }
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
6276 cases.add("for loop with var init but empty body",
6377 \\void foo(void) {
6478 \\ for (int x = 0; x < 10; x++);
......@@ -79,6 +93,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
7993 , // TODO this should be if (1 != 0) break
8094 \\pub fn foo() void {
8195 \\ while (true) {
96 \\ {}
8297 \\ if (!1) break;
8398 \\ }
8499 \\}
......@@ -720,7 +735,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
720735 \\ ;;;;;
721736 \\}
722737 ,
723 \\pub export fn foo() void {}
738 \\pub export fn foo() void {
739 \\ {}
740 \\ {}
741 \\ {}
742 \\ {}
743 \\ {}
744 \\}
724745 );
725746
726747 cases.add("undefined array global",
......@@ -795,6 +816,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
795816 \\}
796817 );
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
798845 cases.addC("bitshift",
799846 \\int foo(void) {
800847 \\ return (1 << 2) >> 1;
......@@ -1425,53 +1472,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14251472 \\pub export fn bar() void {}
14261473 );
14271474
1428 cases.addC("u integer suffix after 0 (zero) in macro definition",
1429 "#define ZERO 0U"
1430 ,
1431 "pub const ZERO = c_uint(0);"
1432 );
1475 cases.addC("u integer suffix after 0 (zero) in macro definition", "#define ZERO 0U", "pub const ZERO = c_uint(0);");
14331476
1434 cases.addC("l integer suffix after 0 (zero) in macro definition",
1435 "#define ZERO 0L"
1436 ,
1437 "pub const ZERO = c_long(0);"
1438 );
1477 cases.addC("l integer suffix after 0 (zero) in macro definition", "#define ZERO 0L", "pub const ZERO = c_long(0);");
14391478
1440 cases.addC("ul integer suffix after 0 (zero) in macro definition",
1441 "#define ZERO 0UL"
1442 ,
1443 "pub const ZERO = c_ulong(0);"
1444 );
1479 cases.addC("ul integer suffix after 0 (zero) in macro definition", "#define ZERO 0UL", "pub const ZERO = c_ulong(0);");
14451480
1446 cases.addC("lu integer suffix after 0 (zero) in macro definition",
1447 "#define ZERO 0LU"
1448 ,
1449 "pub const ZERO = c_ulong(0);"
1450 );
1481 cases.addC("lu integer suffix after 0 (zero) in macro definition", "#define ZERO 0LU", "pub const ZERO = c_ulong(0);");
14511482
1452 cases.addC("ll integer suffix after 0 (zero) in macro definition",
1453 "#define ZERO 0LL"
1454 ,
1455 "pub const ZERO = c_longlong(0);"
1456 );
1483 cases.addC("ll integer suffix after 0 (zero) in macro definition", "#define ZERO 0LL", "pub const ZERO = c_longlong(0);");
14571484
1458 cases.addC("ull integer suffix after 0 (zero) in macro definition",
1459 "#define ZERO 0ULL"
1460 ,
1461 "pub const ZERO = c_ulonglong(0);"
1462 );
1485 cases.addC("ull integer suffix after 0 (zero) in macro definition", "#define ZERO 0ULL", "pub const ZERO = c_ulonglong(0);");
14631486
1464 cases.addC("llu integer suffix after 0 (zero) in macro definition",
1465 "#define ZERO 0LLU"
1466 ,
1467 "pub const ZERO = c_ulonglong(0);"
1468 );
1487 cases.addC("llu integer suffix after 0 (zero) in macro definition", "#define ZERO 0LLU", "pub const ZERO = c_ulonglong(0);");
14691488
1470 cases.addC("bitwise not on u-suffixed 0 (zero) in macro definition",
1471 "#define NOT_ZERO (~0U)"
1472 ,
1473 "pub const NOT_ZERO = ~c_uint(0);"
1474 );
1489 cases.addC("bitwise not on u-suffixed 0 (zero) in macro definition", "#define NOT_ZERO (~0U)", "pub const NOT_ZERO = ~c_uint(0);");
14751490
14761491 // cases.add("empty array with initializer",
14771492 // "int a[4] = {};"