Translate C will now handle ignored return values

This commit is contained in:
Jimmi Holst Christensen 2018-03-08 13:15:30 +01:00
parent 689e241ff8
commit b2887620f3
2 changed files with 53 additions and 13 deletions

View File

@ -500,15 +500,31 @@ static bool qual_type_is_ptr(QualType qt) {
return ty->getTypeClass() == Type::Pointer; return ty->getTypeClass() == Type::Pointer;
} }
static bool qual_type_is_fn_ptr(Context *c, QualType qt) { static const FunctionProtoType *qual_type_get_fn_proto(QualType qt, bool *is_ptr) {
const Type *ty = qual_type_canon(qt); const Type *ty = qual_type_canon(qt);
if (ty->getTypeClass() != Type::Pointer) { *is_ptr = false;
return false;
if (ty->getTypeClass() == Type::Pointer) {
*is_ptr = true;
const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
QualType child_qt = pointer_ty->getPointeeType();
ty = child_qt.getTypePtr();
} }
const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
QualType child_qt = pointer_ty->getPointeeType(); if (ty->getTypeClass() == Type::FunctionProto) {
const Type *child_ty = child_qt.getTypePtr(); return static_cast<const FunctionProtoType*>(ty);
return child_ty->getTypeClass() == Type::FunctionProto; }
return nullptr;
}
static bool qual_type_is_fn_ptr(QualType qt) {
bool is_ptr;
if (qual_type_get_fn_proto(qt, &is_ptr)) {
return is_ptr;
}
return false;
} }
static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) { static 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
AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue); AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
if (value_node == nullptr) if (value_node == nullptr)
return nullptr; return nullptr;
bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType()); bool is_fn_ptr = qual_type_is_fn_ptr(stmt->getSubExpr()->getType());
if (is_fn_ptr) if (is_fn_ptr)
return value_node; return value_node;
AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node); 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 *
if (callee_raw_node == nullptr) if (callee_raw_node == nullptr)
return nullptr; return nullptr;
bool is_ptr = false;
const FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
AstNode *callee_node = nullptr; AstNode *callee_node = nullptr;
if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) { if (is_ptr && fn_ty) {
if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) { if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee()); const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());
if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) { if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
@ -2360,6 +2378,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
node->data.fn_call_expr.params.append(arg_node); node->data.fn_call_expr.params.append(arg_node);
} }
if (result_used == ResultUsedNo && fn_ty && !qual_type_canon(fn_ty->getReturnType())->isVoidType()) {
node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node);
}
return node; return node;
} }

View File

@ -515,11 +515,19 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
cases.addC("function call", cases.addC("function call",
\\static void bar(void) { } \\static void bar(void) { }
\\void foo(void) { bar(); } \\static int baz(void) { return 0; }
\\void foo(void) {
\\ bar();
\\ baz();
\\}
, ,
\\pub fn bar() void {} \\pub fn bar() void {}
\\pub fn baz() c_int {
\\ return 0;
\\}
\\pub export fn foo() void { \\pub export fn foo() void {
\\ bar(); \\ bar();
\\ _ = baz();
\\} \\}
); );
@ -878,21 +886,31 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
cases.addC("deref function pointer", cases.addC("deref function pointer",
\\void foo(void) {} \\void foo(void) {}
\\void baz(void) {} \\int baz(void) { return 0; }
\\void bar(void) { \\void bar(void) {
\\ void(*f)(void) = foo; \\ void(*f)(void) = foo;
\\ int(*b)(void) = baz;
\\ f(); \\ f();
\\ (*(f))(); \\ (*(f))();
\\ foo();
\\ b();
\\ (*(b))();
\\ baz(); \\ baz();
\\} \\}
, ,
\\pub export fn foo() void {} \\pub export fn foo() void {}
\\pub export fn baz() void {} \\pub export fn baz() c_int {
\\ return 0;
\\}
\\pub export fn bar() void { \\pub export fn bar() void {
\\ var f: ?extern fn() void = foo; \\ var f: ?extern fn() void = foo;
\\ var b: ?extern fn() c_int = baz;
\\ (??f)(); \\ (??f)();
\\ (??f)(); \\ (??f)();
\\ baz(); \\ foo();
\\ _ = (??b)();
\\ _ = (??b)();
\\ _ = baz();
\\} \\}
); );