| ... | @@ -17351,14 +17351,15 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, | ... | @@ -17351,14 +17351,15 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, |
| 17351 | ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); | 17351 | ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); |
| 17352 | new_type->data.structure.special = StructSpecialInferredTuple; | 17352 | new_type->data.structure.special = StructSpecialInferredTuple; |
| 17353 | new_type->data.structure.resolve_status = ResolveStatusBeingInferred; | 17353 | new_type->data.structure.resolve_status = ResolveStatusBeingInferred; |
| 17354 | | | |
| 17355 | IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), | | |
| 17356 | new_type, nullptr, false, true); | | |
| 17357 | uint32_t new_field_count = op1_field_count + op2_field_count; | 17354 | uint32_t new_field_count = op1_field_count + op2_field_count; |
| 17358 | | 17355 | |
| 17359 | new_type->data.structure.src_field_count = new_field_count; | 17356 | new_type->data.structure.src_field_count = new_field_count; |
| 17360 | new_type->data.structure.fields = realloc_type_struct_fields(new_type->data.structure.fields, | 17357 | new_type->data.structure.fields = realloc_type_struct_fields(new_type->data.structure.fields, |
| 17361 | 0, new_field_count); | 17358 | 0, new_field_count); |
| | 17359 | |
| | 17360 | IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), |
| | 17361 | new_type, nullptr, false, true); |
| | 17362 | |
| 17362 | for (uint32_t i = 0; i < new_field_count; i += 1) { | 17363 | for (uint32_t i = 0; i < new_field_count; i += 1) { |
| 17363 | TypeStructField *src_field; | 17364 | TypeStructField *src_field; |
| 17364 | if (i < op1_field_count) { | 17365 | if (i < op1_field_count) { |
| ... | @@ -17422,8 +17423,10 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, | ... | @@ -17422,8 +17423,10 @@ static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, |
| 17422 | ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, true); | 17423 | ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, true); |
| 17423 | } | 17424 | } |
| 17424 | } | 17425 | } |
| 17425 | IrInstGen *result = ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); | 17426 | |
| 17426 | return result; | 17427 | const_ptrs.deinit(); |
| | 17428 | |
| | 17429 | return ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); |
| 17427 | } | 17430 | } |
| 17428 | | 17431 | |
| 17429 | static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instruction) { | 17432 | static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instruction) { |
| ... | @@ -17480,8 +17483,9 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi | ... | @@ -17480,8 +17483,9 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi |
| 17480 | ZigValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; | 17483 | ZigValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; |
| 17481 | op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); | 17484 | op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); |
| 17482 | sentinel1 = ptr_type->data.pointer.sentinel; | 17485 | sentinel1 = ptr_type->data.pointer.sentinel; |
| 17483 | } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && | 17486 | } else if (op1_type->id == ZigTypeIdPointer && |
| 17484 | op1_type->data.pointer.child_type->id == ZigTypeIdArray) | 17487 | op1_type->data.pointer.ptr_len == PtrLenSingle && |
| | 17488 | op1_type->data.pointer.child_type->id == ZigTypeIdArray) |
| 17485 | { | 17489 | { |
| 17486 | ZigType *array_type = op1_type->data.pointer.child_type; | 17490 | ZigType *array_type = op1_type->data.pointer.child_type; |
| 17487 | child_type = array_type->data.array.child_type; | 17491 | child_type = array_type->data.array.child_type; |
| ... | @@ -17654,6 +17658,103 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi | ... | @@ -17654,6 +17658,103 @@ static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instructi |
| 17654 | return result; | 17658 | return result; |
| 17655 | } | 17659 | } |
| 17656 | | 17660 | |
| | 17661 | static IrInstGen *ir_analyze_tuple_mult(IrAnalyze *ira, IrInst* source_instr, |
| | 17662 | IrInstGen *op1, IrInstGen *op2) |
| | 17663 | { |
| | 17664 | Error err; |
| | 17665 | ZigType *op1_type = op1->value->type; |
| | 17666 | uint64_t op1_field_count = op1_type->data.structure.src_field_count; |
| | 17667 | |
| | 17668 | uint64_t mult_amt; |
| | 17669 | if (!ir_resolve_usize(ira, op2, &mult_amt)) |
| | 17670 | return ira->codegen->invalid_inst_gen; |
| | 17671 | |
| | 17672 | uint64_t new_field_count; |
| | 17673 | if (mul_u64_overflow(op1_field_count, mult_amt, &new_field_count)) { |
| | 17674 | ir_add_error(ira, source_instr, buf_sprintf("operation results in overflow")); |
| | 17675 | return ira->codegen->invalid_inst_gen; |
| | 17676 | } |
| | 17677 | |
| | 17678 | Buf *bare_name = buf_alloc(); |
| | 17679 | Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), |
| | 17680 | source_instr->scope, source_instr->source_node, bare_name); |
| | 17681 | ZigType *new_type = get_partial_container_type(ira->codegen, source_instr->scope, |
| | 17682 | ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); |
| | 17683 | new_type->data.structure.special = StructSpecialInferredTuple; |
| | 17684 | new_type->data.structure.resolve_status = ResolveStatusBeingInferred; |
| | 17685 | new_type->data.structure.src_field_count = new_field_count; |
| | 17686 | new_type->data.structure.fields = realloc_type_struct_fields( |
| | 17687 | new_type->data.structure.fields, 0, new_field_count); |
| | 17688 | |
| | 17689 | IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), |
| | 17690 | new_type, nullptr, false, true); |
| | 17691 | |
| | 17692 | for (uint64_t i = 0; i < new_field_count; i += 1) { |
| | 17693 | TypeStructField *src_field = op1_type->data.structure.fields[i % op1_field_count]; |
| | 17694 | TypeStructField *new_field = new_type->data.structure.fields[i]; |
| | 17695 | |
| | 17696 | new_field->name = buf_sprintf("%lu", i); |
| | 17697 | new_field->type_entry = src_field->type_entry; |
| | 17698 | new_field->type_val = src_field->type_val; |
| | 17699 | new_field->src_index = i; |
| | 17700 | new_field->decl_node = src_field->decl_node; |
| | 17701 | new_field->init_val = src_field->init_val; |
| | 17702 | new_field->is_comptime = src_field->is_comptime; |
| | 17703 | } |
| | 17704 | |
| | 17705 | if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) |
| | 17706 | return ira->codegen->invalid_inst_gen; |
| | 17707 | |
| | 17708 | ZigList<IrInstGen *> const_ptrs = {}; |
| | 17709 | for (uint64_t i = 0; i < new_field_count; i += 1) { |
| | 17710 | TypeStructField *src_field = op1_type->data.structure.fields[i % op1_field_count]; |
| | 17711 | TypeStructField *dst_field = new_type->data.structure.fields[i]; |
| | 17712 | |
| | 17713 | IrInstGen *field_value = ir_analyze_struct_value_field_value( |
| | 17714 | ira, source_instr, op1, src_field); |
| | 17715 | if (type_is_invalid(field_value->value->type)) |
| | 17716 | return ira->codegen->invalid_inst_gen; |
| | 17717 | |
| | 17718 | IrInstGen *dest_ptr = ir_analyze_struct_field_ptr( |
| | 17719 | ira, source_instr, dst_field, new_struct_ptr, new_type, true); |
| | 17720 | if (type_is_invalid(dest_ptr->value->type)) |
| | 17721 | return ira->codegen->invalid_inst_gen; |
| | 17722 | |
| | 17723 | if (instr_is_comptime(field_value)) { |
| | 17724 | const_ptrs.append(dest_ptr); |
| | 17725 | } |
| | 17726 | |
| | 17727 | IrInstGen *store_ptr_inst = ir_analyze_store_ptr( |
| | 17728 | ira, source_instr, dest_ptr, field_value, true); |
| | 17729 | if (type_is_invalid(store_ptr_inst->value->type)) |
| | 17730 | return ira->codegen->invalid_inst_gen; |
| | 17731 | } |
| | 17732 | |
| | 17733 | if (const_ptrs.length != new_field_count) { |
| | 17734 | new_struct_ptr->value->special = ConstValSpecialRuntime; |
| | 17735 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| | 17736 | IrInstGen *elem_result_loc = const_ptrs.at(i); |
| | 17737 | assert(elem_result_loc->value->special == ConstValSpecialStatic); |
| | 17738 | if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { |
| | 17739 | // This field will be generated comptime; no need to do this. |
| | 17740 | continue; |
| | 17741 | } |
| | 17742 | IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); |
| | 17743 | if (!type_requires_comptime(ira->codegen, elem_result_loc->value->type->data.pointer.child_type)) { |
| | 17744 | elem_result_loc->value->special = ConstValSpecialRuntime; |
| | 17745 | } |
| | 17746 | IrInstGen *store_ptr_inst = ir_analyze_store_ptr( |
| | 17747 | ira, &elem_result_loc->base, elem_result_loc, deref, true); |
| | 17748 | if (type_is_invalid(store_ptr_inst->value->type)) |
| | 17749 | return ira->codegen->invalid_inst_gen; |
| | 17750 | } |
| | 17751 | } |
| | 17752 | |
| | 17753 | const_ptrs.deinit(); |
| | 17754 | |
| | 17755 | return ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); |
| | 17756 | } |
| | 17757 | |
| 17657 | static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruction) { | 17758 | static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruction) { |
| 17658 | IrInstGen *op1 = instruction->op1->child; | 17759 | IrInstGen *op1 = instruction->op1->child; |
| 17659 | if (type_is_invalid(op1->value->type)) | 17760 | if (type_is_invalid(op1->value->type)) |
| ... | @@ -17671,8 +17772,9 @@ static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruct | ... | @@ -17671,8 +17772,9 @@ static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruct |
| 17671 | array_val = ir_resolve_const(ira, op1, UndefOk); | 17772 | array_val = ir_resolve_const(ira, op1, UndefOk); |
| 17672 | if (array_val == nullptr) | 17773 | if (array_val == nullptr) |
| 17673 | return ira->codegen->invalid_inst_gen; | 17774 | return ira->codegen->invalid_inst_gen; |
| 17674 | } else if (op1->value->type->id == ZigTypeIdPointer && op1->value->type->data.pointer.ptr_len == PtrLenSingle && | 17775 | } else if (op1->value->type->id == ZigTypeIdPointer && |
| 17675 | op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) | 17776 | op1->value->type->data.pointer.ptr_len == PtrLenSingle && |
| | 17777 | op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) |
| 17676 | { | 17778 | { |
| 17677 | array_type = op1->value->type->data.pointer.child_type; | 17779 | array_type = op1->value->type->data.pointer.child_type; |
| 17678 | IrInstGen *array_inst = ir_get_deref(ira, &op1->base, op1, nullptr); | 17780 | IrInstGen *array_inst = ir_get_deref(ira, &op1->base, op1, nullptr); |
| ... | @@ -17682,6 +17784,8 @@ static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruct | ... | @@ -17682,6 +17784,8 @@ static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruct |
| 17682 | if (array_val == nullptr) | 17784 | if (array_val == nullptr) |
| 17683 | return ira->codegen->invalid_inst_gen; | 17785 | return ira->codegen->invalid_inst_gen; |
| 17684 | want_ptr_to_array = true; | 17786 | want_ptr_to_array = true; |
| | 17787 | } else if (is_tuple(op1->value->type)) { |
| | 17788 | return ir_analyze_tuple_mult(ira, &instruction->base.base, op1, op2); |
| 17685 | } else { | 17789 | } else { |
| 17686 | ir_add_error(ira, &op1->base, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); | 17790 | ir_add_error(ira, &op1->base, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); |
| 17687 | return ira->codegen->invalid_inst_gen; | 17791 | return ira->codegen->invalid_inst_gen; |