| ... | @@ -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 | } |
| 502 | | 502 | |
| 503 | static bool qual_type_is_fn_ptr(Context *c, QualType qt) { | 503 | static 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 | |
| | 521 | static 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 | } |
| 513 | | 529 | |
| 514 | static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) { | 530 | 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 | ... | @@ -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; |
| 2329 | | 2345 | |
| | 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 | } |
| 2362 | | 2380 | |
| | 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 | } |
| 2365 | | 2387 | |