| ... | @@ -344,11 +344,10 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui | ... | @@ -344,11 +344,10 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, TypeTableEntry *int_type, Bui |
| 344 | return *fn; | 344 | return *fn; |
| 345 | } | 345 | } |
| 346 | | 346 | |
| 347 | static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValueRef ptr, TypeTableEntry *type) { | 347 | static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type) { |
| 348 | if (handle_is_ptr(type)) { | 348 | if (handle_is_ptr(type)) { |
| 349 | return ptr; | 349 | return ptr; |
| 350 | } else { | 350 | } else { |
| 351 | set_debug_source_node(g, source_node); | | |
| 352 | return LLVMBuildLoad(g->builder, ptr, ""); | 351 | return LLVMBuildLoad(g->builder, ptr, ""); |
| 353 | } | 352 | } |
| 354 | } | 353 | } |
| ... | @@ -378,7 +377,7 @@ static void gen_debug_safety_crash(CodeGen *g) { | ... | @@ -378,7 +377,7 @@ static void gen_debug_safety_crash(CodeGen *g) { |
| 378 | LLVMBuildUnreachable(g->builder); | 377 | LLVMBuildUnreachable(g->builder); |
| 379 | } | 378 | } |
| 380 | | 379 | |
| 381 | static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef target_val, | 380 | static void add_bounds_check(CodeGen *g, LLVMValueRef target_val, |
| 382 | LLVMIntPredicate lower_pred, LLVMValueRef lower_value, | 381 | LLVMIntPredicate lower_pred, LLVMValueRef lower_value, |
| 383 | LLVMIntPredicate upper_pred, LLVMValueRef upper_value) | 382 | LLVMIntPredicate upper_pred, LLVMValueRef upper_value) |
| 384 | { | 383 | { |
| ... | @@ -391,8 +390,6 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ | ... | @@ -391,8 +390,6 @@ static void add_bounds_check(CodeGen *g, AstNode *source_node, LLVMValueRef targ |
| 391 | upper_value = nullptr; | 390 | upper_value = nullptr; |
| 392 | } | 391 | } |
| 393 | | 392 | |
| 394 | set_debug_source_node(g, source_node); | | |
| 395 | | | |
| 396 | LLVMBasicBlockRef bounds_check_fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckFail"); | 393 | LLVMBasicBlockRef bounds_check_fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckFail"); |
| 397 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckOk"); | 394 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckOk"); |
| 398 | LLVMBasicBlockRef lower_ok_block = upper_value ? | 395 | LLVMBasicBlockRef lower_ok_block = upper_value ? |
| ... | @@ -425,12 +422,11 @@ static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) { | ... | @@ -425,12 +422,11 @@ static LLVMValueRef gen_err_name(CodeGen *g, AstNode *node) { |
| 425 | | 422 | |
| 426 | AstNode *err_val_node = node->data.fn_call_expr.params.at(0); | 423 | AstNode *err_val_node = node->data.fn_call_expr.params.at(0); |
| 427 | LLVMValueRef err_val = gen_expr(g, err_val_node); | 424 | LLVMValueRef err_val = gen_expr(g, err_val_node); |
| 428 | set_debug_source_node(g, node); | | |
| 429 | | 425 | |
| 430 | if (want_debug_safety(g, node)) { | 426 | if (want_debug_safety(g, node)) { |
| 431 | LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val)); | 427 | LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val)); |
| 432 | LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false); | 428 | LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false); |
| 433 | add_bounds_check(g, node, err_val, LLVMIntNE, zero, LLVMIntULT, end_val); | 429 | add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val); |
| 434 | } | 430 | } |
| 435 | | 431 | |
| 436 | LLVMValueRef indices[] = { | 432 | LLVMValueRef indices[] = { |
| ... | @@ -514,15 +510,12 @@ static LLVMValueRef gen_truncate(CodeGen *g, AstNode *node) { | ... | @@ -514,15 +510,12 @@ static LLVMValueRef gen_truncate(CodeGen *g, AstNode *node) { |
| 514 | | 510 | |
| 515 | LLVMValueRef src_val = gen_expr(g, src_node); | 511 | LLVMValueRef src_val = gen_expr(g, src_node); |
| 516 | | 512 | |
| 517 | set_debug_source_node(g, node); | | |
| 518 | return LLVMBuildTrunc(g->builder, src_val, dest_type->type_ref, ""); | 513 | return LLVMBuildTrunc(g->builder, src_val, dest_type->type_ref, ""); |
| 519 | } | 514 | } |
| 520 | | 515 | |
| 521 | static LLVMValueRef gen_unreachable(CodeGen *g, AstNode *node) { | 516 | static LLVMValueRef gen_unreachable(CodeGen *g, AstNode *node) { |
| 522 | assert(node->type == NodeTypeFnCallExpr); | 517 | assert(node->type == NodeTypeFnCallExpr); |
| 523 | | 518 | |
| 524 | set_debug_source_node(g, node); | | |
| 525 | | | |
| 526 | if (want_debug_safety(g, node) || g->is_test_build) { | 519 | if (want_debug_safety(g, node) || g->is_test_build) { |
| 527 | gen_debug_safety_crash(g); | 520 | gen_debug_safety_crash(g); |
| 528 | } else { | 521 | } else { |
| ... | @@ -545,7 +538,6 @@ static LLVMValueRef gen_shl_with_overflow(CodeGen *g, AstNode *node) { | ... | @@ -545,7 +538,6 @@ static LLVMValueRef gen_shl_with_overflow(CodeGen *g, AstNode *node) { |
| 545 | LLVMValueRef val2 = gen_expr(g, node->data.fn_call_expr.params.at(2)); | 538 | LLVMValueRef val2 = gen_expr(g, node->data.fn_call_expr.params.at(2)); |
| 546 | LLVMValueRef ptr_result = gen_expr(g, node->data.fn_call_expr.params.at(3)); | 539 | LLVMValueRef ptr_result = gen_expr(g, node->data.fn_call_expr.params.at(3)); |
| 547 | | 540 | |
| 548 | set_debug_source_node(g, node); | | |
| 549 | LLVMValueRef result = LLVMBuildShl(g->builder, val1, val2, ""); | 541 | LLVMValueRef result = LLVMBuildShl(g->builder, val1, val2, ""); |
| 550 | LLVMValueRef orig_val; | 542 | LLVMValueRef orig_val; |
| 551 | if (int_type->data.integral.is_signed) { | 543 | if (int_type->data.integral.is_signed) { |
| ... | @@ -590,7 +582,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -590,7 +582,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 590 | operand, | 582 | operand, |
| 591 | LLVMConstNull(LLVMInt1Type()), | 583 | LLVMConstNull(LLVMInt1Type()), |
| 592 | }; | 584 | }; |
| 593 | set_debug_source_node(g, node); | | |
| 594 | return LLVMBuildCall(g->builder, fn_val, params, 2, ""); | 585 | return LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 595 | } | 586 | } |
| 596 | case BuiltinFnIdAddWithOverflow: | 587 | case BuiltinFnIdAddWithOverflow: |
| ... | @@ -622,7 +613,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -622,7 +613,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 622 | op2, | 613 | op2, |
| 623 | }; | 614 | }; |
| 624 | | 615 | |
| 625 | set_debug_source_node(g, node); | | |
| 626 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); | 616 | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 627 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); | 617 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| 628 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); | 618 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| ... | @@ -646,7 +636,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -646,7 +636,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 646 | | 636 | |
| 647 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); | 637 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| 648 | | 638 | |
| 649 | set_debug_source_node(g, node); | | |
| 650 | LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); | 639 | LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); |
| 651 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, ""); | 640 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, ""); |
| 652 | | 641 | |
| ... | @@ -677,7 +666,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -677,7 +666,6 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 677 | | 666 | |
| 678 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); | 667 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| 679 | | 668 | |
| 680 | set_debug_source_node(g, node); | | |
| 681 | LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); | 669 | LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); |
| 682 | | 670 | |
| 683 | uint64_t align_in_bytes = get_memcpy_align(g, dest_type->data.pointer.child_type); | 671 | uint64_t align_in_bytes = get_memcpy_align(g, dest_type->data.pointer.child_type); |
| ... | @@ -707,13 +695,11 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -707,13 +695,11 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 707 | case BuiltinFnIdErrName: | 695 | case BuiltinFnIdErrName: |
| 708 | return gen_err_name(g, node); | 696 | return gen_err_name(g, node); |
| 709 | case BuiltinFnIdBreakpoint: | 697 | case BuiltinFnIdBreakpoint: |
| 710 | set_debug_source_node(g, node); | | |
| 711 | return LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); | 698 | return LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, ""); |
| 712 | case BuiltinFnIdFrameAddress: | 699 | case BuiltinFnIdFrameAddress: |
| 713 | case BuiltinFnIdReturnAddress: | 700 | case BuiltinFnIdReturnAddress: |
| 714 | { | 701 | { |
| 715 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref); | 702 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref); |
| 716 | set_debug_source_node(g, node); | | |
| 717 | return LLVMBuildCall(g->builder, builtin_fn->fn_val, &zero, 1, ""); | 703 | return LLVMBuildCall(g->builder, builtin_fn->fn_val, &zero, 1, ""); |
| 718 | } | 704 | } |
| 719 | case BuiltinFnIdCmpExchange: | 705 | case BuiltinFnIdCmpExchange: |
| ... | @@ -760,7 +746,6 @@ static LLVMValueRef gen_enum_value_expr(CodeGen *g, AstNode *node, TypeTableEntr | ... | @@ -760,7 +746,6 @@ static LLVMValueRef gen_enum_value_expr(CodeGen *g, AstNode *node, TypeTableEntr |
| 760 | LLVMValueRef tmp_struct_ptr = node->data.field_access_expr.resolved_struct_val_expr.ptr; | 746 | LLVMValueRef tmp_struct_ptr = node->data.field_access_expr.resolved_struct_val_expr.ptr; |
| 761 | | 747 | |
| 762 | // populate the new tag value | 748 | // populate the new tag value |
| 763 | set_debug_source_node(g, node); | | |
| 764 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, ""); | 749 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, ""); |
| 765 | LLVMBuildStore(g->builder, tag_value, tag_field_ptr); | 750 | LLVMBuildStore(g->builder, tag_value, tag_field_ptr); |
| 766 | | 751 | |
| ... | @@ -804,7 +789,6 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT | ... | @@ -804,7 +789,6 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT |
| 804 | !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && | 789 | !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && |
| 805 | want_debug_safety(g, source_node)) | 790 | want_debug_safety(g, source_node)) |
| 806 | { | 791 | { |
| 807 | set_debug_source_node(g, source_node); | | |
| 808 | LLVMValueRef zero = LLVMConstNull(actual_type->type_ref); | 792 | LLVMValueRef zero = LLVMConstNull(actual_type->type_ref); |
| 809 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, ""); | 793 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, ""); |
| 810 | | 794 | |
| ... | @@ -822,14 +806,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT | ... | @@ -822,14 +806,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT |
| 822 | return expr_val; | 806 | return expr_val; |
| 823 | } else if (actual_bits < wanted_bits) { | 807 | } else if (actual_bits < wanted_bits) { |
| 824 | if (actual_type->id == TypeTableEntryIdFloat) { | 808 | if (actual_type->id == TypeTableEntryIdFloat) { |
| 825 | set_debug_source_node(g, source_node); | | |
| 826 | return LLVMBuildFPExt(g->builder, expr_val, wanted_type->type_ref, ""); | 809 | return LLVMBuildFPExt(g->builder, expr_val, wanted_type->type_ref, ""); |
| 827 | } else if (actual_type->id == TypeTableEntryIdInt) { | 810 | } else if (actual_type->id == TypeTableEntryIdInt) { |
| 828 | if (actual_type->data.integral.is_signed) { | 811 | if (actual_type->data.integral.is_signed) { |
| 829 | set_debug_source_node(g, source_node); | | |
| 830 | return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, ""); | 812 | return LLVMBuildSExt(g->builder, expr_val, wanted_type->type_ref, ""); |
| 831 | } else { | 813 | } else { |
| 832 | set_debug_source_node(g, source_node); | | |
| 833 | return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); | 814 | return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); |
| 834 | } | 815 | } |
| 835 | } else { | 816 | } else { |
| ... | @@ -837,10 +818,8 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT | ... | @@ -837,10 +818,8 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT |
| 837 | } | 818 | } |
| 838 | } else if (actual_bits > wanted_bits) { | 819 | } else if (actual_bits > wanted_bits) { |
| 839 | if (actual_type->id == TypeTableEntryIdFloat) { | 820 | if (actual_type->id == TypeTableEntryIdFloat) { |
| 840 | set_debug_source_node(g, source_node); | | |
| 841 | return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, ""); | 821 | return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, ""); |
| 842 | } else if (actual_type->id == TypeTableEntryIdInt) { | 822 | } else if (actual_type->id == TypeTableEntryIdInt) { |
| 843 | set_debug_source_node(g, source_node); | | |
| 844 | LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, ""); | 823 | LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, ""); |
| 845 | if (!want_debug_safety(g, source_node)) { | 824 | if (!want_debug_safety(g, source_node)) { |
| 846 | return trunc_val; | 825 | return trunc_val; |
| ... | @@ -869,256 +848,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT | ... | @@ -869,256 +848,11 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT |
| 869 | } | 848 | } |
| 870 | } | 849 | } |
| 871 | | 850 | |
| 872 | static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { | | |
| 873 | assert(node->type == NodeTypeFnCallExpr); | | |
| 874 | | | |
| 875 | AstNode *expr_node = node->data.fn_call_expr.params.at(0); | | |
| 876 | | | |
| 877 | LLVMValueRef expr_val = gen_expr(g, expr_node); | | |
| 878 | | | |
| 879 | TypeTableEntry *actual_type = get_expr_type(expr_node); | | |
| 880 | TypeTableEntry *wanted_type = get_expr_type(node); | | |
| 881 | | | |
| 882 | AstNodeFnCallExpr *cast_expr = &node->data.fn_call_expr; | | |
| 883 | | | |
| 884 | switch (cast_expr->cast_op) { | | |
| 885 | case CastOpNoCast: | | |
| 886 | zig_unreachable(); | | |
| 887 | case CastOpNoop: | | |
| 888 | return expr_val; | | |
| 889 | case CastOpErrToInt: | | |
| 890 | assert(actual_type->id == TypeTableEntryIdErrorUnion); | | |
| 891 | if (!type_has_bits(actual_type->data.error.child_type)) { | | |
| 892 | return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val); | | |
| 893 | } else { | | |
| 894 | zig_panic("TODO"); | | |
| 895 | } | | |
| 896 | case CastOpMaybeWrap: | | |
| 897 | { | | |
| 898 | assert(cast_expr->tmp_ptr); | | |
| 899 | assert(wanted_type->id == TypeTableEntryIdMaybe); | | |
| 900 | assert(actual_type); | | |
| 901 | | | |
| 902 | TypeTableEntry *child_type = wanted_type->data.maybe.child_type; | | |
| 903 | | | |
| 904 | if (child_type->id == TypeTableEntryIdPointer || | | |
| 905 | child_type->id == TypeTableEntryIdFn) | | |
| 906 | { | | |
| 907 | return expr_val; | | |
| 908 | } else { | | |
| 909 | set_debug_source_node(g, node); | | |
| 910 | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, ""); | | |
| 911 | gen_assign_raw(g, node, BinOpTypeAssign, | | |
| 912 | val_ptr, expr_val, child_type, actual_type); | | |
| 913 | | | |
| 914 | set_debug_source_node(g, node); | | |
| 915 | LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, ""); | | |
| 916 | LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr); | | |
| 917 | } | | |
| 918 | | | |
| 919 | return cast_expr->tmp_ptr; | | |
| 920 | } | | |
| 921 | case CastOpNullToMaybe: | | |
| 922 | // handled by constant expression evaluator | | |
| 923 | zig_unreachable(); | | |
| 924 | case CastOpErrorWrap: | | |
| 925 | { | | |
| 926 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); | | |
| 927 | TypeTableEntry *child_type = wanted_type->data.error.child_type; | | |
| 928 | LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref); | | |
| 929 | | | |
| 930 | if (!type_has_bits(child_type)) { | | |
| 931 | return ok_err_val; | | |
| 932 | } else { | | |
| 933 | assert(cast_expr->tmp_ptr); | | |
| 934 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); | | |
| 935 | assert(actual_type); | | |
| 936 | | | |
| 937 | set_debug_source_node(g, node); | | |
| 938 | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, ""); | | |
| 939 | LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr); | | |
| 940 | | | |
| 941 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, ""); | | |
| 942 | gen_assign_raw(g, node, BinOpTypeAssign, | | |
| 943 | payload_ptr, expr_val, child_type, actual_type); | | |
| 944 | | | |
| 945 | return cast_expr->tmp_ptr; | | |
| 946 | } | | |
| 947 | } | | |
| 948 | case CastOpPureErrorWrap: | | |
| 949 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); | | |
| 950 | | | |
| 951 | if (!type_has_bits(wanted_type->data.error.child_type)) { | | |
| 952 | return expr_val; | | |
| 953 | } else { | | |
| 954 | zig_panic("TODO"); | | |
| 955 | } | | |
| 956 | case CastOpPtrToInt: | | |
| 957 | set_debug_source_node(g, node); | | |
| 958 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 959 | case CastOpIntToPtr: | | |
| 960 | set_debug_source_node(g, node); | | |
| 961 | return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 962 | case CastOpPointerReinterpret: | | |
| 963 | set_debug_source_node(g, node); | | |
| 964 | return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 965 | case CastOpWidenOrShorten: | | |
| 966 | return gen_widen_or_shorten(g, node, actual_type, wanted_type, expr_val); | | |
| 967 | case CastOpToUnknownSizeArray: | | |
| 968 | { | | |
| 969 | assert(cast_expr->tmp_ptr); | | |
| 970 | assert(wanted_type->id == TypeTableEntryIdStruct); | | |
| 971 | assert(wanted_type->data.structure.is_slice); | | |
| 972 | | | |
| 973 | TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry; | | |
| 974 | | | |
| 975 | set_debug_source_node(g, node); | | |
| 976 | | | |
| 977 | size_t ptr_index = wanted_type->data.structure.fields[0].gen_index; | | |
| 978 | if (ptr_index != SIZE_MAX) { | | |
| 979 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, ptr_index, ""); | | |
| 980 | LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, ""); | | |
| 981 | LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr); | | |
| 982 | } | | |
| 983 | | | |
| 984 | size_t len_index = wanted_type->data.structure.fields[1].gen_index; | | |
| 985 | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, len_index, ""); | | |
| 986 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, | | |
| 987 | actual_type->data.array.len, false); | | |
| 988 | LLVMBuildStore(g->builder, len_val, len_ptr); | | |
| 989 | | | |
| 990 | return cast_expr->tmp_ptr; | | |
| 991 | } | | |
| 992 | case CastOpResizeSlice: | | |
| 993 | { | | |
| 994 | assert(cast_expr->tmp_ptr); | | |
| 995 | assert(wanted_type->id == TypeTableEntryIdStruct); | | |
| 996 | assert(wanted_type->data.structure.is_slice); | | |
| 997 | assert(actual_type->id == TypeTableEntryIdStruct); | | |
| 998 | assert(actual_type->data.structure.is_slice); | | |
| 999 | | | |
| 1000 | TypeTableEntry *actual_pointer_type = actual_type->data.structure.fields[0].type_entry; | | |
| 1001 | TypeTableEntry *actual_child_type = actual_pointer_type->data.pointer.child_type; | | |
| 1002 | TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; | | |
| 1003 | TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; | | |
| 1004 | | | |
| 1005 | set_debug_source_node(g, node); | | |
| 1006 | | | |
| 1007 | size_t actual_ptr_index = actual_type->data.structure.fields[0].gen_index; | | |
| 1008 | size_t actual_len_index = actual_type->data.structure.fields[1].gen_index; | | |
| 1009 | size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index; | | |
| 1010 | size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index; | | |
| 1011 | | | |
| 1012 | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_ptr_index, ""); | | |
| 1013 | LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, ""); | | |
| 1014 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, | | |
| 1015 | wanted_type->data.structure.fields[0].type_entry->type_ref, ""); | | |
| 1016 | LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, | | |
| 1017 | wanted_ptr_index, ""); | | |
| 1018 | LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr); | | |
| 1019 | | | |
| 1020 | LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_len_index, ""); | | |
| 1021 | LLVMValueRef src_len = LLVMBuildLoad(g->builder, src_len_ptr, ""); | | |
| 1022 | uint64_t src_size = type_size(g, actual_child_type); | | |
| 1023 | uint64_t dest_size = type_size(g, wanted_child_type); | | |
| 1024 | | | |
| 1025 | LLVMValueRef new_len; | | |
| 1026 | if (dest_size == 1) { | | |
| 1027 | LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, src_size, false); | | |
| 1028 | new_len = LLVMBuildMul(g->builder, src_len, src_size_val, ""); | | |
| 1029 | } else if (src_size == 1) { | | |
| 1030 | LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false); | | |
| 1031 | if (want_debug_safety(g, node)) { | | |
| 1032 | LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, ""); | | |
| 1033 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref); | | |
| 1034 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, ""); | | |
| 1035 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenOk"); | | |
| 1036 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenFail"); | | |
| 1037 | LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); | | |
| 1038 | | | |
| 1039 | LLVMPositionBuilderAtEnd(g->builder, fail_block); | | |
| 1040 | gen_debug_safety_crash(g); | | |
| 1041 | | | |
| 1042 | LLVMPositionBuilderAtEnd(g->builder, ok_block); | | |
| 1043 | } | | |
| 1044 | new_len = ZigLLVMBuildExactUDiv(g->builder, src_len, dest_size_val, ""); | | |
| 1045 | } else { | | |
| 1046 | zig_unreachable(); | | |
| 1047 | } | | |
| 1048 | | | |
| 1049 | LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, | | |
| 1050 | wanted_len_index, ""); | | |
| 1051 | LLVMBuildStore(g->builder, new_len, dest_len_ptr); | | |
| 1052 | | | |
| 1053 | | | |
| 1054 | return cast_expr->tmp_ptr; | | |
| 1055 | } | | |
| 1056 | case CastOpBytesToSlice: | | |
| 1057 | { | | |
| 1058 | assert(cast_expr->tmp_ptr); | | |
| 1059 | assert(wanted_type->id == TypeTableEntryIdStruct); | | |
| 1060 | assert(wanted_type->data.structure.is_slice); | | |
| 1061 | assert(actual_type->id == TypeTableEntryIdArray); | | |
| 1062 | | | |
| 1063 | TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; | | |
| 1064 | TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; | | |
| 1065 | | | |
| 1066 | set_debug_source_node(g, node); | | |
| 1067 | | | |
| 1068 | size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index; | | |
| 1069 | LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, wanted_ptr_index, ""); | | |
| 1070 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, ""); | | |
| 1071 | LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr); | | |
| 1072 | | | |
| 1073 | size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index; | | |
| 1074 | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, wanted_len_index, ""); | | |
| 1075 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, | | |
| 1076 | actual_type->data.array.len / type_size(g, wanted_child_type), false); | | |
| 1077 | LLVMBuildStore(g->builder, len_val, len_ptr); | | |
| 1078 | | | |
| 1079 | return cast_expr->tmp_ptr; | | |
| 1080 | } | | |
| 1081 | case CastOpIntToFloat: | | |
| 1082 | assert(actual_type->id == TypeTableEntryIdInt); | | |
| 1083 | if (actual_type->data.integral.is_signed) { | | |
| 1084 | set_debug_source_node(g, node); | | |
| 1085 | return LLVMBuildSIToFP(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 1086 | } else { | | |
| 1087 | set_debug_source_node(g, node); | | |
| 1088 | return LLVMBuildUIToFP(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 1089 | } | | |
| 1090 | case CastOpFloatToInt: | | |
| 1091 | assert(wanted_type->id == TypeTableEntryIdInt); | | |
| 1092 | if (wanted_type->data.integral.is_signed) { | | |
| 1093 | set_debug_source_node(g, node); | | |
| 1094 | return LLVMBuildFPToSI(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 1095 | } else { | | |
| 1096 | set_debug_source_node(g, node); | | |
| 1097 | return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 1098 | } | | |
| 1099 | | | |
| 1100 | case CastOpBoolToInt: | | |
| 1101 | assert(wanted_type->id == TypeTableEntryIdInt); | | |
| 1102 | assert(actual_type->id == TypeTableEntryIdBool); | | |
| 1103 | set_debug_source_node(g, node); | | |
| 1104 | return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); | | |
| 1105 | | | |
| 1106 | case CastOpIntToEnum: | | |
| 1107 | return gen_widen_or_shorten(g, node, actual_type, wanted_type->data.enumeration.tag_type, expr_val); | | |
| 1108 | case CastOpEnumToInt: | | |
| 1109 | return gen_widen_or_shorten(g, node, actual_type->data.enumeration.tag_type, wanted_type, expr_val); | | |
| 1110 | } | | |
| 1111 | zig_unreachable(); | | |
| 1112 | } | | |
| 1113 | | | |
| 1114 | | | |
| 1115 | static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { | 851 | static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { |
| 1116 | assert(node->type == NodeTypeFnCallExpr); | 852 | assert(node->type == NodeTypeFnCallExpr); |
| 1117 | | 853 | |
| 1118 | if (node->data.fn_call_expr.is_builtin) { | 854 | if (node->data.fn_call_expr.is_builtin) { |
| 1119 | return gen_builtin_fn_call_expr(g, node); | 855 | return gen_builtin_fn_call_expr(g, node); |
| 1120 | } else if (node->data.fn_call_expr.cast_op != CastOpNoCast) { | | |
| 1121 | return gen_cast_expr(g, node); | | |
| 1122 | } | 856 | } |
| 1123 | | 857 | |
| 1124 | FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry; | 858 | FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry; |
| ... | @@ -1186,7 +920,6 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -1186,7 +920,6 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { |
| 1186 | } | 920 | } |
| 1187 | } | 921 | } |
| 1188 | | 922 | |
| 1189 | set_debug_source_node(g, node); | | |
| 1190 | LLVMValueRef result = ZigLLVMBuildCall(g->builder, fn_val, | 923 | LLVMValueRef result = ZigLLVMBuildCall(g->builder, fn_val, |
| 1191 | gen_param_values, gen_param_index, fn_type->data.fn.calling_convention, ""); | 924 | gen_param_values, gen_param_index, fn_type->data.fn.calling_convention, ""); |
| 1192 | | 925 | |
| ... | @@ -1209,7 +942,6 @@ static LLVMValueRef gen_array_base_ptr(CodeGen *g, AstNode *node) { | ... | @@ -1209,7 +942,6 @@ static LLVMValueRef gen_array_base_ptr(CodeGen *g, AstNode *node) { |
| 1209 | array_ptr = gen_field_access_expr(g, node, true); | 942 | array_ptr = gen_field_access_expr(g, node, true); |
| 1210 | if (type_entry->id == TypeTableEntryIdPointer) { | 943 | if (type_entry->id == TypeTableEntryIdPointer) { |
| 1211 | // we have a double pointer so we must dereference it once | 944 | // we have a double pointer so we must dereference it once |
| 1212 | set_debug_source_node(g, node); | | |
| 1213 | array_ptr = LLVMBuildLoad(g->builder, array_ptr, ""); | 945 | array_ptr = LLVMBuildLoad(g->builder, array_ptr, ""); |
| 1214 | } | 946 | } |
| 1215 | } else { | 947 | } else { |
| ... | @@ -1234,20 +966,18 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal | ... | @@ -1234,20 +966,18 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal |
| 1234 | if (want_debug_safety(g, source_node)) { | 966 | if (want_debug_safety(g, source_node)) { |
| 1235 | LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->type_ref, | 967 | LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->type_ref, |
| 1236 | array_type->data.array.len, false); | 968 | array_type->data.array.len, false); |
| 1237 | add_bounds_check(g, source_node, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end); | 969 | add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end); |
| 1238 | } | 970 | } |
| 1239 | LLVMValueRef indices[] = { | 971 | LLVMValueRef indices[] = { |
| 1240 | LLVMConstNull(g->builtin_types.entry_usize->type_ref), | 972 | LLVMConstNull(g->builtin_types.entry_usize->type_ref), |
| 1241 | subscript_value | 973 | subscript_value |
| 1242 | }; | 974 | }; |
| 1243 | set_debug_source_node(g, source_node); | | |
| 1244 | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); | 975 | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); |
| 1245 | } else if (array_type->id == TypeTableEntryIdPointer) { | 976 | } else if (array_type->id == TypeTableEntryIdPointer) { |
| 1246 | assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); | 977 | assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); |
| 1247 | LLVMValueRef indices[] = { | 978 | LLVMValueRef indices[] = { |
| 1248 | subscript_value | 979 | subscript_value |
| 1249 | }; | 980 | }; |
| 1250 | set_debug_source_node(g, source_node); | | |
| 1251 | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); | 981 | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); |
| 1252 | } else if (array_type->id == TypeTableEntryIdStruct) { | 982 | } else if (array_type->id == TypeTableEntryIdStruct) { |
| 1253 | assert(array_type->data.structure.is_slice); | 983 | assert(array_type->data.structure.is_slice); |
| ... | @@ -1255,15 +985,13 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal | ... | @@ -1255,15 +985,13 @@ static LLVMValueRef gen_array_elem_ptr(CodeGen *g, AstNode *source_node, LLVMVal |
| 1255 | assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); | 985 | assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); |
| 1256 | | 986 | |
| 1257 | if (want_debug_safety(g, source_node)) { | 987 | if (want_debug_safety(g, source_node)) { |
| 1258 | set_debug_source_node(g, source_node); | | |
| 1259 | size_t len_index = array_type->data.structure.fields[1].gen_index; | 988 | size_t len_index = array_type->data.structure.fields[1].gen_index; |
| 1260 | assert(len_index != SIZE_MAX); | 989 | assert(len_index != SIZE_MAX); |
| 1261 | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, len_index, ""); | 990 | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, len_index, ""); |
| 1262 | LLVMValueRef len = LLVMBuildLoad(g->builder, len_ptr, ""); | 991 | LLVMValueRef len = LLVMBuildLoad(g->builder, len_ptr, ""); |
| 1263 | add_bounds_check(g, source_node, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len); | 992 | add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len); |
| 1264 | } | 993 | } |
| 1265 | | 994 | |
| 1266 | set_debug_source_node(g, source_node); | | |
| 1267 | size_t ptr_index = array_type->data.structure.fields[0].gen_index; | 995 | size_t ptr_index = array_type->data.structure.fields[0].gen_index; |
| 1268 | assert(ptr_index != SIZE_MAX); | 996 | assert(ptr_index != SIZE_MAX); |
| 1269 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, ptr_index, ""); | 997 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, ptr_index, ""); |
| ... | @@ -1302,7 +1030,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou | ... | @@ -1302,7 +1030,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou |
| 1302 | assert(var); | 1030 | assert(var); |
| 1303 | | 1031 | |
| 1304 | if (var->type->id == TypeTableEntryIdPointer) { | 1032 | if (var->type->id == TypeTableEntryIdPointer) { |
| 1305 | set_debug_source_node(g, node); | | |
| 1306 | struct_ptr = LLVMBuildLoad(g->builder, var->value_ref, ""); | 1033 | struct_ptr = LLVMBuildLoad(g->builder, var->value_ref, ""); |
| 1307 | } else { | 1034 | } else { |
| 1308 | struct_ptr = var->value_ref; | 1035 | struct_ptr = var->value_ref; |
| ... | @@ -1312,7 +1039,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou | ... | @@ -1312,7 +1039,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou |
| 1312 | TypeTableEntry *field_type = get_expr_type(struct_expr_node); | 1039 | TypeTableEntry *field_type = get_expr_type(struct_expr_node); |
| 1313 | if (field_type->id == TypeTableEntryIdPointer) { | 1040 | if (field_type->id == TypeTableEntryIdPointer) { |
| 1314 | // we have a double pointer so we must dereference it once | 1041 | // we have a double pointer so we must dereference it once |
| 1315 | set_debug_source_node(g, node); | | |
| 1316 | struct_ptr = LLVMBuildLoad(g->builder, struct_ptr, ""); | 1042 | struct_ptr = LLVMBuildLoad(g->builder, struct_ptr, ""); |
| 1317 | } | 1043 | } |
| 1318 | } else { | 1044 | } else { |
| ... | @@ -1325,7 +1051,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou | ... | @@ -1325,7 +1051,6 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou |
| 1325 | size_t gen_field_index = node->data.field_access_expr.type_struct_field->gen_index; | 1051 | size_t gen_field_index = node->data.field_access_expr.type_struct_field->gen_index; |
| 1326 | assert(gen_field_index != SIZE_MAX); | 1052 | assert(gen_field_index != SIZE_MAX); |
| 1327 | | 1053 | |
| 1328 | set_debug_source_node(g, node); | | |
| 1329 | return LLVMBuildStructGEP(g->builder, struct_ptr, gen_field_index, ""); | 1054 | return LLVMBuildStructGEP(g->builder, struct_ptr, gen_field_index, ""); |
| 1330 | } | 1055 | } |
| 1331 | | 1056 | |
| ... | @@ -1348,15 +1073,14 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1348,15 +1073,14 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1348 | } | 1073 | } |
| 1349 | | 1074 | |
| 1350 | if (want_debug_safety(g, node)) { | 1075 | if (want_debug_safety(g, node)) { |
| 1351 | add_bounds_check(g, node, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); | 1076 | add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); |
| 1352 | if (node->data.slice_expr.end) { | 1077 | if (node->data.slice_expr.end) { |
| 1353 | LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref, | 1078 | LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref, |
| 1354 | array_type->data.array.len, false); | 1079 | array_type->data.array.len, false); |
| 1355 | add_bounds_check(g, node, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end); | 1080 | add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end); |
| 1356 | } | 1081 | } |
| 1357 | } | 1082 | } |
| 1358 | | 1083 | |
| 1359 | set_debug_source_node(g, node); | | |
| 1360 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, ""); | 1084 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, ""); |
| 1361 | LLVMValueRef indices[] = { | 1085 | LLVMValueRef indices[] = { |
| 1362 | LLVMConstNull(g->builtin_types.entry_usize->type_ref), | 1086 | LLVMConstNull(g->builtin_types.entry_usize->type_ref), |
| ... | @@ -1375,10 +1099,9 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1375,10 +1099,9 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1375 | LLVMValueRef end_val = gen_expr(g, node->data.slice_expr.end); | 1099 | LLVMValueRef end_val = gen_expr(g, node->data.slice_expr.end); |
| 1376 | | 1100 | |
| 1377 | if (want_debug_safety(g, node)) { | 1101 | if (want_debug_safety(g, node)) { |
| 1378 | add_bounds_check(g, node, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); | 1102 | add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); |
| 1379 | } | 1103 | } |
| 1380 | | 1104 | |
| 1381 | set_debug_source_node(g, node); | | |
| 1382 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, ""); | 1105 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 0, ""); |
| 1383 | LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, ""); | 1106 | LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, ""); |
| 1384 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); | 1107 | LLVMBuildStore(g->builder, slice_start_ptr, ptr_field_ptr); |
| ... | @@ -1400,7 +1123,6 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1400,7 +1123,6 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1400 | | 1123 | |
| 1401 | LLVMValueRef prev_end = nullptr; | 1124 | LLVMValueRef prev_end = nullptr; |
| 1402 | if (!node->data.slice_expr.end || want_debug_safety(g, node)) { | 1125 | if (!node->data.slice_expr.end || want_debug_safety(g, node)) { |
| 1403 | set_debug_source_node(g, node); | | |
| 1404 | LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, len_index, ""); | 1126 | LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, len_index, ""); |
| 1405 | prev_end = LLVMBuildLoad(g->builder, src_len_ptr, ""); | 1127 | prev_end = LLVMBuildLoad(g->builder, src_len_ptr, ""); |
| 1406 | } | 1128 | } |
| ... | @@ -1415,13 +1137,12 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { | ... | @@ -1415,13 +1137,12 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) { |
| 1415 | | 1137 | |
| 1416 | if (want_debug_safety(g, node)) { | 1138 | if (want_debug_safety(g, node)) { |
| 1417 | assert(prev_end); | 1139 | assert(prev_end); |
| 1418 | add_bounds_check(g, node, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); | 1140 | add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); |
| 1419 | if (node->data.slice_expr.end) { | 1141 | if (node->data.slice_expr.end) { |
| 1420 | add_bounds_check(g, node, end_val, LLVMIntEQ, nullptr, LLVMIntULE, prev_end); | 1142 | add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, prev_end); |
| 1421 | } | 1143 | } |
| 1422 | } | 1144 | } |
| 1423 | | 1145 | |
| 1424 | set_debug_source_node(g, node); | | |
| 1425 | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, ptr_index, ""); | 1146 | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, ptr_index, ""); |
| 1426 | LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, ""); | 1147 | LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, ""); |
| 1427 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, ptr_index, ""); | 1148 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, ptr_index, ""); |
| ... | @@ -1461,7 +1182,6 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node, bool is_lva | ... | @@ -1461,7 +1182,6 @@ static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node, bool is_lva |
| 1461 | if (is_lvalue || !ptr || handle_is_ptr(child_type)) { | 1182 | if (is_lvalue || !ptr || handle_is_ptr(child_type)) { |
| 1462 | return ptr; | 1183 | return ptr; |
| 1463 | } else { | 1184 | } else { |
| 1464 | set_debug_source_node(g, node); | | |
| 1465 | return LLVMBuildLoad(g->builder, ptr, ""); | 1185 | return LLVMBuildLoad(g->builder, ptr, ""); |
| 1466 | } | 1186 | } |
| 1467 | } | 1187 | } |
| ... | @@ -1471,7 +1191,7 @@ static LLVMValueRef gen_variable(CodeGen *g, AstNode *source_node, VariableTable | ... | @@ -1471,7 +1191,7 @@ static LLVMValueRef gen_variable(CodeGen *g, AstNode *source_node, VariableTable |
| 1471 | return nullptr; | 1191 | return nullptr; |
| 1472 | } else { | 1192 | } else { |
| 1473 | assert(variable->value_ref); | 1193 | assert(variable->value_ref); |
| 1474 | return get_handle_value(g, source_node, variable->value_ref, variable->type); | 1194 | return get_handle_value(g, variable->value_ref, variable->type); |
| 1475 | } | 1195 | } |
| 1476 | } | 1196 | } |
| 1477 | | 1197 | |
| ... | @@ -1494,7 +1214,6 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lva | ... | @@ -1494,7 +1214,6 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lva |
| 1494 | if (is_lvalue || handle_is_ptr(type_entry)) { | 1214 | if (is_lvalue || handle_is_ptr(type_entry)) { |
| 1495 | return ptr; | 1215 | return ptr; |
| 1496 | } else { | 1216 | } else { |
| 1497 | set_debug_source_node(g, node); | | |
| 1498 | return LLVMBuildLoad(g->builder, ptr, ""); | 1217 | return LLVMBuildLoad(g->builder, ptr, ""); |
| 1499 | } | 1218 | } |
| 1500 | } else if (struct_type->id == TypeTableEntryIdMetaType) { | 1219 | } else if (struct_type->id == TypeTableEntryIdMetaType) { |
| ... | @@ -1631,7 +1350,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1631,7 +1350,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1631 | case PrefixOpNegationWrap: | 1350 | case PrefixOpNegationWrap: |
| 1632 | { | 1351 | { |
| 1633 | LLVMValueRef expr = gen_expr(g, expr_node); | 1352 | LLVMValueRef expr = gen_expr(g, expr_node); |
| 1634 | set_debug_source_node(g, node); | | |
| 1635 | if (expr_type->id == TypeTableEntryIdFloat) { | 1353 | if (expr_type->id == TypeTableEntryIdFloat) { |
| 1636 | return LLVMBuildFNeg(g->builder, expr, ""); | 1354 | return LLVMBuildFNeg(g->builder, expr, ""); |
| 1637 | } else if (expr_type->id == TypeTableEntryIdInt) { | 1355 | } else if (expr_type->id == TypeTableEntryIdInt) { |
| ... | @@ -1653,13 +1371,11 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1653,13 +1371,11 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1653 | { | 1371 | { |
| 1654 | LLVMValueRef expr = gen_expr(g, expr_node); | 1372 | LLVMValueRef expr = gen_expr(g, expr_node); |
| 1655 | LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr)); | 1373 | LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr)); |
| 1656 | set_debug_source_node(g, node); | | |
| 1657 | return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, ""); | 1374 | return LLVMBuildICmp(g->builder, LLVMIntEQ, expr, zero, ""); |
| 1658 | } | 1375 | } |
| 1659 | case PrefixOpBinNot: | 1376 | case PrefixOpBinNot: |
| 1660 | { | 1377 | { |
| 1661 | LLVMValueRef expr = gen_expr(g, expr_node); | 1378 | LLVMValueRef expr = gen_expr(g, expr_node); |
| 1662 | set_debug_source_node(g, node); | | |
| 1663 | return LLVMBuildNot(g->builder, expr, ""); | 1379 | return LLVMBuildNot(g->builder, expr, ""); |
| 1664 | } | 1380 | } |
| 1665 | case PrefixOpAddressOf: | 1381 | case PrefixOpAddressOf: |
| ... | @@ -1677,7 +1393,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1677,7 +1393,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1677 | return nullptr; | 1393 | return nullptr; |
| 1678 | } else { | 1394 | } else { |
| 1679 | TypeTableEntry *child_type = expr_type->data.pointer.child_type; | 1395 | TypeTableEntry *child_type = expr_type->data.pointer.child_type; |
| 1680 | return get_handle_value(g, node, expr, child_type); | 1396 | return get_handle_value(g, expr, child_type); |
| 1681 | } | 1397 | } |
| 1682 | } | 1398 | } |
| 1683 | case PrefixOpMaybe: | 1399 | case PrefixOpMaybe: |
| ... | @@ -1698,13 +1414,11 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1698,13 +1414,11 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1698 | if (want_debug_safety(g, node)) { | 1414 | if (want_debug_safety(g, node)) { |
| 1699 | LLVMValueRef err_val; | 1415 | LLVMValueRef err_val; |
| 1700 | if (type_has_bits(child_type)) { | 1416 | if (type_has_bits(child_type)) { |
| 1701 | set_debug_source_node(g, node); | | |
| 1702 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); | 1417 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); |
| 1703 | err_val = LLVMBuildLoad(g->builder, err_val_ptr, ""); | 1418 | err_val = LLVMBuildLoad(g->builder, err_val_ptr, ""); |
| 1704 | } else { | 1419 | } else { |
| 1705 | err_val = expr_val; | 1420 | err_val = expr_val; |
| 1706 | } | 1421 | } |
| 1707 | set_debug_source_node(g, node); | | |
| 1708 | LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref); | 1422 | LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref); |
| 1709 | LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, ""); | 1423 | LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, ""); |
| 1710 | LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError"); | 1424 | LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError"); |
| ... | @@ -1719,7 +1433,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1719,7 +1433,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1719 | | 1433 | |
| 1720 | if (type_has_bits(child_type)) { | 1434 | if (type_has_bits(child_type)) { |
| 1721 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); | 1435 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); |
| 1722 | return get_handle_value(g, expr_node, child_val_ptr, child_type); | 1436 | return get_handle_value(g, child_val_ptr, child_type); |
| 1723 | } else { | 1437 | } else { |
| 1724 | return nullptr; | 1438 | return nullptr; |
| 1725 | } | 1439 | } |
| ... | @@ -1733,7 +1447,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1733,7 +1447,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1733 | TypeTableEntry *child_type = expr_type->data.maybe.child_type; | 1447 | TypeTableEntry *child_type = expr_type->data.maybe.child_type; |
| 1734 | | 1448 | |
| 1735 | if (want_debug_safety(g, node)) { | 1449 | if (want_debug_safety(g, node)) { |
| 1736 | set_debug_source_node(g, node); | | |
| 1737 | LLVMValueRef cond_val; | 1450 | LLVMValueRef cond_val; |
| 1738 | if (child_type->id == TypeTableEntryIdPointer || | 1451 | if (child_type->id == TypeTableEntryIdPointer || |
| 1739 | child_type->id == TypeTableEntryIdFn) | 1452 | child_type->id == TypeTableEntryIdFn) |
| ... | @@ -1761,9 +1474,8 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1761,9 +1474,8 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1761 | { | 1474 | { |
| 1762 | return expr_val; | 1475 | return expr_val; |
| 1763 | } else { | 1476 | } else { |
| 1764 | set_debug_source_node(g, node); | | |
| 1765 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); | 1477 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); |
| 1766 | return get_handle_value(g, node, maybe_field_ptr, child_type); | 1478 | return get_handle_value(g, maybe_field_ptr, child_type); |
| 1767 | } | 1479 | } |
| 1768 | } | 1480 | } |
| 1769 | } | 1481 | } |
| ... | @@ -1773,7 +1485,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | ... | @@ -1773,7 +1485,6 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| 1773 | static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1, LLVMValueRef val2, | 1485 | static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1, LLVMValueRef val2, |
| 1774 | TypeTableEntry *type_entry, bool exact) | 1486 | TypeTableEntry *type_entry, bool exact) |
| 1775 | { | 1487 | { |
| 1776 | set_debug_source_node(g, source_node); | | |
| 1777 | | 1488 | |
| 1778 | if (want_debug_safety(g, source_node)) { | 1489 | if (want_debug_safety(g, source_node)) { |
| 1779 | LLVMValueRef zero = LLVMConstNull(type_entry->type_ref); | 1490 | LLVMValueRef zero = LLVMConstNull(type_entry->type_ref); |
| ... | @@ -1846,22 +1557,18 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1846,22 +1557,18 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1846 | switch (bin_op) { | 1557 | switch (bin_op) { |
| 1847 | case BinOpTypeBinOr: | 1558 | case BinOpTypeBinOr: |
| 1848 | case BinOpTypeAssignBitOr: | 1559 | case BinOpTypeAssignBitOr: |
| 1849 | set_debug_source_node(g, source_node); | | |
| 1850 | return LLVMBuildOr(g->builder, val1, val2, ""); | 1560 | return LLVMBuildOr(g->builder, val1, val2, ""); |
| 1851 | case BinOpTypeBinXor: | 1561 | case BinOpTypeBinXor: |
| 1852 | case BinOpTypeAssignBitXor: | 1562 | case BinOpTypeAssignBitXor: |
| 1853 | set_debug_source_node(g, source_node); | | |
| 1854 | return LLVMBuildXor(g->builder, val1, val2, ""); | 1563 | return LLVMBuildXor(g->builder, val1, val2, ""); |
| 1855 | case BinOpTypeBinAnd: | 1564 | case BinOpTypeBinAnd: |
| 1856 | case BinOpTypeAssignBitAnd: | 1565 | case BinOpTypeAssignBitAnd: |
| 1857 | set_debug_source_node(g, source_node); | | |
| 1858 | return LLVMBuildAnd(g->builder, val1, val2, ""); | 1566 | return LLVMBuildAnd(g->builder, val1, val2, ""); |
| 1859 | case BinOpTypeBitShiftLeft: | 1567 | case BinOpTypeBitShiftLeft: |
| 1860 | case BinOpTypeBitShiftLeftWrap: | 1568 | case BinOpTypeBitShiftLeftWrap: |
| 1861 | case BinOpTypeAssignBitShiftLeft: | 1569 | case BinOpTypeAssignBitShiftLeft: |
| 1862 | case BinOpTypeAssignBitShiftLeftWrap: | 1570 | case BinOpTypeAssignBitShiftLeftWrap: |
| 1863 | { | 1571 | { |
| 1864 | set_debug_source_node(g, source_node); | | |
| 1865 | assert(op1_type->id == TypeTableEntryIdInt); | 1572 | assert(op1_type->id == TypeTableEntryIdInt); |
| 1866 | bool is_wrapping = (bin_op == BinOpTypeBitShiftLeftWrap) || | 1573 | bool is_wrapping = (bin_op == BinOpTypeBitShiftLeftWrap) || |
| 1867 | (bin_op == BinOpTypeAssignBitShiftLeftWrap); | 1574 | (bin_op == BinOpTypeAssignBitShiftLeftWrap); |
| ... | @@ -1880,7 +1587,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1880,7 +1587,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1880 | assert(op1_type->id == TypeTableEntryIdInt); | 1587 | assert(op1_type->id == TypeTableEntryIdInt); |
| 1881 | assert(op2_type->id == TypeTableEntryIdInt); | 1588 | assert(op2_type->id == TypeTableEntryIdInt); |
| 1882 | | 1589 | |
| 1883 | set_debug_source_node(g, source_node); | | |
| 1884 | if (op1_type->data.integral.is_signed) { | 1590 | if (op1_type->data.integral.is_signed) { |
| 1885 | return LLVMBuildAShr(g->builder, val1, val2, ""); | 1591 | return LLVMBuildAShr(g->builder, val1, val2, ""); |
| 1886 | } else { | 1592 | } else { |
| ... | @@ -1890,7 +1596,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1890,7 +1596,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1890 | case BinOpTypeAddWrap: | 1596 | case BinOpTypeAddWrap: |
| 1891 | case BinOpTypeAssignPlus: | 1597 | case BinOpTypeAssignPlus: |
| 1892 | case BinOpTypeAssignPlusWrap: | 1598 | case BinOpTypeAssignPlusWrap: |
| 1893 | set_debug_source_node(g, source_node); | | |
| 1894 | if (op1_type->id == TypeTableEntryIdFloat) { | 1599 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1895 | return LLVMBuildFAdd(g->builder, val1, val2, ""); | 1600 | return LLVMBuildFAdd(g->builder, val1, val2, ""); |
| 1896 | } else if (op1_type->id == TypeTableEntryIdInt) { | 1601 | } else if (op1_type->id == TypeTableEntryIdInt) { |
| ... | @@ -1911,7 +1616,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1911,7 +1616,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1911 | case BinOpTypeSubWrap: | 1616 | case BinOpTypeSubWrap: |
| 1912 | case BinOpTypeAssignMinus: | 1617 | case BinOpTypeAssignMinus: |
| 1913 | case BinOpTypeAssignMinusWrap: | 1618 | case BinOpTypeAssignMinusWrap: |
| 1914 | set_debug_source_node(g, source_node); | | |
| 1915 | if (op1_type->id == TypeTableEntryIdFloat) { | 1619 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1916 | return LLVMBuildFSub(g->builder, val1, val2, ""); | 1620 | return LLVMBuildFSub(g->builder, val1, val2, ""); |
| 1917 | } else if (op1_type->id == TypeTableEntryIdInt) { | 1621 | } else if (op1_type->id == TypeTableEntryIdInt) { |
| ... | @@ -1932,7 +1636,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1932,7 +1636,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1932 | case BinOpTypeMultWrap: | 1636 | case BinOpTypeMultWrap: |
| 1933 | case BinOpTypeAssignTimes: | 1637 | case BinOpTypeAssignTimes: |
| 1934 | case BinOpTypeAssignTimesWrap: | 1638 | case BinOpTypeAssignTimesWrap: |
| 1935 | set_debug_source_node(g, source_node); | | |
| 1936 | if (op1_type->id == TypeTableEntryIdFloat) { | 1639 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1937 | return LLVMBuildFMul(g->builder, val1, val2, ""); | 1640 | return LLVMBuildFMul(g->builder, val1, val2, ""); |
| 1938 | } else if (op1_type->id == TypeTableEntryIdInt) { | 1641 | } else if (op1_type->id == TypeTableEntryIdInt) { |
| ... | @@ -1954,7 +1657,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, | ... | @@ -1954,7 +1657,6 @@ static LLVMValueRef gen_arithmetic_bin_op(CodeGen *g, AstNode *source_node, |
| 1954 | return gen_div(g, source_node, val1, val2, op1_type, false); | 1657 | return gen_div(g, source_node, val1, val2, op1_type, false); |
| 1955 | case BinOpTypeMod: | 1658 | case BinOpTypeMod: |
| 1956 | case BinOpTypeAssignMod: | 1659 | case BinOpTypeAssignMod: |
| 1957 | set_debug_source_node(g, source_node); | | |
| 1958 | if (op1_type->id == TypeTableEntryIdFloat) { | 1660 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 1959 | return LLVMBuildFRem(g->builder, val1, val2, ""); | 1661 | return LLVMBuildFRem(g->builder, val1, val2, ""); |
| 1960 | } else { | 1662 | } else { |
| ... | @@ -2044,7 +1746,6 @@ static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) { | ... | @@ -2044,7 +1746,6 @@ static LLVMValueRef gen_cmp_expr(CodeGen *g, AstNode *node) { |
| 2044 | TypeTableEntry *op2_type = get_expr_type(node->data.bin_op_expr.op2); | 1746 | TypeTableEntry *op2_type = get_expr_type(node->data.bin_op_expr.op2); |
| 2045 | assert(op1_type == op2_type); | 1747 | assert(op1_type == op2_type); |
| 2046 | | 1748 | |
| 2047 | set_debug_source_node(g, node); | | |
| 2048 | if (op1_type->id == TypeTableEntryIdFloat) { | 1749 | if (op1_type->id == TypeTableEntryIdFloat) { |
| 2049 | LLVMRealPredicate pred = cmp_op_to_real_predicate(node->data.bin_op_expr.bin_op); | 1750 | LLVMRealPredicate pred = cmp_op_to_real_predicate(node->data.bin_op_expr.bin_op); |
| 2050 | return LLVMBuildFCmp(g->builder, pred, val1, val2, ""); | 1751 | return LLVMBuildFCmp(g->builder, pred, val1, val2, ""); |
| ... | @@ -2081,18 +1782,15 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) { | ... | @@ -2081,18 +1782,15 @@ static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) { |
| 2081 | // block for when val1 == false (don't even evaluate the second part) | 1782 | // block for when val1 == false (don't even evaluate the second part) |
| 2082 | LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse"); | 1783 | LLVMBasicBlockRef false_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolAndFalse"); |
| 2083 | | 1784 | |
| 2084 | set_debug_source_node(g, node); | | |
| 2085 | LLVMBuildCondBr(g->builder, val1, true_block, false_block); | 1785 | LLVMBuildCondBr(g->builder, val1, true_block, false_block); |
| 2086 | | 1786 | |
| 2087 | LLVMPositionBuilderAtEnd(g->builder, true_block); | 1787 | LLVMPositionBuilderAtEnd(g->builder, true_block); |
| 2088 | LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2); | 1788 | LLVMValueRef val2 = gen_expr(g, node->data.bin_op_expr.op2); |
| 2089 | LLVMBasicBlockRef post_val2_block = LLVMGetInsertBlock(g->builder); | 1789 | LLVMBasicBlockRef post_val2_block = LLVMGetInsertBlock(g->builder); |
| 2090 | | 1790 | |
| 2091 | set_debug_source_node(g, node); | | |
| 2092 | LLVMBuildBr(g->builder, false_block); | 1791 | LLVMBuildBr(g->builder, false_block); |
| 2093 | | 1792 | |
| 2094 | LLVMPositionBuilderAtEnd(g->builder, false_block); | 1793 | LLVMPositionBuilderAtEnd(g->builder, false_block); |
| 2095 | set_debug_source_node(g, node); | | |
| 2096 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), ""); | 1794 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), ""); |
| 2097 | LLVMValueRef incoming_values[2] = {val1, val2}; | 1795 | LLVMValueRef incoming_values[2] = {val1, val2}; |
| 2098 | LLVMBasicBlockRef incoming_blocks[2] = {post_val1_block, post_val2_block}; | 1796 | LLVMBasicBlockRef incoming_blocks[2] = {post_val1_block, post_val2_block}; |
| ... | @@ -2112,7 +1810,6 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) { | ... | @@ -2112,7 +1810,6 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) { |
| 2112 | // block for when val1 == true (don't even evaluate the second part) | 1810 | // block for when val1 == true (don't even evaluate the second part) |
| 2113 | LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue"); | 1811 | LLVMBasicBlockRef true_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoolOrTrue"); |
| 2114 | | 1812 | |
| 2115 | set_debug_source_node(g, expr_node); | | |
| 2116 | LLVMBuildCondBr(g->builder, val1, true_block, false_block); | 1813 | LLVMBuildCondBr(g->builder, val1, true_block, false_block); |
| 2117 | | 1814 | |
| 2118 | LLVMPositionBuilderAtEnd(g->builder, false_block); | 1815 | LLVMPositionBuilderAtEnd(g->builder, false_block); |
| ... | @@ -2120,11 +1817,9 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) { | ... | @@ -2120,11 +1817,9 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) { |
| 2120 | | 1817 | |
| 2121 | LLVMBasicBlockRef post_val2_block = LLVMGetInsertBlock(g->builder); | 1818 | LLVMBasicBlockRef post_val2_block = LLVMGetInsertBlock(g->builder); |
| 2122 | | 1819 | |
| 2123 | set_debug_source_node(g, expr_node); | | |
| 2124 | LLVMBuildBr(g->builder, true_block); | 1820 | LLVMBuildBr(g->builder, true_block); |
| 2125 | | 1821 | |
| 2126 | LLVMPositionBuilderAtEnd(g->builder, true_block); | 1822 | LLVMPositionBuilderAtEnd(g->builder, true_block); |
| 2127 | set_debug_source_node(g, expr_node); | | |
| 2128 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), ""); | 1823 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMInt1Type(), ""); |
| 2129 | LLVMValueRef incoming_values[2] = {val1, val2}; | 1824 | LLVMValueRef incoming_values[2] = {val1, val2}; |
| 2130 | LLVMBasicBlockRef incoming_blocks[2] = {post_val1_block, post_val2_block}; | 1825 | LLVMBasicBlockRef incoming_blocks[2] = {post_val1_block, post_val2_block}; |
| ... | @@ -2133,14 +1828,13 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) { | ... | @@ -2133,14 +1828,13 @@ static LLVMValueRef gen_bool_or_expr(CodeGen *g, AstNode *expr_node) { |
| 2133 | return phi; | 1828 | return phi; |
| 2134 | } | 1829 | } |
| 2135 | | 1830 | |
| 2136 | static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValueRef src, LLVMValueRef dest, | 1831 | static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef dest, |
| 2137 | TypeTableEntry *type_entry) | 1832 | TypeTableEntry *type_entry) |
| 2138 | { | 1833 | { |
| 2139 | assert(handle_is_ptr(type_entry)); | 1834 | assert(handle_is_ptr(type_entry)); |
| 2140 | | 1835 | |
| 2141 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); | 1836 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| 2142 | | 1837 | |
| 2143 | set_debug_source_node(g, source_node); | | |
| 2144 | LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, ""); | 1838 | LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, ""); |
| 2145 | LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, dest, ptr_u8, ""); | 1839 | LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, dest, ptr_u8, ""); |
| 2146 | | 1840 | |
| ... | @@ -2172,18 +1866,16 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b | ... | @@ -2172,18 +1866,16 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b |
| 2172 | assert(op1_type == op2_type); | 1866 | assert(op1_type == op2_type); |
| 2173 | assert(bin_op == BinOpTypeAssign); | 1867 | assert(bin_op == BinOpTypeAssign); |
| 2174 | | 1868 | |
| 2175 | return gen_struct_memcpy(g, source_node, value, target_ref, op1_type); | 1869 | return gen_struct_memcpy(g, value, target_ref, op1_type); |
| 2176 | } | 1870 | } |
| 2177 | | 1871 | |
| 2178 | if (bin_op != BinOpTypeAssign) { | 1872 | if (bin_op != BinOpTypeAssign) { |
| 2179 | assert(source_node->type == NodeTypeBinOpExpr); | 1873 | assert(source_node->type == NodeTypeBinOpExpr); |
| 2180 | set_debug_source_node(g, source_node->data.bin_op_expr.op1); | | |
| 2181 | LLVMValueRef left_value = LLVMBuildLoad(g->builder, target_ref, ""); | 1874 | LLVMValueRef left_value = LLVMBuildLoad(g->builder, target_ref, ""); |
| 2182 | | 1875 | |
| 2183 | value = gen_arithmetic_bin_op(g, source_node, left_value, value, op1_type, op2_type, bin_op); | 1876 | value = gen_arithmetic_bin_op(g, source_node, left_value, value, op1_type, op2_type, bin_op); |
| 2184 | } | 1877 | } |
| 2185 | | 1878 | |
| 2186 | set_debug_source_node(g, source_node); | | |
| 2187 | LLVMBuildStore(g->builder, value, target_ref); | 1879 | LLVMBuildStore(g->builder, value, target_ref); |
| 2188 | return nullptr; | 1880 | return nullptr; |
| 2189 | } | 1881 | } |
| ... | @@ -2214,9 +1906,8 @@ static LLVMValueRef gen_unwrap_maybe(CodeGen *g, AstNode *node, LLVMValueRef may | ... | @@ -2214,9 +1906,8 @@ static LLVMValueRef gen_unwrap_maybe(CodeGen *g, AstNode *node, LLVMValueRef may |
| 2214 | { | 1906 | { |
| 2215 | return maybe_struct_ref; | 1907 | return maybe_struct_ref; |
| 2216 | } else { | 1908 | } else { |
| 2217 | set_debug_source_node(g, node); | | |
| 2218 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_struct_ref, 0, ""); | 1909 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_struct_ref, 0, ""); |
| 2219 | return get_handle_value(g, node, maybe_field_ptr, child_type); | 1910 | return get_handle_value(g, maybe_field_ptr, child_type); |
| 2220 | } | 1911 | } |
| 2221 | } | 1912 | } |
| 2222 | | 1913 | |
| ... | @@ -2240,7 +1931,6 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { | ... | @@ -2240,7 +1931,6 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { |
| 2240 | cond_value = LLVMBuildICmp(g->builder, LLVMIntNE, maybe_struct_ref, | 1931 | cond_value = LLVMBuildICmp(g->builder, LLVMIntNE, maybe_struct_ref, |
| 2241 | LLVMConstNull(child_type->type_ref), ""); | 1932 | LLVMConstNull(child_type->type_ref), ""); |
| 2242 | } else { | 1933 | } else { |
| 2243 | set_debug_source_node(g, node); | | |
| 2244 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_struct_ref, 1, ""); | 1934 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_struct_ref, 1, ""); |
| 2245 | cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, ""); | 1935 | cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, ""); |
| 2246 | } | 1936 | } |
| ... | @@ -2255,21 +1945,18 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { | ... | @@ -2255,21 +1945,18 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { |
| 2255 | | 1945 | |
| 2256 | LLVMPositionBuilderAtEnd(g->builder, non_null_block); | 1946 | LLVMPositionBuilderAtEnd(g->builder, non_null_block); |
| 2257 | LLVMValueRef non_null_result = gen_unwrap_maybe(g, op1_node, maybe_struct_ref); | 1947 | LLVMValueRef non_null_result = gen_unwrap_maybe(g, op1_node, maybe_struct_ref); |
| 2258 | set_debug_source_node(g, node); | | |
| 2259 | LLVMBuildBr(g->builder, end_block); | 1948 | LLVMBuildBr(g->builder, end_block); |
| 2260 | LLVMBasicBlockRef post_non_null_result_block = LLVMGetInsertBlock(g->builder); | 1949 | LLVMBasicBlockRef post_non_null_result_block = LLVMGetInsertBlock(g->builder); |
| 2261 | | 1950 | |
| 2262 | LLVMPositionBuilderAtEnd(g->builder, null_block); | 1951 | LLVMPositionBuilderAtEnd(g->builder, null_block); |
| 2263 | LLVMValueRef null_result = gen_expr(g, op2_node); | 1952 | LLVMValueRef null_result = gen_expr(g, op2_node); |
| 2264 | if (null_reachable) { | 1953 | if (null_reachable) { |
| 2265 | set_debug_source_node(g, node); | | |
| 2266 | LLVMBuildBr(g->builder, end_block); | 1954 | LLVMBuildBr(g->builder, end_block); |
| 2267 | } | 1955 | } |
| 2268 | LLVMBasicBlockRef post_null_result_block = LLVMGetInsertBlock(g->builder); | 1956 | LLVMBasicBlockRef post_null_result_block = LLVMGetInsertBlock(g->builder); |
| 2269 | | 1957 | |
| 2270 | LLVMPositionBuilderAtEnd(g->builder, end_block); | 1958 | LLVMPositionBuilderAtEnd(g->builder, end_block); |
| 2271 | if (null_reachable) { | 1959 | if (null_reachable) { |
| 2272 | set_debug_source_node(g, node); | | |
| 2273 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(non_null_result), ""); | 1960 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(non_null_result), ""); |
| 2274 | LLVMValueRef incoming_values[2] = {non_null_result, null_result}; | 1961 | LLVMValueRef incoming_values[2] = {non_null_result, null_result}; |
| 2275 | LLVMBasicBlockRef incoming_blocks[2] = {post_non_null_result_block, post_null_result_block}; | 1962 | LLVMBasicBlockRef incoming_blocks[2] = {post_non_null_result_block, post_null_result_block}; |
| ... | @@ -2351,7 +2038,6 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { | ... | @@ -2351,7 +2038,6 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { |
| 2351 | assert(expr_type->id == TypeTableEntryIdErrorUnion); | 2038 | assert(expr_type->id == TypeTableEntryIdErrorUnion); |
| 2352 | TypeTableEntry *child_type = expr_type->data.error.child_type; | 2039 | TypeTableEntry *child_type = expr_type->data.error.child_type; |
| 2353 | LLVMValueRef err_val; | 2040 | LLVMValueRef err_val; |
| 2354 | set_debug_source_node(g, node); | | |
| 2355 | if (handle_is_ptr(expr_type)) { | 2041 | if (handle_is_ptr(expr_type)) { |
| 2356 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); | 2042 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 0, ""); |
| 2357 | err_val = LLVMBuildLoad(g->builder, err_val_ptr, ""); | 2043 | err_val = LLVMBuildLoad(g->builder, err_val_ptr, ""); |
| ... | @@ -2377,7 +2063,6 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { | ... | @@ -2377,7 +2063,6 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { |
| 2377 | LLVMBuildStore(g->builder, err_val, var->value_ref); | 2063 | LLVMBuildStore(g->builder, err_val, var->value_ref); |
| 2378 | } | 2064 | } |
| 2379 | LLVMValueRef err_result = gen_expr(g, op2); | 2065 | LLVMValueRef err_result = gen_expr(g, op2); |
| 2380 | set_debug_source_node(g, node); | | |
| 2381 | if (have_end_block) { | 2066 | if (have_end_block) { |
| 2382 | LLVMBuildBr(g->builder, end_block); | 2067 | LLVMBuildBr(g->builder, end_block); |
| 2383 | } else if (err_reachable) { | 2068 | } else if (err_reachable) { |
| ... | @@ -2389,7 +2074,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { | ... | @@ -2389,7 +2074,7 @@ static LLVMValueRef gen_unwrap_err_expr(CodeGen *g, AstNode *node) { |
| 2389 | return nullptr; | 2074 | return nullptr; |
| 2390 | } | 2075 | } |
| 2391 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); | 2076 | LLVMValueRef child_val_ptr = LLVMBuildStructGEP(g->builder, expr_val, 1, ""); |
| 2392 | LLVMValueRef child_val = get_handle_value(g, node, child_val_ptr, child_type); | 2077 | LLVMValueRef child_val = get_handle_value(g, child_val_ptr, child_type); |
| 2393 | | 2078 | |
| 2394 | if (!have_end_block) { | 2079 | if (!have_end_block) { |
| 2395 | return child_val; | 2080 | return child_val; |
| ... | @@ -2452,17 +2137,14 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va | ... | @@ -2452,17 +2137,14 @@ static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef va |
| 2452 | bool is_extern = g->cur_fn->type_entry->data.fn.fn_type_id.is_extern; | 2137 | bool is_extern = g->cur_fn->type_entry->data.fn.fn_type_id.is_extern; |
| 2453 | if (handle_is_ptr(return_type)) { | 2138 | if (handle_is_ptr(return_type)) { |
| 2454 | if (is_extern) { | 2139 | if (is_extern) { |
| 2455 | set_debug_source_node(g, source_node); | | |
| 2456 | LLVMValueRef by_val_value = LLVMBuildLoad(g->builder, value, ""); | 2140 | LLVMValueRef by_val_value = LLVMBuildLoad(g->builder, value, ""); |
| 2457 | LLVMBuildRet(g->builder, by_val_value); | 2141 | LLVMBuildRet(g->builder, by_val_value); |
| 2458 | } else { | 2142 | } else { |
| 2459 | assert(g->cur_ret_ptr); | 2143 | assert(g->cur_ret_ptr); |
| 2460 | gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type); | 2144 | gen_assign_raw(g, source_node, BinOpTypeAssign, g->cur_ret_ptr, value, return_type, return_type); |
| 2461 | set_debug_source_node(g, source_node); | | |
| 2462 | LLVMBuildRetVoid(g->builder); | 2145 | LLVMBuildRetVoid(g->builder); |
| 2463 | } | 2146 | } |
| 2464 | } else { | 2147 | } else { |
| 2465 | set_debug_source_node(g, source_node); | | |
| 2466 | LLVMBuildRet(g->builder, value); | 2148 | LLVMBuildRet(g->builder, value); |
| 2467 | } | 2149 | } |
| 2468 | return nullptr; | 2150 | return nullptr; |
| ... | @@ -2504,7 +2186,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { | ... | @@ -2504,7 +2186,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |
| 2504 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetReturn"); | 2186 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetReturn"); |
| 2505 | LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetContinue"); | 2187 | LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "ErrRetContinue"); |
| 2506 | | 2188 | |
| 2507 | set_debug_source_node(g, node); | | |
| 2508 | LLVMValueRef err_val; | 2189 | LLVMValueRef err_val; |
| 2509 | if (type_has_bits(child_type)) { | 2190 | if (type_has_bits(child_type)) { |
| 2510 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, ""); | 2191 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, value, 0, ""); |
| ... | @@ -2524,7 +2205,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { | ... | @@ -2524,7 +2205,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |
| 2524 | if (type_has_bits(return_type->data.error.child_type)) { | 2205 | if (type_has_bits(return_type->data.error.child_type)) { |
| 2525 | assert(g->cur_ret_ptr); | 2206 | assert(g->cur_ret_ptr); |
| 2526 | | 2207 | |
| 2527 | set_debug_source_node(g, node); | | |
| 2528 | LLVMValueRef tag_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 0, ""); | 2208 | LLVMValueRef tag_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 0, ""); |
| 2529 | LLVMBuildStore(g->builder, err_val, tag_ptr); | 2209 | LLVMBuildStore(g->builder, err_val, tag_ptr); |
| 2530 | LLVMBuildRetVoid(g->builder); | 2210 | LLVMBuildRetVoid(g->builder); |
| ... | @@ -2537,9 +2217,8 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { | ... | @@ -2537,9 +2217,8 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |
| 2537 | | 2217 | |
| 2538 | LLVMPositionBuilderAtEnd(g->builder, continue_block); | 2218 | LLVMPositionBuilderAtEnd(g->builder, continue_block); |
| 2539 | if (type_has_bits(child_type)) { | 2219 | if (type_has_bits(child_type)) { |
| 2540 | set_debug_source_node(g, node); | | |
| 2541 | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 1, ""); | 2220 | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 1, ""); |
| 2542 | return get_handle_value(g, node, val_ptr, child_type); | 2221 | return get_handle_value(g, val_ptr, child_type); |
| 2543 | } else { | 2222 | } else { |
| 2544 | return nullptr; | 2223 | return nullptr; |
| 2545 | } | 2224 | } |
| ... | @@ -2552,7 +2231,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { | ... | @@ -2552,7 +2231,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |
| 2552 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeRetReturn"); | 2231 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeRetReturn"); |
| 2553 | LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeRetContinue"); | 2232 | LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeRetContinue"); |
| 2554 | | 2233 | |
| 2555 | set_debug_source_node(g, node); | | |
| 2556 | LLVMValueRef maybe_val_ptr = LLVMBuildStructGEP(g->builder, value, 1, ""); | 2234 | LLVMValueRef maybe_val_ptr = LLVMBuildStructGEP(g->builder, value, 1, ""); |
| 2557 | LLVMValueRef is_non_null = LLVMBuildLoad(g->builder, maybe_val_ptr, ""); | 2235 | LLVMValueRef is_non_null = LLVMBuildLoad(g->builder, maybe_val_ptr, ""); |
| 2558 | | 2236 | |
| ... | @@ -2566,7 +2244,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { | ... | @@ -2566,7 +2244,6 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |
| 2566 | if (handle_is_ptr(return_type)) { | 2244 | if (handle_is_ptr(return_type)) { |
| 2567 | assert(g->cur_ret_ptr); | 2245 | assert(g->cur_ret_ptr); |
| 2568 | | 2246 | |
| 2569 | set_debug_source_node(g, node); | | |
| 2570 | LLVMValueRef maybe_bit_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 1, ""); | 2247 | LLVMValueRef maybe_bit_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 1, ""); |
| 2571 | LLVMBuildStore(g->builder, zero, maybe_bit_ptr); | 2248 | LLVMBuildStore(g->builder, zero, maybe_bit_ptr); |
| 2572 | LLVMBuildRetVoid(g->builder); | 2249 | LLVMBuildRetVoid(g->builder); |
| ... | @@ -2577,9 +2254,8 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { | ... | @@ -2577,9 +2254,8 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { |
| 2577 | | 2254 | |
| 2578 | LLVMPositionBuilderAtEnd(g->builder, continue_block); | 2255 | LLVMPositionBuilderAtEnd(g->builder, continue_block); |
| 2579 | if (type_has_bits(child_type)) { | 2256 | if (type_has_bits(child_type)) { |
| 2580 | set_debug_source_node(g, node); | | |
| 2581 | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 0, ""); | 2257 | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, value, 0, ""); |
| 2582 | return get_handle_value(g, node, val_ptr, child_type); | 2258 | return get_handle_value(g, val_ptr, child_type); |
| 2583 | } else { | 2259 | } else { |
| 2584 | return nullptr; | 2260 | return nullptr; |
| 2585 | } | 2261 | } |
| ... | @@ -2610,7 +2286,6 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV | ... | @@ -2610,7 +2286,6 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV |
| 2610 | endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf"); | 2286 | endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf"); |
| 2611 | } | 2287 | } |
| 2612 | | 2288 | |
| 2613 | set_debug_source_node(g, source_node); | | |
| 2614 | LLVMBuildCondBr(g->builder, cond_value, then_block, else_block); | 2289 | LLVMBuildCondBr(g->builder, cond_value, then_block, else_block); |
| 2615 | | 2290 | |
| 2616 | LLVMPositionBuilderAtEnd(g->builder, then_block); | 2291 | LLVMPositionBuilderAtEnd(g->builder, then_block); |
| ... | @@ -2632,7 +2307,6 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV | ... | @@ -2632,7 +2307,6 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV |
| 2632 | if (then_endif_reachable || else_endif_reachable) { | 2307 | if (then_endif_reachable || else_endif_reachable) { |
| 2633 | LLVMPositionBuilderAtEnd(g->builder, endif_block); | 2308 | LLVMPositionBuilderAtEnd(g->builder, endif_block); |
| 2634 | if (use_then_value && use_else_value) { | 2309 | if (use_then_value && use_else_value) { |
| 2635 | set_debug_source_node(g, source_node); | | |
| 2636 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), ""); | 2310 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), ""); |
| 2637 | LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result}; | 2311 | LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result}; |
| 2638 | LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block}; | 2312 | LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block}; |
| ... | @@ -2697,7 +2371,7 @@ static LLVMValueRef gen_if_var_then_block(CodeGen *g, AstNode *node, VariableTab | ... | @@ -2697,7 +2371,7 @@ static LLVMValueRef gen_if_var_then_block(CodeGen *g, AstNode *node, VariableTab |
| 2697 | payload_val = init_val; | 2371 | payload_val = init_val; |
| 2698 | } else { | 2372 | } else { |
| 2699 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, init_val, 0, ""); | 2373 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, init_val, 0, ""); |
| 2700 | payload_val = get_handle_value(g, node, payload_ptr, child_type); | 2374 | payload_val = get_handle_value(g, payload_ptr, child_type); |
| 2701 | } | 2375 | } |
| 2702 | gen_assign_raw(g, node, BinOpTypeAssign, variable->value_ref, payload_val, | 2376 | gen_assign_raw(g, node, BinOpTypeAssign, variable->value_ref, payload_val, |
| 2703 | variable->type, child_type); | 2377 | variable->type, child_type); |
| ... | @@ -2736,10 +2410,8 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { | ... | @@ -2736,10 +2410,8 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { |
| 2736 | | 2410 | |
| 2737 | LLVMValueRef cond_value; | 2411 | LLVMValueRef cond_value; |
| 2738 | if (maybe_is_ptr) { | 2412 | if (maybe_is_ptr) { |
| 2739 | set_debug_source_node(g, node); | | |
| 2740 | cond_value = LLVMBuildICmp(g->builder, LLVMIntNE, init_val, LLVMConstNull(child_type->type_ref), ""); | 2413 | cond_value = LLVMBuildICmp(g->builder, LLVMIntNE, init_val, LLVMConstNull(child_type->type_ref), ""); |
| 2741 | } else { | 2414 | } else { |
| 2742 | set_debug_source_node(g, node); | | |
| 2743 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, init_val, 1, ""); | 2415 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, init_val, 1, ""); |
| 2744 | cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, ""); | 2416 | cond_value = LLVMBuildLoad(g->builder, maybe_field_ptr, ""); |
| 2745 | } | 2417 | } |
| ... | @@ -2760,7 +2432,6 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { | ... | @@ -2760,7 +2432,6 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) { |
| 2760 | endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeEndIf"); | 2432 | endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "MaybeEndIf"); |
| 2761 | } | 2433 | } |
| 2762 | | 2434 | |
| 2763 | set_debug_source_node(g, node); | | |
| 2764 | LLVMBuildCondBr(g->builder, cond_value, then_block, else_block); | 2435 | LLVMBuildCondBr(g->builder, cond_value, then_block, else_block); |
| 2765 | | 2436 | |
| 2766 | LLVMPositionBuilderAtEnd(g->builder, then_block); | 2437 | LLVMPositionBuilderAtEnd(g->builder, then_block); |
| ... | @@ -2810,7 +2481,7 @@ static LLVMValueRef ir_render_load_var(CodeGen *g, IrExecutable *executable, | ... | @@ -2810,7 +2481,7 @@ static LLVMValueRef ir_render_load_var(CodeGen *g, IrExecutable *executable, |
| 2810 | return nullptr; | 2481 | return nullptr; |
| 2811 | | 2482 | |
| 2812 | assert(var->value_ref); | 2483 | assert(var->value_ref); |
| 2813 | return get_handle_value(g, load_var_instruction->base.source_node, var->value_ref, var->type); | 2484 | return get_handle_value(g, var->value_ref, var->type); |
| 2814 | } | 2485 | } |
| 2815 | | 2486 | |
| 2816 | static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable, | 2487 | static LLVMValueRef ir_render_bin_op_bool(CodeGen *g, IrExecutable *executable, |
| ... | @@ -2894,6 +2565,233 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, | ... | @@ -2894,6 +2565,233 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, |
| 2894 | zig_unreachable(); | 2565 | zig_unreachable(); |
| 2895 | } | 2566 | } |
| 2896 | | 2567 | |
| | 2568 | static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| | 2569 | IrInstructionCast *cast_instruction) |
| | 2570 | { |
| | 2571 | TypeTableEntry *actual_type = cast_instruction->value->type_entry; |
| | 2572 | TypeTableEntry *wanted_type = cast_instruction->base.type_entry; |
| | 2573 | LLVMValueRef expr_val = cast_instruction->value->llvm_value; |
| | 2574 | assert(expr_val); |
| | 2575 | |
| | 2576 | switch (cast_instruction->cast_op) { |
| | 2577 | case CastOpNoCast: |
| | 2578 | zig_unreachable(); |
| | 2579 | case CastOpNoop: |
| | 2580 | return expr_val; |
| | 2581 | case CastOpErrToInt: |
| | 2582 | assert(actual_type->id == TypeTableEntryIdErrorUnion); |
| | 2583 | if (!type_has_bits(actual_type->data.error.child_type)) { |
| | 2584 | return gen_widen_or_shorten(g, cast_instruction->base.source_node, |
| | 2585 | g->err_tag_type, wanted_type, expr_val); |
| | 2586 | } else { |
| | 2587 | zig_panic("TODO"); |
| | 2588 | } |
| | 2589 | case CastOpMaybeWrap: |
| | 2590 | { |
| | 2591 | assert(cast_instruction->tmp_ptr); |
| | 2592 | assert(wanted_type->id == TypeTableEntryIdMaybe); |
| | 2593 | assert(actual_type); |
| | 2594 | |
| | 2595 | TypeTableEntry *child_type = wanted_type->data.maybe.child_type; |
| | 2596 | |
| | 2597 | if (child_type->id == TypeTableEntryIdPointer || |
| | 2598 | child_type->id == TypeTableEntryIdFn) |
| | 2599 | { |
| | 2600 | return expr_val; |
| | 2601 | } else { |
| | 2602 | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 0, ""); |
| | 2603 | gen_assign_raw(g, cast_instruction->base.source_node, BinOpTypeAssign, |
| | 2604 | val_ptr, expr_val, child_type, actual_type); |
| | 2605 | |
| | 2606 | LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 1, ""); |
| | 2607 | LLVMBuildStore(g->builder, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr); |
| | 2608 | } |
| | 2609 | |
| | 2610 | return cast_instruction->tmp_ptr; |
| | 2611 | } |
| | 2612 | case CastOpNullToMaybe: |
| | 2613 | // handled by constant expression evaluator |
| | 2614 | zig_unreachable(); |
| | 2615 | case CastOpErrorWrap: |
| | 2616 | { |
| | 2617 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); |
| | 2618 | TypeTableEntry *child_type = wanted_type->data.error.child_type; |
| | 2619 | LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref); |
| | 2620 | |
| | 2621 | if (!type_has_bits(child_type)) { |
| | 2622 | return ok_err_val; |
| | 2623 | } else { |
| | 2624 | assert(cast_instruction->tmp_ptr); |
| | 2625 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); |
| | 2626 | assert(actual_type); |
| | 2627 | |
| | 2628 | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 0, ""); |
| | 2629 | LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr); |
| | 2630 | |
| | 2631 | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, 1, ""); |
| | 2632 | gen_assign_raw(g, cast_instruction->base.source_node, BinOpTypeAssign, |
| | 2633 | payload_ptr, expr_val, child_type, actual_type); |
| | 2634 | |
| | 2635 | return cast_instruction->tmp_ptr; |
| | 2636 | } |
| | 2637 | } |
| | 2638 | case CastOpPureErrorWrap: |
| | 2639 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); |
| | 2640 | |
| | 2641 | if (!type_has_bits(wanted_type->data.error.child_type)) { |
| | 2642 | return expr_val; |
| | 2643 | } else { |
| | 2644 | zig_panic("TODO"); |
| | 2645 | } |
| | 2646 | case CastOpPtrToInt: |
| | 2647 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2648 | case CastOpIntToPtr: |
| | 2649 | return LLVMBuildIntToPtr(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2650 | case CastOpPointerReinterpret: |
| | 2651 | return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2652 | case CastOpWidenOrShorten: |
| | 2653 | return gen_widen_or_shorten(g, cast_instruction->base.source_node, actual_type, wanted_type, expr_val); |
| | 2654 | case CastOpToUnknownSizeArray: |
| | 2655 | { |
| | 2656 | assert(cast_instruction->tmp_ptr); |
| | 2657 | assert(wanted_type->id == TypeTableEntryIdStruct); |
| | 2658 | assert(wanted_type->data.structure.is_slice); |
| | 2659 | |
| | 2660 | TypeTableEntry *pointer_type = wanted_type->data.structure.fields[0].type_entry; |
| | 2661 | |
| | 2662 | |
| | 2663 | size_t ptr_index = wanted_type->data.structure.fields[0].gen_index; |
| | 2664 | if (ptr_index != SIZE_MAX) { |
| | 2665 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, ptr_index, ""); |
| | 2666 | LLVMValueRef expr_bitcast = LLVMBuildBitCast(g->builder, expr_val, pointer_type->type_ref, ""); |
| | 2667 | LLVMBuildStore(g->builder, expr_bitcast, ptr_ptr); |
| | 2668 | } |
| | 2669 | |
| | 2670 | size_t len_index = wanted_type->data.structure.fields[1].gen_index; |
| | 2671 | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, len_index, ""); |
| | 2672 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, |
| | 2673 | actual_type->data.array.len, false); |
| | 2674 | LLVMBuildStore(g->builder, len_val, len_ptr); |
| | 2675 | |
| | 2676 | return cast_instruction->tmp_ptr; |
| | 2677 | } |
| | 2678 | case CastOpResizeSlice: |
| | 2679 | { |
| | 2680 | assert(cast_instruction->tmp_ptr); |
| | 2681 | assert(wanted_type->id == TypeTableEntryIdStruct); |
| | 2682 | assert(wanted_type->data.structure.is_slice); |
| | 2683 | assert(actual_type->id == TypeTableEntryIdStruct); |
| | 2684 | assert(actual_type->data.structure.is_slice); |
| | 2685 | |
| | 2686 | TypeTableEntry *actual_pointer_type = actual_type->data.structure.fields[0].type_entry; |
| | 2687 | TypeTableEntry *actual_child_type = actual_pointer_type->data.pointer.child_type; |
| | 2688 | TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; |
| | 2689 | TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; |
| | 2690 | |
| | 2691 | |
| | 2692 | size_t actual_ptr_index = actual_type->data.structure.fields[0].gen_index; |
| | 2693 | size_t actual_len_index = actual_type->data.structure.fields[1].gen_index; |
| | 2694 | size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index; |
| | 2695 | size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index; |
| | 2696 | |
| | 2697 | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_ptr_index, ""); |
| | 2698 | LLVMValueRef src_ptr = LLVMBuildLoad(g->builder, src_ptr_ptr, ""); |
| | 2699 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, |
| | 2700 | wanted_type->data.structure.fields[0].type_entry->type_ref, ""); |
| | 2701 | LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, |
| | 2702 | wanted_ptr_index, ""); |
| | 2703 | LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr); |
| | 2704 | |
| | 2705 | LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, actual_len_index, ""); |
| | 2706 | LLVMValueRef src_len = LLVMBuildLoad(g->builder, src_len_ptr, ""); |
| | 2707 | uint64_t src_size = type_size(g, actual_child_type); |
| | 2708 | uint64_t dest_size = type_size(g, wanted_child_type); |
| | 2709 | |
| | 2710 | LLVMValueRef new_len; |
| | 2711 | if (dest_size == 1) { |
| | 2712 | LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, src_size, false); |
| | 2713 | new_len = LLVMBuildMul(g->builder, src_len, src_size_val, ""); |
| | 2714 | } else if (src_size == 1) { |
| | 2715 | LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false); |
| | 2716 | if (ir_want_debug_safety(g, &cast_instruction->base)) { |
| | 2717 | LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, ""); |
| | 2718 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref); |
| | 2719 | LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, ""); |
| | 2720 | LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenOk"); |
| | 2721 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenFail"); |
| | 2722 | LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); |
| | 2723 | |
| | 2724 | LLVMPositionBuilderAtEnd(g->builder, fail_block); |
| | 2725 | gen_debug_safety_crash(g); |
| | 2726 | |
| | 2727 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| | 2728 | } |
| | 2729 | new_len = ZigLLVMBuildExactUDiv(g->builder, src_len, dest_size_val, ""); |
| | 2730 | } else { |
| | 2731 | zig_unreachable(); |
| | 2732 | } |
| | 2733 | |
| | 2734 | LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, |
| | 2735 | wanted_len_index, ""); |
| | 2736 | LLVMBuildStore(g->builder, new_len, dest_len_ptr); |
| | 2737 | |
| | 2738 | |
| | 2739 | return cast_instruction->tmp_ptr; |
| | 2740 | } |
| | 2741 | case CastOpBytesToSlice: |
| | 2742 | { |
| | 2743 | assert(cast_instruction->tmp_ptr); |
| | 2744 | assert(wanted_type->id == TypeTableEntryIdStruct); |
| | 2745 | assert(wanted_type->data.structure.is_slice); |
| | 2746 | assert(actual_type->id == TypeTableEntryIdArray); |
| | 2747 | |
| | 2748 | TypeTableEntry *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; |
| | 2749 | TypeTableEntry *wanted_child_type = wanted_pointer_type->data.pointer.child_type; |
| | 2750 | |
| | 2751 | |
| | 2752 | size_t wanted_ptr_index = wanted_type->data.structure.fields[0].gen_index; |
| | 2753 | LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, wanted_ptr_index, ""); |
| | 2754 | LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, expr_val, wanted_pointer_type->type_ref, ""); |
| | 2755 | LLVMBuildStore(g->builder, src_ptr_casted, dest_ptr_ptr); |
| | 2756 | |
| | 2757 | size_t wanted_len_index = wanted_type->data.structure.fields[1].gen_index; |
| | 2758 | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr, wanted_len_index, ""); |
| | 2759 | LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, |
| | 2760 | actual_type->data.array.len / type_size(g, wanted_child_type), false); |
| | 2761 | LLVMBuildStore(g->builder, len_val, len_ptr); |
| | 2762 | |
| | 2763 | return cast_instruction->tmp_ptr; |
| | 2764 | } |
| | 2765 | case CastOpIntToFloat: |
| | 2766 | assert(actual_type->id == TypeTableEntryIdInt); |
| | 2767 | if (actual_type->data.integral.is_signed) { |
| | 2768 | return LLVMBuildSIToFP(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2769 | } else { |
| | 2770 | return LLVMBuildUIToFP(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2771 | } |
| | 2772 | case CastOpFloatToInt: |
| | 2773 | assert(wanted_type->id == TypeTableEntryIdInt); |
| | 2774 | if (wanted_type->data.integral.is_signed) { |
| | 2775 | return LLVMBuildFPToSI(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2776 | } else { |
| | 2777 | return LLVMBuildFPToUI(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2778 | } |
| | 2779 | |
| | 2780 | case CastOpBoolToInt: |
| | 2781 | assert(wanted_type->id == TypeTableEntryIdInt); |
| | 2782 | assert(actual_type->id == TypeTableEntryIdBool); |
| | 2783 | return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, ""); |
| | 2784 | |
| | 2785 | case CastOpIntToEnum: |
| | 2786 | return gen_widen_or_shorten(g, cast_instruction->base.source_node, |
| | 2787 | actual_type, wanted_type->data.enumeration.tag_type, expr_val); |
| | 2788 | case CastOpEnumToInt: |
| | 2789 | return gen_widen_or_shorten(g, cast_instruction->base.source_node, |
| | 2790 | actual_type->data.enumeration.tag_type, wanted_type, expr_val); |
| | 2791 | } |
| | 2792 | zig_unreachable(); |
| | 2793 | } |
| | 2794 | |
| 2897 | static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { | 2795 | static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { |
| 2898 | set_debug_source_node(g, instruction->source_node); | 2796 | set_debug_source_node(g, instruction->source_node); |
| 2899 | switch (instruction->id) { | 2797 | switch (instruction->id) { |
| ... | @@ -2907,13 +2805,14 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -2907,13 +2805,14 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 2907 | return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction); | 2805 | return ir_render_load_var(g, executable, (IrInstructionLoadVar *)instruction); |
| 2908 | case IrInstructionIdBinOp: | 2806 | case IrInstructionIdBinOp: |
| 2909 | return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction); | 2807 | return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction); |
| | 2808 | case IrInstructionIdCast: |
| | 2809 | return ir_render_cast(g, executable, (IrInstructionCast *)instruction); |
| 2910 | case IrInstructionIdCondBr: | 2810 | case IrInstructionIdCondBr: |
| 2911 | case IrInstructionIdSwitchBr: | 2811 | case IrInstructionIdSwitchBr: |
| 2912 | case IrInstructionIdPhi: | 2812 | case IrInstructionIdPhi: |
| 2913 | case IrInstructionIdStoreVar: | 2813 | case IrInstructionIdStoreVar: |
| 2914 | case IrInstructionIdCall: | 2814 | case IrInstructionIdCall: |
| 2915 | case IrInstructionIdBuiltinCall: | 2815 | case IrInstructionIdBuiltinCall: |
| 2916 | case IrInstructionIdCast: | | |
| 2917 | zig_panic("TODO render more IR instructions to LLVM"); | 2816 | zig_panic("TODO render more IR instructions to LLVM"); |
| 2918 | } | 2817 | } |
| 2919 | zig_unreachable(); | 2818 | zig_unreachable(); |
| ... | @@ -3592,7 +3491,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | ... | @@ -3592,7 +3491,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 3592 | 1, ""); | 3491 | 1, ""); |
| 3593 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, | 3492 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, |
| 3594 | LLVMPointerType(enum_field->type_entry->type_ref, 0), ""); | 3493 | LLVMPointerType(enum_field->type_entry->type_ref, 0), ""); |
| 3595 | LLVMValueRef handle_val = get_handle_value(g, var_node, bitcasted_union_field_ptr, | 3494 | LLVMValueRef handle_val = get_handle_value(g, bitcasted_union_field_ptr, |
| 3596 | enum_field->type_entry); | 3495 | enum_field->type_entry); |
| 3597 | | 3496 | |
| 3598 | gen_assign_raw(g, var_node, BinOpTypeAssign, | 3497 | gen_assign_raw(g, var_node, BinOpTypeAssign, |
| ... | @@ -3602,8 +3501,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { | ... | @@ -3602,8 +3501,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { |
| 3602 | // variable is the payload | 3501 | // variable is the payload |
| 3603 | LLVMValueRef err_payload_ptr = LLVMBuildStructGEP(g->builder, | 3502 | LLVMValueRef err_payload_ptr = LLVMBuildStructGEP(g->builder, |
| 3604 | target_value_handle, 1, ""); | 3503 | target_value_handle, 1, ""); |
| 3605 | LLVMValueRef handle_val = get_handle_value(g, var_node, | 3504 | LLVMValueRef handle_val = get_handle_value(g, err_payload_ptr, prong_var->type); |
| 3606 | err_payload_ptr, prong_var->type); | | |
| 3607 | gen_assign_raw(g, var_node, BinOpTypeAssign, | 3505 | gen_assign_raw(g, var_node, BinOpTypeAssign, |
| 3608 | prong_var->value_ref, handle_val, prong_var->type, prong_var->type); | 3506 | prong_var->value_ref, handle_val, prong_var->type, prong_var->type); |
| 3609 | } else { | 3507 | } else { |
| ... | @@ -4375,10 +4273,8 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -4375,10 +4273,8 @@ static void do_code_gen(CodeGen *g) { |
| 4375 | | 4273 | |
| 4376 | // allocate structs which are the result of casts | 4274 | // allocate structs which are the result of casts |
| 4377 | for (size_t cea_i = 0; cea_i < fn_table_entry->cast_alloca_list.length; cea_i += 1) { | 4275 | for (size_t cea_i = 0; cea_i < fn_table_entry->cast_alloca_list.length; cea_i += 1) { |
| 4378 | AstNode *fn_call_node = fn_table_entry->cast_alloca_list.at(cea_i); | 4276 | IrInstructionCast *cast_instruction = fn_table_entry->cast_alloca_list.at(cea_i); |
| 4379 | Expr *expr = &fn_call_node->data.fn_call_expr.resolved_expr; | 4277 | cast_instruction->tmp_ptr = LLVMBuildAlloca(g->builder, cast_instruction->base.type_entry->type_ref, ""); |
| 4380 | fn_call_node->data.fn_call_expr.tmp_ptr = LLVMBuildAlloca(g->builder, | | |
| 4381 | expr->type_entry->type_ref, ""); | | |
| 4382 | } | 4278 | } |
| 4383 | | 4279 | |
| 4384 | // allocate structs which are struct value expressions | 4280 | // allocate structs which are struct value expressions |