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) {
500500 return ty->getTypeClass() == Type::Pointer;
501501}
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) {
504504 const Type *ty = qual_type_canon(qt);
505 if (ty->getTypeClass() != Type::Pointer) {
506 return false;
505 *is_ptr = 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);
507516 }
508 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
509 QualType child_qt = pointer_ty->getPointeeType();
510 const Type *child_ty = child_qt.getTypePtr();
511 return child_ty->getTypeClass() == Type::FunctionProto;
517
518 return nullptr;
519}
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;
512528}
513529
514530static 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
18711887 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
18721888 if (value_node == nullptr)
18731889 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());
18751891 if (is_fn_ptr)
18761892 return value_node;
18771893 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 *
23272343 if (callee_raw_node == nullptr)
23282344 return nullptr;
23292345
2346 bool is_ptr = false;
2347 const FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
23302348 AstNode *callee_node = nullptr;
2331 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {
2349 if (is_ptr && fn_ty) {
23322350 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
23332351 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());
23342352 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
......@@ -2360,6 +2378,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
23602378 node->data.fn_call_expr.params.append(arg_node);
23612379 }
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
23632385 return node;
23642386}
23652387
test/translate_c.zig+22-4
......@@ -515,11 +515,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
515515
516516 cases.addC("function call",
517517 \\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 \\}
519523 ,
520524 \\pub fn bar() void {}
525 \\pub fn baz() c_int {
526 \\ return 0;
527 \\}
521528 \\pub export fn foo() void {
522529 \\ bar();
530 \\ _ = baz();
523531 \\}
524532 );
525533
......@@ -878,21 +886,31 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
878886
879887 cases.addC("deref function pointer",
880888 \\void foo(void) {}
881 \\void baz(void) {}
889 \\int baz(void) { return 0; }
882890 \\void bar(void) {
883891 \\ void(*f)(void) = foo;
892 \\ int(*b)(void) = baz;
884893 \\ f();
885894 \\ (*(f))();
895 \\ foo();
896 \\ b();
897 \\ (*(b))();
886898 \\ baz();
887899 \\}
888900 ,
889901 \\pub export fn foo() void {}
890 \\pub export fn baz() void {}
902 \\pub export fn baz() c_int {
903 \\ return 0;
904 \\}
891905 \\pub export fn bar() void {
892906 \\ var f: ?extern fn() void = foo;
907 \\ var b: ?extern fn() c_int = baz;
893908 \\ (??f)();
894909 \\ (??f)();
895 \\ baz();
910 \\ foo();
911 \\ _ = (??b)();
912 \\ _ = (??b)();
913 \\ _ = baz();
896914 \\}
897915 );
898916