| ... | ... | @@ -65,6 +65,7 @@ enum ConstCastResultId { |
| 65 | 65 | ConstCastResultIdFnArgNoAlias, |
| 66 | 66 | ConstCastResultIdType, |
| 67 | 67 | ConstCastResultIdUnresolvedInferredErrSet, |
| 68 | ConstCastResultIdAsyncAllocatorType, |
| 68 | 69 | }; |
| 69 | 70 | |
| 70 | 71 | struct ConstCastErrSetMismatch { |
| ... | ... | @@ -92,6 +93,7 @@ struct ConstCastOnly { |
| 92 | 93 | ConstCastOnly *error_union_payload; |
| 93 | 94 | ConstCastOnly *error_union_error_set; |
| 94 | 95 | ConstCastOnly *return_type; |
| 96 | ConstCastOnly *async_allocator_type; |
| 95 | 97 | ConstCastArg fn_arg; |
| 96 | 98 | ConstCastArgNoAlias arg_no_alias; |
| 97 | 99 | } data; |
| ... | ... | @@ -104,6 +106,8 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins |
| 104 | 106 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type); |
| 105 | 107 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr); |
| 106 | 108 | static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); |
| 109 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 110 | IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type); |
| 107 | 111 | |
| 108 | 112 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 109 | 113 | assert(const_val->type->id == TypeTableEntryIdPointer); |
| ... | ... | @@ -641,6 +645,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) { |
| 641 | 645 | return IrInstructionIdCancel; |
| 642 | 646 | } |
| 643 | 647 | |
| 648 | static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) { |
| 649 | return IrInstructionIdGetImplicitAllocator; |
| 650 | } |
| 651 | |
| 644 | 652 | template<typename T> |
| 645 | 653 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 646 | 654 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -954,15 +962,6 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As |
| 954 | 962 | return &instruction->base; |
| 955 | 963 | } |
| 956 | 964 | |
| 957 | | static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, |
| 958 | | IrInstruction *struct_ptr, TypeStructField *type_struct_field) |
| 959 | | { |
| 960 | | IrInstruction *new_instruction = ir_build_struct_field_ptr(irb, old_instruction->scope, |
| 961 | | old_instruction->source_node, struct_ptr, type_struct_field); |
| 962 | | ir_link_new_instruction(new_instruction, old_instruction); |
| 963 | | return new_instruction; |
| 964 | | } |
| 965 | | |
| 966 | 965 | static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 967 | 966 | IrInstruction *union_ptr, TypeUnionField *field) |
| 968 | 967 | { |
| ... | ... | @@ -2415,6 +2414,12 @@ static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *sou |
| 2415 | 2414 | return &instruction->base; |
| 2416 | 2415 | } |
| 2417 | 2416 | |
| 2417 | static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 2418 | IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node); |
| 2419 | |
| 2420 | return &instruction->base; |
| 2421 | } |
| 2422 | |
| 2418 | 2423 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 2419 | 2424 | results[ReturnKindUnconditional] = 0; |
| 2420 | 2425 | results[ReturnKindError] = 0; |
| ... | ... | @@ -6740,6 +6745,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 6740 | 6745 | return result; |
| 6741 | 6746 | } |
| 6742 | 6747 | |
| 6748 | if (expected_type == ira->codegen->builtin_types.entry_promise && |
| 6749 | actual_type->id == TypeTableEntryIdPromise) |
| 6750 | { |
| 6751 | return result; |
| 6752 | } |
| 6753 | |
| 6743 | 6754 | // fn |
| 6744 | 6755 | if (expected_type->id == TypeTableEntryIdFn && |
| 6745 | 6756 | actual_type->id == TypeTableEntryIdFn) |
| ... | ... | @@ -6771,6 +6782,16 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 6771 | 6782 | return result; |
| 6772 | 6783 | } |
| 6773 | 6784 | } |
| 6785 | if (!expected_type->data.fn.is_generic && expected_type->data.fn.fn_type_id.cc == CallingConventionAsync) { |
| 6786 | ConstCastOnly child = types_match_const_cast_only(ira, actual_type->data.fn.fn_type_id.async_allocator_type, |
| 6787 | expected_type->data.fn.fn_type_id.async_allocator_type, source_node); |
| 6788 | if (child.id != ConstCastResultIdOk) { |
| 6789 | result.id = ConstCastResultIdAsyncAllocatorType; |
| 6790 | result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1); |
| 6791 | *result.data.async_allocator_type = child; |
| 6792 | return result; |
| 6793 | } |
| 6794 | } |
| 6774 | 6795 | if (expected_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { |
| 6775 | 6796 | result.id = ConstCastResultIdFnArgCount; |
| 6776 | 6797 | return result; |
| ... | ... | @@ -10768,6 +10789,58 @@ static TypeTableEntry *ir_analyze_instruction_error_union(IrAnalyze *ira, |
| 10768 | 10789 | return ira->codegen->builtin_types.entry_type; |
| 10769 | 10790 | } |
| 10770 | 10791 | |
| 10792 | IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, FnTableEntry *parent_fn_entry) { |
| 10793 | FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id; |
| 10794 | if (parent_fn_type->cc != CallingConventionAsync) { |
| 10795 | ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter")); |
| 10796 | return ira->codegen->invalid_instruction; |
| 10797 | } |
| 10798 | |
| 10799 | assert(parent_fn_type->async_allocator_type != nullptr); |
| 10800 | IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, source_instr->source_node); |
| 10801 | result->value.type = parent_fn_type->async_allocator_type; |
| 10802 | return result; |
| 10803 | } |
| 10804 | |
| 10805 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, FnTableEntry *fn_entry, TypeTableEntry *fn_type, |
| 10806 | IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst) |
| 10807 | { |
| 10808 | Buf *alloc_field_name = buf_create_from_str("allocFn"); |
| 10809 | //Buf *free_field_name = buf_create_from_str("freeFn"); |
| 10810 | assert(async_allocator_inst->value.type->id == TypeTableEntryIdPointer); |
| 10811 | TypeTableEntry *container_type = async_allocator_inst->value.type->data.pointer.child_type; |
| 10812 | IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, alloc_field_name, &call_instruction->base, |
| 10813 | async_allocator_inst, container_type); |
| 10814 | if (type_is_invalid(field_ptr_inst->value.type)) { |
| 10815 | return ira->codegen->invalid_instruction; |
| 10816 | } |
| 10817 | TypeTableEntry *ptr_to_alloc_fn_type = field_ptr_inst->value.type; |
| 10818 | assert(ptr_to_alloc_fn_type->id == TypeTableEntryIdPointer); |
| 10819 | |
| 10820 | TypeTableEntry *alloc_fn_type = ptr_to_alloc_fn_type->data.pointer.child_type; |
| 10821 | if (alloc_fn_type->id != TypeTableEntryIdFn) { |
| 10822 | ir_add_error(ira, &call_instruction->base, |
| 10823 | buf_sprintf("expected allocation function, found '%s'", buf_ptr(&alloc_fn_type->name))); |
| 10824 | return ira->codegen->invalid_instruction; |
| 10825 | } |
| 10826 | |
| 10827 | TypeTableEntry *alloc_fn_return_type = alloc_fn_type->data.fn.fn_type_id.return_type; |
| 10828 | if (alloc_fn_return_type->id != TypeTableEntryIdErrorUnion) { |
| 10829 | ir_add_error(ira, fn_ref, |
| 10830 | buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&alloc_fn_return_type->name))); |
| 10831 | return ira->codegen->invalid_instruction; |
| 10832 | } |
| 10833 | TypeTableEntry *alloc_fn_error_set_type = alloc_fn_return_type->data.error_union.err_set_type; |
| 10834 | TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 10835 | TypeTableEntry *promise_type = get_promise_type(ira->codegen, return_type); |
| 10836 | TypeTableEntry *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); |
| 10837 | |
| 10838 | IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, |
| 10839 | fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst); |
| 10840 | result->value.type = async_return_type; |
| 10841 | return result; |
| 10842 | } |
| 10843 | |
| 10771 | 10844 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 10772 | 10845 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 10773 | 10846 | { |
| ... | ... | @@ -10989,6 +11062,13 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 10989 | 11062 | } |
| 10990 | 11063 | return ira->codegen->builtin_types.entry_invalid; |
| 10991 | 11064 | } |
| 11065 | if (fn_type_id->cc != CallingConventionAsync && call_instruction->is_async) { |
| 11066 | ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("cannot use async keyword to call non-async function")); |
| 11067 | if (fn_proto_node) { |
| 11068 | add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); |
| 11069 | } |
| 11070 | return ira->codegen->builtin_types.entry_invalid; |
| 11071 | } |
| 10992 | 11072 | |
| 10993 | 11073 | |
| 10994 | 11074 | if (fn_type_id->is_var_args) { |
| ... | ... | @@ -11115,6 +11195,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 11115 | 11195 | buf_sprintf("calling a generic function requires compile-time known function value")); |
| 11116 | 11196 | return ira->codegen->builtin_types.entry_invalid; |
| 11117 | 11197 | } |
| 11198 | if (call_instruction->is_async && fn_type_id->is_var_args) { |
| 11199 | ir_add_error(ira, call_instruction->fn_ref, |
| 11200 | buf_sprintf("compiler bug: TODO: implement var args async functions. https://github.com/zig-lang/zig/issues/557")); |
| 11201 | return ira->codegen->builtin_types.entry_invalid; |
| 11202 | } |
| 11118 | 11203 | |
| 11119 | 11204 | // Count the arguments of the function type id we are creating |
| 11120 | 11205 | size_t new_fn_arg_count = first_arg_1_or_0; |
| ... | ... | @@ -11263,6 +11348,35 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 11263 | 11348 | return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto); |
| 11264 | 11349 | } |
| 11265 | 11350 | } |
| 11351 | IrInstruction *async_allocator_inst = nullptr; |
| 11352 | if (call_instruction->is_async) { |
| 11353 | AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; |
| 11354 | if (async_allocator_type_node != nullptr) { |
| 11355 | TypeTableEntry *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node); |
| 11356 | if (type_is_invalid(async_allocator_type)) |
| 11357 | return ira->codegen->builtin_types.entry_invalid; |
| 11358 | inst_fn_type_id.async_allocator_type = async_allocator_type; |
| 11359 | } |
| 11360 | IrInstruction *uncasted_async_allocator_inst; |
| 11361 | if (call_instruction->async_allocator == nullptr) { |
| 11362 | uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, parent_fn_entry); |
| 11363 | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 11364 | return ira->codegen->builtin_types.entry_invalid; |
| 11365 | } else { |
| 11366 | uncasted_async_allocator_inst = call_instruction->async_allocator->other; |
| 11367 | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 11368 | return ira->codegen->builtin_types.entry_invalid; |
| 11369 | } |
| 11370 | if (inst_fn_type_id.async_allocator_type == nullptr) { |
| 11371 | IrInstruction *casted_inst = ir_implicit_byval_const_ref_cast(ira, uncasted_async_allocator_inst); |
| 11372 | if (type_is_invalid(casted_inst->value.type)) |
| 11373 | return ira->codegen->builtin_types.entry_invalid; |
| 11374 | inst_fn_type_id.async_allocator_type = casted_inst->value.type; |
| 11375 | } |
| 11376 | async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); |
| 11377 | if (type_is_invalid(async_allocator_inst->value.type)) |
| 11378 | return ira->codegen->builtin_types.entry_invalid; |
| 11379 | } |
| 11266 | 11380 | |
| 11267 | 11381 | auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); |
| 11268 | 11382 | if (existing_entry) { |
| ... | ... | @@ -11282,17 +11396,24 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 11282 | 11396 | ira->codegen->fn_defs.append(impl_fn); |
| 11283 | 11397 | } |
| 11284 | 11398 | |
| 11285 | | size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count; |
| 11286 | | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 11287 | | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, false, nullptr); |
| 11288 | | |
| 11289 | 11399 | TypeTableEntry *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type; |
| 11290 | | ir_add_alloca(ira, new_call_instruction, return_type); |
| 11291 | | |
| 11292 | 11400 | if (return_type->id == TypeTableEntryIdErrorSet || return_type->id == TypeTableEntryIdErrorUnion) { |
| 11293 | 11401 | parent_fn_entry->calls_errorable_function = true; |
| 11294 | 11402 | } |
| 11295 | 11403 | |
| 11404 | size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count; |
| 11405 | if (call_instruction->is_async) { |
| 11406 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, fn_ref, casted_args, impl_param_count, async_allocator_inst); |
| 11407 | ir_link_new_instruction(result, &call_instruction->base); |
| 11408 | return ir_finish_anal(ira, result->value.type); |
| 11409 | } |
| 11410 | |
| 11411 | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 11412 | impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, |
| 11413 | call_instruction->is_async, async_allocator_inst); |
| 11414 | |
| 11415 | ir_add_alloca(ira, new_call_instruction, return_type); |
| 11416 | |
| 11296 | 11417 | return ir_finish_anal(ira, return_type); |
| 11297 | 11418 | } |
| 11298 | 11419 | |
| ... | ... | @@ -11350,14 +11471,31 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 11350 | 11471 | |
| 11351 | 11472 | assert(next_arg_index == call_param_count); |
| 11352 | 11473 | |
| 11353 | | if (call_instruction->is_async) { |
| 11354 | | zig_panic("TODO handle async fn call"); |
| 11355 | | } |
| 11356 | | |
| 11357 | 11474 | TypeTableEntry *return_type = fn_type_id->return_type; |
| 11358 | 11475 | if (type_is_invalid(return_type)) |
| 11359 | 11476 | return ira->codegen->builtin_types.entry_invalid; |
| 11360 | 11477 | |
| 11478 | if (call_instruction->is_async) { |
| 11479 | IrInstruction *uncasted_async_allocator_inst; |
| 11480 | if (call_instruction->async_allocator == nullptr) { |
| 11481 | uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, parent_fn_entry); |
| 11482 | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 11483 | return ira->codegen->builtin_types.entry_invalid; |
| 11484 | } else { |
| 11485 | uncasted_async_allocator_inst = call_instruction->async_allocator->other; |
| 11486 | if (type_is_invalid(uncasted_async_allocator_inst->value.type)) |
| 11487 | return ira->codegen->builtin_types.entry_invalid; |
| 11488 | } |
| 11489 | IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type); |
| 11490 | if (type_is_invalid(async_allocator_inst->value.type)) |
| 11491 | return ira->codegen->builtin_types.entry_invalid; |
| 11492 | |
| 11493 | IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, casted_args, call_param_count, async_allocator_inst); |
| 11494 | ir_link_new_instruction(result, &call_instruction->base); |
| 11495 | return ir_finish_anal(ira, result->value.type); |
| 11496 | } |
| 11497 | |
| 11498 | |
| 11361 | 11499 | IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base, |
| 11362 | 11500 | fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr); |
| 11363 | 11501 | |
| ... | ... | @@ -12054,8 +12192,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 12054 | 12192 | return return_type; |
| 12055 | 12193 | } |
| 12056 | 12194 | |
| 12057 | | static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 12058 | | TypeTableEntry *bare_struct_type, Buf *field_name, IrInstructionFieldPtr *field_ptr_instruction, |
| 12195 | static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 12196 | TypeTableEntry *bare_struct_type, Buf *field_name, IrInstruction *source_instr, |
| 12059 | 12197 | IrInstruction *container_ptr, TypeTableEntry *container_type) |
| 12060 | 12198 | { |
| 12061 | 12199 | if (!is_slice(bare_struct_type)) { |
| ... | ... | @@ -12063,17 +12201,17 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 12063 | 12201 | auto entry = container_scope->decl_table.maybe_get(field_name); |
| 12064 | 12202 | Tld *tld = entry ? entry->value : nullptr; |
| 12065 | 12203 | if (tld && tld->id == TldIdFn) { |
| 12066 | | resolve_top_level_decl(ira->codegen, tld, false, field_ptr_instruction->base.source_node); |
| 12204 | resolve_top_level_decl(ira->codegen, tld, false, source_instr->source_node); |
| 12067 | 12205 | if (tld->resolution == TldResolutionInvalid) |
| 12068 | | return ira->codegen->builtin_types.entry_invalid; |
| 12206 | return ira->codegen->invalid_instruction; |
| 12069 | 12207 | TldFn *tld_fn = (TldFn *)tld; |
| 12070 | 12208 | FnTableEntry *fn_entry = tld_fn->fn_entry; |
| 12071 | 12209 | if (type_is_invalid(fn_entry->type_entry)) |
| 12072 | | return ira->codegen->builtin_types.entry_invalid; |
| 12210 | return ira->codegen->invalid_instruction; |
| 12073 | 12211 | |
| 12074 | | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope, |
| 12075 | | field_ptr_instruction->base.source_node, fn_entry, container_ptr); |
| 12076 | | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value, true, false); |
| 12212 | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, |
| 12213 | source_instr->source_node, fn_entry, container_ptr); |
| 12214 | return ir_get_ref(ira, source_instr, bound_fn_value, true, false); |
| 12077 | 12215 | } |
| 12078 | 12216 | } |
| 12079 | 12217 | const char *prefix_name; |
| ... | ... | @@ -12088,19 +12226,19 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 12088 | 12226 | } else { |
| 12089 | 12227 | prefix_name = ""; |
| 12090 | 12228 | } |
| 12091 | | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| 12229 | ir_add_error_node(ira, source_instr->source_node, |
| 12092 | 12230 | buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); |
| 12093 | | return ira->codegen->builtin_types.entry_invalid; |
| 12231 | return ira->codegen->invalid_instruction; |
| 12094 | 12232 | } |
| 12095 | 12233 | |
| 12096 | 12234 | |
| 12097 | | static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 12098 | | IrInstructionFieldPtr *field_ptr_instruction, IrInstruction *container_ptr, TypeTableEntry *container_type) |
| 12235 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 12236 | IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type) |
| 12099 | 12237 | { |
| 12100 | 12238 | TypeTableEntry *bare_type = container_ref_type(container_type); |
| 12101 | 12239 | ensure_complete_type(ira->codegen, bare_type); |
| 12102 | 12240 | if (type_is_invalid(bare_type)) |
| 12103 | | return ira->codegen->builtin_types.entry_invalid; |
| 12241 | return ira->codegen->invalid_instruction; |
| 12104 | 12242 | |
| 12105 | 12243 | assert(container_ptr->value.type->id == TypeTableEntryIdPointer); |
| 12106 | 12244 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| ... | ... | @@ -12117,46 +12255,51 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field |
| 12117 | 12255 | if (instr_is_comptime(container_ptr)) { |
| 12118 | 12256 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 12119 | 12257 | if (!ptr_val) |
| 12120 | | return ira->codegen->builtin_types.entry_invalid; |
| 12258 | return ira->codegen->invalid_instruction; |
| 12121 | 12259 | |
| 12122 | 12260 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 12123 | 12261 | ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 12124 | 12262 | if (type_is_invalid(struct_val->type)) |
| 12125 | | return ira->codegen->builtin_types.entry_invalid; |
| 12263 | return ira->codegen->invalid_instruction; |
| 12126 | 12264 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; |
| 12127 | 12265 | TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type, |
| 12128 | 12266 | is_const, is_volatile, align_bytes, |
| 12129 | 12267 | (uint32_t)(ptr_bit_offset + field->packed_bits_offset), |
| 12130 | 12268 | (uint32_t)unaligned_bit_count_for_result_type); |
| 12131 | | ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base); |
| 12269 | IrInstruction *result = ir_get_const(ira, source_instr); |
| 12270 | ConstExprValue *const_val = &result->value; |
| 12132 | 12271 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 12133 | 12272 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 12134 | 12273 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| 12135 | 12274 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| 12136 | | return ptr_type; |
| 12275 | const_val->type = ptr_type; |
| 12276 | return result; |
| 12137 | 12277 | } |
| 12138 | 12278 | } |
| 12139 | | ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field); |
| 12140 | | return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 12279 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 12280 | container_ptr, field); |
| 12281 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 12141 | 12282 | align_bytes, |
| 12142 | 12283 | (uint32_t)(ptr_bit_offset + field->packed_bits_offset), |
| 12143 | 12284 | (uint32_t)unaligned_bit_count_for_result_type); |
| 12285 | return result; |
| 12144 | 12286 | } else { |
| 12145 | 12287 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 12146 | | field_ptr_instruction, container_ptr, container_type); |
| 12288 | source_instr, container_ptr, container_type); |
| 12147 | 12289 | } |
| 12148 | 12290 | } else if (bare_type->id == TypeTableEntryIdEnum) { |
| 12149 | 12291 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 12150 | | field_ptr_instruction, container_ptr, container_type); |
| 12292 | source_instr, container_ptr, container_type); |
| 12151 | 12293 | } else if (bare_type->id == TypeTableEntryIdUnion) { |
| 12152 | 12294 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 12153 | 12295 | if (field) { |
| 12154 | | ir_build_union_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field); |
| 12155 | | return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 12296 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); |
| 12297 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 12156 | 12298 | get_abi_alignment(ira->codegen, field->type_entry), 0, 0); |
| 12299 | return result; |
| 12157 | 12300 | } else { |
| 12158 | 12301 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 12159 | | field_ptr_instruction, container_ptr, container_type); |
| 12302 | source_instr, container_ptr, container_type); |
| 12160 | 12303 | } |
| 12161 | 12304 | } else { |
| 12162 | 12305 | zig_unreachable(); |
| ... | ... | @@ -12266,9 +12409,13 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 12266 | 12409 | if (container_type->id == TypeTableEntryIdPointer) { |
| 12267 | 12410 | TypeTableEntry *bare_type = container_ref_type(container_type); |
| 12268 | 12411 | IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); |
| 12269 | | return ir_analyze_container_field_ptr(ira, field_name, field_ptr_instruction, container_child, bare_type); |
| 12412 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); |
| 12413 | ir_link_new_instruction(result, &field_ptr_instruction->base); |
| 12414 | return result->value.type; |
| 12270 | 12415 | } else { |
| 12271 | | return ir_analyze_container_field_ptr(ira, field_name, field_ptr_instruction, container_ptr, container_type); |
| 12416 | IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); |
| 12417 | ir_link_new_instruction(result, &field_ptr_instruction->base); |
| 12418 | return result->value.type; |
| 12272 | 12419 | } |
| 12273 | 12420 | } else if (container_type->id == TypeTableEntryIdArray) { |
| 12274 | 12421 | if (buf_eql_str(field_name, "len")) { |
| ... | ... | @@ -16539,7 +16686,8 @@ static TypeTableEntry *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructi |
| 16539 | 16686 | return ira->codegen->builtin_types.entry_invalid; |
| 16540 | 16687 | |
| 16541 | 16688 | IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target); |
| 16542 | | result->value.type = casted_target->value.type; |
| 16689 | result->value.type = ira->codegen->builtin_types.entry_void; |
| 16690 | result->value.special = ConstValSpecialStatic; |
| 16543 | 16691 | ir_link_new_instruction(result, &instruction->base); |
| 16544 | 16692 | return result->value.type; |
| 16545 | 16693 | } |
| ... | ... | @@ -16559,6 +16707,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 16559 | 16707 | case IrInstructionIdErrWrapCode: |
| 16560 | 16708 | case IrInstructionIdErrWrapPayload: |
| 16561 | 16709 | case IrInstructionIdCast: |
| 16710 | case IrInstructionIdGetImplicitAllocator: |
| 16562 | 16711 | zig_unreachable(); |
| 16563 | 16712 | case IrInstructionIdReturn: |
| 16564 | 16713 | return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); |
| ... | ... | @@ -16936,7 +17085,9 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 16936 | 17085 | case IrInstructionIdTagType: |
| 16937 | 17086 | case IrInstructionIdErrorReturnTrace: |
| 16938 | 17087 | case IrInstructionIdErrorUnion: |
| 17088 | case IrInstructionIdGetImplicitAllocator: |
| 16939 | 17089 | return false; |
| 17090 | |
| 16940 | 17091 | case IrInstructionIdAsm: |
| 16941 | 17092 | { |
| 16942 | 17093 | IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; |