From 9b7ad124810e4a3df964927ace449502daa167f9 Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Thu, 9 May 2019 02:28:14 -0700 Subject: Implement @unionInit --- src/ir.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 7 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 2d81f0c219..643f6845c6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -188,7 +188,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c assert(get_src_ptr_type(const_val->type) != nullptr); assert(const_val->special == ConstValSpecialStatic); ConstExprValue *result; - + switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { case OnePossibleValueInvalid: zig_unreachable(); @@ -200,7 +200,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c case OnePossibleValueNo: break; } - + switch (const_val->data.x_ptr.special) { case ConstPtrSpecialInvalid: zig_unreachable(); @@ -1011,6 +1011,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) return IrInstructionIdAssertNonNull; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit2 *) { + return IrInstructionIdUnionInit2; +} + template static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { T *special_instruction = allocate(1); @@ -1312,6 +1316,7 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast return &instruction->base; } + static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, @@ -3025,6 +3030,21 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, return &instruction->base; } +static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) { + IrInstructionUnionInit2 *instruction = ir_build_instruction(irb, scope, source_node); + instruction->union_type_value = union_type_value; + instruction->field_name_expr = field_name_expr; + instruction->value = value; + + ir_ref_instruction(union_type_value, irb->current_basic_block); + ir_ref_instruction(field_name_expr, irb->current_basic_block); + ir_ref_instruction(value, irb->current_basic_block); + + return &instruction->base; +} + + static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *vector, ZigType *result_type) { @@ -3868,7 +3888,7 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode TldVar *tld_var = allocate(1); init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); tld_var->base.resolution = TldResolutionInvalid; - tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, + tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); scope_decls->decl_table.put(var_name, &tld_var->base); } @@ -5098,6 +5118,29 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } return ir_lval_wrap(irb, scope, result, lval); } + case BuiltinFnIdUnionInit: + { + + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + AstNode *arg2_node = node->data.fn_call_expr.params.at(2); + IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_instruction) + return arg2_value; + + IrInstruction *result = ir_build_union_init_2(irb, scope, node, arg0_value, arg1_value, arg2_value); + + // TODO: Not sure if we need ir_lval_wrap or not. + return result; + } } zig_unreachable(); } @@ -6328,7 +6371,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit prong_values, prong_values_len); var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); } else { - var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, + var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); } IrInstruction *var_type = nullptr; // infer the type @@ -12372,7 +12415,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * } else { return is_non_null; } - } else if (is_equality_cmp && + } else if (is_equality_cmp && ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && op2->value.type->data.pointer.ptr_len == PtrLenC) || (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && @@ -19383,7 +19426,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); return ira->codegen->invalid_instruction; } - + if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); return ira->codegen->invalid_instruction; @@ -20333,7 +20376,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio return ira->codegen->invalid_instruction; // TODO test this at comptime with u8 and non-u8 types - // TODO test with dest ptr being a global runtime variable + // TODO test with dest ptr being a global runtime variable if (casted_dest_ptr->value.special == ConstValSpecialStatic && casted_src_ptr->value.special == ConstValSpecialStatic && casted_count->value.special == ConstValSpecialStatic && @@ -23151,6 +23194,35 @@ static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, return ir_const_void(ira, &instruction->base); } +static IrInstruction *ir_analyze_instruction_union_init_2(IrAnalyze *ira, IrInstructionUnionInit2 *union_init_instruction) +{ + Error err; + IrInstruction *union_type_value = union_init_instruction->union_type_value->child; + ZigType *union_type = ir_resolve_type(ira, union_type_value); + if (type_is_invalid(union_type)) { + return ira->codegen->invalid_instruction; + } + + if (union_type->id != ZigTypeIdUnion) + return ira->codegen->invalid_instruction; + + if ((err = ensure_complete_type(ira->codegen, union_type))) + return ira->codegen->invalid_instruction; + + IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child; + Buf *field_name = ir_resolve_str(ira, field_name_expr); + if (!field_name) + return ira->codegen->invalid_instruction; + + IrInstructionContainerInitFieldsField *fields = allocate(1); + + fields[0].name = field_name; + fields[0].value = union_init_instruction->value; + fields[0].source_node = union_init_instruction->base.source_node; + + return ir_analyze_container_init_fields_union(ira, &union_init_instruction->base, union_type, 1, fields); +} + static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { switch (instruction->id) { case IrInstructionIdInvalid: @@ -23445,6 +23517,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); case IrInstructionIdCheckRuntimeScope: return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); + case IrInstructionIdUnionInit2: + return ir_analyze_instruction_union_init_2(ira, (IrInstructionUnionInit2 *)instruction); } zig_unreachable(); } @@ -23681,6 +23755,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdEnumToInt: case IrInstructionIdVectorToArray: case IrInstructionIdArrayToVector: + case IrInstructionIdUnionInit2: + return false; case IrInstructionIdAsm: -- cgit v1.2.3 From 4bae87764fc455f4df8b9d96be856921b0dd97db Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 3 Jul 2019 13:40:40 -0400 Subject: update `@unionInit` to integrate with result location semantics --- doc/langref.html.in | 17 ++++++ src/all_types.hpp | 3 +- src/ir.cpp | 167 ++++++++++++++++++++++++++++++---------------------- src/ir_print.cpp | 4 +- 4 files changed, 118 insertions(+), 73 deletions(-) (limited to 'src/ir.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index fda741930b..ef914375f4 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5065,6 +5065,12 @@ test "@intToPtr for pointer to zero bit type" { {#header_close#} {#header_close#} + {#header_open|Result Location Semantics#} +

+ TODO add documentation for this +

+ {#header_close#} + {#header_open|comptime#}

Zig places importance on the concept of whether an expression is known at compile-time. @@ -7809,6 +7815,17 @@ pub const TypeInfo = union(TypeId) { {#header_close#} + {#header_open|@unionInit#} +

{#syntax#}@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union{#endsyntax#}
+

+ This is the same thing as {#link|union#} initialization syntax, except that the field name is a + {#link|comptime#}-known value rather than an identifier token. +

+

+ {#syntax#}@unionInit{#endsyntax#} forwards its {#link|result location|Result Location Semantics#} to {#syntax#}init_expr{#endsyntax#}. +

+ {#header_close#} + {#header_open|@Vector#}
{#syntax#}@Vector(comptime len: u32, comptime ElemType: type) type{#endsyntax#}

diff --git a/src/all_types.hpp b/src/all_types.hpp index 0d187a1c4e..c1e54baf8d 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3610,7 +3610,8 @@ struct IrInstructionUnionInitNamedField { IrInstruction *union_type; IrInstruction *field_name; - IrInstruction *value; + IrInstruction *field_result_loc; + IrInstruction *result_loc; }; struct IrInstructionHasDecl { diff --git a/src/ir.cpp b/src/ir.cpp index 594f61982a..6b19ce2909 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -198,6 +198,9 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * IrInstruction *base_ptr, bool initializing); static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, IrInstruction *uncasted_value); +static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, + LVal lval, ResultLoc *parent_result_loc); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -1069,7 +1072,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) return IrInstructionIdAssertNonNull; } -<<<<<<< HEAD static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { return IrInstructionIdHasDecl; } @@ -1357,12 +1359,13 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s } static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_ptr, IrInstruction *field_name_expr) + IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing) { IrInstructionFieldPtr *instruction = ir_build_instruction(irb, scope, source_node); instruction->container_ptr = container_ptr; instruction->field_name_buffer = nullptr; instruction->field_name_expr = field_name_expr; + instruction->initializing = initializing; ir_ref_instruction(container_ptr, irb->current_basic_block); 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, return &instruction->base; } -static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) { - IrInstructionUnionInit2 *instruction = ir_build_instruction(irb, scope, source_node); - instruction->union_type_value = union_type_value; - instruction->field_name_expr = field_name_expr; - instruction->value = value; +static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) +{ + IrInstructionUnionInitNamedField *instruction = ir_build_instruction(irb, scope, source_node); + instruction->union_type = union_type; + instruction->field_name = field_name; + instruction->field_result_loc = field_result_loc; + instruction->result_loc = result_loc; - ir_ref_instruction(union_type_value, irb->current_basic_block); - ir_ref_instruction(field_name_expr, irb->current_basic_block); - ir_ref_instruction(value, irb->current_basic_block); + ir_ref_instruction(union_type, irb->current_basic_block); + ir_ref_instruction(field_name, irb->current_basic_block); + ir_ref_instruction(field_result_loc, irb->current_basic_block); + if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); return &instruction->base; } @@ -5130,7 +5136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo if (arg1_value == irb->codegen->invalid_instruction) return arg1_value; - IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value); + IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, + arg0_value, arg1_value, false); if (lval == LValPtr) return ptr_instruction; @@ -5673,26 +5680,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } case BuiltinFnIdUnionInit: { + AstNode *union_type_node = node->data.fn_call_expr.params.at(0); + IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope); + if (union_type_inst == irb->codegen->invalid_instruction) + return union_type_inst; - AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) - return arg0_value; - - AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) - return arg1_value; - - AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) - return arg2_value; + AstNode *name_node = node->data.fn_call_expr.params.at(1); + IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); + if (name_inst == irb->codegen->invalid_instruction) + return name_inst; - IrInstruction *result = ir_build_union_init_2(irb, scope, node, arg0_value, arg1_value, arg2_value); + AstNode *init_node = node->data.fn_call_expr.params.at(2); - // TODO: Not sure if we need ir_lval_wrap or not. - return result; + return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, + lval, result_loc); } } zig_unreachable(); @@ -5972,6 +5973,31 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod zig_unreachable(); } +static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, + LVal lval, ResultLoc *parent_result_loc) +{ + IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); + IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, + field_name, true); + + ResultLocInstruction *result_loc_inst = allocate(1); + result_loc_inst->base.id = ResultLocIdInstruction; + result_loc_inst->base.source_instruction = field_ptr; + ir_ref_instruction(field_ptr, irb->current_basic_block); + ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); + + IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, + &result_loc_inst->base); + if (expr_value == irb->codegen->invalid_instruction) + return expr_value; + + IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, + field_name, field_ptr, container_ptr); + + return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); +} + static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *parent_result_loc) { @@ -19451,32 +19477,21 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); } -static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, - ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, - IrInstruction *result_loc) +static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, + AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, + IrInstruction *result_loc) { Error err; - assert(container_type->id == ZigTypeIdUnion); - - if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; - - if (instr_field_count != 1) { - ir_add_error(ira, instruction, - buf_sprintf("union initialization expects exactly one field")); - return ira->codegen->invalid_instruction; - } + assert(union_type->id == ZigTypeIdUnion); - IrInstructionContainerInitFieldsField *field = &fields[0]; - IrInstruction *field_result_loc = field->result_loc->child; - if (type_is_invalid(field_result_loc->value.type)) + if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) return ira->codegen->invalid_instruction; - TypeUnionField *type_field = find_union_type_field(container_type, field->name); + TypeUnionField *type_field = find_union_type_field(union_type, field_name); if (type_field == nullptr) { - ir_add_error_node(ira, field->source_node, + ir_add_error_node(ira, field_source_node, buf_sprintf("no member named '%s' in union '%s'", - buf_ptr(field->name), buf_ptr(&container_type->name))); + buf_ptr(field_name), buf_ptr(&union_type->name))); return ira->codegen->invalid_instruction; } @@ -19493,12 +19508,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI } } - bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) - || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; + bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) + || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; - IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); + IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); if (is_comptime && !instr_is_comptime(result)) { - ir_add_error(ira, field->result_loc, + ir_add_error(ira, field_result_loc, buf_sprintf("unable to evaluate constant expression")); return ira->codegen->invalid_instruction; } @@ -19511,8 +19526,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc { Error err; if (container_type->id == ZigTypeIdUnion) { - return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, - fields, result_loc); + if (instr_field_count != 1) { + ir_add_error(ira, instruction, + buf_sprintf("union initialization expects exactly one field")); + return ira->codegen->invalid_instruction; + } + IrInstructionContainerInitFieldsField *field = &fields[0]; + IrInstruction *field_result_loc = field->result_loc->child; + if (type_is_invalid(field_result_loc->value.type)) + return ira->codegen->invalid_instruction; + + return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name, + field_result_loc, result_loc); } if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { ir_add_error(ira, instruction, @@ -25369,33 +25394,33 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst return instruction->result_loc_bit_cast->parent->gen_instruction; } -static IrInstruction *ir_analyze_instruction_union_init_2(IrAnalyze *ira, IrInstructionUnionInit2 *union_init_instruction) +static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, + IrInstructionUnionInitNamedField *instruction) { - Error err; - IrInstruction *union_type_value = union_init_instruction->union_type_value->child; - ZigType *union_type = ir_resolve_type(ira, union_type_value); - if (type_is_invalid(union_type)) { + ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); + if (type_is_invalid(union_type)) return ira->codegen->invalid_instruction; - } - if (union_type->id != ZigTypeIdUnion) + if (union_type->id != ZigTypeIdUnion) { + ir_add_error(ira, instruction->union_type, + buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); return ira->codegen->invalid_instruction; + } - if ((err = ensure_complete_type(ira->codegen, union_type))) + Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); + if (field_name == nullptr) return ira->codegen->invalid_instruction; - IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child; - Buf *field_name = ir_resolve_str(ira, field_name_expr); - if (!field_name) + IrInstruction *field_result_loc = instruction->field_result_loc->child; + if (type_is_invalid(field_result_loc->value.type)) return ira->codegen->invalid_instruction; - IrInstructionContainerInitFieldsField *fields = allocate(1); - - fields[0].name = field_name; - fields[0].value = union_init_instruction->value; - fields[0].source_node = union_init_instruction->base.source_node; + IrInstruction *result_loc = instruction->result_loc->child; + if (type_is_invalid(result_loc->value.type)) + return ira->codegen->invalid_instruction; - return ir_analyze_container_init_fields_union(ira, &union_init_instruction->base, union_type, 1, fields); + return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node, + union_type, field_name, field_result_loc, result_loc); } static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 3ecb7fb683..588a9b2882 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1632,7 +1632,9 @@ static void ir_print_union_init_named_field(IrPrint *irp, IrInstructionUnionInit fprintf(irp->f, ", "); ir_print_other_instruction(irp, instruction->field_name); fprintf(irp->f, ", "); - ir_print_other_instruction(irp, instruction->value); + ir_print_other_instruction(irp, instruction->field_result_loc); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->result_loc); fprintf(irp->f, ")"); } -- cgit v1.2.3