get_codegen_ptr_type returns possible error
And fix most of the fallout. This also makes optional pointers not require resolving zero bits, because the comptime value struct layout no longer depends on whether the type has zero bits. Thanks to @LemonBoy for the behavior test case Closes #4357 Closes #4359master
parent
6cbd1ac51a
commit
f247a90541
385
src/analyze.cpp
385
src/analyze.cpp
|
@ -597,7 +597,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
|
|||
entry->size_in_bits = SIZE_MAX;
|
||||
entry->abi_align = UINT32_MAX;
|
||||
} else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) {
|
||||
if (type_has_bits(child_type)) {
|
||||
if (type_has_bits(g, child_type)) {
|
||||
entry->abi_size = g->builtin_types.entry_usize->abi_size;
|
||||
entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
|
||||
entry->abi_align = g->builtin_types.entry_usize->abi_align;
|
||||
|
@ -660,11 +660,11 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
|
|||
buf_resize(&entry->name, 0);
|
||||
buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));
|
||||
|
||||
if (!type_has_bits(child_type)) {
|
||||
if (!type_has_bits(g, child_type)) {
|
||||
entry->size_in_bits = g->builtin_types.entry_bool->size_in_bits;
|
||||
entry->abi_size = g->builtin_types.entry_bool->abi_size;
|
||||
entry->abi_align = g->builtin_types.entry_bool->abi_align;
|
||||
} else if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) {
|
||||
} else if (type_is_nonnull_ptr(g, child_type) || child_type->id == ZigTypeIdErrorSet) {
|
||||
// This is an optimization but also is necessary for calling C
|
||||
// functions where all pointers are optional pointers.
|
||||
// Function types are technically pointers.
|
||||
|
@ -729,8 +729,8 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
|
|||
entry->data.error_union.err_set_type = err_set_type;
|
||||
entry->data.error_union.payload_type = payload_type;
|
||||
|
||||
if (!type_has_bits(payload_type)) {
|
||||
if (type_has_bits(err_set_type)) {
|
||||
if (!type_has_bits(g, payload_type)) {
|
||||
if (type_has_bits(g, err_set_type)) {
|
||||
entry->size_in_bits = err_set_type->size_in_bits;
|
||||
entry->abi_size = err_set_type->abi_size;
|
||||
entry->abi_align = err_set_type->abi_align;
|
||||
|
@ -739,7 +739,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
|
|||
entry->abi_size = 0;
|
||||
entry->abi_align = 0;
|
||||
}
|
||||
} else if (!type_has_bits(err_set_type)) {
|
||||
} else if (!type_has_bits(g, err_set_type)) {
|
||||
entry->size_in_bits = payload_type->size_in_bits;
|
||||
entry->abi_size = payload_type->abi_size;
|
||||
entry->abi_align = payload_type->abi_align;
|
||||
|
@ -856,13 +856,13 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
|
|||
entry->data.structure.requires_comptime = true;
|
||||
}
|
||||
|
||||
if (!type_has_bits(ptr_type)) {
|
||||
if (!type_has_bits(g, ptr_type)) {
|
||||
entry->data.structure.gen_field_count = 1;
|
||||
entry->data.structure.fields[slice_ptr_index]->gen_index = SIZE_MAX;
|
||||
entry->data.structure.fields[slice_len_index]->gen_index = 0;
|
||||
}
|
||||
|
||||
if (type_has_bits(ptr_type)) {
|
||||
if (type_has_bits(g, ptr_type)) {
|
||||
entry->size_in_bits = ptr_type->size_in_bits + g->builtin_types.entry_usize->size_in_bits;
|
||||
entry->abi_size = ptr_type->abi_size + g->builtin_types.entry_usize->abi_size;
|
||||
entry->abi_align = ptr_type->abi_align;
|
||||
|
@ -969,12 +969,12 @@ ZigType *get_stack_trace_type(CodeGen *g) {
|
|||
|
||||
bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
|
||||
if (fn_type_id->cc == CallingConventionUnspecified) {
|
||||
return handle_is_ptr(fn_type_id->return_type);
|
||||
return handle_is_ptr(g, fn_type_id->return_type);
|
||||
}
|
||||
if (fn_type_id->cc != CallingConventionC) {
|
||||
return false;
|
||||
}
|
||||
if (type_is_c_abi_int(g, fn_type_id->return_type)) {
|
||||
if (type_is_c_abi_int_bail(g, fn_type_id->return_type)) {
|
||||
return false;
|
||||
}
|
||||
if (g->zig_target->arch == ZigLLVM_x86 ||
|
||||
|
@ -1650,15 +1650,16 @@ static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigT
|
|||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
zig_unreachable();
|
||||
case ZigTypeIdOptional:
|
||||
if (get_codegen_ptr_type(type_entry) != nullptr) {
|
||||
return ErrorNone;
|
||||
} else {
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
case ZigTypeIdOptional: {
|
||||
ZigType *ptr_type;
|
||||
if ((err = get_codegen_ptr_type(g, type_entry, &ptr_type))) return err;
|
||||
if (ptr_type != nullptr) return ErrorNone;
|
||||
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("type '%s' not allowed in packed %s; no guaranteed in-memory representation",
|
||||
buf_ptr(&type_entry->name), container_name));
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
}
|
||||
case ZigTypeIdEnum: {
|
||||
AstNode *decl_node = type_entry->data.enumeration.decl_node;
|
||||
if (decl_node->data.container_decl.init_arg_expr != nullptr) {
|
||||
|
@ -1737,7 +1738,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
|
|||
case ZigTypeIdPointer:
|
||||
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
|
||||
return err;
|
||||
if (!type_has_bits(type_entry)) {
|
||||
if (!type_has_bits(g, type_entry)) {
|
||||
*result = false;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
@ -1753,7 +1754,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
|
|||
*result = false;
|
||||
return ErrorNone;
|
||||
}
|
||||
if (!type_is_nonnull_ptr(child_type)) {
|
||||
if (!type_is_nonnull_ptr(g, child_type)) {
|
||||
*result = false;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
@ -1848,7 +1849,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
|||
if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
|
||||
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
|
||||
return g->builtin_types.entry_invalid;
|
||||
if (!type_has_bits(type_entry)) {
|
||||
if (!type_has_bits(g, type_entry)) {
|
||||
add_node_error(g, param_node->data.param_decl.type,
|
||||
buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'",
|
||||
buf_ptr(&type_entry->name), calling_convention_name(fn_type_id.cc)));
|
||||
|
@ -2082,7 +2083,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
|
|||
field->src_index = i;
|
||||
field->align = fields[i].align;
|
||||
|
||||
if (type_has_bits(field->type_entry)) {
|
||||
if (type_has_bits(g, field->type_entry)) {
|
||||
assert(type_is_resolved(field->type_entry, ResolveStatusSizeKnown));
|
||||
unsigned field_abi_align = max(field->align, field->type_entry->abi_align);
|
||||
if (field_abi_align > abi_align) {
|
||||
|
@ -2097,7 +2098,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
|
|||
size_t next_offset = 0;
|
||||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
TypeStructField *field = struct_type->data.structure.fields[i];
|
||||
if (!type_has_bits(field->type_entry))
|
||||
if (!type_has_bits(g, field->type_entry))
|
||||
continue;
|
||||
|
||||
field->offset = next_offset;
|
||||
|
@ -2105,7 +2106,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
|
|||
// find the next non-zero-byte field for offset calculations
|
||||
size_t next_src_field_index = i + 1;
|
||||
for (; next_src_field_index < field_count; next_src_field_index += 1) {
|
||||
if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry))
|
||||
if (type_has_bits(g, struct_type->data.structure.fields[next_src_field_index]->type_entry))
|
||||
break;
|
||||
}
|
||||
size_t next_abi_align;
|
||||
|
@ -2402,7 +2403,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
|
|||
union_type->data.unionation.most_aligned_union_member = most_aligned_union_member;
|
||||
|
||||
ZigType *tag_type = union_type->data.unionation.tag_type;
|
||||
if (tag_type != nullptr && type_has_bits(tag_type)) {
|
||||
if (tag_type != nullptr && type_has_bits(g, tag_type)) {
|
||||
if ((err = type_resolve(g, tag_type, ResolveStatusAlignmentKnown))) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
|
@ -2504,7 +2505,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
|
|||
if (type_is_invalid(union_type))
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
|
||||
if (!type_has_bits(field_type))
|
||||
if (!type_has_bits(g, field_type))
|
||||
continue;
|
||||
|
||||
union_abi_size = max(union_abi_size, field_type->abi_size);
|
||||
|
@ -2523,7 +2524,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
|
|||
union_type->data.unionation.union_abi_size = union_abi_size;
|
||||
|
||||
ZigType *tag_type = union_type->data.unionation.tag_type;
|
||||
if (tag_type != nullptr && type_has_bits(tag_type)) {
|
||||
if (tag_type != nullptr && type_has_bits(g, tag_type)) {
|
||||
if ((err = type_resolve(g, tag_type, ResolveStatusSizeKnown))) {
|
||||
union_type->data.unionation.resolve_status = ResolveStatusInvalid;
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
|
@ -2998,7 +2999,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!type_has_bits(struct_type)) {
|
||||
if (!type_has_bits(g, struct_type)) {
|
||||
assert(struct_type->abi_align == 0);
|
||||
}
|
||||
|
||||
|
@ -4416,15 +4417,50 @@ ZigType *get_src_ptr_type(ZigType *type) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ZigType *get_codegen_ptr_type(ZigType *type) {
|
||||
Error get_codegen_ptr_type(CodeGen *g, ZigType *type, ZigType **result) {
|
||||
Error err;
|
||||
|
||||
ZigType *ty = get_src_ptr_type(type);
|
||||
if (ty == nullptr || !type_has_bits(ty))
|
||||
return nullptr;
|
||||
return ty;
|
||||
if (ty == nullptr) {
|
||||
*result = nullptr;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
bool has_bits;
|
||||
if ((err = type_has_bits2(g, ty, &has_bits))) return err;
|
||||
if (!has_bits) {
|
||||
*result = nullptr;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
*result = ty;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
bool type_is_nonnull_ptr(ZigType *type) {
|
||||
return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type);
|
||||
ZigType *get_codegen_ptr_type_bail(CodeGen *g, ZigType *type) {
|
||||
Error err;
|
||||
ZigType *result;
|
||||
if ((err = get_codegen_ptr_type(g, type, &result))) {
|
||||
codegen_report_errors_and_exit(g);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool type_is_nonnull_ptr(CodeGen *g, ZigType *type) {
|
||||
Error err;
|
||||
bool result;
|
||||
if ((err = type_is_nonnull_ptr2(g, type, &result))) {
|
||||
codegen_report_errors_and_exit(g);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Error type_is_nonnull_ptr2(CodeGen *g, ZigType *type, bool *result) {
|
||||
Error err;
|
||||
ZigType *ptr_type;
|
||||
if ((err = get_codegen_ptr_type(g, type, &ptr_type))) return err;
|
||||
*result = ptr_type == type && !ptr_allows_addr_zero(type);
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
static uint32_t get_async_frame_align_bytes(CodeGen *g) {
|
||||
|
@ -4499,8 +4535,12 @@ static Error define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) {
|
|||
}
|
||||
|
||||
bool is_noalias = param_info->is_noalias;
|
||||
if (is_noalias && get_codegen_ptr_type(param_type) == nullptr) {
|
||||
add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));
|
||||
if (is_noalias) {
|
||||
ZigType *ptr_type;
|
||||
if ((err = get_codegen_ptr_type(g, param_type, &ptr_type))) return err;
|
||||
if (ptr_type == nullptr) {
|
||||
add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));
|
||||
}
|
||||
}
|
||||
|
||||
ZigVar *var = add_variable(g, param_decl_node, fn_table_entry->child_scope,
|
||||
|
@ -4509,7 +4549,7 @@ static Error define_local_param_variables(CodeGen *g, ZigFn *fn_table_entry) {
|
|||
fn_table_entry->child_scope = var->child_scope;
|
||||
var->shadowable = var->shadowable || is_var_args;
|
||||
|
||||
if (type_has_bits(param_type)) {
|
||||
if (type_has_bits(g, param_type)) {
|
||||
fn_table_entry->variable_list.append(var);
|
||||
}
|
||||
}
|
||||
|
@ -5027,15 +5067,35 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
|
|||
return new_entry;
|
||||
}
|
||||
|
||||
bool is_valid_vector_elem_type(ZigType *elem_type) {
|
||||
return elem_type->id == ZigTypeIdInt ||
|
||||
Error is_valid_vector_elem_type(CodeGen *g, ZigType *elem_type, bool *result) {
|
||||
if (elem_type->id == ZigTypeIdInt ||
|
||||
elem_type->id == ZigTypeIdFloat ||
|
||||
elem_type->id == ZigTypeIdBool ||
|
||||
get_codegen_ptr_type(elem_type) != nullptr;
|
||||
elem_type->id == ZigTypeIdBool)
|
||||
{
|
||||
*result = true;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
Error err;
|
||||
ZigType *ptr_type;
|
||||
if ((err = get_codegen_ptr_type(g, elem_type, &ptr_type))) return err;
|
||||
if (ptr_type != nullptr) {
|
||||
*result = true;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
*result = false;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
|
||||
assert(is_valid_vector_elem_type(elem_type));
|
||||
Error err;
|
||||
|
||||
bool valid_vector_elem;
|
||||
if ((err = is_valid_vector_elem_type(g, elem_type, &valid_vector_elem))) {
|
||||
codegen_report_errors_and_exit(g);
|
||||
}
|
||||
assert(valid_vector_elem);
|
||||
|
||||
TypeId type_id = {};
|
||||
type_id.id = ZigTypeIdVector;
|
||||
|
@ -5049,7 +5109,7 @@ ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
|
|||
}
|
||||
|
||||
ZigType *entry = new_type_table_entry(ZigTypeIdVector);
|
||||
if ((len != 0) && type_has_bits(elem_type)) {
|
||||
if ((len != 0) && type_has_bits(g, elem_type)) {
|
||||
// Vectors can only be ints, floats, bools, or pointers. ints (inc. bools) and floats have trivially resolvable
|
||||
// llvm type refs. pointers we will use usize instead.
|
||||
LLVMTypeRef example_vector_llvm_type;
|
||||
|
@ -5081,7 +5141,7 @@ ZigType *get_c_int_type(CodeGen *g, CIntType c_int_type) {
|
|||
return *get_c_int_type_ptr(g, c_int_type);
|
||||
}
|
||||
|
||||
bool handle_is_ptr(ZigType *type_entry) {
|
||||
bool handle_is_ptr(CodeGen *g, ZigType *type_entry) {
|
||||
switch (type_entry->id) {
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdMetaType:
|
||||
|
@ -5108,15 +5168,15 @@ bool handle_is_ptr(ZigType *type_entry) {
|
|||
case ZigTypeIdArray:
|
||||
case ZigTypeIdStruct:
|
||||
case ZigTypeIdFnFrame:
|
||||
return type_has_bits(type_entry);
|
||||
return type_has_bits(g, type_entry);
|
||||
case ZigTypeIdErrorUnion:
|
||||
return type_has_bits(type_entry->data.error_union.payload_type);
|
||||
return type_has_bits(g, type_entry->data.error_union.payload_type);
|
||||
case ZigTypeIdOptional:
|
||||
return type_has_bits(type_entry->data.maybe.child_type) &&
|
||||
!type_is_nonnull_ptr(type_entry->data.maybe.child_type) &&
|
||||
return type_has_bits(g, type_entry->data.maybe.child_type) &&
|
||||
!type_is_nonnull_ptr(g, type_entry->data.maybe.child_type) &&
|
||||
type_entry->data.maybe.child_type->id != ZigTypeIdErrorSet;
|
||||
case ZigTypeIdUnion:
|
||||
return type_has_bits(type_entry) && type_entry->data.unionation.gen_field_count != 0;
|
||||
return type_has_bits(g, type_entry) && type_entry->data.unionation.gen_field_count != 0;
|
||||
|
||||
}
|
||||
zig_unreachable();
|
||||
|
@ -5329,7 +5389,7 @@ static uint32_t hash_const_val(ZigValue *const_val) {
|
|||
// TODO better hashing algorithm
|
||||
return 2709806591;
|
||||
case ZigTypeIdOptional:
|
||||
if (get_codegen_ptr_type(const_val->type) != nullptr) {
|
||||
if (get_src_ptr_type(const_val->type) != nullptr) {
|
||||
return hash_const_val_ptr(const_val) * 1992916303;
|
||||
} else if (const_val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) {
|
||||
return hash_const_val_error_set(const_val) * 3147031929;
|
||||
|
@ -5455,7 +5515,7 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {
|
|||
return false;
|
||||
|
||||
case ZigTypeIdOptional:
|
||||
if (get_codegen_ptr_type(value->type) != nullptr)
|
||||
if (get_src_ptr_type(value->type) != nullptr)
|
||||
return value->data.x_ptr.mut == ConstPtrMutComptimeVar;
|
||||
if (value->data.x_optional == nullptr)
|
||||
return false;
|
||||
|
@ -5593,11 +5653,13 @@ bool fn_eval_eql(Scope *a, Scope *b) {
|
|||
}
|
||||
|
||||
// Deprecated. Use type_has_bits2.
|
||||
bool type_has_bits(ZigType *type_entry) {
|
||||
assert(type_entry != nullptr);
|
||||
assert(!type_is_invalid(type_entry));
|
||||
assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
|
||||
return type_entry->abi_size != 0;
|
||||
bool type_has_bits(CodeGen *g, ZigType *type_entry) {
|
||||
Error err;
|
||||
bool result;
|
||||
if ((err = type_has_bits2(g, type_entry, &result))) {
|
||||
codegen_report_errors_and_exit(g);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Whether the type has bits at runtime.
|
||||
|
@ -5687,7 +5749,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
|||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdInt:
|
||||
case ZigTypeIdVector:
|
||||
return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes;
|
||||
return type_has_bits(g, type_entry) ? OnePossibleValueNo : OnePossibleValueYes;
|
||||
case ZigTypeIdPointer: {
|
||||
ZigType *elem_type = type_entry->data.pointer.child_type;
|
||||
// If the recursive function call asks, then we are not one possible value.
|
||||
|
@ -6365,7 +6427,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
|||
}
|
||||
if (await->base.base.ref_count == 0)
|
||||
continue;
|
||||
if (!type_has_bits(await->base.value->type))
|
||||
if (!type_has_bits(g, await->base.value->type))
|
||||
continue;
|
||||
await->result_loc = ir_create_alloca(g, await->base.base.scope, await->base.base.source_node, fn,
|
||||
await->base.value->type, "");
|
||||
|
@ -6406,7 +6468,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
|||
continue;
|
||||
if ((err = type_resolve(g, instruction->value->type, ResolveStatusZeroBitsKnown)))
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
if (!type_has_bits(instruction->value->type))
|
||||
if (!type_has_bits(g, instruction->value->type))
|
||||
continue;
|
||||
if (scope_needs_spill(instruction->base.scope)) {
|
||||
instruction->spill = ir_create_alloca(g, instruction->base.scope, instruction->base.source_node,
|
||||
|
@ -6465,7 +6527,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
|
|||
ZigType *ptr_type = instruction->base.value->type;
|
||||
assert(ptr_type->id == ZigTypeIdPointer);
|
||||
ZigType *child_type = resolve_type_isf(ptr_type->data.pointer.child_type);
|
||||
if (!type_has_bits(child_type))
|
||||
if (!type_has_bits(g, child_type))
|
||||
continue;
|
||||
if (instruction->base.base.ref_count == 0)
|
||||
continue;
|
||||
|
@ -6763,7 +6825,7 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
|
|||
if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
|
||||
TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
|
||||
assert(field != nullptr);
|
||||
if (!type_has_bits(field->type_entry))
|
||||
if (!type_has_bits(g, field->type_entry))
|
||||
return true;
|
||||
assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr);
|
||||
return const_values_equal(g, union1->payload, union2->payload);
|
||||
|
@ -6826,7 +6888,7 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
|
|||
case ZigTypeIdNull:
|
||||
zig_panic("TODO");
|
||||
case ZigTypeIdOptional:
|
||||
if (get_codegen_ptr_type(a->type) != nullptr)
|
||||
if (get_src_ptr_type(a->type) != nullptr)
|
||||
return const_values_equal_ptr(a, b);
|
||||
if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) {
|
||||
return (a->data.x_optional == nullptr && b->data.x_optional == nullptr);
|
||||
|
@ -7097,7 +7159,7 @@ void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) {
|
|||
}
|
||||
case ZigTypeIdOptional:
|
||||
{
|
||||
if (get_codegen_ptr_type(const_val->type) != nullptr)
|
||||
if (get_src_ptr_type(const_val->type) != nullptr)
|
||||
return render_const_val_ptr(g, buf, const_val, type_entry->data.maybe.child_type);
|
||||
if (type_entry->data.maybe.child_type->id == ZigTypeIdErrorSet)
|
||||
return render_const_val_err_set(g, buf, const_val, type_entry->data.maybe.child_type);
|
||||
|
@ -7881,8 +7943,12 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size
|
|||
}
|
||||
|
||||
X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
|
||||
Error err;
|
||||
|
||||
const size_t ty_size = type_size(g, ty);
|
||||
if (get_codegen_ptr_type(ty) != nullptr)
|
||||
ZigType *ptr_type;
|
||||
if ((err = get_codegen_ptr_type(g, ty, &ptr_type))) return X64CABIClass_Unknown;
|
||||
if (ptr_type != nullptr)
|
||||
return X64CABIClass_INTEGER;
|
||||
|
||||
if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
|
||||
|
@ -7898,14 +7964,32 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
|
|||
}
|
||||
|
||||
// NOTE this does not depend on x86_64
|
||||
bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {
|
||||
return (ty->id == ZigTypeIdInt ||
|
||||
Error type_is_c_abi_int(CodeGen *g, ZigType *ty, bool *result) {
|
||||
if (ty->id == ZigTypeIdInt ||
|
||||
ty->id == ZigTypeIdFloat ||
|
||||
ty->id == ZigTypeIdBool ||
|
||||
ty->id == ZigTypeIdEnum ||
|
||||
ty->id == ZigTypeIdVoid ||
|
||||
ty->id == ZigTypeIdUnreachable ||
|
||||
get_codegen_ptr_type(ty) != nullptr);
|
||||
ty->id == ZigTypeIdUnreachable)
|
||||
{
|
||||
*result = true;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
Error err;
|
||||
ZigType *ptr_type;
|
||||
if ((err = get_codegen_ptr_type(g, ty, &ptr_type))) return err;
|
||||
*result = ptr_type != nullptr;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
bool type_is_c_abi_int_bail(CodeGen *g, ZigType *ty) {
|
||||
Error err;
|
||||
bool result;
|
||||
if ((err = type_is_c_abi_int(g, ty, &result)))
|
||||
codegen_report_errors_and_exit(g);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field) {
|
||||
|
@ -8036,7 +8120,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa
|
|||
if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
|
||||
}
|
||||
|
||||
if (!type_has_bits(child_type)) {
|
||||
if (!type_has_bits(g, child_type)) {
|
||||
LLVMTypeRef element_types[] = {
|
||||
usize_llvm_type,
|
||||
};
|
||||
|
@ -8145,7 +8229,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
|||
}
|
||||
|
||||
if (struct_type->data.structure.resolve_status < ResolveStatusLLVMFwdDecl) {
|
||||
struct_type->llvm_type = type_has_bits(struct_type) ?
|
||||
struct_type->llvm_type = type_has_bits(g, struct_type) ?
|
||||
LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&struct_type->name)) : LLVMVoidType();
|
||||
unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
|
||||
struct_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
|
||||
|
@ -8175,7 +8259,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
|||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
TypeStructField *field = struct_type->data.structure.fields[i];
|
||||
ZigType *field_type = field->type_entry;
|
||||
if (!type_has_bits(field_type))
|
||||
if (!type_has_bits(g, field_type))
|
||||
continue;
|
||||
(void)get_llvm_type(g, field_type);
|
||||
if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;
|
||||
|
@ -8189,7 +8273,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
|||
for (size_t i = 0; i < field_count; i += 1) {
|
||||
TypeStructField *field = struct_type->data.structure.fields[i];
|
||||
ZigType *field_type = field->type_entry;
|
||||
if (field->is_comptime || !type_has_bits(field_type))
|
||||
if (field->is_comptime || !type_has_bits(g, field_type))
|
||||
continue;
|
||||
LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
|
||||
size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type);
|
||||
|
@ -8200,7 +8284,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
|||
TypeStructField *field = struct_type->data.structure.fields[i];
|
||||
ZigType *field_type = field->type_entry;
|
||||
|
||||
if (field->is_comptime || !type_has_bits(field_type)) {
|
||||
if (field->is_comptime || !type_has_bits(g, field_type)) {
|
||||
field->gen_index = SIZE_MAX;
|
||||
continue;
|
||||
}
|
||||
|
@ -8247,7 +8331,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
|||
// find the next non-zero-byte field for offset calculations
|
||||
size_t next_src_field_index = i + 1;
|
||||
for (; next_src_field_index < field_count; next_src_field_index += 1) {
|
||||
if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry))
|
||||
if (type_has_bits(g, struct_type->data.structure.fields[next_src_field_index]->type_entry))
|
||||
break;
|
||||
}
|
||||
size_t next_abi_align;
|
||||
|
@ -8293,7 +8377,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
|
|||
gen_field_index += 1;
|
||||
}
|
||||
|
||||
if (type_has_bits(struct_type)) {
|
||||
if (type_has_bits(g, struct_type)) {
|
||||
assert(struct_type->data.structure.gen_field_count == gen_field_index);
|
||||
LLVMStructSetBody(struct_type->llvm_type, element_types,
|
||||
(unsigned)struct_type->data.structure.gen_field_count, packed);
|
||||
|
@ -8405,7 +8489,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
|
|||
ZigType *import = get_scope_import(scope);
|
||||
AstNode *decl_node = enum_type->data.enumeration.decl_node;
|
||||
|
||||
if (!type_has_bits(enum_type)) {
|
||||
if (!type_has_bits(g, enum_type)) {
|
||||
enum_type->llvm_type = g->builtin_types.entry_void->llvm_type;
|
||||
enum_type->llvm_di_type = make_empty_namespace_llvm_di_type(g, import, buf_ptr(&enum_type->name),
|
||||
decl_node);
|
||||
|
@ -8487,7 +8571,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
|||
uint32_t field_count = union_type->data.unionation.src_field_count;
|
||||
for (uint32_t i = 0; i < field_count; i += 1) {
|
||||
TypeUnionField *union_field = &union_type->data.unionation.fields[i];
|
||||
if (!type_has_bits(union_field->type_entry))
|
||||
if (!type_has_bits(g, union_field->type_entry))
|
||||
continue;
|
||||
|
||||
ZigLLVMDIType *field_di_type = get_llvm_di_type(g, union_field->type_entry);
|
||||
|
@ -8506,7 +8590,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
|
|||
|
||||
}
|
||||
|
||||
if (tag_type == nullptr || !type_has_bits(tag_type)) {
|
||||
if (tag_type == nullptr || !type_has_bits(g, tag_type)) {
|
||||
assert(most_aligned_union_member != nullptr);
|
||||
|
||||
size_t padding_bytes = union_type->data.unionation.union_abi_size - most_aligned_union_member->type_entry->abi_size;
|
||||
|
@ -8616,7 +8700,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus
|
|||
if (resolve_pointer_zero_bits(g, type) != ErrorNone)
|
||||
zig_unreachable();
|
||||
|
||||
if (!type_has_bits(type)) {
|
||||
if (!type_has_bits(g, type)) {
|
||||
type->llvm_type = g->builtin_types.entry_void->llvm_type;
|
||||
type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
|
||||
return;
|
||||
|
@ -8669,7 +8753,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus
|
|||
static void resolve_llvm_types_integer(CodeGen *g, ZigType *type) {
|
||||
if (type->llvm_di_type != nullptr) return;
|
||||
|
||||
if (!type_has_bits(type)) {
|
||||
if (!type_has_bits(g, type)) {
|
||||
type->llvm_type = g->builtin_types.entry_void->llvm_type;
|
||||
type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
|
||||
return;
|
||||
|
@ -8705,14 +8789,14 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus
|
|||
ZigLLVMDIType *bool_llvm_di_type = get_llvm_di_type(g, g->builtin_types.entry_bool);
|
||||
|
||||
ZigType *child_type = type->data.maybe.child_type;
|
||||
if (!type_has_bits(child_type)) {
|
||||
if (!type_has_bits(g, child_type)) {
|
||||
type->llvm_type = bool_llvm_type;
|
||||
type->llvm_di_type = bool_llvm_di_type;
|
||||
type->data.maybe.resolve_status = ResolveStatusLLVMFull;
|
||||
return;
|
||||
}
|
||||
|
||||
if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) {
|
||||
if (type_is_nonnull_ptr(g, child_type) || child_type->id == ZigTypeIdErrorSet) {
|
||||
type->llvm_type = get_llvm_type(g, child_type);
|
||||
type->llvm_di_type = get_llvm_di_type(g, child_type);
|
||||
type->data.maybe.resolve_status = ResolveStatusLLVMFull;
|
||||
|
@ -8778,11 +8862,11 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
|
|||
ZigType *payload_type = type->data.error_union.payload_type;
|
||||
ZigType *err_set_type = type->data.error_union.err_set_type;
|
||||
|
||||
if (!type_has_bits(payload_type)) {
|
||||
assert(type_has_bits(err_set_type));
|
||||
if (!type_has_bits(g, payload_type)) {
|
||||
assert(type_has_bits(g, err_set_type));
|
||||
type->llvm_type = get_llvm_type(g, err_set_type);
|
||||
type->llvm_di_type = get_llvm_di_type(g, err_set_type);
|
||||
} else if (!type_has_bits(err_set_type)) {
|
||||
} else if (!type_has_bits(g, err_set_type)) {
|
||||
type->llvm_type = get_llvm_type(g, payload_type);
|
||||
type->llvm_di_type = get_llvm_di_type(g, payload_type);
|
||||
} else {
|
||||
|
@ -8852,7 +8936,7 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
|
|||
static void resolve_llvm_types_array(CodeGen *g, ZigType *type) {
|
||||
if (type->llvm_di_type != nullptr) return;
|
||||
|
||||
if (!type_has_bits(type)) {
|
||||
if (!type_has_bits(g, type)) {
|
||||
type->llvm_type = g->builtin_types.entry_void->llvm_type;
|
||||
type->llvm_di_type = g->builtin_types.entry_void->llvm_di_type;
|
||||
return;
|
||||
|
@ -8893,7 +8977,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
|
|||
if (is_async) {
|
||||
gen_return_type = g->builtin_types.entry_void;
|
||||
param_di_types.append(nullptr);
|
||||
} else if (!type_has_bits(fn_type_id->return_type)) {
|
||||
} else if (!type_has_bits(g, fn_type_id->return_type)) {
|
||||
gen_return_type = g->builtin_types.entry_void;
|
||||
param_di_types.append(nullptr);
|
||||
} else if (first_arg_return) {
|
||||
|
@ -8940,11 +9024,11 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
|
|||
gen_param_info->src_index = i;
|
||||
gen_param_info->gen_index = SIZE_MAX;
|
||||
|
||||
if (is_c_abi || !type_has_bits(type_entry))
|
||||
if (is_c_abi || !type_has_bits(g, type_entry))
|
||||
continue;
|
||||
|
||||
ZigType *gen_type;
|
||||
if (handle_is_ptr(type_entry)) {
|
||||
if (handle_is_ptr(g, type_entry)) {
|
||||
gen_type = get_pointer_to_type(g, type_entry, true);
|
||||
gen_param_info->is_byval = true;
|
||||
} else {
|
||||
|
@ -9098,7 +9182,7 @@ static void resolve_llvm_types_any_frame(CodeGen *g, ZigType *any_frame_type, Re
|
|||
field_types.append(usize_type_ref); // resume_index
|
||||
field_types.append(usize_type_ref); // awaiter
|
||||
|
||||
bool have_result_type = result_type != nullptr && type_has_bits(result_type);
|
||||
bool have_result_type = result_type != nullptr && type_has_bits(g, result_type);
|
||||
if (have_result_type) {
|
||||
field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_callee
|
||||
field_types.append(get_llvm_type(g, ptr_result_type)); // result_ptr_awaiter
|
||||
|
@ -9379,7 +9463,7 @@ bool is_opt_err_set(ZigType *ty) {
|
|||
bool type_has_optional_repr(ZigType *ty) {
|
||||
if (ty->id != ZigTypeIdOptional) {
|
||||
return false;
|
||||
} else if (get_codegen_ptr_type(ty) != nullptr) {
|
||||
} else if (get_src_ptr_type(ty) != nullptr) {
|
||||
return false;
|
||||
} else if (is_opt_err_set(ty)) {
|
||||
return false;
|
||||
|
@ -9471,6 +9555,58 @@ bool type_is_numeric(ZigType *ty) {
|
|||
zig_unreachable();
|
||||
}
|
||||
|
||||
static void dump_value_indent_error_set(ZigValue *val, int indent) {
|
||||
fprintf(stderr, "<TODO dump value>\n");
|
||||
}
|
||||
|
||||
static void dump_value_indent(ZigValue *val, int indent);
|
||||
|
||||
static void dump_value_indent_ptr(ZigValue *val, int indent) {
|
||||
switch (val->data.x_ptr.special) {
|
||||
case ConstPtrSpecialInvalid:
|
||||
fprintf(stderr, "<!invalid ptr!>\n");
|
||||
return;
|
||||
case ConstPtrSpecialNull:
|
||||
fprintf(stderr, "<null>\n");
|
||||
return;
|
||||
case ConstPtrSpecialRef:
|
||||
fprintf(stderr, "<ref\n");
|
||||
dump_value_indent(val->data.x_ptr.data.ref.pointee, indent + 1);
|
||||
break;
|
||||
case ConstPtrSpecialBaseStruct: {
|
||||
ZigValue *struct_val = val->data.x_ptr.data.base_struct.struct_val;
|
||||
size_t field_index = val->data.x_ptr.data.base_struct.field_index;
|
||||
fprintf(stderr, "<struct %p field %zu\n", struct_val, field_index);
|
||||
if (struct_val != nullptr) {
|
||||
ZigValue *field_val = struct_val->data.x_struct.fields[field_index];
|
||||
if (field_val != nullptr) {
|
||||
dump_value_indent(field_val, indent + 1);
|
||||
} else {
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "(invalid null field)\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConstPtrSpecialBaseOptionalPayload: {
|
||||
ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val;
|
||||
fprintf(stderr, "<optional %p payload\n", optional_val);
|
||||
if (optional_val != nullptr) {
|
||||
dump_value_indent(optional_val, indent + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "TODO dump more pointer things\n");
|
||||
}
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
}
|
||||
|
||||
static void dump_value_indent(ZigValue *val, int indent) {
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
|
@ -9548,15 +9684,20 @@ static void dump_value_indent(ZigValue *val, int indent) {
|
|||
return;
|
||||
|
||||
case ZigTypeIdOptional:
|
||||
fprintf(stderr, "<\n");
|
||||
dump_value_indent(val->data.x_optional, indent + 1);
|
||||
if (get_src_ptr_type(val->type) != nullptr) {
|
||||
return dump_value_indent_ptr(val, indent);
|
||||
} else if (val->type->data.maybe.child_type->id == ZigTypeIdErrorSet) {
|
||||
return dump_value_indent_error_set(val, indent);
|
||||
} else {
|
||||
fprintf(stderr, "<\n");
|
||||
dump_value_indent(val->data.x_optional, indent + 1);
|
||||
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
|
||||
case ZigTypeIdErrorUnion:
|
||||
if (val->data.x_err_union.payload != nullptr) {
|
||||
fprintf(stderr, "<\n");
|
||||
|
@ -9572,52 +9713,14 @@ static void dump_value_indent(ZigValue *val, int indent) {
|
|||
return;
|
||||
|
||||
case ZigTypeIdPointer:
|
||||
switch (val->data.x_ptr.special) {
|
||||
case ConstPtrSpecialInvalid:
|
||||
fprintf(stderr, "<!invalid ptr!>\n");
|
||||
return;
|
||||
case ConstPtrSpecialRef:
|
||||
fprintf(stderr, "<ref\n");
|
||||
dump_value_indent(val->data.x_ptr.data.ref.pointee, indent + 1);
|
||||
break;
|
||||
case ConstPtrSpecialBaseStruct: {
|
||||
ZigValue *struct_val = val->data.x_ptr.data.base_struct.struct_val;
|
||||
size_t field_index = val->data.x_ptr.data.base_struct.field_index;
|
||||
fprintf(stderr, "<struct %p field %zu\n", struct_val, field_index);
|
||||
if (struct_val != nullptr) {
|
||||
ZigValue *field_val = struct_val->data.x_struct.fields[field_index];
|
||||
if (field_val != nullptr) {
|
||||
dump_value_indent(field_val, indent + 1);
|
||||
} else {
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "(invalid null field)\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConstPtrSpecialBaseOptionalPayload: {
|
||||
ZigValue *optional_val = val->data.x_ptr.data.base_optional_payload.optional_val;
|
||||
fprintf(stderr, "<optional %p payload\n", optional_val);
|
||||
if (optional_val != nullptr) {
|
||||
dump_value_indent(optional_val, indent + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "TODO dump more pointer things\n");
|
||||
}
|
||||
for (int i = 0; i < indent; i += 1) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, ">\n");
|
||||
return;
|
||||
return dump_value_indent_ptr(val, indent);
|
||||
|
||||
case ZigTypeIdErrorSet:
|
||||
return dump_value_indent_error_set(val, indent);
|
||||
|
||||
case ZigTypeIdVector:
|
||||
case ZigTypeIdArray:
|
||||
case ZigTypeIdNull:
|
||||
case ZigTypeIdErrorSet:
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdUnion:
|
||||
case ZigTypeIdFn:
|
||||
|
|
|
@ -44,14 +44,20 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
|
|||
ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
|
||||
ZigType *get_test_fn_type(CodeGen *g);
|
||||
ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
|
||||
bool handle_is_ptr(ZigType *type_entry);
|
||||
bool handle_is_ptr(CodeGen *g, ZigType *type_entry);
|
||||
|
||||
bool type_has_bits(ZigType *type_entry);
|
||||
bool type_has_bits(CodeGen *g, ZigType *type_entry);
|
||||
Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
|
||||
|
||||
Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
|
||||
bool ptr_allows_addr_zero(ZigType *ptr_type);
|
||||
bool type_is_nonnull_ptr(ZigType *type);
|
||||
|
||||
// Deprecated, use `type_is_nonnull_ptr2`
|
||||
bool type_is_nonnull_ptr(CodeGen *g, ZigType *type);
|
||||
Error type_is_nonnull_ptr2(CodeGen *g, ZigType *type, bool *result);
|
||||
|
||||
ZigType *get_codegen_ptr_type_bail(CodeGen *g, ZigType *type);
|
||||
Error get_codegen_ptr_type(CodeGen *g, ZigType *type, ZigType **result);
|
||||
|
||||
enum SourceKind {
|
||||
SourceKindRoot,
|
||||
|
@ -68,7 +74,6 @@ Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name);
|
|||
void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy);
|
||||
|
||||
ZigType *get_src_ptr_type(ZigType *type);
|
||||
ZigType *get_codegen_ptr_type(ZigType *type);
|
||||
uint32_t get_ptr_align(CodeGen *g, ZigType *type);
|
||||
bool get_ptr_const(ZigType *type);
|
||||
ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry);
|
||||
|
@ -87,7 +92,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag);
|
|||
bool is_ref(ZigType *type_entry);
|
||||
bool is_array_ref(ZigType *type_entry);
|
||||
bool is_container_ref(ZigType *type_entry);
|
||||
bool is_valid_vector_elem_type(ZigType *elem_type);
|
||||
Error is_valid_vector_elem_type(CodeGen *g, ZigType *elem_type, bool *result);
|
||||
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
|
||||
ZigFn *scope_fn_entry(Scope *scope);
|
||||
ZigPackage *scope_package(Scope *scope);
|
||||
|
@ -223,7 +228,8 @@ Error ATTRIBUTE_MUST_USE file_fetch(CodeGen *g, Buf *resolved_path, Buf *content
|
|||
|
||||
void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk);
|
||||
X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty);
|
||||
bool type_is_c_abi_int(CodeGen *g, ZigType *ty);
|
||||
bool type_is_c_abi_int_bail(CodeGen *g, ZigType *ty);
|
||||
Error type_is_c_abi_int(CodeGen *g, ZigType *ty, bool *result);
|
||||
bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id);
|
||||
const char *container_string(ContainerKind kind);
|
||||
|
||||
|
|
196
src/codegen.cpp
196
src/codegen.cpp
|
@ -313,7 +313,7 @@ struct CalcLLVMFieldIndex {
|
|||
};
|
||||
|
||||
static void calc_llvm_field_index_add(CodeGen *g, CalcLLVMFieldIndex *calc, ZigType *ty) {
|
||||
if (!type_has_bits(ty)) return;
|
||||
if (!type_has_bits(g, ty)) return;
|
||||
uint32_t ty_align = get_abi_alignment(g, ty);
|
||||
if (calc->offset % ty_align != 0) {
|
||||
uint32_t llvm_align = LLVMABIAlignmentOfType(g->target_data_ref, get_llvm_type(g, ty));
|
||||
|
@ -334,7 +334,7 @@ static void frame_index_trace_arg_calc(CodeGen *g, CalcLLVMFieldIndex *calc, Zig
|
|||
calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // resume index
|
||||
calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // awaiter index
|
||||
|
||||
if (type_has_bits(return_type)) {
|
||||
if (type_has_bits(g, return_type)) {
|
||||
calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // *ReturnType (callee's)
|
||||
calc_llvm_field_index_add(g, calc, g->builtin_types.entry_usize); // *ReturnType (awaiter's)
|
||||
calc_llvm_field_index_add(g, calc, return_type); // ReturnType
|
||||
|
@ -383,7 +383,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
|
|||
return UINT32_MAX;
|
||||
}
|
||||
ZigType *return_type = fn_type->data.fn.fn_type_id.return_type;
|
||||
bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type);
|
||||
bool first_arg_ret = type_has_bits(g, return_type) && handle_is_ptr(g, return_type);
|
||||
return first_arg_ret ? 1 : 0;
|
||||
}
|
||||
|
||||
|
@ -581,9 +581,9 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
|||
addLLVMArgAttr(llvm_fn, 0, "nonnull");
|
||||
} else {
|
||||
unsigned init_gen_i = 0;
|
||||
if (!type_has_bits(return_type)) {
|
||||
if (!type_has_bits(g, return_type)) {
|
||||
// nothing to do
|
||||
} else if (type_is_nonnull_ptr(return_type)) {
|
||||
} else if (type_is_nonnull_ptr(g, return_type)) {
|
||||
addLLVMAttr(llvm_fn, 0, "nonnull");
|
||||
} else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) {
|
||||
// Sret pointers must not be address 0
|
||||
|
@ -859,8 +859,8 @@ static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, co
|
|||
}
|
||||
|
||||
static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) {
|
||||
if (type_has_bits(type)) {
|
||||
if (handle_is_ptr(type)) {
|
||||
if (type_has_bits(g, type)) {
|
||||
if (handle_is_ptr(g, type)) {
|
||||
return ptr;
|
||||
} else {
|
||||
assert(ptr_type->id == ZigTypeIdPointer);
|
||||
|
@ -1671,10 +1671,10 @@ static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type,
|
|||
assert(ptr_type->id == ZigTypeIdPointer);
|
||||
ZigType *child_type = ptr_type->data.pointer.child_type;
|
||||
|
||||
if (!type_has_bits(child_type))
|
||||
if (!type_has_bits(g, child_type))
|
||||
return;
|
||||
|
||||
if (handle_is_ptr(child_type)) {
|
||||
if (handle_is_ptr(g, child_type)) {
|
||||
assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind);
|
||||
assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
|
||||
|
||||
|
@ -1782,7 +1782,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstGen *instruction) {
|
|||
render_const_val(g, instruction->value, "");
|
||||
// we might have to do some pointer casting here due to the way union
|
||||
// values are rendered with a type other than the one we expect
|
||||
if (handle_is_ptr(instruction->value->type)) {
|
||||
if (handle_is_ptr(g, instruction->value->type)) {
|
||||
render_const_val_global(g, instruction->value, "");
|
||||
ZigType *ptr_type = get_pointer_to_type(g, instruction->value->type, true);
|
||||
instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->llvm_global, get_llvm_type(g, ptr_type), "");
|
||||
|
@ -1879,14 +1879,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
break;
|
||||
}
|
||||
|
||||
if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector ||
|
||||
if (type_is_c_abi_int_bail(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector ||
|
||||
ty->id == ZigTypeIdInt // TODO investigate if we need to change this
|
||||
) {
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs: {
|
||||
ZigType *ptr_type = get_codegen_ptr_type(ty);
|
||||
ZigType *ptr_type = get_codegen_ptr_type_bail(g, ty);
|
||||
if (ptr_type != nullptr) {
|
||||
if (type_is_nonnull_ptr(ty)) {
|
||||
if (type_is_nonnull_ptr(g, ty)) {
|
||||
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
|
||||
}
|
||||
if (ptr_type->data.pointer.is_const) {
|
||||
|
@ -1928,7 +1928,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
{
|
||||
// Arrays are just pointers
|
||||
if (ty->id == ZigTypeIdArray) {
|
||||
assert(handle_is_ptr(ty));
|
||||
assert(handle_is_ptr(g, ty));
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs:
|
||||
// arrays passed to C ABI functions may not be at address 0
|
||||
|
@ -1965,7 +1965,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
|
|||
X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty);
|
||||
size_t ty_size = type_size(g, ty);
|
||||
if (abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval) {
|
||||
assert(handle_is_ptr(ty));
|
||||
assert(handle_is_ptr(g, ty));
|
||||
switch (fn_walk->id) {
|
||||
case FnWalkIdAttrs:
|
||||
if (abi_class != X64CABIClass_MEMORY_nobyval) {
|
||||
|
@ -2088,7 +2088,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
|
|||
for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
|
||||
IrInstGen *param_instruction = instruction->args[call_i];
|
||||
ZigType *param_type = param_instruction->value->type;
|
||||
if (is_var_args || type_has_bits(param_type)) {
|
||||
if (is_var_args || type_has_bits(g, param_type)) {
|
||||
LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
|
||||
assert(param_value);
|
||||
fn_walk->data.call.gen_param_values->append(param_value);
|
||||
|
@ -2119,10 +2119,10 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
|
|||
if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) {
|
||||
addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly");
|
||||
}
|
||||
if (get_codegen_ptr_type(param_type) != nullptr) {
|
||||
if (get_codegen_ptr_type_bail(g, param_type) != nullptr) {
|
||||
addLLVMArgAttrInt(llvm_fn, (unsigned)gen_index, "align", get_ptr_align(g, param_type));
|
||||
}
|
||||
if (type_is_nonnull_ptr(param_type)) {
|
||||
if (type_is_nonnull_ptr(g, param_type)) {
|
||||
addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull");
|
||||
}
|
||||
break;
|
||||
|
@ -2137,7 +2137,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
|
|||
assert(variable);
|
||||
assert(variable->value_ref);
|
||||
|
||||
if (!handle_is_ptr(variable->var_type) && !fn_is_async(fn_walk->data.inits.fn)) {
|
||||
if (!handle_is_ptr(g, variable->var_type) && !fn_is_async(fn_walk->data.inits.fn)) {
|
||||
clear_debug_source_node(g);
|
||||
ZigType *fn_type = fn_table_entry->type_entry;
|
||||
unsigned gen_arg_index = fn_type->data.fn.gen_param_info[variable->src_arg_index].gen_index;
|
||||
|
@ -2404,12 +2404,12 @@ static void gen_async_return(CodeGen *g, IrInstGenReturn *instruction) {
|
|||
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
|
||||
|
||||
ZigType *operand_type = (instruction->operand != nullptr) ? instruction->operand->value->type : nullptr;
|
||||
bool operand_has_bits = (operand_type != nullptr) && type_has_bits(operand_type);
|
||||
bool operand_has_bits = (operand_type != nullptr) && type_has_bits(g, operand_type);
|
||||
ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
|
||||
bool ret_type_has_bits = type_has_bits(ret_type);
|
||||
bool ret_type_has_bits = type_has_bits(g, ret_type);
|
||||
|
||||
if (operand_has_bits && instruction->operand != nullptr) {
|
||||
bool need_store = instruction->operand->value->special != ConstValSpecialRuntime || !handle_is_ptr(ret_type);
|
||||
bool need_store = instruction->operand->value->special != ConstValSpecialRuntime || !handle_is_ptr(g, ret_type);
|
||||
if (need_store) {
|
||||
// It didn't get written to the result ptr. We do that now.
|
||||
ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true);
|
||||
|
@ -2512,7 +2512,7 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, Ir
|
|||
gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
|
||||
LLVMBuildRetVoid(g->builder);
|
||||
} else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync &&
|
||||
handle_is_ptr(g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
|
||||
handle_is_ptr(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
|
||||
{
|
||||
if (instruction->operand == nullptr) {
|
||||
LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
|
||||
|
@ -2883,7 +2883,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutableGen *executable,
|
|||
} else if (scalar_type->id == ZigTypeIdEnum ||
|
||||
scalar_type->id == ZigTypeIdErrorSet ||
|
||||
scalar_type->id == ZigTypeIdBool ||
|
||||
get_codegen_ptr_type(scalar_type) != nullptr)
|
||||
get_codegen_ptr_type_bail(g, scalar_type) != nullptr)
|
||||
{
|
||||
LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
|
||||
return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
|
||||
|
@ -3149,7 +3149,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen
|
|||
ZigType *array_type = actual_type->data.pointer.child_type;
|
||||
assert(array_type->id == ZigTypeIdArray);
|
||||
|
||||
if (type_has_bits(actual_type)) {
|
||||
if (type_has_bits(g, actual_type)) {
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, "");
|
||||
LLVMValueRef indices[] = {
|
||||
LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
|
||||
|
@ -3175,7 +3175,7 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,
|
|||
IrInstGenPtrCast *instruction)
|
||||
{
|
||||
ZigType *wanted_type = instruction->base.value->type;
|
||||
if (!type_has_bits(wanted_type)) {
|
||||
if (!type_has_bits(g, wanted_type)) {
|
||||
return nullptr;
|
||||
}
|
||||
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
|
||||
|
@ -3204,8 +3204,8 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,
|
|||
ZigType *actual_type = instruction->operand->value->type;
|
||||
LLVMValueRef value = ir_llvm_value(g, instruction->operand);
|
||||
|
||||
bool wanted_is_ptr = handle_is_ptr(wanted_type);
|
||||
bool actual_is_ptr = handle_is_ptr(actual_type);
|
||||
bool wanted_is_ptr = handle_is_ptr(g, wanted_type);
|
||||
bool actual_is_ptr = handle_is_ptr(g, actual_type);
|
||||
if (wanted_is_ptr == actual_is_ptr) {
|
||||
// We either bitcast the value directly or bitcast the pointer which does a pointer cast
|
||||
LLVMTypeRef wanted_type_ref = wanted_is_ptr ?
|
||||
|
@ -3352,9 +3352,9 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable
|
|||
g->err_tag_type, wanted_type, target_val);
|
||||
} else if (actual_type->id == ZigTypeIdErrorUnion) {
|
||||
// this should have been a compile time constant
|
||||
assert(type_has_bits(actual_type->data.error_union.err_set_type));
|
||||
assert(type_has_bits(g, actual_type->data.error_union.err_set_type));
|
||||
|
||||
if (!type_has_bits(actual_type->data.error_union.payload_type)) {
|
||||
if (!type_has_bits(g, actual_type->data.error_union.payload_type)) {
|
||||
return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
|
||||
g->err_tag_type, wanted_type, target_val);
|
||||
} else {
|
||||
|
@ -3442,7 +3442,7 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable,
|
|||
}
|
||||
|
||||
static void render_decl_var(CodeGen *g, ZigVar *var) {
|
||||
if (!type_has_bits(var->var_type))
|
||||
if (!type_has_bits(g, var->var_type))
|
||||
return;
|
||||
|
||||
var->value_ref = ir_llvm_value(g, var->ptr_instruction);
|
||||
|
@ -3460,7 +3460,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable,
|
|||
IrInstGenLoadPtr *instruction)
|
||||
{
|
||||
ZigType *child_type = instruction->base.value->type;
|
||||
if (!type_has_bits(child_type))
|
||||
if (!type_has_bits(g, child_type))
|
||||
return nullptr;
|
||||
|
||||
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
|
||||
|
@ -3495,7 +3495,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable,
|
|||
LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);
|
||||
LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
|
||||
|
||||
if (handle_is_ptr(child_type)) {
|
||||
if (handle_is_ptr(g, child_type)) {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
|
||||
LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");
|
||||
|
@ -3642,7 +3642,7 @@ static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef b
|
|||
}
|
||||
|
||||
static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) {
|
||||
assert(type_has_bits(value_type));
|
||||
assert(type_has_bits(g, value_type));
|
||||
uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type));
|
||||
assert(size_bytes > 0);
|
||||
assert(ptr_align_bytes > 0);
|
||||
|
@ -3708,7 +3708,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I
|
|||
if (instruction->base.value->special != ConstValSpecialRuntime)
|
||||
return ir_llvm_value(g, &instruction->base);
|
||||
ZigVar *var = instruction->var;
|
||||
if (type_has_bits(var->var_type)) {
|
||||
if (type_has_bits(g, var->var_type)) {
|
||||
assert(var->value_ref);
|
||||
return var->value_ref;
|
||||
} else {
|
||||
|
@ -3719,7 +3719,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I
|
|||
static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable,
|
||||
IrInstGenReturnPtr *instruction)
|
||||
{
|
||||
if (!type_has_bits(instruction->base.value->type))
|
||||
if (!type_has_bits(g, instruction->base.value->type))
|
||||
return nullptr;
|
||||
ir_assert(g->cur_ret_ptr != nullptr, &instruction->base);
|
||||
return g->cur_ret_ptr;
|
||||
|
@ -3733,7 +3733,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable,
|
|||
LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index);
|
||||
assert(subscript_value);
|
||||
|
||||
if (!type_has_bits(array_type))
|
||||
if (!type_has_bits(g, array_type))
|
||||
return nullptr;
|
||||
|
||||
bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on;
|
||||
|
@ -3793,7 +3793,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable,
|
|||
assert(array_type->data.structure.special == StructSpecialSlice);
|
||||
|
||||
ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry;
|
||||
if (!type_has_bits(ptr_type)) {
|
||||
if (!type_has_bits(g, ptr_type)) {
|
||||
if (safety_check_on) {
|
||||
assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMIntegerTypeKind);
|
||||
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, array_ptr);
|
||||
|
@ -3872,7 +3872,7 @@ static void render_async_spills(CodeGen *g) {
|
|||
for (size_t var_i = 0; var_i < g->cur_fn->variable_list.length; var_i += 1) {
|
||||
ZigVar *var = g->cur_fn->variable_list.at(var_i);
|
||||
|
||||
if (!type_has_bits(var->var_type)) {
|
||||
if (!type_has_bits(g, var->var_type)) {
|
||||
continue;
|
||||
}
|
||||
if (ir_get_var_is_comptime(var))
|
||||
|
@ -3992,7 +3992,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
|
|||
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
|
||||
|
||||
ZigType *src_return_type = fn_type_id->return_type;
|
||||
bool ret_has_bits = type_has_bits(src_return_type);
|
||||
bool ret_has_bits = type_has_bits(g, src_return_type);
|
||||
|
||||
CallingConvention cc = fn_type->data.fn.fn_type_id.cc;
|
||||
|
||||
|
@ -4312,7 +4312,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
|
|||
gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr);
|
||||
render_async_var_decls(g, instruction->base.base.scope);
|
||||
|
||||
if (!type_has_bits(src_return_type))
|
||||
if (!type_has_bits(g, src_return_type))
|
||||
return nullptr;
|
||||
|
||||
if (result_loc != nullptr) {
|
||||
|
@ -4372,7 +4372,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
|
|||
} else if (first_arg_ret) {
|
||||
set_call_instr_sret(g, result);
|
||||
return result_loc;
|
||||
} else if (handle_is_ptr(src_return_type)) {
|
||||
} else if (handle_is_ptr(g, src_return_type)) {
|
||||
LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);
|
||||
LLVMSetAlignment(store_instr, get_ptr_align(g, instruction->result_loc->value->type));
|
||||
return result_loc;
|
||||
|
@ -4397,7 +4397,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *exec
|
|||
ZigType *struct_ptr_type = instruction->struct_ptr->value->type;
|
||||
TypeStructField *field = instruction->field;
|
||||
|
||||
if (!type_has_bits(field->type_entry))
|
||||
if (!type_has_bits(g, field->type_entry))
|
||||
return nullptr;
|
||||
|
||||
if (struct_ptr_type->id == ZigTypeIdPointer &&
|
||||
|
@ -4448,9 +4448,9 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *execu
|
|||
|
||||
TypeUnionField *field = instruction->field;
|
||||
|
||||
if (!type_has_bits(field->type_entry)) {
|
||||
if (!type_has_bits(g, field->type_entry)) {
|
||||
ZigType *tag_type = union_type->data.unionation.tag_type;
|
||||
if (!instruction->initializing || tag_type == nullptr || !type_has_bits(tag_type))
|
||||
if (!instruction->initializing || tag_type == nullptr || !type_has_bits(g, tag_type))
|
||||
return nullptr;
|
||||
|
||||
// The field has no bits but we still have to change the discriminant
|
||||
|
@ -4672,10 +4672,10 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR
|
|||
(maybe_type->id == ZigTypeIdPointer && maybe_type->data.pointer.allow_zero));
|
||||
|
||||
ZigType *child_type = maybe_type->data.maybe.child_type;
|
||||
if (!type_has_bits(child_type))
|
||||
if (!type_has_bits(g, child_type))
|
||||
return maybe_handle;
|
||||
|
||||
bool is_scalar = !handle_is_ptr(maybe_type);
|
||||
bool is_scalar = !handle_is_ptr(g, maybe_type);
|
||||
if (is_scalar)
|
||||
return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
|
||||
|
||||
|
@ -4713,14 +4713,14 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutableGen *e
|
|||
|
||||
LLVMPositionBuilderAtEnd(g->builder, ok_block);
|
||||
}
|
||||
if (!type_has_bits(child_type)) {
|
||||
if (!type_has_bits(g, child_type)) {
|
||||
if (instruction->initializing) {
|
||||
LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
|
||||
gen_store_untyped(g, non_null_bit, base_ptr, 0, false);
|
||||
}
|
||||
return nullptr;
|
||||
} else {
|
||||
bool is_scalar = !handle_is_ptr(maybe_type);
|
||||
bool is_scalar = !handle_is_ptr(g, maybe_type);
|
||||
if (is_scalar) {
|
||||
return base_ptr;
|
||||
} else {
|
||||
|
@ -4899,11 +4899,11 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable,
|
|||
}
|
||||
|
||||
static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrInstGenPhi *instruction) {
|
||||
if (!type_has_bits(instruction->base.value->type))
|
||||
if (!type_has_bits(g, instruction->base.value->type))
|
||||
return nullptr;
|
||||
|
||||
LLVMTypeRef phi_type;
|
||||
if (handle_is_ptr(instruction->base.value->type)) {
|
||||
if (handle_is_ptr(g, instruction->base.value->type)) {
|
||||
phi_type = LLVMPointerType(get_llvm_type(g,instruction->base.value->type), 0);
|
||||
} else {
|
||||
phi_type = get_llvm_type(g, instruction->base.value->type);
|
||||
|
@ -4921,7 +4921,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrIns
|
|||
}
|
||||
|
||||
static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrInstGenRef *instruction) {
|
||||
if (!type_has_bits(instruction->base.value->type)) {
|
||||
if (!type_has_bits(g, instruction->base.value->type)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instruction->operand->id == IrInstGenIdCall) {
|
||||
|
@ -4931,7 +4931,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
|
|||
}
|
||||
}
|
||||
LLVMValueRef value = ir_llvm_value(g, instruction->operand);
|
||||
if (handle_is_ptr(instruction->operand->value->type)) {
|
||||
if (handle_is_ptr(g, instruction->operand->value->type)) {
|
||||
return value;
|
||||
} else {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
|
@ -5232,20 +5232,20 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
|
|||
assert(optional_type->id == ZigTypeIdOptional);
|
||||
ZigType *child_type = optional_type->data.maybe.child_type;
|
||||
|
||||
if (!handle_is_ptr(optional_type)) {
|
||||
if (!handle_is_ptr(g, optional_type)) {
|
||||
LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
|
||||
LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
|
||||
return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
|
||||
}
|
||||
|
||||
// When the cmpxchg is discarded, the result location will have no bits.
|
||||
if (!type_has_bits(instruction->result_loc->value->type)) {
|
||||
if (!type_has_bits(g, instruction->result_loc->value->type)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
ir_assert(result_loc != nullptr, &instruction->base);
|
||||
ir_assert(type_has_bits(child_type), &instruction->base);
|
||||
ir_assert(type_has_bits(g, child_type), &instruction->base);
|
||||
|
||||
LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
|
||||
LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
|
||||
|
@ -5373,7 +5373,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!type_has_bits(array_type)) {
|
||||
if (!type_has_bits(g, array_type)) {
|
||||
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
|
||||
|
||||
// TODO if runtime safety is on, store 0xaaaaaaa in ptr field
|
||||
|
@ -5409,7 +5409,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrI
|
|||
}
|
||||
}
|
||||
|
||||
if (type_has_bits(array_type)) {
|
||||
if (type_has_bits(g, array_type)) {
|
||||
size_t gen_ptr_index = instruction->base.value->type->data.structure.fields[slice_ptr_index]->gen_index;
|
||||
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
|
||||
LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
|
||||
|
@ -5597,7 +5597,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutableGen *executable,
|
|||
LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);
|
||||
|
||||
LLVMValueRef err_val;
|
||||
if (type_has_bits(payload_type)) {
|
||||
if (type_has_bits(g, payload_type)) {
|
||||
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
|
||||
err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
|
||||
} else {
|
||||
|
@ -5619,7 +5619,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *execu
|
|||
ZigType *err_union_type = ptr_type->data.pointer.child_type;
|
||||
ZigType *payload_type = err_union_type->data.error_union.payload_type;
|
||||
LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union_ptr);
|
||||
if (!type_has_bits(payload_type)) {
|
||||
if (!type_has_bits(g, payload_type)) {
|
||||
return err_union_ptr;
|
||||
} else {
|
||||
// TODO assign undef to the payload
|
||||
|
@ -5659,13 +5659,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex
|
|||
|
||||
LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
|
||||
|
||||
if (!type_has_bits(err_union_type->data.error_union.err_set_type)) {
|
||||
if (!type_has_bits(g, err_union_type->data.error_union.err_set_type)) {
|
||||
return err_union_handle;
|
||||
}
|
||||
|
||||
if (want_safety) {
|
||||
LLVMValueRef err_val;
|
||||
if (type_has_bits(payload_type)) {
|
||||
if (type_has_bits(g, payload_type)) {
|
||||
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
|
||||
err_val = gen_load_untyped(g, err_val_ptr, 0, false, "");
|
||||
} else {
|
||||
|
@ -5682,7 +5682,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex
|
|||
LLVMPositionBuilderAtEnd(g->builder, ok_block);
|
||||
}
|
||||
|
||||
if (type_has_bits(payload_type)) {
|
||||
if (type_has_bits(g, payload_type)) {
|
||||
if (instruction->initializing) {
|
||||
LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
|
||||
LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
|
||||
|
@ -5704,7 +5704,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa
|
|||
|
||||
ZigType *child_type = wanted_type->data.maybe.child_type;
|
||||
|
||||
if (!type_has_bits(child_type)) {
|
||||
if (!type_has_bits(g, child_type)) {
|
||||
LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type());
|
||||
if (instruction->result_loc != nullptr) {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
|
@ -5714,7 +5714,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa
|
|||
}
|
||||
|
||||
LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
|
||||
if (!handle_is_ptr(wanted_type)) {
|
||||
if (!handle_is_ptr(g, wanted_type)) {
|
||||
if (instruction->result_loc != nullptr) {
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
gen_store_untyped(g, payload_val, result_loc, 0, false);
|
||||
|
@ -5740,7 +5740,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executa
|
|||
|
||||
LLVMValueRef err_val = ir_llvm_value(g, instruction->operand);
|
||||
|
||||
if (!handle_is_ptr(wanted_type))
|
||||
if (!handle_is_ptr(g, wanted_type))
|
||||
return err_val;
|
||||
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
|
@ -5761,13 +5761,13 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *exec
|
|||
ZigType *payload_type = wanted_type->data.error_union.payload_type;
|
||||
ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
|
||||
|
||||
if (!type_has_bits(err_set_type)) {
|
||||
if (!type_has_bits(g, err_set_type)) {
|
||||
return ir_llvm_value(g, instruction->operand);
|
||||
}
|
||||
|
||||
LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
|
||||
|
||||
if (!type_has_bits(payload_type))
|
||||
if (!type_has_bits(g, payload_type))
|
||||
return ok_err_val;
|
||||
|
||||
|
||||
|
@ -5788,7 +5788,7 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable,
|
|||
ZigType *union_type = instruction->value->value->type;
|
||||
|
||||
ZigType *tag_type = union_type->data.unionation.tag_type;
|
||||
if (!type_has_bits(tag_type))
|
||||
if (!type_has_bits(g, tag_type))
|
||||
return nullptr;
|
||||
|
||||
LLVMValueRef union_val = ir_llvm_value(g, instruction->value);
|
||||
|
@ -5825,7 +5825,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable
|
|||
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
|
||||
LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
|
||||
|
||||
if (get_codegen_ptr_type(operand_type) == nullptr) {
|
||||
if (get_codegen_ptr_type_bail(g, operand_type) == nullptr) {
|
||||
return ZigLLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded);
|
||||
}
|
||||
|
||||
|
@ -5927,7 +5927,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *execu
|
|||
{
|
||||
ZigType *array_type = instruction->base.value->type;
|
||||
assert(array_type->id == ZigTypeIdArray);
|
||||
assert(handle_is_ptr(array_type));
|
||||
assert(handle_is_ptr(g, array_type));
|
||||
LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
|
||||
LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
|
||||
|
||||
|
@ -5961,7 +5961,7 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *execu
|
|||
{
|
||||
ZigType *vector_type = instruction->base.value->type;
|
||||
assert(vector_type->id == ZigTypeIdVector);
|
||||
assert(!handle_is_ptr(vector_type));
|
||||
assert(!handle_is_ptr(g, vector_type));
|
||||
LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array);
|
||||
LLVMTypeRef vector_type_ref = get_llvm_type(g, vector_type);
|
||||
|
||||
|
@ -6057,7 +6057,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
|
|||
{
|
||||
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
|
||||
LLVMValueRef their_result_ptr = nullptr;
|
||||
if (type_has_bits(result_type) && (non_async || result_loc != nullptr)) {
|
||||
if (type_has_bits(g, result_type) && (non_async || result_loc != nullptr)) {
|
||||
LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, "");
|
||||
their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, "");
|
||||
if (result_loc != nullptr) {
|
||||
|
@ -6082,7 +6082,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
|
|||
ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2,
|
||||
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
|
||||
}
|
||||
if (non_async && type_has_bits(result_type)) {
|
||||
if (non_async && type_has_bits(g, result_type)) {
|
||||
LLVMValueRef result_ptr = (result_loc == nullptr) ? their_result_ptr : result_loc;
|
||||
return get_handle_value(g, result_ptr, result_type, ptr_result_type);
|
||||
} else {
|
||||
|
@ -6115,7 +6115,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
|
|||
// This code is as if it is running inside the suspend block.
|
||||
|
||||
// supply the awaiter return pointer
|
||||
if (type_has_bits(result_type)) {
|
||||
if (type_has_bits(g, result_type)) {
|
||||
LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, "");
|
||||
if (result_loc == nullptr) {
|
||||
// no copy needed
|
||||
|
@ -6599,7 +6599,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Zig
|
|||
}
|
||||
|
||||
ZigType *type_entry = const_val->type;
|
||||
assert(type_has_bits(type_entry));
|
||||
assert(type_has_bits(g, type_entry));
|
||||
switch (type_entry->id) {
|
||||
case ZigTypeIdInvalid:
|
||||
case ZigTypeIdMetaType:
|
||||
|
@ -6732,7 +6732,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
|
|||
{
|
||||
ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;
|
||||
assert(array_const_val->type->id == ZigTypeIdArray);
|
||||
if (!type_has_bits(array_const_val->type)) {
|
||||
if (!type_has_bits(g, array_const_val->type)) {
|
||||
if (array_const_val->type->data.array.sentinel != nullptr) {
|
||||
ZigValue *pointee = array_const_val->type->data.array.sentinel;
|
||||
render_const_val(g, pointee, "");
|
||||
|
@ -6758,7 +6758,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
|
|||
{
|
||||
ZigValue *struct_const_val = const_val->data.x_ptr.data.base_struct.struct_val;
|
||||
assert(struct_const_val->type->id == ZigTypeIdStruct);
|
||||
if (!type_has_bits(struct_const_val->type)) {
|
||||
if (!type_has_bits(g, struct_const_val->type)) {
|
||||
// make this a null pointer
|
||||
ZigType *usize = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type),
|
||||
|
@ -6777,7 +6777,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
|
|||
{
|
||||
ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_code.err_union_val;
|
||||
assert(err_union_const_val->type->id == ZigTypeIdErrorUnion);
|
||||
if (!type_has_bits(err_union_const_val->type)) {
|
||||
if (!type_has_bits(g, err_union_const_val->type)) {
|
||||
// make this a null pointer
|
||||
ZigType *usize = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type),
|
||||
|
@ -6793,7 +6793,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
|
|||
{
|
||||
ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_payload.err_union_val;
|
||||
assert(err_union_const_val->type->id == ZigTypeIdErrorUnion);
|
||||
if (!type_has_bits(err_union_const_val->type)) {
|
||||
if (!type_has_bits(g, err_union_const_val->type)) {
|
||||
// make this a null pointer
|
||||
ZigType *usize = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type),
|
||||
|
@ -6809,7 +6809,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const cha
|
|||
{
|
||||
ZigValue *optional_const_val = const_val->data.x_ptr.data.base_optional_payload.optional_val;
|
||||
assert(optional_const_val->type->id == ZigTypeIdOptional);
|
||||
if (!type_has_bits(optional_const_val->type)) {
|
||||
if (!type_has_bits(g, optional_const_val->type)) {
|
||||
// make this a null pointer
|
||||
ZigType *usize = g->builtin_types.entry_usize;
|
||||
const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type),
|
||||
|
@ -6847,7 +6847,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
|
|||
Error err;
|
||||
|
||||
ZigType *type_entry = const_val->type;
|
||||
assert(type_has_bits(type_entry));
|
||||
assert(type_has_bits(g, type_entry));
|
||||
|
||||
check: switch (const_val->special) {
|
||||
case ConstValSpecialLazy:
|
||||
|
@ -6900,12 +6900,12 @@ check: switch (const_val->special) {
|
|||
case ZigTypeIdOptional:
|
||||
{
|
||||
ZigType *child_type = type_entry->data.maybe.child_type;
|
||||
if (!type_has_bits(child_type)) {
|
||||
return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false);
|
||||
} else if (get_codegen_ptr_type(type_entry) != nullptr) {
|
||||
if (get_src_ptr_type(type_entry) != nullptr) {
|
||||
return gen_const_val_ptr(g, const_val, name);
|
||||
} else if (child_type->id == ZigTypeIdErrorSet) {
|
||||
return gen_const_val_err_set(g, const_val, name);
|
||||
} else if (!type_has_bits(g, child_type)) {
|
||||
return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false);
|
||||
} else {
|
||||
LLVMValueRef child_val;
|
||||
LLVMValueRef maybe_val;
|
||||
|
@ -7128,7 +7128,7 @@ check: switch (const_val->special) {
|
|||
LLVMValueRef union_value_ref;
|
||||
bool make_unnamed_struct;
|
||||
ZigValue *payload_value = const_val->data.x_union.payload;
|
||||
if (payload_value == nullptr || !type_has_bits(payload_value->type)) {
|
||||
if (payload_value == nullptr || !type_has_bits(g, payload_value->type)) {
|
||||
if (type_entry->data.unionation.gen_tag_index == SIZE_MAX)
|
||||
return LLVMGetUndef(get_llvm_type(g, type_entry));
|
||||
|
||||
|
@ -7205,13 +7205,13 @@ check: switch (const_val->special) {
|
|||
{
|
||||
ZigType *payload_type = type_entry->data.error_union.payload_type;
|
||||
ZigType *err_set_type = type_entry->data.error_union.err_set_type;
|
||||
if (!type_has_bits(payload_type)) {
|
||||
assert(type_has_bits(err_set_type));
|
||||
if (!type_has_bits(g, payload_type)) {
|
||||
assert(type_has_bits(g, err_set_type));
|
||||
ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set;
|
||||
uint64_t value = (err_set == nullptr) ? 0 : err_set->value;
|
||||
return LLVMConstInt(get_llvm_type(g, g->err_tag_type), value, false);
|
||||
} else if (!type_has_bits(err_set_type)) {
|
||||
assert(type_has_bits(payload_type));
|
||||
} else if (!type_has_bits(g, err_set_type)) {
|
||||
assert(type_has_bits(g, payload_type));
|
||||
return gen_const_val(g, const_val->data.x_err_union.payload, "");
|
||||
} else {
|
||||
LLVMValueRef err_tag_value;
|
||||
|
@ -7445,7 +7445,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!type_has_bits(var->var_type))
|
||||
if (!type_has_bits(g, var->var_type))
|
||||
continue;
|
||||
|
||||
assert(var->decl_node);
|
||||
|
@ -7544,7 +7544,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
} else {
|
||||
if (want_sret) {
|
||||
g->cur_ret_ptr = LLVMGetParam(fn, 0);
|
||||
} else if (type_has_bits(fn_type_id->return_type)) {
|
||||
} else if (type_has_bits(g, fn_type_id->return_type)) {
|
||||
g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
|
||||
// TODO add debug info variable for this
|
||||
} else {
|
||||
|
@ -7609,7 +7609,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
ZigType *child_type = ptr_type->data.pointer.child_type;
|
||||
if (type_resolve(g, child_type, ResolveStatusSizeKnown))
|
||||
zig_unreachable();
|
||||
if (!type_has_bits(child_type))
|
||||
if (!type_has_bits(g, child_type))
|
||||
continue;
|
||||
if (instruction->base.base.ref_count == 0)
|
||||
continue;
|
||||
|
@ -7640,7 +7640,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
|
||||
ZigVar *var = fn_table_entry->variable_list.at(var_i);
|
||||
|
||||
if (!type_has_bits(var->var_type)) {
|
||||
if (!type_has_bits(g, var->var_type)) {
|
||||
continue;
|
||||
}
|
||||
if (ir_get_var_is_comptime(var))
|
||||
|
@ -7667,7 +7667,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index];
|
||||
assert(gen_info->gen_index != SIZE_MAX);
|
||||
|
||||
if (handle_is_ptr(var->var_type)) {
|
||||
if (handle_is_ptr(g, var->var_type)) {
|
||||
if (gen_info->is_byval) {
|
||||
gen_type = var->var_type;
|
||||
} else {
|
||||
|
@ -7739,7 +7739,7 @@ static void do_code_gen(CodeGen *g) {
|
|||
LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_resume_index, "");
|
||||
g->cur_async_resume_index_ptr = resume_index_ptr;
|
||||
|
||||
if (type_has_bits(fn_type_id->return_type)) {
|
||||
if (type_has_bits(g, fn_type_id->return_type)) {
|
||||
LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, "");
|
||||
g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, "");
|
||||
}
|
||||
|
@ -9847,10 +9847,10 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
|
|||
case ZigTypeIdOptional:
|
||||
{
|
||||
ZigType *child_type = type_entry->data.maybe.child_type;
|
||||
if (!type_has_bits(child_type)) {
|
||||
if (!type_has_bits(g, child_type)) {
|
||||
buf_init_from_str(out_buf, "bool");
|
||||
return;
|
||||
} else if (type_is_nonnull_ptr(child_type)) {
|
||||
} else if (type_is_nonnull_ptr(g, child_type)) {
|
||||
return get_c_type(g, gen_h, child_type, out_buf);
|
||||
} else {
|
||||
zig_unreachable();
|
||||
|
|
133
src/ir.cpp
133
src/ir.cpp
|
@ -860,7 +860,7 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
|
|||
if (expected == actual)
|
||||
return true;
|
||||
|
||||
if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr)
|
||||
if (get_src_ptr_type(expected) != nullptr && get_src_ptr_type(actual) != nullptr)
|
||||
return true;
|
||||
|
||||
if (is_opt_err_set(expected) && is_opt_err_set(actual))
|
||||
|
@ -11399,7 +11399,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
|||
result.id = ConstCastResultIdInvalid;
|
||||
return result;
|
||||
}
|
||||
if (type_has_bits(wanted_type) == type_has_bits(actual_type) &&
|
||||
if (type_has_bits(g, wanted_type) == type_has_bits(g, actual_type) &&
|
||||
actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
|
||||
actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes &&
|
||||
get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type))
|
||||
|
@ -12532,7 +12532,7 @@ static IrInstGen *ir_const_move(IrAnalyze *ira, IrInst *old_instruction, ZigValu
|
|||
static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
|
||||
ZigType *wanted_type, CastOp cast_op)
|
||||
{
|
||||
if (instr_is_comptime(value) || !type_has_bits(wanted_type)) {
|
||||
if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) {
|
||||
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
|
||||
if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type,
|
||||
result->value, wanted_type))
|
||||
|
@ -12918,7 +12918,7 @@ static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNo
|
|||
case ConstValSpecialStatic:
|
||||
return ErrorNone;
|
||||
case ConstValSpecialRuntime:
|
||||
if (!type_has_bits(val->type))
|
||||
if (!type_has_bits(codegen, val->type))
|
||||
return ErrorNone;
|
||||
|
||||
exec_add_error_node_gen(codegen, exec, source_node,
|
||||
|
@ -13082,7 +13082,11 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstGen *type_value) {
|
|||
}
|
||||
|
||||
static Error ir_validate_vector_elem_type(IrAnalyze *ira, AstNode *source_node, ZigType *elem_type) {
|
||||
if (!is_valid_vector_elem_type(elem_type)) {
|
||||
Error err;
|
||||
bool is_valid;
|
||||
if ((err = is_valid_vector_elem_type(ira->codegen, elem_type, &is_valid)))
|
||||
return err;
|
||||
if (!is_valid) {
|
||||
ir_add_error_node(ira, source_node,
|
||||
buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid",
|
||||
buf_ptr(&elem_type->name)));
|
||||
|
@ -13198,7 +13202,7 @@ static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr,
|
|||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
if (result_loc == nullptr && handle_is_ptr(wanted_type)) {
|
||||
if (result_loc == nullptr && handle_is_ptr(ira->codegen, wanted_type)) {
|
||||
result_loc = no_result_loc();
|
||||
}
|
||||
IrInstGen *result_loc_inst = nullptr;
|
||||
|
@ -13246,7 +13250,7 @@ static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_ins
|
|||
}
|
||||
|
||||
IrInstGen *result_loc_inst;
|
||||
if (handle_is_ptr(wanted_type)) {
|
||||
if (handle_is_ptr(ira->codegen, wanted_type)) {
|
||||
if (result_loc == nullptr) result_loc = no_result_loc();
|
||||
result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true);
|
||||
if (type_is_invalid(result_loc_inst->value->type) ||
|
||||
|
@ -13358,7 +13362,7 @@ static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr,
|
|||
}
|
||||
|
||||
IrInstGen *result_loc_inst;
|
||||
if (handle_is_ptr(wanted_type)) {
|
||||
if (handle_is_ptr(ira->codegen, wanted_type)) {
|
||||
if (result_loc == nullptr) result_loc = no_result_loc();
|
||||
result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true);
|
||||
if (type_is_invalid(result_loc_inst->value->type) ||
|
||||
|
@ -13385,7 +13389,8 @@ static IrInstGen *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInst *source_instr,
|
|||
|
||||
IrInstGen *result = ir_const(ira, source_instr, wanted_type);
|
||||
result->value->special = ConstValSpecialStatic;
|
||||
if (get_codegen_ptr_type(wanted_type) != nullptr) {
|
||||
|
||||
if (get_src_ptr_type(wanted_type) != nullptr) {
|
||||
result->value->data.x_ptr.special = ConstPtrSpecialNull;
|
||||
} else if (is_opt_err_set(wanted_type)) {
|
||||
result->value->data.x_err_set = nullptr;
|
||||
|
@ -13434,7 +13439,7 @@ static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInst
|
|||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
IrInstGen *result_loc;
|
||||
if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) {
|
||||
if (type_has_bits(ira->codegen, ptr_type) && !handle_is_ptr(ira->codegen, elem_type)) {
|
||||
result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true);
|
||||
} else {
|
||||
result_loc = nullptr;
|
||||
|
@ -13679,9 +13684,9 @@ static IrInstGen *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInst* source_ins
|
|||
// If the destination integer type has no bits, then we can emit a comptime
|
||||
// zero. However, we still want to emit a runtime safety check to make sure
|
||||
// the target is zero.
|
||||
if (!type_has_bits(wanted_type)) {
|
||||
if (!type_has_bits(ira->codegen, wanted_type)) {
|
||||
assert(wanted_type->id == ZigTypeIdInt);
|
||||
assert(type_has_bits(target->value->type));
|
||||
assert(type_has_bits(ira->codegen, target->value->type));
|
||||
ir_build_assert_zero(ira, source_instr, target);
|
||||
IrInstGen *result = ir_const_unsigned(ira, source_instr, 0);
|
||||
result->value->type = wanted_type;
|
||||
|
@ -15038,7 +15043,7 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns
|
|||
}
|
||||
|
||||
IrInstGen *result_loc_inst;
|
||||
if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {
|
||||
if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(ira->codegen, child_type)) {
|
||||
if (result_loc == nullptr) result_loc = no_result_loc();
|
||||
result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, true);
|
||||
if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) {
|
||||
|
@ -15298,7 +15303,7 @@ static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn
|
|||
}
|
||||
|
||||
if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr &&
|
||||
handle_is_ptr(ira->explicit_return_type))
|
||||
handle_is_ptr(ira->codegen, ira->explicit_return_type))
|
||||
{
|
||||
// result location mechanism took care of it.
|
||||
IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr);
|
||||
|
@ -15387,7 +15392,7 @@ static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) {
|
|||
|
||||
static bool optional_value_is_null(ZigValue *val) {
|
||||
assert(val->special == ConstValSpecialStatic);
|
||||
if (get_codegen_ptr_type(val->type) != nullptr) {
|
||||
if (get_src_ptr_type(val->type) != nullptr) {
|
||||
if (val->data.x_ptr.special == ConstPtrSpecialNull) {
|
||||
return true;
|
||||
} else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
|
||||
|
@ -15406,7 +15411,7 @@ static void set_optional_value_to_null(ZigValue *val) {
|
|||
assert(val->special == ConstValSpecialStatic);
|
||||
if (val->type->id == ZigTypeIdNull) return; // nothing to do
|
||||
assert(val->type->id == ZigTypeIdOptional);
|
||||
if (get_codegen_ptr_type(val->type) != nullptr) {
|
||||
if (get_src_ptr_type(val->type) != nullptr) {
|
||||
val->data.x_ptr.special = ConstPtrSpecialNull;
|
||||
} else if (is_opt_err_set(val->type)) {
|
||||
val->data.x_err_set = nullptr;
|
||||
|
@ -16244,7 +16249,7 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i
|
|||
operator_allowed = false;
|
||||
break;
|
||||
case ZigTypeIdOptional:
|
||||
operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr;
|
||||
operator_allowed = is_equality_cmp && get_src_ptr_type(resolved_type) != nullptr;
|
||||
break;
|
||||
}
|
||||
if (!operator_allowed) {
|
||||
|
@ -17894,7 +17899,7 @@ static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
|
|||
if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) {
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type);
|
||||
ZigValue *out_val = result->value;
|
||||
assert(get_codegen_ptr_type(optional_type) != nullptr);
|
||||
assert(get_src_ptr_type(optional_type) != nullptr);
|
||||
out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
|
||||
out_val->data.x_ptr.data.hard_coded_addr.addr = 0;
|
||||
return result;
|
||||
|
@ -18283,7 +18288,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
|
|||
if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) {
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
if (!type_has_bits(value_type)) {
|
||||
if (!type_has_bits(ira->codegen, value_type)) {
|
||||
parent_ptr_align = 0;
|
||||
}
|
||||
// If we're casting from a sentinel-terminated array to a non-sentinel-terminated array,
|
||||
|
@ -18328,7 +18333,10 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
|
|||
if (type_is_invalid(dest_type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (get_codegen_ptr_type(dest_type) != nullptr) {
|
||||
ZigType *dest_cg_ptr_type;
|
||||
if ((err = get_codegen_ptr_type(ira->codegen, dest_type, &dest_cg_ptr_type)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (dest_cg_ptr_type != nullptr) {
|
||||
ir_add_error(ira, &result_loc->source_instruction->base,
|
||||
buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
@ -18340,7 +18348,10 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
|
|||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
|
||||
if (get_codegen_ptr_type(value_type) != nullptr) {
|
||||
ZigType *value_cg_ptr_type;
|
||||
if ((err = get_codegen_ptr_type(ira->codegen, value_type, &value_cg_ptr_type)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
if (value_cg_ptr_type != nullptr) {
|
||||
ir_add_error(ira, suspend_source_instr,
|
||||
buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
@ -18400,7 +18411,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
|
|||
}
|
||||
}
|
||||
uint64_t parent_ptr_align = 0;
|
||||
if (type_has_bits(value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type);
|
||||
if (type_has_bits(ira->codegen, value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type);
|
||||
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type,
|
||||
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);
|
||||
|
@ -19118,7 +19129,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
}
|
||||
|
||||
IrInstGen *first_arg;
|
||||
if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) {
|
||||
if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) {
|
||||
first_arg = first_arg_ptr;
|
||||
} else {
|
||||
first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
|
||||
|
@ -19247,7 +19258,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
}
|
||||
|
||||
IrInstGen *first_arg;
|
||||
if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) {
|
||||
if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) {
|
||||
first_arg = first_arg_ptr;
|
||||
} else {
|
||||
first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr);
|
||||
|
@ -19366,7 +19377,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
}
|
||||
|
||||
IrInstGen *result_loc;
|
||||
if (handle_is_ptr(impl_fn_type_id->return_type)) {
|
||||
if (handle_is_ptr(ira->codegen, impl_fn_type_id->return_type)) {
|
||||
result_loc = ir_resolve_result(ira, source_instr, call_result_loc,
|
||||
impl_fn_type_id->return_type, nullptr, true, false);
|
||||
if (result_loc != nullptr) {
|
||||
|
@ -19383,7 +19394,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
if (res_child_type == ira->codegen->builtin_types.entry_var) {
|
||||
res_child_type = impl_fn_type_id->return_type;
|
||||
}
|
||||
if (!handle_is_ptr(res_child_type)) {
|
||||
if (!handle_is_ptr(ira->codegen, res_child_type)) {
|
||||
ir_reset_result(call_result_loc);
|
||||
result_loc = nullptr;
|
||||
}
|
||||
|
@ -19435,7 +19446,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
|
||||
IrInstGen *first_arg;
|
||||
if (param_type->id == ZigTypeIdPointer &&
|
||||
handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type))
|
||||
handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type))
|
||||
{
|
||||
first_arg = first_arg_ptr;
|
||||
} else {
|
||||
|
@ -19504,7 +19515,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
}
|
||||
|
||||
IrInstGen *result_loc;
|
||||
if (handle_is_ptr(return_type)) {
|
||||
if (handle_is_ptr(ira->codegen, return_type)) {
|
||||
result_loc = ir_resolve_result(ira, source_instr, call_result_loc,
|
||||
return_type, nullptr, true, false);
|
||||
if (result_loc != nullptr) {
|
||||
|
@ -19521,7 +19532,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||
if (res_child_type == ira->codegen->builtin_types.entry_var) {
|
||||
res_child_type = return_type;
|
||||
}
|
||||
if (!handle_is_ptr(res_child_type)) {
|
||||
if (!handle_is_ptr(ira->codegen, res_child_type)) {
|
||||
ir_reset_result(call_result_loc);
|
||||
result_loc = nullptr;
|
||||
}
|
||||
|
@ -23346,7 +23357,7 @@ static TypeStructField *validate_byte_offset(IrAnalyze *ira,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!type_has_bits(field->type_entry)) {
|
||||
if (!type_has_bits(ira->codegen, field->type_entry)) {
|
||||
ir_add_error(ira, &field_name_value->base,
|
||||
buf_sprintf("zero-bit field '%s' in struct '%s' has no offset",
|
||||
buf_ptr(field_name), buf_ptr(&container_type->name)));
|
||||
|
@ -24264,7 +24275,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
|
|||
return ErrorSemanticAnalyzeFail;
|
||||
if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
|
||||
return err;
|
||||
if (!type_has_bits(struct_field->type_entry)) {
|
||||
if (!type_has_bits(ira->codegen, struct_field->type_entry)) {
|
||||
inner_fields[1]->data.x_optional = nullptr;
|
||||
} else {
|
||||
size_t byte_offset = struct_field->offset;
|
||||
|
@ -25077,7 +25088,7 @@ static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxch
|
|||
|
||||
ZigType *result_type = get_optional_type(ira->codegen, operand_type);
|
||||
IrInstGen *result_loc;
|
||||
if (handle_is_ptr(result_type)) {
|
||||
if (handle_is_ptr(ira->codegen, result_type)) {
|
||||
result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
|
||||
result_type, nullptr, true, true);
|
||||
if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
|
||||
|
@ -25396,8 +25407,11 @@ static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVe
|
|||
static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr,
|
||||
ZigType *scalar_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask)
|
||||
{
|
||||
Error err;
|
||||
ir_assert(source_instr && scalar_type && a && b && mask, source_instr);
|
||||
ir_assert(is_valid_vector_elem_type(scalar_type), source_instr);
|
||||
|
||||
if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, scalar_type)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
uint32_t len_mask;
|
||||
if (mask->value->type->id == ZigTypeIdVector) {
|
||||
|
@ -27364,7 +27378,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
|
|||
if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown)))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (type_has_bits(dest_type) && !type_has_bits(src_type) && safety_check_on) {
|
||||
if (type_has_bits(ira->codegen, dest_type) && !type_has_bits(ira->codegen, src_type) && safety_check_on) {
|
||||
ErrorMsg *msg = ir_add_error(ira, source_instr,
|
||||
buf_sprintf("'%s' and '%s' do not have the same in-memory representation",
|
||||
buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));
|
||||
|
@ -27423,7 +27437,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
|
|||
|
||||
// Keep the bigger alignment, it can only help-
|
||||
// unless the target is zero bits.
|
||||
if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) {
|
||||
if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) {
|
||||
result = ir_align_cast(ira, result, src_align_bytes, false);
|
||||
}
|
||||
|
||||
|
@ -27444,7 +27458,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
|
|||
// Keep the bigger alignment, it can only help-
|
||||
// unless the target is zero bits.
|
||||
IrInstGen *result;
|
||||
if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) {
|
||||
if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) {
|
||||
result = ir_align_cast(ira, casted_ptr, src_align_bytes, false);
|
||||
if (type_is_invalid(result->value->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
@ -27802,9 +27816,7 @@ static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
|
|||
Error err;
|
||||
|
||||
ZigType *src_type = value->value->type;
|
||||
ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr);
|
||||
ir_assert(type_can_bit_cast(src_type), source_instr);
|
||||
ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr);
|
||||
ir_assert(type_can_bit_cast(dest_type), source_instr);
|
||||
|
||||
if (dest_type->id == ZigTypeIdEnum) {
|
||||
|
@ -27863,7 +27875,7 @@ static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, Ir
|
|||
Error err;
|
||||
|
||||
ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr);
|
||||
ir_assert(type_has_bits(ptr_type), source_instr);
|
||||
ir_assert(type_has_bits(ira->codegen, ptr_type), source_instr);
|
||||
|
||||
IrInstGen *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize);
|
||||
if (type_is_invalid(casted_int->value->type))
|
||||
|
@ -27981,7 +27993,7 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr
|
|||
if (!val)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
// Since we've already run this type trough get_codegen_ptr_type it is
|
||||
// Since we've already run this type trough get_src_ptr_type it is
|
||||
// safe to access the x_ptr fields
|
||||
if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
|
||||
IrInstGen *result = ir_const(ira, &instruction->base.base, usize);
|
||||
|
@ -28232,10 +28244,17 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) {
|
|||
max_atomic_bits, (uint32_t) operand_type->data.floating.bit_count));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
} else if (get_codegen_ptr_type(operand_type) == nullptr) {
|
||||
ir_add_error(ira, &op->base,
|
||||
buf_sprintf("expected integer, float, enum or pointer type, found '%s'", buf_ptr(&operand_type->name)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
} else {
|
||||
Error err;
|
||||
ZigType *operand_ptr_type;
|
||||
if ((err = get_codegen_ptr_type(ira->codegen, operand_type, &operand_ptr_type)))
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
if (operand_ptr_type == nullptr) {
|
||||
ir_add_error(ira, &op->base,
|
||||
buf_sprintf("expected integer, float, enum or pointer type, found '%s'",
|
||||
buf_ptr(&operand_type->name)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
return operand_type;
|
||||
|
@ -28666,15 +28685,19 @@ static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *i
|
|||
if (type_is_invalid(uncasted_op->value->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
uint32_t vector_len; // UINT32_MAX means not a vector
|
||||
if (uncasted_op->value->type->id == ZigTypeIdArray &&
|
||||
is_valid_vector_elem_type(uncasted_op->value->type->data.array.child_type))
|
||||
{
|
||||
vector_len = uncasted_op->value->type->data.array.len;
|
||||
uint32_t vector_len = UINT32_MAX; // means not a vector
|
||||
if (uncasted_op->value->type->id == ZigTypeIdArray) {
|
||||
bool can_be_vec_elem;
|
||||
if ((err = is_valid_vector_elem_type(ira->codegen, uncasted_op->value->type->data.array.child_type,
|
||||
&can_be_vec_elem)))
|
||||
{
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
if (can_be_vec_elem) {
|
||||
vector_len = uncasted_op->value->type->data.array.len;
|
||||
}
|
||||
} else if (uncasted_op->value->type->id == ZigTypeIdVector) {
|
||||
vector_len = uncasted_op->value->type->data.vector.len;
|
||||
} else {
|
||||
vector_len = UINT32_MAX;
|
||||
}
|
||||
|
||||
bool is_vector = (vector_len != UINT32_MAX);
|
||||
|
@ -29075,7 +29098,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
|
|||
}
|
||||
|
||||
IrInstGen *result_loc;
|
||||
if (type_has_bits(result_type)) {
|
||||
if (type_has_bits(ira->codegen, result_type)) {
|
||||
result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
|
||||
result_type, nullptr, true, true);
|
||||
if (result_loc != nullptr &&
|
||||
|
@ -29125,7 +29148,7 @@ static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSp
|
|||
if (type_is_invalid(operand->value->type))
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (!type_has_bits(operand->value->type))
|
||||
if (!type_has_bits(ira->codegen, operand->value->type))
|
||||
return ir_const_void(ira, &instruction->base.base);
|
||||
|
||||
switch (instruction->spill_id) {
|
||||
|
@ -29145,7 +29168,7 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil
|
|||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) ||
|
||||
!type_has_bits(operand->value->type) ||
|
||||
!type_has_bits(ira->codegen, operand->value->type) ||
|
||||
instr_is_comptime(operand))
|
||||
{
|
||||
return operand;
|
||||
|
@ -30188,7 +30211,7 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
|||
if (align_bytes != 0) {
|
||||
if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown)))
|
||||
return err;
|
||||
if (!type_has_bits(elem_type))
|
||||
if (!type_has_bits(ira->codegen, elem_type))
|
||||
align_bytes = 0;
|
||||
}
|
||||
bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC;
|
||||
|
|
|
@ -786,3 +786,10 @@ test "cast between C pointer with different but compatible types" {
|
|||
};
|
||||
S.doTheTest();
|
||||
}
|
||||
|
||||
var global_struct: struct { f0: usize } = undefined;
|
||||
|
||||
test "assignment to optional pointer result loc" {
|
||||
var foo: struct { ptr: ?*c_void } = .{ .ptr = &global_struct };
|
||||
expect(foo.ptr.? == @ptrCast(*c_void, &global_struct));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue