| ... | ... | @@ -206,6 +206,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction |
| 206 | 206 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); |
| 207 | 207 | static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 208 | 208 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); |
| 209 | static ResultLoc *no_result_loc(void); |
| 209 | 210 | |
| 210 | 211 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 211 | 212 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -3115,11 +3116,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast |
| 3115 | 3116 | } |
| 3116 | 3117 | |
| 3117 | 3118 | static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3118 | | IrInstruction *fn_type, IrInstruction *arg_index) |
| 3119 | IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var) |
| 3119 | 3120 | { |
| 3120 | 3121 | IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); |
| 3121 | 3122 | instruction->fn_type = fn_type; |
| 3122 | 3123 | instruction->arg_index = arg_index; |
| 3124 | instruction->allow_var = allow_var; |
| 3123 | 3125 | |
| 3124 | 3126 | ir_ref_instruction(fn_type, irb->current_basic_block); |
| 3125 | 3127 | ir_ref_instruction(arg_index, irb->current_basic_block); |
| ... | ... | @@ -5647,7 +5649,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5647 | 5649 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5648 | 5650 | return arg1_value; |
| 5649 | 5651 | |
| 5650 | | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| 5652 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false); |
| 5651 | 5653 | return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); |
| 5652 | 5654 | } |
| 5653 | 5655 | case BuiltinFnIdExport: |
| ... | ... | @@ -5842,13 +5844,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 5842 | 5844 | if (fn_ref == irb->codegen->invalid_instruction) |
| 5843 | 5845 | return fn_ref; |
| 5844 | 5846 | |
| 5847 | IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref); |
| 5848 | |
| 5845 | 5849 | size_t arg_count = node->data.fn_call_expr.params.length; |
| 5846 | 5850 | IrInstruction **args = allocate<IrInstruction*>(arg_count); |
| 5847 | 5851 | for (size_t i = 0; i < arg_count; i += 1) { |
| 5848 | 5852 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); |
| 5849 | | args[i] = ir_gen_node(irb, arg_node, scope); |
| 5850 | | if (args[i] == irb->codegen->invalid_instruction) |
| 5851 | | return args[i]; |
| 5853 | |
| 5854 | IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); |
| 5855 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); |
| 5856 | ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc()); |
| 5857 | |
| 5858 | IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); |
| 5859 | if (arg == irb->codegen->invalid_instruction) |
| 5860 | return arg; |
| 5861 | |
| 5862 | args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); |
| 5852 | 5863 | } |
| 5853 | 5864 | |
| 5854 | 5865 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, |
| ... | ... | @@ -12504,6 +12515,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou |
| 12504 | 12515 | return result; |
| 12505 | 12516 | } |
| 12506 | 12517 | |
| 12518 | static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr, |
| 12519 | IrInstruction *value, ZigType *wanted_type) |
| 12520 | { |
| 12521 | ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); |
| 12522 | return ira->codegen->invalid_instruction; |
| 12523 | } |
| 12524 | |
| 12525 | static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr, |
| 12526 | IrInstruction *value, ZigType *wanted_type) |
| 12527 | { |
| 12528 | ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct")); |
| 12529 | return ira->codegen->invalid_instruction; |
| 12530 | } |
| 12531 | |
| 12532 | static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr, |
| 12533 | IrInstruction *value, ZigType *wanted_type) |
| 12534 | { |
| 12535 | ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); |
| 12536 | return ira->codegen->invalid_instruction; |
| 12537 | } |
| 12538 | |
| 12507 | 12539 | static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, |
| 12508 | 12540 | ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) |
| 12509 | 12541 | { |
| ... | ... | @@ -12515,6 +12547,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12515 | 12547 | return ira->codegen->invalid_instruction; |
| 12516 | 12548 | } |
| 12517 | 12549 | |
| 12550 | // This means the wanted type is anything. |
| 12551 | if (wanted_type == ira->codegen->builtin_types.entry_var) { |
| 12552 | return value; |
| 12553 | } |
| 12554 | |
| 12518 | 12555 | // perfect match or non-const to const |
| 12519 | 12556 | ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, |
| 12520 | 12557 | source_node, false); |
| ... | ... | @@ -13071,6 +13108,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13071 | 13108 | return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); |
| 13072 | 13109 | } |
| 13073 | 13110 | |
| 13111 | // cast from inferred struct type to array, union, or struct |
| 13112 | if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) { |
| 13113 | AstNode *decl_node = actual_type->data.structure.decl_node; |
| 13114 | ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); |
| 13115 | ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; |
| 13116 | uint32_t field_count = actual_type->data.structure.src_field_count; |
| 13117 | if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) && |
| 13118 | wanted_type->data.array.len == field_count) |
| 13119 | { |
| 13120 | return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); |
| 13121 | } else if (wanted_type->id == ZigTypeIdStruct && |
| 13122 | (init_kind == ContainerInitKindStruct || field_count == 0)) |
| 13123 | { |
| 13124 | return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); |
| 13125 | } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) { |
| 13126 | return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); |
| 13127 | } |
| 13128 | } |
| 13129 | |
| 13074 | 13130 | // cast from undefined to anything |
| 13075 | 13131 | if (actual_type->id == ZigTypeIdUndefined) { |
| 13076 | 13132 | return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); |
| ... | ... | @@ -15537,21 +15593,31 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| 15537 | 15593 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| 15538 | 15594 | } |
| 15539 | 15595 | |
| 15540 | | static bool ir_result_has_type(ResultLoc *result_loc) { |
| 15596 | static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { |
| 15541 | 15597 | switch (result_loc->id) { |
| 15542 | 15598 | case ResultLocIdInvalid: |
| 15543 | 15599 | case ResultLocIdPeerParent: |
| 15544 | 15600 | zig_unreachable(); |
| 15545 | 15601 | case ResultLocIdNone: |
| 15546 | 15602 | case ResultLocIdPeer: |
| 15547 | | return false; |
| 15603 | *out = false; |
| 15604 | return ErrorNone; |
| 15548 | 15605 | case ResultLocIdReturn: |
| 15549 | 15606 | case ResultLocIdInstruction: |
| 15550 | 15607 | case ResultLocIdBitCast: |
| 15551 | | case ResultLocIdCast: |
| 15552 | | return true; |
| 15608 | *out = true; |
| 15609 | return ErrorNone; |
| 15610 | case ResultLocIdCast: { |
| 15611 | ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); |
| 15612 | ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); |
| 15613 | if (type_is_invalid(dest_type)) |
| 15614 | return ErrorSemanticAnalyzeFail; |
| 15615 | *out = (dest_type != ira->codegen->builtin_types.entry_var); |
| 15616 | return ErrorNone; |
| 15617 | } |
| 15553 | 15618 | case ResultLocIdVar: |
| 15554 | | return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; |
| 15619 | *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; |
| 15620 | return ErrorNone; |
| 15555 | 15621 | } |
| 15556 | 15622 | zig_unreachable(); |
| 15557 | 15623 | } |
| ... | ... | @@ -15698,7 +15764,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15698 | 15764 | } |
| 15699 | 15765 | return nullptr; |
| 15700 | 15766 | } |
| 15701 | | if (ir_result_has_type(peer_parent->parent)) { |
| 15767 | bool peer_parent_has_type; |
| 15768 | if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) |
| 15769 | return ira->codegen->invalid_instruction; |
| 15770 | if (peer_parent_has_type) { |
| 15702 | 15771 | if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { |
| 15703 | 15772 | reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true; |
| 15704 | 15773 | ira->src_implicit_return_type_list.append(value); |
| ... | ... | @@ -15741,6 +15810,11 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15741 | 15810 | if (type_is_invalid(dest_type)) |
| 15742 | 15811 | return ira->codegen->invalid_instruction; |
| 15743 | 15812 | |
| 15813 | if (dest_type == ira->codegen->builtin_types.entry_var) { |
| 15814 | return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, |
| 15815 | force_runtime, non_null_comptime); |
| 15816 | } |
| 15817 | |
| 15744 | 15818 | ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, |
| 15745 | 15819 | result_cast->base.source_instruction->source_node, false); |
| 15746 | 15820 | if (const_cast_result.id == ConstCastResultIdInvalid) |
| ... | ... | @@ -15948,6 +16022,9 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, |
| 15948 | 16022 | if (type_is_invalid(implicit_elem_type)) |
| 15949 | 16023 | return ira->codegen->invalid_instruction; |
| 15950 | 16024 | } else { |
| 16025 | implicit_elem_type = ira->codegen->builtin_types.entry_var; |
| 16026 | } |
| 16027 | if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { |
| 15951 | 16028 | Buf *bare_name = buf_alloc(); |
| 15952 | 16029 | Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), |
| 15953 | 16030 | instruction->base.scope, instruction->base.source_node, bare_name); |
| ... | ... | @@ -17532,6 +17609,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, |
| 17532 | 17609 | } |
| 17533 | 17610 | |
| 17534 | 17611 | static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { |
| 17612 | Error err; |
| 17613 | |
| 17535 | 17614 | if (ira->const_predecessor_bb) { |
| 17536 | 17615 | for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { |
| 17537 | 17616 | IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; |
| ... | ... | @@ -17663,24 +17742,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 17663 | 17742 | } |
| 17664 | 17743 | |
| 17665 | 17744 | ZigType *resolved_type; |
| 17666 | | if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) { |
| 17667 | | if (peer_parent->parent->id == ResultLocIdReturn) { |
| 17668 | | resolved_type = ira->explicit_return_type; |
| 17669 | | } else if (peer_parent->parent->id == ResultLocIdCast) { |
| 17670 | | resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); |
| 17671 | | if (type_is_invalid(resolved_type)) |
| 17672 | | return ira->codegen->invalid_instruction; |
| 17673 | | } else { |
| 17674 | | ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; |
| 17675 | | ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); |
| 17676 | | resolved_type = resolved_loc_ptr_type->data.pointer.child_type; |
| 17745 | if (peer_parent != nullptr) { |
| 17746 | bool peer_parent_has_type; |
| 17747 | if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) |
| 17748 | return ira->codegen->invalid_instruction; |
| 17749 | if (peer_parent_has_type) { |
| 17750 | if (peer_parent->parent->id == ResultLocIdReturn) { |
| 17751 | resolved_type = ira->explicit_return_type; |
| 17752 | } else if (peer_parent->parent->id == ResultLocIdCast) { |
| 17753 | resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); |
| 17754 | if (type_is_invalid(resolved_type)) |
| 17755 | return ira->codegen->invalid_instruction; |
| 17756 | } else { |
| 17757 | ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; |
| 17758 | ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); |
| 17759 | resolved_type = resolved_loc_ptr_type->data.pointer.child_type; |
| 17760 | } |
| 17761 | goto skip_resolve_peer_types; |
| 17677 | 17762 | } |
| 17678 | | } else { |
| 17763 | } |
| 17764 | { |
| 17679 | 17765 | resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, |
| 17680 | 17766 | new_incoming_values.items, new_incoming_values.length); |
| 17681 | 17767 | if (type_is_invalid(resolved_type)) |
| 17682 | 17768 | return ira->codegen->invalid_instruction; |
| 17683 | 17769 | } |
| 17770 | skip_resolve_peer_types: |
| 17684 | 17771 | |
| 17685 | 17772 | switch (type_has_one_possible_value(ira->codegen, resolved_type)) { |
| 17686 | 17773 | case OnePossibleValueInvalid: |
| ... | ... | @@ -18379,7 +18466,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n |
| 18379 | 18466 | inferred_struct_field->inferred_struct_type = container_type; |
| 18380 | 18467 | inferred_struct_field->field_name = field_name; |
| 18381 | 18468 | |
| 18382 | | ZigType *elem_type = ira->codegen->builtin_types.entry_c_void; |
| 18469 | ZigType *elem_type = ira->codegen->builtin_types.entry_var; |
| 18383 | 18470 | ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, |
| 18384 | 18471 | container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, |
| 18385 | 18472 | PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field); |
| ... | ... | @@ -25547,6 +25634,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct |
| 25547 | 25634 | if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) |
| 25548 | 25635 | return ira->codegen->invalid_instruction; |
| 25549 | 25636 | |
| 25637 | if (fn_type->id == ZigTypeIdBoundFn) { |
| 25638 | fn_type = fn_type->data.bound_fn.fn_type; |
| 25639 | arg_index += 1; |
| 25640 | } |
| 25550 | 25641 | if (fn_type->id != ZigTypeIdFn) { |
| 25551 | 25642 | ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); |
| 25552 | 25643 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -25554,6 +25645,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct |
| 25554 | 25645 | |
| 25555 | 25646 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| 25556 | 25647 | if (arg_index >= fn_type_id->param_count) { |
| 25648 | if (instruction->allow_var) { |
| 25649 | // TODO remove this with var args |
| 25650 | return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); |
| 25651 | } |
| 25557 | 25652 | ir_add_error(ira, arg_index_inst, |
| 25558 | 25653 | buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", |
| 25559 | 25654 | arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); |
| ... | ... | @@ -25565,10 +25660,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct |
| 25565 | 25660 | // Args are only unresolved if our function is generic. |
| 25566 | 25661 | ir_assert(fn_type->data.fn.is_generic, &instruction->base); |
| 25567 | 25662 | |
| 25568 | | ir_add_error(ira, arg_index_inst, |
| 25569 | | buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", |
| 25570 | | arg_index, buf_ptr(&fn_type->name))); |
| 25571 | | return ira->codegen->invalid_instruction; |
| 25663 | if (instruction->allow_var) { |
| 25664 | return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); |
| 25665 | } else { |
| 25666 | ir_add_error(ira, arg_index_inst, |
| 25667 | buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", |
| 25668 | arg_index, buf_ptr(&fn_type->name))); |
| 25669 | return ira->codegen->invalid_instruction; |
| 25670 | } |
| 25572 | 25671 | } |
| 25573 | 25672 | return ir_const_type(ira, &instruction->base, result_type); |
| 25574 | 25673 | } |