| ... | @@ -198,6 +198,9 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * | ... | @@ -198,6 +198,9 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * |
| 198 | IrInstruction *base_ptr, bool initializing); | 198 | IrInstruction *base_ptr, bool initializing); |
| 199 | static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, | 199 | static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 200 | IrInstruction *ptr, IrInstruction *uncasted_value); | 200 | IrInstruction *ptr, IrInstruction *uncasted_value); |
| | 201 | static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 202 | IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, |
| | 203 | LVal lval, ResultLoc *parent_result_loc); |
| 201 | | 204 | |
| 202 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 205 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 203 | assert(get_src_ptr_type(const_val->type) != nullptr); | 206 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -1069,7 +1072,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) | ... | @@ -1069,7 +1072,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) |
| 1069 | return IrInstructionIdAssertNonNull; | 1072 | return IrInstructionIdAssertNonNull; |
| 1070 | } | 1073 | } |
| 1071 | | 1074 | |
| 1072 | <<<<<<< HEAD | | |
| 1073 | static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { | 1075 | static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { |
| 1074 | return IrInstructionIdHasDecl; | 1076 | return IrInstructionIdHasDecl; |
| 1075 | } | 1077 | } |
| ... | @@ -1357,12 +1359,13 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s | ... | @@ -1357,12 +1359,13 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s |
| 1357 | } | 1359 | } |
| 1358 | | 1360 | |
| 1359 | static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1361 | static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1360 | IrInstruction *container_ptr, IrInstruction *field_name_expr) | 1362 | IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing) |
| 1361 | { | 1363 | { |
| 1362 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); | 1364 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); |
| 1363 | instruction->container_ptr = container_ptr; | 1365 | instruction->container_ptr = container_ptr; |
| 1364 | instruction->field_name_buffer = nullptr; | 1366 | instruction->field_name_buffer = nullptr; |
| 1365 | instruction->field_name_expr = field_name_expr; | 1367 | instruction->field_name_expr = field_name_expr; |
| | 1368 | instruction->initializing = initializing; |
| 1366 | | 1369 | |
| 1367 | ir_ref_instruction(container_ptr, irb->current_basic_block); | 1370 | ir_ref_instruction(container_ptr, irb->current_basic_block); |
| 1368 | ir_ref_instruction(field_name_expr, irb->current_basic_block); | 1371 | ir_ref_instruction(field_name_expr, irb->current_basic_block); |
| ... | @@ -3329,16 +3332,19 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, | ... | @@ -3329,16 +3332,19 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, |
| 3329 | return &instruction->base; | 3332 | return &instruction->base; |
| 3330 | } | 3333 | } |
| 3331 | | 3334 | |
| 3332 | static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node, | 3335 | static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3333 | IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) { | 3336 | IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) |
| 3334 | IrInstructionUnionInit2 *instruction = ir_build_instruction<IrInstructionUnionInit2>(irb, scope, source_node); | 3337 | { |
| 3335 | instruction->union_type_value = union_type_value; | 3338 | IrInstructionUnionInitNamedField *instruction = ir_build_instruction<IrInstructionUnionInitNamedField>(irb, scope, source_node); |
| 3336 | instruction->field_name_expr = field_name_expr; | 3339 | instruction->union_type = union_type; |
| 3337 | instruction->value = value; | 3340 | instruction->field_name = field_name; |
| | 3341 | instruction->field_result_loc = field_result_loc; |
| | 3342 | instruction->result_loc = result_loc; |
| 3338 | | 3343 | |
| 3339 | ir_ref_instruction(union_type_value, irb->current_basic_block); | 3344 | ir_ref_instruction(union_type, irb->current_basic_block); |
| 3340 | ir_ref_instruction(field_name_expr, irb->current_basic_block); | 3345 | ir_ref_instruction(field_name, irb->current_basic_block); |
| 3341 | ir_ref_instruction(value, irb->current_basic_block); | 3346 | ir_ref_instruction(field_result_loc, irb->current_basic_block); |
| | 3347 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 3342 | | 3348 | |
| 3343 | return &instruction->base; | 3349 | return &instruction->base; |
| 3344 | } | 3350 | } |
| ... | @@ -5130,7 +5136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5130,7 +5136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5130 | if (arg1_value == irb->codegen->invalid_instruction) | 5136 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5131 | return arg1_value; | 5137 | return arg1_value; |
| 5132 | | 5138 | |
| 5133 | IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value); | 5139 | IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, |
| | 5140 | arg0_value, arg1_value, false); |
| 5134 | | 5141 | |
| 5135 | if (lval == LValPtr) | 5142 | if (lval == LValPtr) |
| 5136 | return ptr_instruction; | 5143 | return ptr_instruction; |
| ... | @@ -5673,26 +5680,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -5673,26 +5680,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5673 | } | 5680 | } |
| 5674 | case BuiltinFnIdUnionInit: | 5681 | case BuiltinFnIdUnionInit: |
| 5675 | { | 5682 | { |
| | 5683 | AstNode *union_type_node = node->data.fn_call_expr.params.at(0); |
| | 5684 | IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope); |
| | 5685 | if (union_type_inst == irb->codegen->invalid_instruction) |
| | 5686 | return union_type_inst; |
| 5676 | | 5687 | |
| 5677 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5688 | AstNode *name_node = node->data.fn_call_expr.params.at(1); |
| 5678 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | 5689 | IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); |
| 5679 | if (arg0_value == irb->codegen->invalid_instruction) | 5690 | if (name_inst == irb->codegen->invalid_instruction) |
| 5680 | return arg0_value; | 5691 | return name_inst; |
| 5681 | | | |
| 5682 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | | |
| 5683 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | | |
| 5684 | if (arg1_value == irb->codegen->invalid_instruction) | | |
| 5685 | return arg1_value; | | |
| 5686 | | | |
| 5687 | AstNode *arg2_node = node->data.fn_call_expr.params.at(2); | | |
| 5688 | IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); | | |
| 5689 | if (arg2_value == irb->codegen->invalid_instruction) | | |
| 5690 | return arg2_value; | | |
| 5691 | | 5692 | |
| 5692 | IrInstruction *result = ir_build_union_init_2(irb, scope, node, arg0_value, arg1_value, arg2_value); | 5693 | AstNode *init_node = node->data.fn_call_expr.params.at(2); |
| 5693 | | 5694 | |
| 5694 | // TODO: Not sure if we need ir_lval_wrap or not. | 5695 | return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, |
| 5695 | return result; | 5696 | lval, result_loc); |
| 5696 | } | 5697 | } |
| 5697 | } | 5698 | } |
| 5698 | zig_unreachable(); | 5699 | zig_unreachable(); |
| ... | @@ -5972,6 +5973,31 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod | ... | @@ -5972,6 +5973,31 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5972 | zig_unreachable(); | 5973 | zig_unreachable(); |
| 5973 | } | 5974 | } |
| 5974 | | 5975 | |
| | 5976 | static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 5977 | IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, |
| | 5978 | LVal lval, ResultLoc *parent_result_loc) |
| | 5979 | { |
| | 5980 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); |
| | 5981 | IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, |
| | 5982 | field_name, true); |
| | 5983 | |
| | 5984 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| | 5985 | result_loc_inst->base.id = ResultLocIdInstruction; |
| | 5986 | result_loc_inst->base.source_instruction = field_ptr; |
| | 5987 | ir_ref_instruction(field_ptr, irb->current_basic_block); |
| | 5988 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| | 5989 | |
| | 5990 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| | 5991 | &result_loc_inst->base); |
| | 5992 | if (expr_value == irb->codegen->invalid_instruction) |
| | 5993 | return expr_value; |
| | 5994 | |
| | 5995 | IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, |
| | 5996 | field_name, field_ptr, container_ptr); |
| | 5997 | |
| | 5998 | return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); |
| | 5999 | } |
| | 6000 | |
| 5975 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, | 6001 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5976 | ResultLoc *parent_result_loc) | 6002 | ResultLoc *parent_result_loc) |
| 5977 | { | 6003 | { |
| ... | @@ -19451,32 +19477,21 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe | ... | @@ -19451,32 +19477,21 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 19451 | return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); | 19477 | return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); |
| 19452 | } | 19478 | } |
| 19453 | | 19479 | |
| 19454 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, | 19480 | static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, |
| 19455 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, | 19481 | AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, |
| 19456 | IrInstruction *result_loc) | 19482 | IrInstruction *result_loc) |
| 19457 | { | 19483 | { |
| 19458 | Error err; | 19484 | Error err; |
| 19459 | assert(container_type->id == ZigTypeIdUnion); | 19485 | assert(union_type->id == ZigTypeIdUnion); |
| 19460 | | | |
| 19461 | if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) | | |
| 19462 | return ira->codegen->invalid_instruction; | | |
| 19463 | | | |
| 19464 | if (instr_field_count != 1) { | | |
| 19465 | ir_add_error(ira, instruction, | | |
| 19466 | buf_sprintf("union initialization expects exactly one field")); | | |
| 19467 | return ira->codegen->invalid_instruction; | | |
| 19468 | } | | |
| 19469 | | 19486 | |
| 19470 | IrInstructionContainerInitFieldsField *field = &fields[0]; | 19487 | if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) |
| 19471 | IrInstruction *field_result_loc = field->result_loc->child; | | |
| 19472 | if (type_is_invalid(field_result_loc->value.type)) | | |
| 19473 | return ira->codegen->invalid_instruction; | 19488 | return ira->codegen->invalid_instruction; |
| 19474 | | 19489 | |
| 19475 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); | 19490 | TypeUnionField *type_field = find_union_type_field(union_type, field_name); |
| 19476 | if (type_field == nullptr) { | 19491 | if (type_field == nullptr) { |
| 19477 | ir_add_error_node(ira, field->source_node, | 19492 | ir_add_error_node(ira, field_source_node, |
| 19478 | buf_sprintf("no member named '%s' in union '%s'", | 19493 | buf_sprintf("no member named '%s' in union '%s'", |
| 19479 | buf_ptr(field->name), buf_ptr(&container_type->name))); | 19494 | buf_ptr(field_name), buf_ptr(&union_type->name))); |
| 19480 | return ira->codegen->invalid_instruction; | 19495 | return ira->codegen->invalid_instruction; |
| 19481 | } | 19496 | } |
| 19482 | | 19497 | |
| ... | @@ -19493,12 +19508,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI | ... | @@ -19493,12 +19508,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 19493 | } | 19508 | } |
| 19494 | } | 19509 | } |
| 19495 | | 19510 | |
| 19496 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) | 19511 | bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) |
| 19497 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; | 19512 | || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; |
| 19498 | | 19513 | |
| 19499 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); | 19514 | IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); |
| 19500 | if (is_comptime && !instr_is_comptime(result)) { | 19515 | if (is_comptime && !instr_is_comptime(result)) { |
| 19501 | ir_add_error(ira, field->result_loc, | 19516 | ir_add_error(ira, field_result_loc, |
| 19502 | buf_sprintf("unable to evaluate constant expression")); | 19517 | buf_sprintf("unable to evaluate constant expression")); |
| 19503 | return ira->codegen->invalid_instruction; | 19518 | return ira->codegen->invalid_instruction; |
| 19504 | } | 19519 | } |
| ... | @@ -19511,8 +19526,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -19511,8 +19526,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 19511 | { | 19526 | { |
| 19512 | Error err; | 19527 | Error err; |
| 19513 | if (container_type->id == ZigTypeIdUnion) { | 19528 | if (container_type->id == ZigTypeIdUnion) { |
| 19514 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, | 19529 | if (instr_field_count != 1) { |
| 19515 | fields, result_loc); | 19530 | ir_add_error(ira, instruction, |
| | 19531 | buf_sprintf("union initialization expects exactly one field")); |
| | 19532 | return ira->codegen->invalid_instruction; |
| | 19533 | } |
| | 19534 | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| | 19535 | IrInstruction *field_result_loc = field->result_loc->child; |
| | 19536 | if (type_is_invalid(field_result_loc->value.type)) |
| | 19537 | return ira->codegen->invalid_instruction; |
| | 19538 | |
| | 19539 | return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name, |
| | 19540 | field_result_loc, result_loc); |
| 19516 | } | 19541 | } |
| 19517 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { | 19542 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 19518 | ir_add_error(ira, instruction, | 19543 | ir_add_error(ira, instruction, |
| ... | @@ -25369,33 +25394,33 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst | ... | @@ -25369,33 +25394,33 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst |
| 25369 | return instruction->result_loc_bit_cast->parent->gen_instruction; | 25394 | return instruction->result_loc_bit_cast->parent->gen_instruction; |
| 25370 | } | 25395 | } |
| 25371 | | 25396 | |
| 25372 | static IrInstruction *ir_analyze_instruction_union_init_2(IrAnalyze *ira, IrInstructionUnionInit2 *union_init_instruction) | 25397 | static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, |
| | 25398 | IrInstructionUnionInitNamedField *instruction) |
| 25373 | { | 25399 | { |
| 25374 | Error err; | 25400 | ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); |
| 25375 | IrInstruction *union_type_value = union_init_instruction->union_type_value->child; | 25401 | if (type_is_invalid(union_type)) |
| 25376 | ZigType *union_type = ir_resolve_type(ira, union_type_value); | | |
| 25377 | if (type_is_invalid(union_type)) { | | |
| 25378 | return ira->codegen->invalid_instruction; | 25402 | return ira->codegen->invalid_instruction; |
| 25379 | } | | |
| 25380 | | 25403 | |
| 25381 | if (union_type->id != ZigTypeIdUnion) | 25404 | if (union_type->id != ZigTypeIdUnion) { |
| | 25405 | ir_add_error(ira, instruction->union_type, |
| | 25406 | buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); |
| 25382 | return ira->codegen->invalid_instruction; | 25407 | return ira->codegen->invalid_instruction; |
| | 25408 | } |
| 25383 | | 25409 | |
| 25384 | if ((err = ensure_complete_type(ira->codegen, union_type))) | 25410 | Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); |
| | 25411 | if (field_name == nullptr) |
| 25385 | return ira->codegen->invalid_instruction; | 25412 | return ira->codegen->invalid_instruction; |
| 25386 | | 25413 | |
| 25387 | IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child; | 25414 | IrInstruction *field_result_loc = instruction->field_result_loc->child; |
| 25388 | Buf *field_name = ir_resolve_str(ira, field_name_expr); | 25415 | if (type_is_invalid(field_result_loc->value.type)) |
| 25389 | if (!field_name) | | |
| 25390 | return ira->codegen->invalid_instruction; | 25416 | return ira->codegen->invalid_instruction; |
| 25391 | | 25417 | |
| 25392 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(1); | 25418 | IrInstruction *result_loc = instruction->result_loc->child; |
| 25393 | | 25419 | if (type_is_invalid(result_loc->value.type)) |
| 25394 | fields[0].name = field_name; | 25420 | return ira->codegen->invalid_instruction; |
| 25395 | fields[0].value = union_init_instruction->value; | | |
| 25396 | fields[0].source_node = union_init_instruction->base.source_node; | | |
| 25397 | | 25421 | |
| 25398 | return ir_analyze_container_init_fields_union(ira, &union_init_instruction->base, union_type, 1, fields); | 25422 | return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node, |
| | 25423 | union_type, field_name, field_result_loc, result_loc); |
| 25399 | } | 25424 | } |
| 25400 | | 25425 | |
| 25401 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { | 25426 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { |