| ... | @@ -350,6 +350,21 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, | ... | @@ -350,6 +350,21 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, |
| 350 | return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr); | 350 | return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr); |
| 351 | } | 351 | } |
| 352 | | 352 | |
| | 353 | static bool qual_type_is_fn_ptr(Context *c, const QualType &qt) { |
| | 354 | const Type *ty = qt.getTypePtr(); |
| | 355 | if (ty->getTypeClass() != Type::Pointer) { |
| | 356 | return false; |
| | 357 | } |
| | 358 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); |
| | 359 | QualType child_qt = pointer_ty->getPointeeType(); |
| | 360 | const Type *child_ty = child_qt.getTypePtr(); |
| | 361 | if (child_ty->getTypeClass() != Type::Paren) { |
| | 362 | return false; |
| | 363 | } |
| | 364 | const ParenType *paren_ty = static_cast<const ParenType *>(child_ty); |
| | 365 | return paren_ty->getInnerType().getTypePtr()->getTypeClass() == Type::FunctionProto; |
| | 366 | } |
| | 367 | |
| 353 | static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) { | 368 | static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) { |
| 354 | const Type *ty = qt.getTypePtr(); | 369 | const Type *ty = qt.getTypePtr(); |
| 355 | switch (ty->getTypeClass()) { | 370 | switch (ty->getTypeClass()) { |
| ... | @@ -1575,8 +1590,14 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc | ... | @@ -1575,8 +1590,14 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc |
| 1575 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_AddrOf"); | 1590 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_AddrOf"); |
| 1576 | return nullptr; | 1591 | return nullptr; |
| 1577 | case UO_Deref: | 1592 | case UO_Deref: |
| 1578 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Deref"); | 1593 | { |
| 1579 | return nullptr; | 1594 | bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType()); |
| | 1595 | AstNode *value_node = trans_expr(c, result_used, block, stmt->getSubExpr(), TransRValue); |
| | 1596 | if (is_fn_ptr) |
| | 1597 | return value_node; |
| | 1598 | AstNode *unwrapped = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, value_node); |
| | 1599 | return trans_create_node_prefix_op(c, PrefixOpDereference, unwrapped); |
| | 1600 | } |
| 1580 | case UO_Plus: | 1601 | case UO_Plus: |
| 1581 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus"); | 1602 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus"); |
| 1582 | return nullptr; | 1603 | return nullptr; |
| ... | @@ -1919,10 +1940,20 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) { | ... | @@ -1919,10 +1940,20 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) { |
| 1919 | | 1940 | |
| 1920 | static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) { | 1941 | static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) { |
| 1921 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); | 1942 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| 1922 | node->data.fn_call_expr.fn_ref_expr = trans_expr(c, true, block, stmt->getCallee(), TransRValue); | 1943 | |
| 1923 | if (node->data.fn_call_expr.fn_ref_expr == nullptr) | 1944 | AstNode *callee_raw_node = trans_expr(c, true, block, stmt->getCallee(), TransRValue); |
| | 1945 | if (callee_raw_node == nullptr) |
| 1924 | return nullptr; | 1946 | return nullptr; |
| 1925 | | 1947 | |
| | 1948 | AstNode *callee_node; |
| | 1949 | if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) { |
| | 1950 | callee_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, callee_raw_node); |
| | 1951 | } else { |
| | 1952 | callee_node = callee_raw_node; |
| | 1953 | } |
| | 1954 | |
| | 1955 | node->data.fn_call_expr.fn_ref_expr = callee_node; |
| | 1956 | |
| 1926 | unsigned num_args = stmt->getNumArgs(); | 1957 | unsigned num_args = stmt->getNumArgs(); |
| 1927 | Expr **args = stmt->getArgs(); | 1958 | Expr **args = stmt->getArgs(); |
| 1928 | for (unsigned i = 0; i < num_args; i += 1) { | 1959 | for (unsigned i = 0; i < num_args; i += 1) { |