| ... | ... | @@ -198,6 +198,9 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * |
| 198 | 198 | IrInstruction *base_ptr, bool initializing); |
| 199 | 199 | static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 200 | 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 | 205 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 203 | 206 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -1069,7 +1072,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) |
| 1069 | 1072 | return IrInstructionIdAssertNonNull; |
| 1070 | 1073 | } |
| 1071 | 1074 | |
| 1072 | | <<<<<<< HEAD |
| 1073 | 1075 | static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { |
| 1074 | 1076 | return IrInstructionIdHasDecl; |
| 1075 | 1077 | } |
| ... | ... | @@ -1357,12 +1359,13 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s |
| 1357 | 1359 | } |
| 1358 | 1360 | |
| 1359 | 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 | 1364 | IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); |
| 1363 | 1365 | instruction->container_ptr = container_ptr; |
| 1364 | 1366 | instruction->field_name_buffer = nullptr; |
| 1365 | 1367 | instruction->field_name_expr = field_name_expr; |
| 1368 | instruction->initializing = initializing; |
| 1366 | 1369 | |
| 1367 | 1370 | ir_ref_instruction(container_ptr, irb->current_basic_block); |
| 1368 | 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 | 3332 | return &instruction->base; |
| 3330 | 3333 | } |
| 3331 | 3334 | |
| 3332 | | static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3333 | | IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) { |
| 3334 | | IrInstructionUnionInit2 *instruction = ir_build_instruction<IrInstructionUnionInit2>(irb, scope, source_node); |
| 3335 | | instruction->union_type_value = union_type_value; |
| 3336 | | instruction->field_name_expr = field_name_expr; |
| 3337 | | instruction->value = value; |
| 3335 | static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3336 | IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) |
| 3337 | { |
| 3338 | IrInstructionUnionInitNamedField *instruction = ir_build_instruction<IrInstructionUnionInitNamedField>(irb, scope, source_node); |
| 3339 | instruction->union_type = union_type; |
| 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); |
| 3340 | | ir_ref_instruction(field_name_expr, irb->current_basic_block); |
| 3341 | | ir_ref_instruction(value, irb->current_basic_block); |
| 3344 | ir_ref_instruction(union_type, irb->current_basic_block); |
| 3345 | ir_ref_instruction(field_name, 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 | 3349 | return &instruction->base; |
| 3344 | 3350 | } |
| ... | ... | @@ -5130,7 +5136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5130 | 5136 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5131 | 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 | 5142 | if (lval == LValPtr) |
| 5136 | 5143 | return ptr_instruction; |
| ... | ... | @@ -5673,26 +5680,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5673 | 5680 | } |
| 5674 | 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); |
| 5678 | | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| 5679 | | if (arg0_value == irb->codegen->invalid_instruction) |
| 5680 | | return arg0_value; |
| 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; |
| 5688 | AstNode *name_node = node->data.fn_call_expr.params.at(1); |
| 5689 | IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); |
| 5690 | if (name_inst == irb->codegen->invalid_instruction) |
| 5691 | return name_inst; |
| 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 result; |
| 5695 | return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, |
| 5696 | lval, result_loc); |
| 5696 | 5697 | } |
| 5697 | 5698 | } |
| 5698 | 5699 | zig_unreachable(); |
| ... | ... | @@ -5972,6 +5973,31 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod |
| 5972 | 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 | 6001 | static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5976 | 6002 | ResultLoc *parent_result_loc) |
| 5977 | 6003 | { |
| ... | ... | @@ -19451,32 +19477,21 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 19451 | 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, |
| 19455 | | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 19456 | | IrInstruction *result_loc) |
| 19480 | static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, |
| 19481 | AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, |
| 19482 | IrInstruction *result_loc) |
| 19457 | 19483 | { |
| 19458 | 19484 | Error err; |
| 19459 | | assert(container_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 | | } |
| 19485 | assert(union_type->id == ZigTypeIdUnion); |
| 19469 | 19486 | |
| 19470 | | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| 19471 | | IrInstruction *field_result_loc = field->result_loc->child; |
| 19472 | | if (type_is_invalid(field_result_loc->value.type)) |
| 19487 | if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) |
| 19473 | 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 | 19491 | if (type_field == nullptr) { |
| 19477 | | ir_add_error_node(ira, field->source_node, |
| 19492 | ir_add_error_node(ira, field_source_node, |
| 19478 | 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 | 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 | 19508 | } |
| 19494 | 19509 | } |
| 19495 | 19510 | |
| 19496 | | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 19497 | | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 19511 | bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) |
| 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 | 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 | 19517 | buf_sprintf("unable to evaluate constant expression")); |
| 19503 | 19518 | return ira->codegen->invalid_instruction; |
| 19504 | 19519 | } |
| ... | ... | @@ -19511,8 +19526,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 19511 | 19526 | { |
| 19512 | 19527 | Error err; |
| 19513 | 19528 | if (container_type->id == ZigTypeIdUnion) { |
| 19514 | | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, |
| 19515 | | fields, result_loc); |
| 19529 | if (instr_field_count != 1) { |
| 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 | 19542 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 19518 | 19543 | ir_add_error(ira, instruction, |
| ... | ... | @@ -25369,33 +25394,33 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst |
| 25369 | 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; |
| 25375 | | IrInstruction *union_type_value = union_init_instruction->union_type_value->child; |
| 25376 | | ZigType *union_type = ir_resolve_type(ira, union_type_value); |
| 25377 | | if (type_is_invalid(union_type)) { |
| 25400 | ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); |
| 25401 | if (type_is_invalid(union_type)) |
| 25378 | 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 | 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 | 25412 | return ira->codegen->invalid_instruction; |
| 25386 | 25413 | |
| 25387 | | IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child; |
| 25388 | | Buf *field_name = ir_resolve_str(ira, field_name_expr); |
| 25389 | | if (!field_name) |
| 25414 | IrInstruction *field_result_loc = instruction->field_result_loc->child; |
| 25415 | if (type_is_invalid(field_result_loc->value.type)) |
| 25390 | 25416 | return ira->codegen->invalid_instruction; |
| 25391 | 25417 | |
| 25392 | | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(1); |
| 25393 | | |
| 25394 | | fields[0].name = field_name; |
| 25395 | | fields[0].value = union_init_instruction->value; |
| 25396 | | fields[0].source_node = union_init_instruction->base.source_node; |
| 25418 | IrInstruction *result_loc = instruction->result_loc->child; |
| 25419 | if (type_is_invalid(result_loc->value.type)) |
| 25420 | return ira->codegen->invalid_instruction; |
| 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 | 25426 | static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { |