authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-03-08 13:15:30+01:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-03-08 13:15:30+01:00
logb2887620f39d756b9f73a93b8b0932b3e471d996
treef85a34c5e8777f5e2cebe767e4d76d31ecd778e0
parent689e241ff8a826ac03cca0e8d1c9f8628cc88756

Translate C will now handle ignored return values


2 files changed, 53 insertions(+), 13 deletions(-)

src/translate_c.cpp+31-9
...@@ -500,15 +500,31 @@ static bool qual_type_is_ptr(QualType qt) {...@@ -500,15 +500,31 @@ static bool qual_type_is_ptr(QualType qt) {
500 return ty->getTypeClass() == Type::Pointer;500 return ty->getTypeClass() == Type::Pointer;
501}501}
502502
503static bool qual_type_is_fn_ptr(Context *c, QualType qt) {503static const FunctionProtoType *qual_type_get_fn_proto(QualType qt, bool *is_ptr) {
504 const Type *ty = qual_type_canon(qt);504 const Type *ty = qual_type_canon(qt);
505 if (ty->getTypeClass() != Type::Pointer) {505 *is_ptr = false;
506 return false;506
507 if (ty->getTypeClass() == Type::Pointer) {
508 *is_ptr = true;
509 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
510 QualType child_qt = pointer_ty->getPointeeType();
511 ty = child_qt.getTypePtr();
512 }
513
514 if (ty->getTypeClass() == Type::FunctionProto) {
515 return static_cast<const FunctionProtoType*>(ty);
507 }516 }
508 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);517
509 QualType child_qt = pointer_ty->getPointeeType();518 return nullptr;
510 const Type *child_ty = child_qt.getTypePtr();519}
511 return child_ty->getTypeClass() == Type::FunctionProto;520
521static bool qual_type_is_fn_ptr(QualType qt) {
522 bool is_ptr;
523 if (qual_type_get_fn_proto(qt, &is_ptr)) {
524 return is_ptr;
525 }
526
527 return false;
512}528}
513529
514static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {530static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {
...@@ -1871,7 +1887,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc...@@ -1871,7 +1887,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
1871 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);1887 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
1872 if (value_node == nullptr)1888 if (value_node == nullptr)
1873 return nullptr;1889 return nullptr;
1874 bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType());1890 bool is_fn_ptr = qual_type_is_fn_ptr(stmt->getSubExpr()->getType());
1875 if (is_fn_ptr)1891 if (is_fn_ptr)
1876 return value_node;1892 return value_node;
1877 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);1893 AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node);
...@@ -2327,8 +2343,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *...@@ -2327,8 +2343,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
2327 if (callee_raw_node == nullptr)2343 if (callee_raw_node == nullptr)
2328 return nullptr;2344 return nullptr;
23292345
2346 bool is_ptr = false;
2347 const FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
2330 AstNode *callee_node = nullptr;2348 AstNode *callee_node = nullptr;
2331 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {2349 if (is_ptr && fn_ty) {
2332 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {2350 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
2333 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());2351 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());
2334 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {2352 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
...@@ -2360,6 +2378,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *...@@ -2360,6 +2378,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
2360 node->data.fn_call_expr.params.append(arg_node);2378 node->data.fn_call_expr.params.append(arg_node);
2361 }2379 }
23622380
2381 if (result_used == ResultUsedNo && fn_ty && !qual_type_canon(fn_ty->getReturnType())->isVoidType()) {
2382 node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node);
2383 }
2384
2363 return node;2385 return node;
2364}2386}
23652387
test/translate_c.zig+22-4
...@@ -515,11 +515,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -515,11 +515,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
515515
516 cases.addC("function call",516 cases.addC("function call",
517 \\static void bar(void) { }517 \\static void bar(void) { }
518 \\void foo(void) { bar(); }518 \\static int baz(void) { return 0; }
519 \\void foo(void) {
520 \\ bar();
521 \\ baz();
522 \\}
519 ,523 ,
520 \\pub fn bar() void {}524 \\pub fn bar() void {}
525 \\pub fn baz() c_int {
526 \\ return 0;
527 \\}
521 \\pub export fn foo() void {528 \\pub export fn foo() void {
522 \\ bar();529 \\ bar();
530 \\ _ = baz();
523 \\}531 \\}
524 );532 );
525533
...@@ -878,21 +886,31 @@ pub fn addCases(cases: &tests.TranslateCContext) void {...@@ -878,21 +886,31 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
878886
879 cases.addC("deref function pointer",887 cases.addC("deref function pointer",
880 \\void foo(void) {}888 \\void foo(void) {}
881 \\void baz(void) {}889 \\int baz(void) { return 0; }
882 \\void bar(void) {890 \\void bar(void) {
883 \\ void(*f)(void) = foo;891 \\ void(*f)(void) = foo;
892 \\ int(*b)(void) = baz;
884 \\ f();893 \\ f();
885 \\ (*(f))();894 \\ (*(f))();
895 \\ foo();
896 \\ b();
897 \\ (*(b))();
886 \\ baz();898 \\ baz();
887 \\}899 \\}
888 ,900 ,
889 \\pub export fn foo() void {}901 \\pub export fn foo() void {}
890 \\pub export fn baz() void {}902 \\pub export fn baz() c_int {
903 \\ return 0;
904 \\}
891 \\pub export fn bar() void {905 \\pub export fn bar() void {
892 \\ var f: ?extern fn() void = foo;906 \\ var f: ?extern fn() void = foo;
907 \\ var b: ?extern fn() c_int = baz;
893 \\ (??f)();908 \\ (??f)();
894 \\ (??f)();909 \\ (??f)();
895 \\ baz();910 \\ foo();
911 \\ _ = (??b)();
912 \\ _ = (??b)();
913 \\ _ = baz();
896 \\}914 \\}
897 );915 );
898916