| ... | ... | @@ -500,15 +500,31 @@ static bool qual_type_is_ptr(QualType qt) { |
| 500 | 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 | 504 | 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); |
| 507 | 516 | } |
| 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 | |
| 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 | 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 | 1887 | AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue); |
| 1872 | 1888 | if (value_node == nullptr) |
| 1873 | 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 | 1891 | if (is_fn_ptr) |
| 1876 | 1892 | return value_node; |
| 1877 | 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 | 2343 | if (callee_raw_node == nullptr) |
| 2328 | 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 | 2348 | AstNode *callee_node = nullptr; |
| 2331 | | if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) { |
| 2349 | if (is_ptr && fn_ty) { |
| 2332 | 2350 | if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) { |
| 2333 | 2351 | const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee()); |
| 2334 | 2352 | if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) { |
| ... | ... | @@ -2360,6 +2378,10 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope * |
| 2360 | 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 | 2385 | return node; |
| 2364 | 2386 | } |
| 2365 | 2387 | |