aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp727
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;
+}