| ... | ... | @@ -200,6 +200,8 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo |
| 200 | 200 | static void ir_reset_result(ResultLoc *result_loc); |
| 201 | 201 | static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, |
| 202 | 202 | Scope *scope, AstNode *source_node, Buf *out_bare_name); |
| 203 | static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, |
| 204 | ResultLoc *parent_result_loc); |
| 203 | 205 | |
| 204 | 206 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 205 | 207 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -2766,6 +2768,18 @@ static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *sourc |
| 2766 | 2768 | return &instruction->base; |
| 2767 | 2769 | } |
| 2768 | 2770 | |
| 2771 | static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2772 | IrInstruction *operand, ResultLocCast *result_loc_cast) |
| 2773 | { |
| 2774 | IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); |
| 2775 | instruction->operand = operand; |
| 2776 | instruction->result_loc_cast = result_loc_cast; |
| 2777 | |
| 2778 | ir_ref_instruction(operand, irb->current_basic_block); |
| 2779 | |
| 2780 | return &instruction->base; |
| 2781 | } |
| 2782 | |
| 2769 | 2783 | static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2770 | 2784 | IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) |
| 2771 | 2785 | { |
| ... | ... | @@ -3063,20 +3077,6 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode |
| 3063 | 3077 | return &instruction->base; |
| 3064 | 3078 | } |
| 3065 | 3079 | |
| 3066 | | static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3067 | | IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc) |
| 3068 | | { |
| 3069 | | IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node); |
| 3070 | | instruction->dest_type = dest_type; |
| 3071 | | instruction->target = target; |
| 3072 | | instruction->result_loc = result_loc; |
| 3073 | | |
| 3074 | | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 3075 | | ir_ref_instruction(target, irb->current_basic_block); |
| 3076 | | |
| 3077 | | return &instruction->base; |
| 3078 | | } |
| 3079 | | |
| 3080 | 3080 | static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3081 | 3081 | ResultLoc *result_loc, IrInstruction *ty) |
| 3082 | 3082 | { |
| ... | ... | @@ -5374,6 +5374,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5374 | 5374 | IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); |
| 5375 | 5375 | return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); |
| 5376 | 5376 | } |
| 5377 | case BuiltinFnIdAs: |
| 5378 | { |
| 5379 | AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); |
| 5380 | IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); |
| 5381 | if (dest_type == irb->codegen->invalid_instruction) |
| 5382 | return dest_type; |
| 5383 | |
| 5384 | ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); |
| 5385 | |
| 5386 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); |
| 5387 | IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, |
| 5388 | &result_loc_cast->base); |
| 5389 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5390 | return arg1_value; |
| 5391 | |
| 5392 | IrInstruction *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); |
| 5393 | return ir_lval_wrap(irb, scope, result, lval, result_loc); |
| 5394 | } |
| 5377 | 5395 | case BuiltinFnIdIntToPtr: |
| 5378 | 5396 | { |
| 5379 | 5397 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -6214,6 +6232,20 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo |
| 6214 | 6232 | return result_loc_var; |
| 6215 | 6233 | } |
| 6216 | 6234 | |
| 6235 | static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, |
| 6236 | ResultLoc *parent_result_loc) |
| 6237 | { |
| 6238 | ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); |
| 6239 | result_loc_cast->base.id = ResultLocIdCast; |
| 6240 | result_loc_cast->base.source_instruction = dest_type; |
| 6241 | ir_ref_instruction(dest_type, irb->current_basic_block); |
| 6242 | result_loc_cast->parent = parent_result_loc; |
| 6243 | |
| 6244 | ir_build_reset_result(irb, dest_type->scope, dest_type->source_node, &result_loc_cast->base); |
| 6245 | |
| 6246 | return result_loc_cast; |
| 6247 | } |
| 6248 | |
| 6217 | 6249 | static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, |
| 6218 | 6250 | IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) |
| 6219 | 6251 | { |
| ... | ... | @@ -6282,7 +6314,15 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6282 | 6314 | |
| 6283 | 6315 | // Create a result location for the initialization expression. |
| 6284 | 6316 | ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); |
| 6285 | | ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; |
| 6317 | ResultLoc *init_result_loc; |
| 6318 | ResultLocCast *result_loc_cast; |
| 6319 | if (type_instruction != nullptr) { |
| 6320 | result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base); |
| 6321 | init_result_loc = &result_loc_cast->base; |
| 6322 | } else { |
| 6323 | result_loc_cast = nullptr; |
| 6324 | init_result_loc = &result_loc_var->base; |
| 6325 | } |
| 6286 | 6326 | |
| 6287 | 6327 | Scope *init_scope = is_comptime_scalar ? |
| 6288 | 6328 | create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; |
| ... | ... | @@ -6298,9 +6338,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6298 | 6338 | if (init_value == irb->codegen->invalid_instruction) |
| 6299 | 6339 | return irb->codegen->invalid_instruction; |
| 6300 | 6340 | |
| 6301 | | if (type_instruction != nullptr) { |
| 6302 | | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value, |
| 6303 | | &result_loc_var->base); |
| 6341 | if (result_loc_cast != nullptr) { |
| 6342 | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, init_value, result_loc_cast); |
| 6304 | 6343 | ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); |
| 6305 | 6344 | } |
| 6306 | 6345 | |
| ... | ... | @@ -15435,6 +15474,7 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspe |
| 15435 | 15474 | case ResultLocIdNone: |
| 15436 | 15475 | case ResultLocIdVar: |
| 15437 | 15476 | case ResultLocIdBitCast: |
| 15477 | case ResultLocIdCast: |
| 15438 | 15478 | return nullptr; |
| 15439 | 15479 | case ResultLocIdInstruction: |
| 15440 | 15480 | return result_loc->source_instruction->child->value.type; |
| ... | ... | @@ -15489,6 +15529,7 @@ static bool ir_result_has_type(ResultLoc *result_loc) { |
| 15489 | 15529 | case ResultLocIdReturn: |
| 15490 | 15530 | case ResultLocIdInstruction: |
| 15491 | 15531 | case ResultLocIdBitCast: |
| 15532 | case ResultLocIdCast: |
| 15492 | 15533 | return true; |
| 15493 | 15534 | case ResultLocIdVar: |
| 15494 | 15535 | return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; |
| ... | ... | @@ -15668,6 +15709,61 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15668 | 15709 | result_loc->resolved_loc = parent_result_loc; |
| 15669 | 15710 | return result_loc->resolved_loc; |
| 15670 | 15711 | } |
| 15712 | case ResultLocIdCast: { |
| 15713 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); |
| 15714 | ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); |
| 15715 | if (type_is_invalid(dest_type)) |
| 15716 | return ira->codegen->invalid_instruction; |
| 15717 | |
| 15718 | ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, |
| 15719 | result_cast->base.source_instruction->source_node, false); |
| 15720 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| 15721 | return ira->codegen->invalid_instruction; |
| 15722 | if (const_cast_result.id != ConstCastResultIdOk) { |
| 15723 | // We will not be able to provide a result location for this value. Allow the |
| 15724 | // code to create a new result location and then type coerce to the old one. |
| 15725 | return nullptr; |
| 15726 | } |
| 15727 | |
| 15728 | // In this case we can pointer cast the result location. |
| 15729 | IrInstruction *casted_value; |
| 15730 | if (value != nullptr) { |
| 15731 | casted_value = ir_implicit_cast(ira, value, dest_type); |
| 15732 | } else { |
| 15733 | casted_value = nullptr; |
| 15734 | } |
| 15735 | |
| 15736 | if (casted_value == nullptr || type_is_invalid(casted_value->value.type)) { |
| 15737 | return casted_value; |
| 15738 | } |
| 15739 | |
| 15740 | IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, |
| 15741 | dest_type, casted_value, force_runtime, non_null_comptime, true); |
| 15742 | if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || |
| 15743 | parent_result_loc->value.type->id == ZigTypeIdUnreachable) |
| 15744 | { |
| 15745 | return parent_result_loc; |
| 15746 | } |
| 15747 | ZigType *parent_ptr_type = parent_result_loc->value.type; |
| 15748 | assert(parent_ptr_type->id == ZigTypeIdPointer); |
| 15749 | if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, |
| 15750 | ResolveStatusAlignmentKnown))) |
| 15751 | { |
| 15752 | return ira->codegen->invalid_instruction; |
| 15753 | } |
| 15754 | uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); |
| 15755 | if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { |
| 15756 | return ira->codegen->invalid_instruction; |
| 15757 | } |
| 15758 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, |
| 15759 | parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| 15760 | parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); |
| 15761 | |
| 15762 | result_loc->written = true; |
| 15763 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, |
| 15764 | ptr_type, result_cast->base.source_instruction, false); |
| 15765 | return result_loc->resolved_loc; |
| 15766 | } |
| 15671 | 15767 | case ResultLocIdBitCast: { |
| 15672 | 15768 | ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); |
| 15673 | 15769 | ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); |
| ... | ... | @@ -15790,18 +15886,6 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 15790 | 15886 | return result_loc; |
| 15791 | 15887 | } |
| 15792 | 15888 | |
| 15793 | | static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { |
| 15794 | | ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); |
| 15795 | | if (type_is_invalid(dest_type)) |
| 15796 | | return ira->codegen->invalid_instruction; |
| 15797 | | |
| 15798 | | IrInstruction *target = instruction->target->child; |
| 15799 | | if (type_is_invalid(target->value.type)) |
| 15800 | | return ira->codegen->invalid_instruction; |
| 15801 | | |
| 15802 | | return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc); |
| 15803 | | } |
| 15804 | | |
| 15805 | 15889 | static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) { |
| 15806 | 15890 | ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); |
| 15807 | 15891 | if (type_is_invalid(implicit_elem_type)) |
| ... | ... | @@ -15864,6 +15948,7 @@ static void ir_reset_result(ResultLoc *result_loc) { |
| 15864 | 15948 | case ResultLocIdNone: |
| 15865 | 15949 | case ResultLocIdInstruction: |
| 15866 | 15950 | case ResultLocIdBitCast: |
| 15951 | case ResultLocIdCast: |
| 15867 | 15952 | break; |
| 15868 | 15953 | } |
| 15869 | 15954 | } |
| ... | ... | @@ -16903,25 +16988,14 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC |
| 16903 | 16988 | |
| 16904 | 16989 | if (is_comptime || instr_is_comptime(fn_ref)) { |
| 16905 | 16990 | if (fn_ref->value.type->id == ZigTypeIdMetaType) { |
| 16906 | | ZigType *dest_type = ir_resolve_type(ira, fn_ref); |
| 16907 | | if (type_is_invalid(dest_type)) |
| 16991 | ZigType *ty = ir_resolve_type(ira, fn_ref); |
| 16992 | if (ty == nullptr) |
| 16908 | 16993 | return ira->codegen->invalid_instruction; |
| 16909 | | |
| 16910 | | size_t actual_param_count = call_instruction->arg_count; |
| 16911 | | |
| 16912 | | if (actual_param_count != 1) { |
| 16913 | | ir_add_error_node(ira, call_instruction->base.source_node, |
| 16914 | | buf_sprintf("cast expression expects exactly one parameter")); |
| 16915 | | return ira->codegen->invalid_instruction; |
| 16916 | | } |
| 16917 | | |
| 16918 | | IrInstruction *arg = call_instruction->args[0]->child; |
| 16919 | | |
| 16920 | | IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg, |
| 16921 | | call_instruction->result_loc); |
| 16922 | | if (type_is_invalid(cast_instruction->value.type)) |
| 16923 | | return ira->codegen->invalid_instruction; |
| 16924 | | return ir_finish_anal(ira, cast_instruction); |
| 16994 | ErrorMsg *msg = ir_add_error_node(ira, fn_ref->source_node, |
| 16995 | buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); |
| 16996 | add_error_note(ira->codegen, msg, call_instruction->base.source_node, |
| 16997 | buf_sprintf("use @as builtin for type coercion")); |
| 16998 | return ira->codegen->invalid_instruction; |
| 16925 | 16999 | } else if (fn_ref->value.type->id == ZigTypeIdFn) { |
| 16926 | 17000 | ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); |
| 16927 | 17001 | ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value.type; |
| ... | ... | @@ -25958,6 +26032,26 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 25958 | 26032 | return ir_const_void(ira, &instruction->base); |
| 25959 | 26033 | } |
| 25960 | 26034 | |
| 26035 | static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { |
| 26036 | IrInstruction *operand = instruction->operand->child; |
| 26037 | if (type_is_invalid(operand->value.type)) |
| 26038 | return operand; |
| 26039 | |
| 26040 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, |
| 26041 | &instruction->result_loc_cast->base, operand->value.type, operand, false, false, true); |
| 26042 | if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) |
| 26043 | return result_loc; |
| 26044 | |
| 26045 | if (instruction->result_loc_cast->parent->gen_instruction != nullptr) { |
| 26046 | return instruction->result_loc_cast->parent->gen_instruction; |
| 26047 | } |
| 26048 | |
| 26049 | ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); |
| 26050 | if (type_is_invalid(dest_type)) |
| 26051 | return ira->codegen->invalid_instruction; |
| 26052 | return ir_implicit_cast(ira, operand, dest_type); |
| 26053 | } |
| 26054 | |
| 25961 | 26055 | static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { |
| 25962 | 26056 | IrInstruction *operand = instruction->operand->child; |
| 25963 | 26057 | if (type_is_invalid(operand->value.type)) |