diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-12-02 00:03:41 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-02 00:03:41 -0500 |
| commit | fecd540826b14275784f10fe429ed147543377b6 (patch) | |
| tree | cb2e096bd1b4ec17f7badc7ac73e706d66c99df1 /src/ir.cpp | |
| parent | 4b6740e19d57454f3c4eac0c2e9a92ce08e7ec04 (diff) | |
| parent | e7ee6647a16738d344173d0482028dc5578cc6c2 (diff) | |
| download | zig-fecd540826b14275784f10fe429ed147543377b6.tar.gz zig-fecd540826b14275784f10fe429ed147543377b6.zip | |
Merge pull request #3787 from ziglang/remove-array-type-coercion
Remove array type coercion and fix result location bugs
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 727 |
1 files changed, 381 insertions, 346 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 93b16dc8d3..fbb1f1761e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -42,6 +42,10 @@ struct IrAnalyze { ZigList<IrSuspendPosition> resume_stack; IrBasicBlock *const_predecessor_bb; size_t ref_count; + size_t break_debug_id; // for debugging purposes + + // For the purpose of using in a debugger + void dump(); }; enum ConstCastResultId { @@ -195,6 +199,14 @@ struct ConstCastIntShorten { ZigType *actual_type; }; +// for debugging purposes +struct DbgIrBreakPoint { + const char *src_file; + uint32_t line; +}; +DbgIrBreakPoint dbg_ir_breakpoints_buf[20]; +size_t dbg_ir_breakpoints_count = 0; + static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, ResultLoc *result_loc); @@ -220,14 +232,15 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on); static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); -static void copy_const_val(ZigValue *dest, ZigValue *src, bool same_global_refs); +static void copy_const_val(ZigValue *dest, ZigValue *src); static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, ZigType *ptr_type); static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *dest_type); static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); + ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, + bool non_null_comptime, bool allow_discard); static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime, bool allow_discard); @@ -733,6 +746,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte case ZigTypeIdErrorSet: case ZigTypeIdOpaque: case ZigTypeIdAnyFrame: + case ZigTypeIdFn: return true; case ZigTypeIdFloat: return expected->data.floating.bit_count == actual->data.floating.bit_count; @@ -744,7 +758,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte case ZigTypeIdErrorUnion: case ZigTypeIdEnum: case ZigTypeIdUnion: - case ZigTypeIdFn: case ZigTypeIdArgTuple: case ZigTypeIdVector: case ZigTypeIdFnFrame: @@ -1541,7 +1554,6 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no special_instruction->base.debug_id = exec_next_debug_id(irb->exec); special_instruction->base.owner_bb = irb->current_basic_block; special_instruction->base.value = allocate<ZigValue>(1, "ZigValue"); - special_instruction->base.value->global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs"); return special_instruction; } @@ -4324,6 +4336,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode scope_block->peer_parent = allocate<ResultLocPeerParent>(1, "ResultLocPeerParent"); scope_block->peer_parent->base.id = ResultLocIdPeerParent; scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; + scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; scope_block->peer_parent->end_bb = scope_block->end_block; scope_block->peer_parent->is_comptime = scope_block->is_comptime; scope_block->peer_parent->parent = result_loc; @@ -4578,6 +4591,7 @@ static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); peer_parent->base.id = ResultLocIdPeerParent; peer_parent->base.source_instruction = cond_br_inst; + peer_parent->base.allow_write_through_const = parent->allow_write_through_const; peer_parent->end_bb = end_block; peer_parent->is_comptime = is_comptime; peer_parent->parent = parent; @@ -6349,7 +6363,9 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); - ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc()); + ResultLoc *no_result = no_result_loc(); + ir_build_reset_result(irb, scope, node, no_result); + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); if (arg == irb->codegen->invalid_instruction) @@ -6771,6 +6787,7 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo ResultLocVar *result_loc_var = allocate<ResultLocVar>(1); result_loc_var->base.id = ResultLocIdVar; result_loc_var->base.source_instruction = alloca; + result_loc_var->base.allow_write_through_const = true; result_loc_var->var = var; ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base); @@ -6784,6 +6801,7 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1); result_loc_cast->base.id = ResultLocIdCast; result_loc_cast->base.source_instruction = dest_type; + result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; ir_ref_instruction(dest_type, irb->current_basic_block); result_loc_cast->parent = parent_result_loc; @@ -7964,6 +7982,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); peer_parent->base.id = ResultLocIdPeerParent; + peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; peer_parent->end_bb = end_block; peer_parent->is_comptime = is_comptime; peer_parent->parent = result_loc; @@ -9111,7 +9130,7 @@ static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, Ast if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) return err; ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); - copy_const_val(child_val, &tmp, false); + copy_const_val(child_val, &tmp); return ErrorNone; } @@ -10756,10 +10775,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT continue; } ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; - if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { + bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && + cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; + if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { return ira->codegen->builtin_types.entry_invalid; } - if (type_is_global_error_set(cur_err_set_type)) { + if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { err_set_type = ira->codegen->builtin_types.entry_global_error_set; prev_inst = cur_inst; continue; @@ -10809,9 +10830,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } if (cur_type->id == ZigTypeIdErrorSet) { - if (prev_type->id == ZigTypeIdArray) { - convert_to_const_slice = true; - } if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { return ira->codegen->builtin_types.entry_invalid; } @@ -11146,25 +11164,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } - if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && - cur_type->data.array.len != prev_type->data.array.len && - types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - convert_to_const_slice = true; - prev_inst = cur_inst; - continue; - } - - if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && - cur_type->data.array.len != prev_type->data.array.len && - types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - convert_to_const_slice = true; - continue; - } - // *[N]T to []T // *[N]T to E![]T if (cur_type->id == ZigTypeIdPointer && @@ -11212,19 +11211,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } - // [N]T to []T - if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && - (prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || - cur_type->data.array.len == 0) && - types_match_const_cast_only(ira, - prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type, - cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) - { - convert_to_const_slice = false; - continue; - } - - // *[N]T and *[M]T if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && cur_type->data.pointer.child_type->id == ZigTypeIdArray && @@ -11268,19 +11254,6 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT continue; } - // [N]T to []T - if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && - (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || - prev_type->data.array.len == 0) && - types_match_const_cast_only(ira, - cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type, - prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) - { - prev_inst = cur_inst; - convert_to_const_slice = false; - continue; - } - if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) { @@ -11316,18 +11289,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT free(errors); if (convert_to_const_slice) { - if (prev_inst->value->type->id == ZigTypeIdArray) { - ZigType *ptr_type = get_pointer_to_type_extra( - ira->codegen, prev_inst->value->type->data.array.child_type, - true, false, PtrLenUnknown, - 0, 0, 0, false); - ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); - if (err_set_type != nullptr) { - return get_error_union_type(ira->codegen, err_set_type, slice_type); - } else { - return slice_type; - } - } else if (prev_inst->value->type->id == ZigTypeIdPointer) { + if (prev_inst->value->type->id == ZigTypeIdPointer) { ZigType *array_type = prev_inst->value->type->data.pointer.child_type; src_assert(array_type->id == ZigTypeIdArray, source_node); ZigType *ptr_type = get_pointer_to_type_extra2( @@ -11394,19 +11356,37 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } } -static void copy_const_val(ZigValue *dest, ZigValue *src, bool same_global_refs) { - ConstGlobalRefs *global_refs = dest->global_refs; +// Returns whether the x_optional field of ZigValue is active. +static bool type_has_optional_repr(ZigType *ty) { + if (ty->id != ZigTypeIdOptional) { + return false; + } else if (get_codegen_ptr_type(ty) != nullptr) { + return false; + } else if (is_opt_err_set(ty)) { + return false; + } else { + return true; + } +} + +static void copy_const_val(ZigValue *dest, ZigValue *src) { memcpy(dest, src, sizeof(ZigValue)); - if (!same_global_refs) { - dest->global_refs = global_refs; - if (src->special != ConstValSpecialStatic) - return; - if (dest->type->id == ZigTypeIdStruct) { - dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); - for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { - copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i], false); - } + if (src->special != ConstValSpecialStatic) + return; + dest->parent.id = ConstParentIdNone; + if (dest->type->id == ZigTypeIdStruct) { + dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); + for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { + copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i]); + dest->data.x_struct.fields[i]->parent.id = ConstParentIdStruct; + dest->data.x_struct.fields[i]->parent.data.p_struct.struct_val = dest; + dest->data.x_struct.fields[i]->parent.data.p_struct.field_index = i; } + } else if (type_has_optional_repr(dest->type) && dest->data.x_optional != nullptr) { + dest->data.x_optional = create_const_vals(1); + copy_const_val(dest->data.x_optional, src->data.x_optional); + dest->data.x_optional->parent.id = ConstParentIdOptionalPayload; + dest->data.x_optional->parent.data.p_optional_payload.optional_val = dest; } } @@ -11424,13 +11404,11 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_ case CastOpErrSet: case CastOpBitCast: zig_panic("TODO"); - case CastOpNoop: - { - bool same_global_refs = other_val->special == ConstValSpecialStatic; - copy_const_val(const_val, other_val, same_global_refs); - const_val->type = new_type; - break; - } + case CastOpNoop: { + copy_const_val(const_val, other_val); + const_val->type = new_type; + break; + } case CastOpNumLitToConcrete: if (other_val->type->id == ZigTypeIdComptimeFloat) { assert(new_type->id == ZigTypeIdFloat); @@ -11527,6 +11505,14 @@ static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruct return &const_instruction->base; } +// This function initializes the new IrInstruction with the provided ZigValue, +// rather than creating a new one. +static IrInstruction *ir_const_move(IrAnalyze *ira, IrInstruction *old_instruction, ZigValue *val) { + IrInstruction *result = ir_const_noval(ira, old_instruction); + result->value = val; + return result; +} + static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type, CastOp cast_op) { @@ -12151,7 +12137,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so source_instr->scope, source_instr->source_node); const_instruction->base.value->special = ConstValSpecialStatic; if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { - copy_const_val(const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); + copy_const_val(const_instruction->base.value, val); } else { const_instruction->base.value->data.x_optional = val; } @@ -12413,52 +12399,6 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi return new_instruction; } -static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc) -{ - assert(is_slice(wanted_type)); - // In this function we honor the const-ness of wanted_type, because - // we may be casting [0]T to []const T which is perfectly valid. - - IrInstruction *array_ptr = nullptr; - IrInstruction *array; - if (array_arg->value->type->id == ZigTypeIdPointer) { - array = ir_get_deref(ira, source_instr, array_arg, nullptr); - array_ptr = array_arg; - } else { - array = array_arg; - } - ZigType *array_type = array->value->type; - assert(array_type->id == ZigTypeIdArray); - - if (instr_is_comptime(array) || array_type->data.array.len == 0) { - IrInstruction *result = ir_const(ira, source_instr, wanted_type); - init_const_slice(ira->codegen, result->value, array->value, 0, array_type->data.array.len, true); - result->value->type = wanted_type; - return result; - } - - IrInstruction *start = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); - init_const_usize(ira->codegen, start->value, 0); - - IrInstruction *end = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); - init_const_usize(ira->codegen, end->value, array_type->data.array.len); - - if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); - - if (result_loc == nullptr) result_loc = no_result_loc(); - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, - true, false, true); - if (type_is_invalid(result_loc_inst->value->type) || instr_is_unreachable(result_loc_inst)) { - return result_loc_inst; - } - IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst); - result->value->data.rh_slice.id = RuntimeHintSliceIdLen; - result->value->data.rh_slice.len = array_type->data.array.len; - - return result; -} - static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, IrInstruction *source_instr, ZigType *union_type) { assert(union_type->id == ZigTypeIdUnion); @@ -13155,7 +13095,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction * if (instr_is_comptime(array)) { // arrays and vectors have the same ZigValue representation IrInstruction *result = ir_const(ira, source_instr, vector_type); - copy_const_val(result->value, array->value, false); + copy_const_val(result->value, array->value); result->value->type = vector_type; return result; } @@ -13168,7 +13108,7 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * if (instr_is_comptime(vector)) { // arrays and vectors have the same ZigValue representation IrInstruction *result = ir_const(ira, source_instr, array_type); - copy_const_val(result->value, vector->value, false); + copy_const_val(result->value, vector->value); result->value->type = array_type; return result; } @@ -13456,7 +13396,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { IrInstruction *result = ir_const(ira, source_instr, wanted_type); if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { - copy_const_val(result->value, value->value, false); + copy_const_val(result->value, value->value); result->value->type = wanted_type; } else { float_init_bigint(&result->value->data.x_bigint, value->value); @@ -13504,44 +13444,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } - // cast from [N]T to []const T - // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this - if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { - ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; - assert(ptr_type->id == ZigTypeIdPointer); - if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && - types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, nullptr); - } - } - - // cast from [N]T to ?[]const T - // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this - if (wanted_type->id == ZigTypeIdOptional && - is_slice(wanted_type->data.maybe.child_type) && - actual_type->id == ZigTypeIdArray) - { - ZigType *ptr_type = - wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index]->type_entry; - assert(ptr_type->id == ZigTypeIdPointer); - if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && - types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); - if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; - - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); - if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; - - return cast2; - } - } - // *[N]T to ?[]const T if (wanted_type->id == ZigTypeIdOptional && is_slice(wanted_type->data.maybe.child_type) && @@ -13687,20 +13589,41 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } // *@Frame(func) to anyframe->T or anyframe + // *@Frame(func) to ?anyframe->T or ?anyframe + // *@Frame(func) to E!anyframe->T or E!anyframe if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && !actual_type->data.pointer.is_const && - actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame && wanted_type->id == ZigTypeIdAnyFrame) + actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame) { - bool ok = true; - if (wanted_type->data.any_frame.result_type != nullptr) { - ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; - ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; - if (wanted_type->data.any_frame.result_type != fn_return_type) { - ok = false; + ZigType *anyframe_type; + if (wanted_type->id == ZigTypeIdAnyFrame) { + anyframe_type = wanted_type; + } else if (wanted_type->id == ZigTypeIdOptional && + wanted_type->data.maybe.child_type->id == ZigTypeIdAnyFrame) + { + anyframe_type = wanted_type->data.maybe.child_type; + } else if (wanted_type->id == ZigTypeIdErrorUnion && + wanted_type->data.error_union.payload_type->id == ZigTypeIdAnyFrame) + { + anyframe_type = wanted_type->data.error_union.payload_type; + } else { + anyframe_type = nullptr; + } + if (anyframe_type != nullptr) { + bool ok = true; + if (anyframe_type->data.any_frame.result_type != nullptr) { + ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; + ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; + if (anyframe_type->data.any_frame.result_type != fn_return_type) { + ok = false; + } + } + if (ok) { + IrInstruction *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); + if (anyframe_type == wanted_type) + return cast1; + return ir_analyze_cast(ira, source_instr, wanted_type, cast1); } - } - if (ok) { - return ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, wanted_type); } } @@ -13725,30 +13648,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); } - // cast from [N]T to E![]const T - if (wanted_type->id == ZigTypeIdErrorUnion && - is_slice(wanted_type->data.error_union.payload_type) && - actual_type->id == ZigTypeIdArray) - { - ZigType *ptr_type = - wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index]->type_entry; - assert(ptr_type->id == ZigTypeIdPointer); - if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && - types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, - source_node, false).id == ConstCastResultIdOk) - { - IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); - if (type_is_invalid(cast1->value->type)) - return ira->codegen->invalid_instruction; - - IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); - if (type_is_invalid(cast2->value->type)) - return ira->codegen->invalid_instruction; - - return cast2; - } - } - // cast from E to E!T if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorSet) @@ -13944,6 +13843,24 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); } + // T to ?U, where T implicitly casts to U + if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { + IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); + if (type_is_invalid(cast1->value->type)) + return ira->codegen->invalid_instruction; + return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); + } + + // T to E!U, where T implicitly casts to U + if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && + actual_type->id != ZigTypeIdErrorSet) + { + IrInstruction *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); + if (type_is_invalid(cast1->value->type)) + return ira->codegen->invalid_instruction; + return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); + } + ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, buf_sprintf("expected type '%s', found '%s'", buf_ptr(&wanted_type->name), @@ -14338,9 +14255,7 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio } static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { - IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, instruction->base.value, true); - return result; + return ir_const_move(ira, &instruction->base, instruction->base.value); } static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { @@ -14878,7 +14793,7 @@ never_mind_just_calculate_it_normally: &op1_val->data.x_array.data.s_none.elements[i], &op2_val->data.x_array.data.s_none.elements[i], bin_op_instruction, op_id, one_possible_value); - copy_const_val(&result->value->data.x_array.data.s_none.elements[i], cur_res->value, false); + copy_const_val(&result->value->data.x_array.data.s_none.elements[i], cur_res->value); } return result; } @@ -15686,10 +15601,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i ZigValue *out_array_val; size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); - if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { - result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); - out_array_val = out_val; - } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { + if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { out_array_val = create_const_vals(1); out_array_val->special = ConstValSpecialStatic; out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); @@ -15717,6 +15629,9 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); + } else if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { + result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); + out_array_val = out_val; } else { result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); @@ -15744,21 +15659,21 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i size_t next_index = 0; for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; - copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i], false); + copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_array_val; elem_dest_val->parent.data.p_array.elem_index = next_index; } for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; - copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i], false); + copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_array_val; elem_dest_val->parent.data.p_array.elem_index = next_index; } if (next_index < full_len) { ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; - copy_const_val(elem_dest_val, sentinel, false); + copy_const_val(elem_dest_val, sentinel); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_array_val; elem_dest_val->parent.data.p_array.elem_index = next_index; @@ -15843,7 +15758,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * for (uint64_t x = 0; x < mult_amt; x += 1) { for (uint64_t y = 0; y < old_array_len; y += 1) { ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; - copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y], false); + copy_const_val(elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_val; elem_dest_val->parent.data.p_array.elem_index = i; @@ -15854,7 +15769,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * if (array_type->data.array.sentinel != nullptr) { ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; - copy_const_val(elem_dest_val, array_type->data.array.sentinel, false); + copy_const_val(elem_dest_val, array_type->data.array.sentinel); elem_dest_val->parent.id = ConstParentIdArray; elem_dest_val->parent.data.p_array.array_val = out_val; elem_dest_val->parent.data.p_array.elem_index = i; @@ -16004,7 +15919,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, var->const_value = init_val; } else { var->const_value = create_const_vals(1); - copy_const_val(var->const_value, init_val, false); + copy_const_val(var->const_value, init_val); } } } @@ -16030,7 +15945,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, result_type = ira->codegen->builtin_types.entry_invalid; } else if (init_val->type->id == ZigTypeIdFn && init_val->special != ConstValSpecialUndef && - init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && + init_val->data.x_ptr.special == ConstPtrSpecialFunction && init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) { var_class_requires_const = true; @@ -16114,7 +16029,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); ZigValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); - copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); + copy_const_val(mem_slot, init_val); ira_ref(var->owner_exec->analysis); if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { @@ -16546,7 +16461,8 @@ static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *su // when calling this function, at the callsite must check for result type noreturn and propagate it up static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) + ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, + bool non_null_comptime, bool allow_discard) { Error err; if (result_loc->resolved_loc != nullptr) { @@ -16584,7 +16500,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe bool force_comptime; if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) return ira->codegen->invalid_instruction; - bool is_comptime = force_comptime || (value != nullptr && + bool is_comptime = force_comptime || (!force_runtime && value != nullptr && value->value->special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const); if (alloca_src->base.child == nullptr || is_comptime) { @@ -16594,15 +16510,19 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } IrInstruction *alloca_gen; if (is_comptime && value != nullptr) { - if (align > value->value->global_refs->align) { - value->value->global_refs->align = align; + if (align > value->value->llvm_align) { + value->value->llvm_align = align; } alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false); } else { alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align, alloca_src->name_hint, force_comptime); + if (force_runtime) { + alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; + alloca_gen->value->special = ConstValSpecialRuntime; + } } - if (alloca_src->base.child != nullptr) { + if (alloca_src->base.child != nullptr && !result_loc->written) { alloca_src->base.child->ref_count = 0; } alloca_src->base.child = alloca_gen; @@ -16617,6 +16537,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return result_loc->resolved_loc; } case ResultLocIdReturn: { + if (value != nullptr) { + reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; + ira->src_implicit_return_type_list.append(value); + } if (!non_null_comptime) { bool is_comptime = value != nullptr && value->value->special != ConstValSpecialRuntime; if (is_comptime) @@ -16659,10 +16583,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe return result_loc->resolved_loc; } - bool is_comptime; - if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) + bool is_condition_comptime; + if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) return ira->codegen->invalid_instruction; - if (is_comptime) { + if (is_condition_comptime) { peer_parent->skipped = true; if (non_null_comptime) { return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, @@ -16674,13 +16598,18 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) return ira->codegen->invalid_instruction; if (peer_parent_has_type) { - if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { - reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true; - ira->src_implicit_return_type_list.append(value); - } peer_parent->skipped = true; - return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime || !is_comptime, true, true); + IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, + value_type, value, force_runtime || !is_condition_comptime, true, true); + if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || + parent_result_loc->value->type->id == ZigTypeIdUnreachable) + { + return parent_result_loc; + } + peer_parent->parent->written = true; + result_loc->written = true; + result_loc->resolved_loc = parent_result_loc; + return result_loc->resolved_loc; } if (peer_parent->resolved_type == nullptr) { @@ -16702,14 +16631,14 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe { return parent_result_loc; } - // because is_comptime is false, we mark this a runtime pointer + // because is_condition_comptime is false, we mark this a runtime pointer parent_result_loc->value->special = ConstValSpecialRuntime; result_loc->written = true; result_loc->resolved_loc = parent_result_loc; return result_loc->resolved_loc; } case ResultLocIdCast: { - if (value != nullptr && value->value->special != ConstValSpecialRuntime) + if (value != nullptr && value->value->special != ConstValSpecialRuntime && !non_null_comptime) return nullptr; ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); @@ -16721,30 +16650,16 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe force_runtime, non_null_comptime); } - ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, - result_cast->base.source_instruction->source_node, false); - if (const_cast_result.id == ConstCastResultIdInvalid) - return ira->codegen->invalid_instruction; - if (const_cast_result.id != ConstCastResultIdOk) { - // We will not be able to provide a result location for this value. Create - // a new result location. - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); - } - - // In this case we can pointer cast the result location. IrInstruction *casted_value; if (value != nullptr) { casted_value = ir_implicit_cast(ira, value, dest_type); + if (type_is_invalid(casted_value->value->type)) + return ira->codegen->invalid_instruction; + dest_type = casted_value->value->type; } else { casted_value = nullptr; } - if (casted_value != nullptr && type_is_invalid(casted_value->value->type)) { - return casted_value; - } - - bool old_parent_result_loc_written = result_cast->parent->written; IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, dest_type, casted_value, force_runtime, non_null_comptime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || @@ -16752,8 +16667,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe { return parent_result_loc; } + ZigType *parent_ptr_type = parent_result_loc->value->type; assert(parent_ptr_type->id == ZigTypeIdPointer); + if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { @@ -16782,20 +16699,20 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); - { - // we also need to check that this cast is OK. - ConstCastOnly const_cast_result = types_match_const_cast_only(ira, - parent_result_loc->value->type, ptr_type, - result_cast->base.source_instruction->source_node, false); - if (const_cast_result.id == ConstCastResultIdInvalid) - return ira->codegen->invalid_instruction; - if (const_cast_result.id != ConstCastResultIdOk) { - // We will not be able to provide a result location for this value. Create - // a new result location. - result_cast->parent->written = old_parent_result_loc_written; - return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, - force_runtime, non_null_comptime); + ConstCastOnly const_cast_result = types_match_const_cast_only(ira, + parent_result_loc->value->type, ptr_type, + result_cast->base.source_instruction->source_node, false); + if (const_cast_result.id == ConstCastResultIdInvalid) + return ira->codegen->invalid_instruction; + if (const_cast_result.id != ConstCastResultIdOk) { + if (allow_discard) { + return parent_result_loc; } + // We will not be able to provide a result location for this value. Create + // a new result location. + result_cast->parent->written = false; + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, + force_runtime, non_null_comptime); } result_loc->written = true; @@ -16836,6 +16753,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe IrInstruction *bitcasted_value; if (value != nullptr) { bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type); + dest_type = bitcasted_value->value->type; } else { bitcasted_value = nullptr; } @@ -16887,7 +16805,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s result_loc_pass1 = no_result_loc(); } IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, - value, force_runtime, non_null_comptime); + value, force_runtime, non_null_comptime, allow_discard); if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value->type))) return result_loc; @@ -16900,11 +16818,13 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && - value_type->id != ZigTypeIdNull) + value_type->id != ZigTypeIdNull && type_has_bits(value_type)) { result_loc_pass1->written = false; return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); - } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { + } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && + type_has_bits(value_type)) + { if (value_type->id == ZigTypeIdErrorSet) { return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); } else { @@ -16918,9 +16838,6 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s return unwrapped_err_ptr; } } - } else if (is_slice(actual_elem_type) && value_type->id == ZigTypeIdArray) { - // need to allow EndExpr to do the implicit cast from array to slice - result_loc_pass1->written = false; } return result_loc; } @@ -17159,7 +17076,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod arg_val = create_const_runtime(casted_arg->value->type); } if (arg_part_of_generic_id) { - copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); + copy_const_val(&generic_id->params[generic_id->param_count], arg_val); generic_id->param_count += 1; } @@ -17340,7 +17257,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source IrInstruction *casted_ptr; if (instr_is_comptime(ptr)) { casted_ptr = ir_const(ira, source_instr, struct_ptr_type); - copy_const_val(casted_ptr->value, ptr->value, false); + copy_const_val(casted_ptr->value, ptr->value); casted_ptr->value->type = struct_ptr_type; } else { casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope, @@ -17403,14 +17320,8 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source if (dest_val == nullptr) return ira->codegen->invalid_instruction; if (dest_val->special != ConstValSpecialRuntime) { - // TODO this allows a value stored to have the original value modified and then - // have that affect what should be a copy. We need some kind of advanced copy-on-write - // system to make these two tests pass at the same time: - // * "string literal used as comptime slice is memoized" - // * "comptime modification of const struct field" - except modified to avoid - // ConstPtrMutComptimeVar, thus defeating the logic below. - bool same_global_refs = ptr->value->data.x_ptr.mut != ConstPtrMutComptimeVar; - copy_const_val(dest_val, value->value, same_global_refs); + copy_const_val(dest_val, value->value); + if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && !ira->new_irb.current_basic_block->must_be_comptime_source_instr) { @@ -17684,9 +17595,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c } } - IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->type); - copy_const_val(new_instruction->value, result, true); - new_instruction->value->type = return_type; + IrInstruction *new_instruction = ir_const_move(ira, &call_instruction->base, result); return ir_finish_anal(ira, new_instruction); } @@ -17842,7 +17751,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c nullptr, UndefBad); IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); - copy_const_val(const_instruction->base.value, align_result, true); + copy_const_val(const_instruction->base.value, align_result); uint32_t align_bytes = 0; ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); @@ -18172,7 +18081,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source if (dst_size <= src_size) { if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { - copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); + copy_const_val(out_val, pointee); return ErrorNone; } Buf buf = BUF_INIT; @@ -18535,7 +18444,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh if (value->value->special != ConstValSpecialRuntime) { IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); - copy_const_val(result->value, value->value, true); + copy_const_val(result->value, value->value); return result; } else { return value; @@ -18928,7 +18837,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct if (index == array_len && array_type->data.array.sentinel != nullptr) { ZigType *elem_type = array_type->data.array.child_type; IrInstruction *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base, elem_type); - copy_const_val(sentinel_elem->value, array_type->data.array.sentinel, false); + copy_const_val(sentinel_elem->value, array_type->data.array.sentinel); return ir_get_ref(ira, &elem_ptr_instruction->base, sentinel_elem, true, false); } if (index >= array_len) { @@ -19007,7 +18916,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct return ira->codegen->invalid_instruction; if (actual_array_type->id != ZigTypeIdArray) { ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, - buf_sprintf("expected array type or [_], found slice")); + buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", + buf_ptr(&actual_array_type->name))); return ira->codegen->invalid_instruction; } @@ -19419,7 +19329,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n if (instr_is_comptime(container_ptr)) { IrInstruction *result = ir_const(ira, source_instr, field_ptr_type); - copy_const_val(result->value, container_ptr->value, false); + copy_const_val(result->value, container_ptr->value); result->value->type = field_ptr_type; return result; } @@ -20851,7 +20761,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, case ZigTypeIdErrorSet: { if (pointee_val) { IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); - copy_const_val(result->value, pointee_val, true); + copy_const_val(result->value, pointee_val); result->value->type = target_type; return result; } @@ -21347,7 +21257,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc return ira->codegen->invalid_instruction; IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); - copy_const_val(runtime_inst->value, field->init_val, true); + copy_const_val(runtime_inst->value, field->init_val); IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, container_type, true); @@ -21399,7 +21309,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, if (is_slice(container_type)) { ir_add_error_node(ira, instruction->init_array_type_source_node, - buf_sprintf("expected array type or [_], found slice")); + buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", + buf_ptr(&container_type->name))); return ira->codegen->invalid_instruction; } @@ -21435,6 +21346,8 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, { // We're now done inferring the type. container_type->data.structure.resolve_status = ResolveStatusUnstarted; + } else if (container_type->id == ZigTypeIdVector) { + // OK } else { ir_add_error_node(ira, instruction->base.source_node, buf_sprintf("type '%s' does not support array initialization", @@ -21605,7 +21518,7 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); } IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, err->cached_error_name_val, true); + copy_const_val(result->value, err->cached_error_name_val); result->value->type = str_type; return result; } @@ -22828,17 +22741,23 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, return result; } -static ZigValue *get_const_field(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, + const char *name, size_t field_index) { + Error err; ensure_field_index(struct_value->type, name, field_index); - assert(struct_value->data.x_struct.fields[field_index]->special == ConstValSpecialStatic); - return struct_value->data.x_struct.fields[field_index]; + ZigValue *val = struct_value->data.x_struct.fields[field_index]; + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad))) + return nullptr; + return val; } static Error get_const_field_sentinel(IrAnalyze *ira, IrInstruction *source_instr, ZigValue *struct_value, const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) { - ZigValue *field_val = get_const_field(ira, struct_value, name, field_index); + ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); + if (field_val == nullptr) + return ErrorSemanticAnalyzeFail; IrInstruction *field_inst = ir_const(ira, source_instr, field_val->type); IrInstruction *casted_field_inst = ir_implicit_cast(ira, field_inst, get_optional_type(ira->codegen, elem_type)); @@ -22849,23 +22768,31 @@ static Error get_const_field_sentinel(IrAnalyze *ira, IrInstruction *source_inst return ErrorNone; } -static bool get_const_field_bool(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, + const char *name, size_t field_index, bool *out) { - ZigValue *value = get_const_field(ira, struct_value, name, field_index); + ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); + if (value == nullptr) + return ErrorSemanticAnalyzeFail; assert(value->type == ira->codegen->builtin_types.entry_bool); - return value->data.x_bool; + *out = value->data.x_bool; + return ErrorNone; } -static BigInt *get_const_field_lit_int(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) { - ZigValue *value = get_const_field(ira, struct_value, name, field_index); + ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); + if (value == nullptr) + return nullptr; assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); return &value->data.x_bigint; } -static ZigType *get_const_field_meta_type(IrAnalyze *ira, ZigValue *struct_value, const char *name, size_t field_index) +static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) { - ZigValue *value = get_const_field(ira, struct_value, name, field_index); + ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); + if (value == nullptr) + return ira->codegen->invalid_instruction->value->type; assert(value->type == ira->codegen->builtin_types.entry_type); return value->data.x_type; } @@ -22883,17 +22810,25 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi return ira->codegen->builtin_types.entry_bool; case ZigTypeIdUnreachable: return ira->codegen->builtin_types.entry_unreachable; - case ZigTypeIdInt: + case ZigTypeIdInt: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); - return get_int_type(ira->codegen, - get_const_field_bool(ira, payload, "is_signed", 0), - bigint_as_u32(get_const_field_lit_int(ira, payload, "bits", 1))); + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 1); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + bool is_signed; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_signed", 0, &is_signed))) + return ira->codegen->invalid_instruction->value->type; + return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); + } case ZigTypeIdFloat: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); - uint32_t bits = bigint_as_u32(get_const_field_lit_int(ira, payload, "bits", 0)); + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "bits", 0); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + uint32_t bits = bigint_as_u32(bi); switch (bits) { case 16: return ira->codegen->builtin_types.entry_f16; case 32: return ira->codegen->builtin_types.entry_f32; @@ -22902,34 +22837,58 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi } ir_add_error(ira, instruction, buf_sprintf("%d-bit float unsupported", bits)); - return nullptr; + return ira->codegen->invalid_instruction->value->type; } case ZigTypeIdPointer: { ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); assert(payload->special == ConstValSpecialStatic); assert(payload->type == type_info_pointer_type); - ZigValue *size_value = get_const_field(ira, payload, "size", 0); + ZigValue *size_value = get_const_field(ira, instruction->source_node, payload, "size", 0); assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); - ZigType *elem_type = get_const_field_meta_type(ira, payload, "child", 4); + ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 4); + if (type_is_invalid(elem_type)) + return ira->codegen->invalid_instruction->value->type; ZigValue *sentinel; if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 6, elem_type, &sentinel))) { - return nullptr; + return ira->codegen->invalid_instruction->value->type; + } + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "alignment", 3); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + + bool is_const; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_const", 1, &is_const))) + return ira->codegen->invalid_instruction->value->type; + + bool is_volatile; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_volatile", 2, + &is_volatile))) + { + return ira->codegen->invalid_instruction->value->type; } + bool is_allowzero; + if ((err = get_const_field_bool(ira, instruction->source_node, payload, "is_allowzero", 5, + &is_allowzero))) + { + return ira->codegen->invalid_instruction->value->type; + } + + ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, - get_const_field_bool(ira, payload, "is_const", 1), - get_const_field_bool(ira, payload, "is_volatile", 2), + is_const, + is_volatile, ptr_len, - bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)), + bigint_as_u32(bi), 0, // bit_offset_in_host 0, // host_int_bytes - get_const_field_bool(ira, payload, "is_allowzero", 5), + is_allowzero, VECTOR_INDEX_NONE, nullptr, sentinel); if (size_enum_index != 2) return ptr_type; @@ -22938,17 +22897,19 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdArray: { assert(payload->special == ConstValSpecialStatic); assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); - ZigType *elem_type = get_const_field_meta_type(ira, payload, "child", 1); + ZigType *elem_type = get_const_field_meta_type(ira, instruction->source_node, payload, "child", 1); + if (type_is_invalid(elem_type)) + return ira->codegen->invalid_instruction->value->type; ZigValue *sentinel; if ((err = get_const_field_sentinel(ira, instruction, payload, "sentinel", 2, elem_type, &sentinel))) { - return nullptr; + return ira->codegen->invalid_instruction->value->type; } - return get_array_type(ira->codegen, - elem_type, - bigint_as_u64(get_const_field_lit_int(ira, payload, "len", 0)), - sentinel); + BigInt *bi = get_const_field_lit_int(ira, instruction->source_node, payload, "len", 0); + if (bi == nullptr) + return ira->codegen->invalid_instruction->value->type; + return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); } case ZigTypeIdComptimeFloat: return ira->codegen->builtin_types.entry_num_lit_float; @@ -22969,7 +22930,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdEnumLiteral: ir_add_error(ira, instruction, buf_sprintf( "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); - return nullptr; + return ira->codegen->invalid_instruction->value->type; case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdBoundFn: @@ -22977,7 +22938,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi case ZigTypeIdStruct: ir_add_error(ira, instruction, buf_sprintf( "@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId))); - return nullptr; + return ira->codegen->invalid_instruction->value->type; } zig_unreachable(); } @@ -22996,7 +22957,7 @@ static IrInstruction *ir_analyze_instruction_type(IrAnalyze *ira, IrInstructionT return ira->codegen->invalid_instruction; ZigTypeId typeId = type_id_at_index(bigint_as_usize(&type_info_value->data.x_union.tag)); ZigType *type = type_info_to_type(ira, type_info_ir, typeId, type_info_value->data.x_union.payload); - if (!type) + if (type_is_invalid(type)) return ira->codegen->invalid_instruction; return ir_const_type(ira, &instruction->base, type); } @@ -23042,7 +23003,7 @@ static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstruc type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); } IrInstruction *result = ir_const(ira, &instruction->base, nullptr); - copy_const_val(result->value, type_entry->cached_const_name_val, true); + copy_const_val(result->value, type_entry->cached_const_name_val); return result; } @@ -23684,7 +23645,13 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru return result_loc; } - if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) { + if (target->value->type->id == ZigTypeIdPointer && + target->value->type->data.pointer.ptr_len == PtrLenSingle && + target->value->type->data.pointer.child_type->id == ZigTypeIdArray) + { + known_len = target->value->type->data.pointer.child_type->data.array.len; + have_known_len = true; + } else if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) { known_len = casted_value->value->data.rh_slice.len; have_known_len = true; } @@ -23742,7 +23709,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index]; - copy_const_val(ptr_val, target_ptr_val, false); + copy_const_val(ptr_val, target_ptr_val); ptr_val->type = dest_ptr_type; ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index]; @@ -24035,7 +24002,7 @@ static IrInstruction *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInstruction *s ZigValue *src_elem_val = (v >= 0) ? &a->value->data.x_array.data.s_none.elements[v] : &b->value->data.x_array.data.s_none.elements[~v]; - copy_const_val(result_elem_val, src_elem_val, false); + copy_const_val(result_elem_val, src_elem_val); ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); } @@ -24130,7 +24097,7 @@ static IrInstruction *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstruction IrInstruction *result = ir_const(ira, &instruction->base, return_type); result->value->data.x_array.data.s_none.elements = create_const_vals(len_int); for (uint32_t i = 0; i < len_int; i += 1) { - copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val, false); + copy_const_val(&result->value->data.x_array.data.s_none.elements[i], scalar_val); } return result; } @@ -24271,7 +24238,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio } for (size_t i = start; i < end; i += 1) { - copy_const_val(&dest_elements[i], byte_val, true); + copy_const_val(&dest_elements[i], byte_val); } return ir_const_void(ira, &instruction->base); @@ -24450,7 +24417,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio // TODO check for noalias violations - this should be generalized to work for any function for (size_t i = 0; i < count; i += 1) { - copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); + copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i]); } return ir_const_void(ira, &instruction->base); @@ -25892,7 +25859,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 } IrInstruction *result = ir_const(ira, target, result_type); - copy_const_val(result->value, val, true); + copy_const_val(result->value, val); result->value->type = result_type; return result; } @@ -25974,7 +25941,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ } else { result = ir_const(ira, source_instr, dest_type); } - copy_const_val(result->value, val, true); + copy_const_val(result->value, val); result->value->type = dest_type; // Keep the bigger alignment, it can only help- @@ -27474,10 +27441,6 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || instr_is_unreachable(result_loc))) return result_loc; - if (instruction->result_loc_cast->parent->gen_instruction != nullptr) { - return instruction->result_loc_cast->parent->gen_instruction; - } - ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); if (type_is_invalid(dest_type)) return ira->codegen->invalid_instruction; @@ -28060,7 +28023,24 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ } if (ira->codegen->verbose_ir) { - fprintf(stderr, "analyze #%" PRIu32 "\n", old_instruction->debug_id); + fprintf(stderr, "~ "); + old_instruction->src(); + fprintf(stderr, "~ "); + ir_print_instruction(codegen, stderr, old_instruction, 0, IrPassSrc); + bool want_break = false; + if (ira->break_debug_id == old_instruction->debug_id) { + want_break = true; + } else if (old_instruction->source_node != nullptr) { + for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { + if (dbg_ir_breakpoints_buf[i].line == old_instruction->source_node->line + 1 && + buf_ends_with_str(old_instruction->source_node->owner->data.structure.root_struct->path, + dbg_ir_breakpoints_buf[i].src_file)) + { + want_break = true; + } + } + } + if (want_break) BREAKPOINT; } IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); if (new_instruction != nullptr) { @@ -28068,6 +28048,10 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ old_instruction->child = new_instruction; if (type_is_invalid(new_instruction->value->type)) { + if (ira->codegen->verbose_ir) { + fprintf(stderr, "-> (invalid)"); + } + if (new_exec->first_err_trace_msg != nullptr) { ira->codegen->trace_err = new_exec->first_err_trace_msg; } else { @@ -28081,11 +28065,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ old_instruction->source_node, buf_create_from_str("referenced here")); } return ira->codegen->builtin_types.entry_invalid; + } else if (ira->codegen->verbose_ir) { + fprintf(stderr, "-> "); + if (instr_is_unreachable(new_instruction)) { + fprintf(stderr, "(noreturn)\n"); + } else { + ir_print_instruction(codegen, stderr, new_instruction, 0, IrPassGen); + } } // unreachable instructions do their own control flow. if (new_instruction->value->type->id == ZigTypeIdUnreachable) continue; + } else { + if (ira->codegen->verbose_ir) { + fprintf(stderr, "-> (null"); + } } ira->instruction_index += 1; @@ -28748,3 +28743,43 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { } return ErrorNone; } + +void IrInstruction::src() { + IrInstruction *inst = this; + if (inst->source_node != nullptr) { + inst->source_node->src(); + } else { + fprintf(stderr, "(null source node)\n"); + } +} + +void IrInstruction::dump() { + IrInstruction *inst = this; + inst->src(); + IrPass pass = (inst->child == nullptr) ? IrPassGen : IrPassSrc; + if (inst->scope == nullptr) { + fprintf(stderr, "(null scope)\n"); + } else { + ir_print_instruction(inst->scope->codegen, stderr, inst, 0, pass); + if (pass == IrPassSrc) { + fprintf(stderr, "-> "); + ir_print_instruction(inst->scope->codegen, stderr, inst->child, 0, IrPassGen); + } + } +} + +void IrAnalyze::dump() { + ir_print(this->codegen, stderr, this->new_irb.exec, 0, IrPassGen); + if (this->new_irb.current_basic_block != nullptr) { + fprintf(stderr, "Current basic block:\n"); + ir_print_basic_block(this->codegen, stderr, this->new_irb.current_basic_block, 1, IrPassGen); + } +} + +void dbg_ir_break(const char *src_file, uint32_t line) { + dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line}; + dbg_ir_breakpoints_count += 1; +} +void dbg_ir_clear(void) { + dbg_ir_breakpoints_count = 0; +} |
