| ... | ... | @@ -121,6 +121,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *s |
| 121 | 121 | TransScope **out_node_scope); |
| 122 | 122 | static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node); |
| 123 | 123 | static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval); |
| 124 | static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc); |
| 124 | 125 | static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc); |
| 125 | 126 | static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, |
| 126 | 127 | const ZigClangExpr *expr, TransLRValue lrval); |
| ... | ... | @@ -575,13 +576,6 @@ static bool is_c_void_type(AstNode *node) { |
| 575 | 576 | return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); |
| 576 | 577 | } |
| 577 | 578 | |
| 578 | | static bool expr_types_equal(Context *c, const ZigClangExpr *expr1, const ZigClangExpr *expr2) { |
| 579 | | ZigClangQualType t1 = get_expr_qual_type(c, expr1); |
| 580 | | ZigClangQualType t2 = get_expr_qual_type(c, expr2); |
| 581 | | |
| 582 | | return ZigClangQualType_eq(t1, t2); |
| 583 | | } |
| 584 | | |
| 585 | 579 | static bool qual_type_is_ptr(ZigClangQualType qt) { |
| 586 | 580 | const ZigClangType *ty = qual_type_canon(qt); |
| 587 | 581 | return ZigClangType_getTypeClass(ty) == ZigClangType_Pointer; |
| ... | ... | @@ -593,8 +587,7 @@ static const clang::FunctionProtoType *qual_type_get_fn_proto(ZigClangQualType q |
| 593 | 587 | |
| 594 | 588 | if (ZigClangType_getTypeClass(ty) == ZigClangType_Pointer) { |
| 595 | 589 | *is_ptr = true; |
| 596 | | const clang::PointerType *pointer_ty = reinterpret_cast<const clang::PointerType*>(ty); |
| 597 | | ZigClangQualType child_qt = bitcast(pointer_ty->getPointeeType()); |
| 590 | ZigClangQualType child_qt = ZigClangType_getPointeeType(ty); |
| 598 | 591 | ty = ZigClangQualType_getTypePtr(child_qt); |
| 599 | 592 | } |
| 600 | 593 | |
| ... | ... | @@ -705,6 +698,36 @@ static bool qual_type_child_is_fn_proto(ZigClangQualType qt) { |
| 705 | 698 | return false; |
| 706 | 699 | } |
| 707 | 700 | |
| 701 | static AstNode* trans_c_ptr_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type, |
| 702 | ZigClangQualType src_type, AstNode *expr) |
| 703 | { |
| 704 | const ZigClangType *ty = ZigClangQualType_getTypePtr(dest_type); |
| 705 | const ZigClangQualType child_type = ZigClangType_getPointeeType(ty); |
| 706 | |
| 707 | AstNode *dest_type_node = trans_type(c, ty, source_location); |
| 708 | AstNode *child_type_node = trans_qual_type(c, child_type, source_location); |
| 709 | |
| 710 | // Implicit downcasting from higher to lower alignment values is forbidden, |
| 711 | // use @alignCast to side-step this problem |
| 712 | AstNode *ptrcast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 713 | ptrcast_node->data.fn_call_expr.params.append(dest_type_node); |
| 714 | |
| 715 | if (ZigClangType_isVoidType(qual_type_canon(child_type))) { |
| 716 | // void has 1-byte alignment |
| 717 | ptrcast_node->data.fn_call_expr.params.append(expr); |
| 718 | } else { |
| 719 | AstNode *alignof_node = trans_create_node_builtin_fn_call_str(c, "alignOf"); |
| 720 | alignof_node->data.fn_call_expr.params.append(child_type_node); |
| 721 | AstNode *aligncast_node = trans_create_node_builtin_fn_call_str(c, "alignCast"); |
| 722 | aligncast_node->data.fn_call_expr.params.append(alignof_node); |
| 723 | aligncast_node->data.fn_call_expr.params.append(expr); |
| 724 | |
| 725 | ptrcast_node->data.fn_call_expr.params.append(aligncast_node); |
| 726 | } |
| 727 | |
| 728 | return ptrcast_node; |
| 729 | } |
| 730 | |
| 708 | 731 | static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type, |
| 709 | 732 | ZigClangQualType src_type, AstNode *expr) |
| 710 | 733 | { |
| ... | ... | @@ -719,10 +742,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, |
| 719 | 742 | return expr; |
| 720 | 743 | } |
| 721 | 744 | if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) { |
| 722 | | AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 723 | | ptr_cast_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location)); |
| 724 | | ptr_cast_node->data.fn_call_expr.params.append(expr); |
| 725 | | return ptr_cast_node; |
| 745 | return trans_c_ptr_cast(c, source_location, dest_type, src_type, expr); |
| 726 | 746 | } |
| 727 | 747 | // TODO: maybe widen to increase size |
| 728 | 748 | // TODO: maybe bitcast to change sign |
| ... | ... | @@ -980,8 +1000,7 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc |
| 980 | 1000 | } |
| 981 | 1001 | case ZigClangType_Pointer: |
| 982 | 1002 | { |
| 983 | | const clang::PointerType *pointer_ty = reinterpret_cast<const clang::PointerType*>(ty); |
| 984 | | ZigClangQualType child_qt = bitcast(pointer_ty->getPointeeType()); |
| 1003 | ZigClangQualType child_qt = ZigClangType_getPointeeType(ty); |
| 985 | 1004 | AstNode *child_node = trans_qual_type(c, child_qt, source_loc); |
| 986 | 1005 | if (child_node == nullptr) { |
| 987 | 1006 | emit_warning(c, source_loc, "pointer to unsupported type"); |
| ... | ... | @@ -1889,16 +1908,10 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra |
| 1889 | 1908 | if (target_node == nullptr) |
| 1890 | 1909 | return nullptr; |
| 1891 | 1910 | |
| 1892 | | if (expr_types_equal(c, (const ZigClangExpr *)stmt, bitcast(stmt->getSubExpr()))) { |
| 1893 | | return target_node; |
| 1894 | | } |
| 1911 | const ZigClangQualType dest_type = get_expr_qual_type(c, bitcast(stmt)); |
| 1912 | const ZigClangQualType src_type = get_expr_qual_type(c, bitcast(stmt->getSubExpr())); |
| 1895 | 1913 | |
| 1896 | | AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt); |
| 1897 | | |
| 1898 | | AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast"); |
| 1899 | | node->data.fn_call_expr.params.append(dest_type_node); |
| 1900 | | node->data.fn_call_expr.params.append(target_node); |
| 1901 | | return maybe_suppress_result(c, result_used, node); |
| 1914 | return trans_c_cast(c, bitcast(stmt->getBeginLoc()), dest_type, src_type, target_node); |
| 1902 | 1915 | } |
| 1903 | 1916 | case ZigClangCK_NullToPointer: |
| 1904 | 1917 | return trans_create_node_unsigned(c, 0); |